[cdo] 81/84: New upstream 1.6.9

Alastair McKinstry mckinstry at moszumanska.debian.org
Sat Jun 13 16:48:47 UTC 2015


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

mckinstry pushed a commit to branch master
in repository cdo.

commit 2ea9ed4e48031fe12759e0803073495896190c75
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Wed Apr 29 12:07:40 2015 +0100

    New upstream 1.6.9
---
 ChangeLog                                          |    179 +-
 Makefile.in                                        |      6 +-
 NEWS                                               |     48 +-
 OPERATORS                                          |     30 +-
 README                                             |      2 +-
 aclocal.m4                                         |     60 +
 cdo.spec                                           |      2 +-
 config/ar-lib                                      |    270 +
 config/default                                     |     51 +-
 configure                                          |    641 +-
 configure.ac                                       |     19 +-
 contrib/Makefile.in                                |      1 +
 contrib/cdoCompletion.bash                         |     13 +
 contrib/cdoCompletion.tcsh                         |     13 +
 contrib/cdoCompletion.zsh                          |     13 +
 doc/cdo.pdf                                        |    Bin 1314332 -> 1455478 bytes
 doc/cdo_refcard.pdf                                |    Bin 96705 -> 97809 bytes
 libcdi/AUTHORS                                     |      2 +-
 libcdi/ChangeLog                                   |     66 +
 libcdi/Makefile.in                                 |     25 +-
 libcdi/NEWS                                        |      8 +
 libcdi/README                                      |      2 +-
 libcdi/acinclude.m4                                |      3 +
 libcdi/aclocal.m4                                  |      6 +
 libcdi/app/Makefile.in                             |     25 +-
 libcdi/app/cdi.c                                   |     26 +-
 libcdi/app/printinfo.h                             |     26 +-
 libcdi/cdi.settings.in                             |    129 +-
 libcdi/config/default                              |      8 +-
 libcdi/configure                                   |    792 +-
 libcdi/configure.ac                                |     70 +-
 libcdi/doc/cdi_cman.pdf                            |    Bin 333218 -> 332301 bytes
 libcdi/doc/cdi_fman.pdf                            |    Bin 361058 -> 360652 bytes
 libcdi/examples/Makefile.in                        |     25 +-
 libcdi/examples/cdi_read_f2003.f90                 |      2 +-
 libcdi/examples/pio/Makefile.am                    |     14 +-
 libcdi/examples/pio/Makefile.in                    |     44 +-
 libcdi/examples/pio/compareResourcesArray.c        |     19 +-
 libcdi/interfaces/Makefile.in                      |     25 +-
 libcdi/interfaces/cdi.hpp                          |      3 +-
 libcdi/interfaces/f2003/bindGen.rb                 |   1234 +-
 libcdi/interfaces/python/CdiObj.py                 |    704 +-
 libcdi/interfaces/python/cdiobj_wrap.cpp           |  21705 ++--
 libcdi/interfaces/python/testObj.py                |     42 +-
 libcdi/m4/ac_lang_program_fortran.m4               |     57 +
 libcdi/m4/acx_c_package.m4                         |     66 +
 libcdi/m4/acx_fortran_package.m4                   |    144 +
 ...od_path_flag.m4 => acx_lang_c_check_include.m4} |     62 +-
 libcdi/m4/acx_lang_check_include.m4                |    123 +
 ...h_flag.m4 => acx_lang_fortran_check_include.m4} |     66 +-
 libcdi/m4/acx_lang_package.m4                      |    134 +
 libcdi/m4/acx_option_search_libs.m4                |    128 +
 libcdi/m4/acx_options.m4                           |      1 +
 libcdi/m4/acx_sl_fc_mod_path_flag.m4               |     20 +-
 libcdi/m4/acx_sl_mod_suffix.m4                     |     11 +-
 .../{acx_sl_fc_mod_path_flag.m4 => asx_tr_arg.m4}  |     67 +-
 libcdi/m4/libtool.m4                               |      2 +
 libcdi/m4/starlink_fpp.m4                          |    135 +-
 libcdi/src/Makefile.am                             |     28 +-
 libcdi/src/Makefile.in                             |    775 +-
 libcdi/src/cdf.c                                   |      2 +-
 libcdi/src/cdf_int.c                               |      3 +-
 libcdi/src/cdf_int.h                               |      2 +-
 libcdi/src/cdi.h                                   |     88 +-
 libcdi/src/cdi.inc                                 |     47 +-
 libcdi/src/cdiFortran.c                            |     19 +-
 libcdi/src/cdi_int.c                               |      6 -
 libcdi/src/cdi_int.h                               |     14 +-
 libcdi/src/cdilib.c                                | 103742 +++++++++---------
 libcdi/src/cfortran.h                              |      2 +-
 libcdi/src/cgribexlib.c                            |    291 +-
 libcdi/src/config.h.in                             |     14 +
 libcdi/{tests => src}/create_uuid.h                |      0
 libcdi/src/dmemory.c                               |     51 +-
 libcdi/src/dmemory.h                               |      4 +
 libcdi/src/error.h                                 |      2 +-
 libcdi/src/gribapi.h                               |     15 +-
 libcdi/src/gribapi_utilities.c                     |    711 +
 libcdi/src/gribapi_utilities.h                     |     37 +
 libcdi/src/grid.c                                  |     76 +-
 libcdi/src/grid.h                                  |      9 +-
 libcdi/src/input_file.c                            |    141 +
 libcdi/src/input_file.h                            |     27 +
 libcdi/src/institution.c                           |      8 +-
 libcdi/src/iterator.c                              |    965 +
 libcdi/src/iterator.h                              |     48 +
 libcdi/src/iterator_fallback.c                     |    285 +
 libcdi/src/iterator_fallback.h                     |     41 +
 libcdi/src/iterator_grib.c                         |    815 +
 libcdi/src/iterator_grib.h                         |     48 +
 libcdi/src/mo_cdi.f90                              |  11646 +-
 libcdi/src/model.c                                 |      5 -
 libcdi/src/namespace.c                             |     25 +-
 libcdi/src/pio_interface.c                         |     44 +-
 libcdi/src/pio_server.c                            |     26 +-
 libcdi/src/pio_util.c                              |      2 +-
 libcdi/src/proprietarySystemWorkarounds.c          |     45 +
 libcdi/src/proprietarySystemWorkarounds.h          |      8 +
 libcdi/src/referenceCounting.c                     |     28 +
 libcdi/src/referenceCounting.h                     |     38 +
 libcdi/src/resource_handle.c                       |     25 +-
 libcdi/src/resource_handle.h                       |      4 +-
 libcdi/src/serialize.h                             |      4 +
 libcdi/src/servicelib.c                            |      3 +
 libcdi/src/stream.c                                |     16 +-
 libcdi/src/stream_cdf.c                            |    312 +-
 libcdi/src/stream_cgribex.c                        |     34 +-
 libcdi/src/stream_fcommon.h                        |      2 +
 libcdi/src/stream_gribapi.c                        |   1393 +-
 libcdi/src/stream_gribapi.h                        |      4 +
 libcdi/src/stream_record.c                         |     64 +-
 libcdi/src/stream_srv.c                            |     39 +-
 libcdi/src/table.c                                 |    108 +-
 libcdi/src/taxis.c                                 |     20 +-
 libcdi/src/util.c                                  |    136 +
 libcdi/src/varscan.c                               |    228 +-
 libcdi/src/vlist.c                                 |    424 +-
 libcdi/src/vlist.h                                 |      7 +-
 libcdi/src/vlist_var.c                             |     59 +-
 libcdi/src/zaxis.c                                 |     55 +-
 libcdi/src/zaxis.h                                 |     10 +
 libcdi/tests/Makefile.am                           |     23 +-
 libcdi/tests/Makefile.in                           |     81 +-
 libcdi/tests/create_uuid.c                         |     91 -
 libcdi/util/sunf95preproc-wrapper                  |      6 +-
 m4/._ax_pthread.m4                                 |    Bin 0 -> 197 bytes
 m4/acx_options.m4                                  |     23 +-
 src/Adisit.c                                       |     17 +-
 src/Afterburner.c                                  |   2414 +
 src/Arith.c                                        |      2 +-
 src/Arithc.c                                       |      4 +-
 src/Arithdays.c                                    |      2 +-
 src/Arithlat.c                                     |     15 +-
 src/CDIread.c                                      |      5 +-
 src/CDItest.c                                      |      4 +-
 src/CDIwrite.c                                     |     11 +-
 src/Cat.c                                          |      9 +-
 src/Change.c                                       |     18 +-
 src/Change_e5slm.c                                 |      2 +-
 src/Cloudlayer.c                                   |     35 +-
 src/Collgrid.c                                     |      2 +-
 src/Command.c                                      |      2 +-
 src/Comp.c                                         |      2 +-
 src/Compc.c                                        |      4 +-
 src/Complextorect.c                                |      2 +-
 src/Cond.c                                         |      2 +-
 src/Cond2.c                                        |      2 +-
 src/Condc.c                                        |      4 +-
 src/Consecstat.c                                   |      4 +-
 src/Copy.c                                         |      2 +-
 src/Deltime.c                                      |      2 +-
 src/Derivepar.c                                    |    199 +-
 src/Detrend.c                                      |     36 +-
 src/Diff.c                                         |      4 +-
 src/Distgrid.c                                     |     12 +-
 src/Duplicate.c                                    |      4 +-
 src/EOFs.c                                         |    963 +-
 src/EcaIndices.c                                   |     42 +-
 src/Echam5ini.c                                    |      2 +-
 src/Enlarge.c                                      |      2 +-
 src/Enlargegrid.c                                  |      2 +-
 src/Ensstat.c                                      |    123 +-
 src/Ensstat3.c                                     |      4 +-
 src/Ensval.c                                       |      4 +-
 src/Eof3d.c                                        |    404 +-
 src/Eofcoeff.c                                     |      2 +-
 src/Eofcoeff3d.c                                   |      2 +-
 src/Exprf.c                                        |     54 +-
 src/FC.c                                           |      2 +-
 src/Filedes.c                                      |      6 +-
 src/Fillmiss.c                                     |      2 +-
 src/Filter.c                                       |     88 +-
 src/Fldrms.c                                       |      2 +-
 src/Fldstat.c                                      |     93 +-
 src/Fldstat2.c                                     |      2 +-
 src/Fourier.c                                      |      4 +-
 src/Gengrid.c                                      |      2 +-
 src/Gradsdes.c                                     |    137 +-
 src/Gridboxstat.c                                  |    357 +-
 src/Gridcell.c                                     |     24 +-
 src/Gridsearch.c                                   |      2 +-
 src/Harmonic.c                                     |      6 +-
 src/Hi.c                                           |      0
 src/Histogram.c                                    |      2 +-
 src/Importamsr.c                                   |      5 +-
 src/Importbinary.c                                 |     10 +-
 src/Importcmsaf.c                                  |      2 +-
 src/Importobs.c                                    |      5 +-
 src/Info.c                                         |     39 +-
 src/Input.c                                        |      6 +-
 src/Intgrid.c                                      |     10 +-
 src/Intgridtraj.c                                  |      2 +-
 src/Intlevel.c                                     |     48 +-
 src/Intlevel3d.c                                   |    209 +-
 src/Intntime.c                                     |      4 +-
 src/Inttime.c                                      |      2 +-
 src/Intyear.c                                      |      2 +-
 src/Invert.c                                       |     55 +-
 src/Invertlev.c                                    |     53 +-
 src/Isosurface.c                                   |      4 +-
 src/Kvl.c                                          |      2 +-
 src/Log.c                                          |     17 +-
 src/Makefile.am                                    |    294 +-
 src/Makefile.in                                    |   2299 +-
 src/Maskbox.c                                      |      2 +-
 src/Mastrfu.c                                      |     63 +-
 src/Math.c                                         |      4 +-
 src/Merge.c                                        |     53 +-
 src/Mergegrid.c                                    |      5 +-
 src/Mergetime.c                                    |      2 +-
 src/Merstat.c                                      |      4 +-
 src/Monarith.c                                     |      2 +-
 src/Mrotuv.c                                       |      2 +-
 src/Mrotuvb.c                                      |      2 +-
 src/Ninfo.c                                        |      2 +-
 src/Nmltest.c                                      |      2 +-
 src/Output.c                                       |     10 +-
 src/Outputgmt.c                                    |      4 +-
 src/Pack.c                                         |     33 +-
 src/Pinfo.c                                        |      4 +-
 src/Pressure.c                                     |     69 +-
 src/Regres.c                                       |      2 +-
 src/Remap.c                                        |     85 +-
 src/Remapeta.c                                     |    143 +-
 src/Replace.c                                      |      2 +-
 src/Replacevalues.c                                |     28 +-
 src/Rhopot.c                                       |     24 +-
 src/Rotuv.c                                        |      4 +-
 src/Runpctl.c                                      |     71 +-
 src/Runstat.c                                      |    209 +-
 src/SSOpar.c                                       |     76 +-
 src/Seaspctl.c                                     |     76 +-
 src/Seasstat.c                                     |     74 +-
 src/Selbox.c                                       |     26 +-
 src/Select.c                                       |    179 +-
 src/Seloperator.c                                  |      8 +-
 src/Selrec.c                                       |      2 +-
 src/Seltime.c                                      |    156 +-
 src/Selvar.c                                       |    218 +-
 src/Set.c                                          |      8 +-
 src/Setbox.c                                       |      4 +-
 src/Setgatt.c                                      |      2 +-
 src/Setgrid.c                                      |     18 +-
 src/Sethalo.c                                      |      6 +-
 src/Setmiss.c                                      |     67 +-
 src/Setpartab.c                                    |    201 +-
 src/Setrcaname.c                                   |      2 +-
 src/Settime.c                                      |     77 +-
 src/Setzaxis.c                                     |    108 +-
 src/Showinfo.c                                     |      9 +-
 src/Sinfo.c                                        |     15 +-
 src/Smooth9.c                                      |      5 +-
 src/Sort.c                                         |      4 +-
 src/Sorttimestamp.c                                |      2 +-
 src/Specinfo.c                                     |      4 +-
 src/Spectral.c                                     |      4 +-
 src/Spectrum.c                                     |     10 +-
 src/Split.c                                        |     96 +-
 src/Splitrec.c                                     |      2 +-
 src/Splitsel.c                                     |     14 +-
 src/Splittime.c                                    |     51 +-
 src/Splityear.c                                    |    105 +-
 src/Subtrend.c                                     |      2 +-
 src/Tee.c                                          |      2 +-
 src/Templates.c                                    |      2 +-
 src/Test.c                                         |      2 +-
 src/Tests.c                                        |     12 +-
 src/Timpctl.c                                      |     80 +-
 src/Timselpctl.c                                   |    125 +-
 src/Timselstat.c                                   |     98 +-
 src/Timsort.c                                      |      2 +-
 src/Timstat.c                                      |    142 +-
 src/Timstat2.c                                     |     58 +-
 src/Timstat3.c                                     |     44 +-
 src/Tinfo.c                                        |      2 +-
 src/Tocomplex.c                                    |      2 +-
 src/Transpose.c                                    |      2 +-
 src/Trend.c                                        |      2 +-
 src/Trms.c                                         |      2 +-
 src/Tstepcount.c                                   |      4 +-
 src/Vardup.c                                       |      4 +-
 src/Vargen.c                                       |     19 +-
 src/Varrms.c                                       |      2 +-
 src/Vertintap.c                                    |    464 +
 src/{Vertint.c => Vertintml.c}                     |    191 +-
 src/Vertstat.c                                     |    281 +-
 src/Vertwind.c                                     |     35 +-
 src/Wct.c                                          |      0
 src/Wind.c                                         |      2 +-
 src/Writegrid.c                                    |      2 +-
 src/Writerandom.c                                  |      2 +-
 src/YAR.c                                          |     43 +-
 src/Ydayarith.c                                    |      2 +-
 src/Ydaypctl.c                                     |      2 +-
 src/Ydaystat.c                                     |      2 +-
 src/Ydrunpctl.c                                    |     86 +-
 src/Ydrunstat.c                                    |     57 +-
 src/Yearmonstat.c                                  |     78 +-
 src/Yhourarith.c                                   |      2 +-
 src/Yhourstat.c                                    |      2 +-
 src/Ymonarith.c                                    |    112 +-
 src/Ymonpctl.c                                     |      2 +-
 src/Ymonstat.c                                     |      2 +-
 src/Yseaspctl.c                                    |      2 +-
 src/Yseasstat.c                                    |      2 +-
 src/Zonstat.c                                      |      8 +-
 src/after_dvtrans.c                                |    256 +
 src/{fouriertrans.c => after_fctrans.c}            |    188 +-
 src/after_namelist.c                               |    141 +
 src/{legendre.c => after_sptrans.c}                |    230 +-
 src/after_vertint.c                                |    665 +
 src/{vinterp.h => after_vertint.h}                 |     10 +-
 src/afterburner.h                                  |    260 +
 src/afterburnerlib.c                               |   2946 +
 src/cdo.c                                          |   1328 +-
 src/cdo.h                                          |     62 +-
 src/cdo_getopt.c                                   |     10 +-
 src/cdo_getopt.h                                   |      2 +-
 src/{history.c => cdo_history.c}                   |      7 +-
 src/cdo_int.h                                      |     81 +-
 src/cdo_pthread.c                                  |      2 +-
 src/cdo_vlist.c                                    |     36 +-
 src/clipping/area.c                                |    158 +-
 src/clipping/area.h                                |     44 +-
 src/clipping/clipping.c                            |    138 +-
 src/clipping/clipping.h                            |     40 +-
 src/clipping/dep_list.h                            |     54 +-
 src/clipping/ensure_array_size.c                   |      4 +-
 src/clipping/ensure_array_size.h                   |      8 +-
 src/clipping/geometry.h                            |    156 +-
 src/clipping/geometry_tools.c                      |     39 -
 src/clipping/grid.h                                |    156 +-
 src/clipping/grid_cell.c                           |    113 +-
 src/clipping/grid_cell.h                           |     22 +-
 src/clipping/intersection.c                        |    135 +-
 src/clipping/points.h                              |     24 +-
 src/clipping/utils.c                               |     12 +-
 src/clipping/utils.h                               |     20 +-
 src/commandline.c                                  |      2 +-
 src/compare.h                                      |     53 +
 src/config.h.in                                    |     32 +
 src/constants.c                                    |      5 +
 src/constants.h                                    |     39 +
 src/datetime.c                                     |    258 +
 src/datetime.h                                     |     63 +
 src/ecacore.c                                      |      3 +-
 src/ecautil.c                                      |      0
 src/expr.c                                         |    637 +-
 src/expr_lex.c                                     |    223 +-
 src/expr_yacc.c                                    |    369 +-
 src/expr_yacc.h                                    |     14 +-
 src/features.c                                     |     11 +
 src/field.c                                        |      2 +-
 src/field.h                                        |      2 +-
 src/field2.c                                       |      2 +-
 src/fieldc.c                                       |      2 +-
 src/fieldmer.c                                     |      2 +-
 src/fieldzon.c                                     |      2 +-
 src/gradsdeslib.c                                  |   1480 +-
 src/gradsdeslib.h                                  |     18 +-
 src/grid.c                                         |     10 +-
 src/grid_area.c                                    |     33 +-
 src/griddes.c                                      |    176 +-
 src/gridreference.c                                |      3 +-
 src/institution.c                                  |      4 +-
 src/interpol.c                                     |      4 +-
 src/kvlist.c                                       |      2 +-
 src/kvlist.h                                       |      2 +-
 src/list.c                                         |     12 +-
 src/list.h                                         |      2 +-
 src/modules.c                                      |     29 +-
 src/modules.h                                      |      2 +-
 src/namelist.c                                     |      2 +-
 src/namelist.h                                     |      2 +-
 src/operator_help.h                                |    589 +-
 src/pipe.c                                         |      2 +-
 src/pipe.h                                         |      2 +-
 src/printinfo.h                                    |     30 +-
 src/process.c                                      |    380 +-
 src/process.h                                      |      2 +-
 src/pstream.c                                      |     23 +-
 src/pstream.h                                      |     18 +-
 src/pstream_int.h                                  |      2 +-
 src/pstream_write.h                                |     45 +
 src/readline.c                                     |      2 +-
 src/remap.h                                        |      8 +-
 src/remap_bicubic_scrip.c                          |    230 +-
 src/remap_bilinear_scrip.c                         |    168 +-
 src/remap_conserv.c                                |    255 +-
 src/remap_conserv_scrip.c                          |    218 +-
 src/remap_distwgt_scrip.c                          |    163 +-
 src/remap_scrip_io.c                               |     34 +-
 src/remap_search_latbins.c                         |     38 +-
 src/remap_store_link.c                             |    425 +-
 src/remap_store_link.h                             |     53 +-
 ...remap_store_link.c => remap_store_link_cnsrv.c} |     24 +-
 ...remap_store_link.h => remap_store_link_cnsrv.h} |      6 +-
 src/remaplib.c                                     |     70 +-
 src/specspace.c                                    |    549 +-
 src/specspace.h                                    |     16 +-
 src/statistic.c                                    |    162 +-
 src/statistic.h                                    |      5 +-
 src/stdnametable.c                                 |      2 +
 src/stdnametable.h                                 |      4 +-
 src/table.c                                        |      2 +-
 src/timer.c                                        |      2 +-
 src/util.c                                         |    364 +-
 src/util.h                                         |     94 +-
 src/vct_l191.h                                     |    388 +
 src/vinterp.c                                      |    427 -
 src/zaxis.c                                        |     66 +-
 test/Afterburner.test.in                           |    142 +
 test/Arith.test.in                                 |      2 +-
 test/File.test.in                                  |      2 +-
 test/Genweights.test.in                            |     16 +-
 test/Gradsdes.test.in                              |     52 +
 test/Makefile.am                                   |     24 +-
 test/Makefile.in                                   |     38 +-
 test/Remap.test.in                                 |     16 +-
 test/Select.test.in                                |      2 +-
 test/Spectral.test.in                              |      4 +
 test/data/._netcdf_testfile01.nc                   |    Bin 0 -> 197 bytes
 test/data/Makefile.am                              |      7 +-
 test/data/Makefile.in                              |      8 +-
 test/data/grib_testfile01.grb                      |    Bin 63264 -> 63264 bytes
 test/data/grib_testfile01_info_ref                 |     24 +-
 test/data/grib_testfile01_sinfo_ref                |      7 +-
 test/data/n16_dis_ref                              |    Bin 0 -> 8240 bytes
 test/data/n32_dis_ref                              |    Bin 0 -> 32816 bytes
 test/data/pl_data.ctl                              |     16 +
 test/data/pl_data.gmp                              |    Bin 0 -> 793 bytes
 test/wildcard.test.in                              |     69 +
 432 files changed, 100033 insertions(+), 79505 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 68d8a6b..238246d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,183 @@
-2014-12-11  Uwe Schulzweida
+2015-10-28  Uwe Schulzweida
+
+	* using CDI library version 1.6.9
+	* Version 1.6.9 released
+	* clipping: update to YAC version 1.0.3
+
+2015-04-23  Uwe Schulzweida
+
+	* ydrunpctl: does not work in combination with ydrunmin/ydrunmax (bug fix)
+
+2015-04-21  Uwe Schulzweida
+
+	* New operator: genlevelbounds - Generate level bounds
+	* Added option --reduce_dim to reduce dimension (Timstat, Fldstat)
+	* Ensstat: added support for different missing values (bug fix)
+
+2015-04-17  Uwe Schulzweida
+
+	* Select: added parameter date
+
+2015-04-16  Uwe Schulzweida
+
+	* Select: added parameter startdate, enddate
+
+2015-04-13  Karl-Hermann Wieners
+
+	* New operator: aexpr -  Evaluate expressions and append results
+	* New operator: aexprf  - Evaluate expression script and append results
+	* New operator: selzaxisname  - Select z-axes by name
+
+2015-04-10  Uwe Schulzweida
+
+	* New operator: after - ECHAM standard post processor
+
+2015-04-02  Uwe Schulzweida
+
+	* Seltime: abort if no timestep is seleced
+
+2015-03-27  Uwe Schulzweida
+
+	* Fldstat: added parameter noweights to use constant grid cell area weights
+	* expr: added support for operator ?:,&&,||
+
+2015-03-26  Uwe Schulzweida
+
+	* using CDI library version 1.6.8
+	* Version 1.6.8 released
+
+2015-03-25  Uwe Schulzweida
+
+	* expr: added support for operator ?: (short ifelse)
+	* eof, eof3d: use area weights instead of no weights
+	* vertmean, vertavg: changed to weighted means if layer bounds are available
+
+2015-03-23  Uwe Schulzweida
+
+	* expr: added support for operator ?: (short ifelse test version)
+
+2015-03-22  Uwe Schulzweida
+
+	* configure: check whether netCDF4/HDF5 is threadsafe
+
+2015-03-21  Uwe Schulzweida
+
+	* expr: added support for logical operator <=>
+
+2015-03-20  Uwe Schulzweida
+
+	* Remap: renamed env. variable CDO_REMAP_NORMALIZE_OPT to CDO_REMAP_NORM
+	* Remap: renamed env. variable CDO_REMAP_SEARCH_RADIUS to CDO_REMAP_RADIUS
+
+2015-03-19  Uwe Schulzweida
+
+	* remapycon:  correct weights only for norm_opt=fracarea
+
+2015-03-18  Uwe Schulzweida
+
+	* expr: added support for logical operators <, >, <=, >=, !=, ==
+
+2015-03-17  Uwe Schulzweida
+
+	* gradsdes: grib index file is empty (introduced in 1.6.7)
+
+2015-03-11  Uwe Schulzweida
+
+	* delname: added wildcard support
+	* wildcardmatch(): use fnmatch() if available
+	* eofspatial: removed scaling with grid cell area weights (bug fix)
+	* eoftime: removed scaling with grid cell area weights (bug fix)
+
+2015-03-10  Uwe Schulzweida
+
+	* ensSTAT: added optional parameter count to count the number of valid values
+
+2015-03-09  Uwe Schulzweida
+
+	* setpartabp, setpartabn: added optional parameter convert to convert the units
+
+2015-02-04  Uwe Schulzweida
+
+	* select: added wildcard support for parameter name and param
+	* selname: added wildcard support
+
+2015-01-31  Uwe Schulzweida
+
+	* changed remapnn test to remapdis
+
+2015-01-30  Uwe Schulzweida
+
+        * cdoGenFileSuffix: filter wildcard characters
+
+2015-01-27  Uwe Schulzweida
+
+	* remapnn: Segmentation fault for extrapolation of regular 2D source grids [Bug #5448]
+
+2015-01-21  Uwe Schulzweida
+
+	* New operator: splityearmon - Split in years and months
+
+2015-01-20  Uwe Schulzweida
+
+	* remap: replaced critical section with store_link() by store_weightlinks()
+
+2015-01-06  Uwe Schulzweida
+
+	* intersection: use function sqrt(x) if sqrtl(x) is missing
+
+2015-01-05  Uwe Schulzweida
+
+	* New operator: yseasadd - Add multi-year seasonal time series
+	* New operator: yseassub - Subtract multi-year seasonal time series
+	* New operator: yseasmul - Multiply multi-year seasonal time series
+	* New operator: yseasdiv - Divide multi-year seasonal time series
+
+2014-12-26  Uwe Schulzweida
+
+	* sinfo: limit length of model and institute to CDI_MAX_NAME (bug fix)
+
+2014-12-19  Uwe Schulzweida
+
+	* Seaspctl: changed timestat_date to mean
+	* Seaspctl: added support for env. CDO_TIMESTAT_DATE
+	* Seasstat: changed timestat_date to mean
+	* Timpctl: changed timestat_date to mean
+	* Timpctl: added support for env. CDO_TIMESTAT_DATE
+	* Timstat: changed timestat_date to mean
+
+2014-12-18  Uwe Schulzweida
+
+	* Timselpctl: changed timestat_date to mean
+	* Timselpctl: added support for env. CDO_TIMESTAT_DATE
+	* Timselpctl: last output time step is written two times (bug fix)
+	* Timselstat: changed timestat_date to mean
+
+2014-12-16  Uwe Schulzweida
+
+	* intlevel3d: works only for regular grids, grid coordinate check disabled (bug fix)
+
+2014-12-15  Uwe Schulzweida
+
+	* Seasstat: added support for env. CDO_TIMESTAT_DATE
+	* Timselstat: added support for env. CDO_TIMESTAT_DATE
+
+2014-12-14  Uwe Schulzweida
+
+	* Timstat: added support for env. CDO_TIMESTAT_DATE
+
+2014-12-13  Uwe Schulzweida
+
+	* Runstat: added time bounds
+
+2014-12-12  Uwe Schulzweida
 
 	* using CDI library version 1.6.7
 	* Version 1.6.7 released
 
+2014-12-11  Uwe Schulzweida
+
+	* intlevel3d: does not work (bug fix)
+
 2014-12-03  Uwe Schulzweida
 
 	* added File.test.in to test all file formats
@@ -2038,7 +2213,7 @@
 	* pstream: add function pstreamInqFiletype
 	* Reduced grids: read/write record if -R is used
 	* Version 0.9.5 released
-	
+
 2005-01-03  Uwe Schulzweida
 
 	* using CDI library version 0.8.7
diff --git a/Makefile.in b/Makefile.in
index f788090..1d1ead8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -82,10 +82,11 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/configure $(am__configure_deps) \
 	$(top_srcdir)/config/mkinstalldirs $(srcdir)/cdo.spec.in \
 	$(srcdir)/cdo.settings.in AUTHORS COPYING ChangeLog INSTALL \
-	NEWS README config/compile config/config.guess \
+	NEWS README config/ar-lib config/compile config/config.guess \
 	config/config.sub config/depcomp config/install-sh \
 	config/missing config/mkinstalldirs config/ltmain.sh \
-	$(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \
+	$(top_srcdir)/config/ar-lib $(top_srcdir)/config/compile \
+	$(top_srcdir)/config/config.guess \
 	$(top_srcdir)/config/config.sub \
 	$(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \
 	$(top_srcdir)/config/missing \
@@ -244,6 +245,7 @@ ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
 ENABLE_IEG = @ENABLE_IEG@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
+ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
 ENABLE_NETCDF = @ENABLE_NETCDF@
 ENABLE_SERVICE = @ENABLE_SERVICE@
 EXEEXT = @EXEEXT@
diff --git a/NEWS b/NEWS
index 0776c46..9aedde5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,55 @@
 CDO NEWS
 --------
 
-Version 1.6.7 (11 December 2014):
+Version 1.6.9 (28 April 2015):
+
+   New features:
+     * select: added parameter date, startdate, enddate 
+     * expr: added support for operator ?:,&&,||
+     * option --reduce_dim: reduce dimension (Timstat, Fldstat)
+   New operators:
+     * after: ECHAM standard post processor
+     * aexpr: Evaluate expressions and append results
+     * aexprf: Evaluate expression script and append results
+     * selzaxisname: Select z-axes by name
+     * genlevelbounds: Generate level bounds
+   Fixed bugs:
+     * ydrunpctl: does not work in combination with ydrunmin/ydrunmax
+     * Ensstat: added support for different missing values
+     * seltimestep: abort if none of the selected timesteps are found
+
+Version 1.6.8 (26 March 2015):
+
+   New features:
+     * select, delete: added wildcard support for parameter name
+     * expr: added support for logical operators <, >, <=, >=, !=, ==, <=>
+   New operators:
+     * splityearmon: Split in years and months
+     * yseasadd: Add multi-year seasonal time series
+     * yseassub: Subtract multi-year seasonal time series
+     * yseasmul: Multiply multi-year seasonal time series
+     * yseasdiv: Divide multi-year seasonal time series
+   Changed operators:
+     * vertmean, vertavg: changed to weighted means if layer bounds are available
+     * setpartabp, setpartabn: added optional parameter convert to convert the units.
+       Units are not converted anymore if this parameter is not set!
+     * TimSTAT, Timpctl, TimselSTAT, Timselpctl, SeasSTAT, Seaspctl:
+       The output time stamp of all operators from the above modules
+       are changed from the last to the middle contributing timestep.
+       Use the environment variable CDO_TIMESTAT_DATE=last to set
+       the output time stamp to the last contributing timestep.
+     * eof, eof3d: use area weights instead of no weights
+       Use the environment variable CDO_WEIGHT_MODE=off to switch back to
+       the non weighted version
+   Fixed bugs:
+     * gradsdes: grib index file is empty (introduced in 1.6.7)
+     * grib2 output: segfaults when writing grib2 files [Bug #5351]
+     * remapnn: Segmentation fault for extrapolation of regular 2D source grids [Bug #5448]
+
+Version 1.6.7 (12 December 2014):
 
    Fixed bugs:
+     * intlevel3d: does not work
      * GRIB_API: segfaults when writing grib2 files [Bug #5351]
 
 Version 1.6.6 (27 November 2014):
diff --git a/OPERATORS b/OPERATORS
index 66e4230..8594c75 100644
--- a/OPERATORS
+++ b/OPERATORS
@@ -46,7 +46,7 @@ Operator catalog:
    Merge         merge           Merge datasets with different fields
    Merge         mergetime       Merge datasets sorted by date and time
    Split         splitcode       Split code numbers
-   Split         splitparam      Split parammeter identifiers
+   Split         splitparam      Split parameter identifiers
    Split         splitname       Split variable names
    Split         splitlevel      Split levels
    Split         splitgrid       Split grids
@@ -56,6 +56,7 @@ Operator catalog:
    Splittime     splitday        Split days
    Splittime     splitseas       Split seasons
    Splittime     splityear       Split years
+   Splittime     splityearmon    Split in years and months
    Splittime     splitmon        Split months
    Splitsel      splitsel        Split time selection
    Distgrid      distgrid        Distribute horizontal grid
@@ -76,6 +77,7 @@ Operator catalog:
    Selvar        sellevidx       Select levels by index
    Selvar        selgrid         Select grids
    Selvar        selzaxis        Select z-axes
+   Selvar        selzaxisname    Select z-axes by name
    Selvar        selltype        Select GRIB level types
    Selvar        seltabnum       Select parameter table numbers
    Seltime       seltimestep     Select timesteps
@@ -145,6 +147,7 @@ Operator catalog:
    Setgrid       setgridtype     Set grid type
    Setgrid       setgridarea     Set grid cell area
    Setzaxis      setzaxis        Set z-axis
+   Setzaxis      genlevelbounds  Generate level bounds
    Setgatt       setgatt         Set global attribute
    Setgatt       setgatts        Set global attributes
    Invert        invertlat       Invert latitudes
@@ -164,7 +167,9 @@ Operator catalog:
    Arithmetic
 -------------------------------------------------------------
    Exprf         expr            Evaluate expressions
-   Exprf         exprf           Evaluate expressions from script file
+   Exprf         exprf           Evaluate expressions script
+   Exprf         aexpr           Evaluate expressions and append results
+   Exprf         aexprf          Evaluate expression script and append results
    Math          abs             Absolute value
    Math          int             Integer value
    Math          nint            Nearest integer value
@@ -195,18 +200,22 @@ Operator catalog:
    Monarith      monsub          Subtract monthly time series
    Monarith      monmul          Multiply monthly time series
    Monarith      mondiv          Divide monthly time series
-   Ymonarith     ymonadd         Add multi-year monthly time series
-   Ymonarith     ymonsub         Subtract multi-year monthly time series
-   Ymonarith     ymonmul         Multiply multi-year monthly time series
-   Ymonarith     ymondiv         Divide multi-year monthly time series
-   Ydayarith     ydayadd         Add multi-year daily time series
-   Ydayarith     ydaysub         Subtract multi-year daily time series
-   Ydayarith     ydaymul         Multiply multi-year daily time series
-   Ydayarith     ydaydiv         Divide multi-year daily time series
    Yhourarith    yhouradd        Add multi-year hourly time series
    Yhourarith    yhoursub        Subtract multi-year hourly time series
    Yhourarith    yhourmul        Multiply multi-year hourly time series
    Yhourarith    yhourdiv        Divide multi-year hourly time series
+   Ydayarith     ydayadd         Add multi-year daily time series
+   Ydayarith     ydaysub         Subtract multi-year daily time series
+   Ydayarith     ydaymul         Multiply multi-year daily time series
+   Ydayarith     ydaydiv         Divide multi-year daily time series
+   Ymonarith     ymonadd         Add multi-year monthly time series
+   Ymonarith     ymonsub         Subtract multi-year monthly time series
+   Ymonarith     ymonmul         Multiply multi-year monthly time series
+   Ymonarith     ymondiv         Divide multi-year monthly time series
+   Yseasarith    yseasadd        Add multi-year seasonal time series
+   Yseasarith    yseassub        Subtract multi-year seasonal time series
+   Yseasarith    yseasmul        Multiply multi-year seasonal time series
+   Yseasarith    yseasdiv        Divide multi-year seasonal time series
    Arithdays     muldpm          Multiply with days per month
    Arithdays     divdpm          Divide by days per month
    Arithdays     muldpy          Multiply with days per year
@@ -478,6 +487,7 @@ Operator catalog:
    Miscellaneous
 -------------------------------------------------------------
    Gradsdes      gradsdes        GrADS data descriptor file
+   Afterburner   after           ECHAM standard post processor
    Filter        bandpass        Bandpass filtering
    Filter        lowpass         Lowpass filtering
    Filter        highpass        Highpass filtering
diff --git a/README b/README
index e10a6dd..4d385ea 100644
--- a/README
+++ b/README
@@ -70,4 +70,4 @@ Porting:
      
 Contact:
 
-     Send questions, comments and bug reports to <https://code.zmaw.de/projects/cdo>
+     Send questions, comments and bug reports to <http://mpimet.mpg.de/cdo>
diff --git a/aclocal.m4 b/aclocal.m4
index 2ed0cb7..9580d75 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -56,6 +56,66 @@ m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [AC_LANG_PUSH([C])
+   am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   AC_LANG_POP([C])])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
 # Copyright (C) 2001-2013 Free Software Foundation, Inc.
diff --git a/cdo.spec b/cdo.spec
index a6f0d96..68401e9 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.6.7
+Version:        1.6.9
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/config/ar-lib b/config/ar-lib
new file mode 100755
index 0000000..fe2301e
--- /dev/null
+++ b/config/ar-lib
@@ -0,0 +1,270 @@
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2013 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda at lysator.liu.se>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+
+# func_error message
+func_error ()
+{
+  echo "$me: $1" 1>&2
+  exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv in
+	mingw)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+  operation=$2
+  archive=$3
+  at_file_contents=`cat "$1"`
+  eval set x "$at_file_contents"
+  shift
+
+  for member
+  do
+    $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+  done
+}
+
+case $1 in
+  '')
+     func_error "no command.  Try '$0 --help' for more information."
+     ;;
+  -h | --h*)
+    cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "$me, version $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test $# -lt 3; then
+  func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+  if test $# -lt 2; then
+    func_error "you must specify a program, an action and an archive"
+  fi
+  case $1 in
+    -lib | -LIB \
+    | -ltcg | -LTCG \
+    | -machine* | -MACHINE* \
+    | -subsystem* | -SUBSYSTEM* \
+    | -verbose | -VERBOSE \
+    | -wx* | -WX* )
+      AR="$AR $1"
+      shift
+      ;;
+    *)
+      action=$1
+      shift
+      break
+      ;;
+  esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+  case $action in
+    d*) delete=yes  ;;
+    x*) extract=yes ;;
+    t*) list=yes    ;;
+    q*) quick=yes   ;;
+    r*) replace=yes ;;
+    s*) index=yes   ;;
+    S*)             ;; # the index is always updated implicitly
+    c*) create=yes  ;;
+    u*)             ;; # TODO: don't ignore the update modifier
+    v*)             ;; # TODO: don't ignore the verbose modifier
+    *)
+      func_error "unknown action specified"
+      ;;
+  esac
+  action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+  yes,* | ,yes)
+    ;;
+  yesyes*)
+    func_error "more than one action specified"
+    ;;
+  *)
+    func_error "no action specified"
+    ;;
+esac
+
+if test -n "$delete"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  for member
+  do
+    case $1 in
+      @*)
+        func_at_file "${1#@}" -REMOVE "$archive"
+        ;;
+      *)
+        func_file_conv "$1"
+        $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+        ;;
+    esac
+  done
+
+elif test -n "$extract"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  if test $# -gt 0; then
+    for member
+    do
+      case $1 in
+        @*)
+          func_at_file "${1#@}" -EXTRACT "$archive"
+          ;;
+        *)
+          func_file_conv "$1"
+          $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+          ;;
+      esac
+    done
+  else
+    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+    do
+      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+    done
+  fi
+
+elif test -n "$quick$replace"; then
+  if test ! -f "$orig_archive"; then
+    if test -z "$create"; then
+      echo "$me: creating $orig_archive"
+    fi
+    orig_archive=
+  else
+    orig_archive=$archive
+  fi
+
+  for member
+  do
+    case $1 in
+    @*)
+      func_file_conv "${1#@}"
+      set x "$@" "@$file"
+      ;;
+    *)
+      func_file_conv "$1"
+      set x "$@" "$file"
+      ;;
+    esac
+    shift
+    shift
+  done
+
+  if test -n "$orig_archive"; then
+    $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+  else
+    $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+  fi
+
+elif test -n "$list"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  $AR -NOLOGO -LIST "$archive" || exit $?
+fi
diff --git a/config/default b/config/default
index 7de3ed3..beee417 100755
--- a/config/default
+++ b/config/default
@@ -43,7 +43,7 @@ case "${HOSTNAME}" in
 	  ${CONFPATH}configure  \
                     $CDOLIBS \
                     LIBS="-L/opt/local/lib -lopenjpeg" \
-	            CC=icc CFLAGS="-g -Wall -O3 -vec-report2 -march=native -fp-model source -fast-transcendentals"
+	            CC=icc CFLAGS="-g -Wall -O2 -vec-report2 -march=native -fp-model source -fast-transcendentals"
         elif  test "$COMP" = clang ; then
 	  ${CONFPATH}configure  \
                     $CDOLIBS \
@@ -60,28 +60,32 @@ case "${HOSTNAME}" in
         fi
 	;;
     hama*)
+#        CDOLIBS="--with-fftw3 \
+#                 --with-jasper=/opt/local \
+#                 --with-grib_api=$HOME/local/gribapi-1.13.0 \
+#                 --with-netcdf=/opt/local \
+#                 --with-hdf5=/opt/local \
+#                 --with-szlib=$HOME/local \
+#                 --with-proj=/opt/local \
+#                 --with-curl=/opt/local"
         CDOLIBS="--with-fftw3 \
-                 --with-jasper=/opt/local \
                  --with-grib_api=$HOME/local/gribapi-1.13.0 \
-                 --with-netcdf=/opt/local \
-                 --with-hdf5=/opt/local \
-                 --with-szlib=$HOME/local \
-                 --with-proj=/opt/local \
-                 --with-curl=/opt/local"
+                 --with-netcdf=$HOME/local \
+                 --with-hdf5=$HOME/local"
 
         if  test "$COMP" = icc ; then
 	  ${CONFPATH}configure --prefix=$HOME/local \
                     $CDOLIBS \
-	            CC=icc CFLAGS="-g -Wall -O3 -vec-report2 -march=native -openmp -fp-model source -fast-transcendentals"
+	            CC=icc CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native -openmp -fp-model source -fast-transcendentals"
         elif  test "$COMP" = clang ; then
 	  ${CONFPATH}configure  \
                     $CDOLIBS \
-	            CC=clang CFLAGS="-g -Wall -O3"
+	            CC=clang CFLAGS="-g -Wall -Ofast -march=native"
         else
 	  ${CONFPATH}configure --prefix=$HOME/local \
                     --enable-maintainer-mode \
                     $CDOLIBS \
-	            CC=gcc CFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fstack-protector"
+	            CC=gcc CFLAGS="-g -pipe -Wall -W -Wfloat-equal -pedantic -O3 -fstack-protector"
 #                    --with-libxml2=/usr \
 #                    --with-magics=/Users/m214003/local/Magics-2.18.14nio \
         fi
@@ -89,7 +93,7 @@ case "${HOSTNAME}" in
 # x86_64-squeeze-x64-linux
     thunder*)
         CDOLIBS="--with-jasper=/sw/squeeze-x64/jasper-1.900.1-static \
-                    --with-grib_api=/sw/squeeze-x64/grib_api-1.9.9-static \
+                    --with-grib_api=/sw/squeeze-x64/grib_api-1.13.0-static-gccsys \
                     --with-netcdf=/sw/squeeze-x64/netcdf-4.2-static \
                     --with-hdf5=/sw/squeeze-x64/hdf5-1.8.8-static \
                     --with-szlib=/sw/squeeze-x64/szip-2.1 \
@@ -98,36 +102,35 @@ case "${HOSTNAME}" in
 
         if  test "$COMP" = icc ; then
           ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/thunder \
-                    --enable-all-static \
                     --with-fftw3 \
                     $CDOLIBS \
-	            CC=icc CFLAGS="-g -Wall -O3 -vec-report2 -march=native -fp-model source -fast-transcendentals"
+	            CC=icc CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native -fp-model source -fast-transcendentals"
         elif  test "$COMP" = pgcc ; then
           ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/thunder \
-                    --enable-all-static \
                     $CDOLIBS \
 	            CC=pgcc CFLAGS="-g -fast"
 	else
           ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/thunder \
-                    --enable-all-static \
                     --with-fftw3 \
                     $CDOLIBS \
                     CC=gcc CFLAGS='-g -Wall -O3'
 	fi
 	;;
 # x86_64-unknown-linux-gnu
-    btlogin*)
-        CDOLIBS=""
-
+    btc*)
         if  test "$COMP" = icc ; then
           ${CONFPATH}configure --prefix=$HOME/local \
+                    --with-grib_api=/lustre/sw/rhel6-x64/grib_api/grib_api-1.13.0-intel15 \
+	            --with-netcdf=/lustre/sw/rhel6-x64/netcdf/netcdf_c-4.3.2-intel15 \
+                    --with-hdf5=/lustre/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-intel15 \
                     --with-fftw3 \
-                    $CDOLIBS \
-	            CC=icc CFLAGS="-g -Wall -O3 -vec-report2 -march=native -fp-model source -fast-transcendentals"
+	            CC=icc CFLAGS="-g -Wall -O2 -qopt-report=5 -xCORE-AVX2 -fp-model source -fast-transcendentals"
 	else
           ${CONFPATH}configure --prefix=$HOME/local \
+                    --with-grib_api=/lustre/sw/rhel6-x64/grib_api/grib_api-1.13.0-gcc48 \
+	            --with-netcdf=/lustre/sw/rhel6-x64/netcdf/netcdf_c-4.3.2-gcc48 \
+                    --with-hdf5=/lustre/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48 \
                     --with-fftw3 \
-                    $CDOLIBS \
                     CC=gcc CFLAGS='-g -Wall -O3 -march=native'
 	fi
 	;;
@@ -178,7 +181,7 @@ case "${HOSTNAME}" in
 	            --with-hdf5=/sw/etch-ia32/hdf5-1.8.4-threadsafe \
                     --with-zlib=/sw/etch-ia32/zlib-1.2.3 \
                     --with-szlib=/sw/etch-ia32/szip-2.1 \
-                    --with-proj=/sw/etch-ia32/proj-4.6.0 \
+                    --withroj=/sw/etch-ia32/proj-4.6.0 \
 	            --enable-all-static CC=icc CFLAGS="-g -fast -openmp" AR=xiar LD=xild
 #	            CC=gcc CFLAGS="-g -Wall -W -Wfloat-equal -pedantic -O2"
     ;;
@@ -217,7 +220,7 @@ case "${HOSTNAME}" in
                     --with-hdf5=/sw/centos58-x64/hdf5-1.8.10-patch1 \
                     --with-udunits2=/sw/centos58-x64/udunits-2.1.19 \
                     --with-jasper=/sw/centos58-x64/jasper-1.900.1 \
-                    --with-grib_api=/sw/centos58-x64/grib_api-1.9.0-static \
+                    --with-grib_api=/sw/centos58-x64/grib_api-1.12.3 \
                     --with-netcdf=/sw/centos58-x64/netcdf-4.2.1.1 \
                     --with-szlib=/sw/centos58-x64/szip-2.1 \
                     --with-zlib=/usr \
@@ -226,8 +229,6 @@ case "${HOSTNAME}" in
 # powerpc-ibm-aix5.3.0.0
     blizzard*)
 	${CONFPATH}configure --prefix=$HOME/local \
-                    --with-jasper=/sw/aix53/jasper-1.900.1 \
-                    --with-grib_api=/sw/aix61/grib_api-1.9.9 \
                     --with-netcdf=/sw/aix61/netcdf-4.2-threadsafe \
                     --with-hdf5=/sw/aix61/hdf5-1.8.8-threadsafe \
                     --with-szlib=/sw/aix61/szip-2.1-threadsafe \
diff --git a/configure b/configure
index eec326f..426a0fd 100755
--- a/configure
+++ b/configure
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdo 1.6.7.
+# Generated by GNU Autoconf 2.68 for cdo 1.6.9.
 #
-# Report bugs to <https://code.zmaw.de/projects/cdo>.
+# Report bugs to <http://mpimet.mpg.de/cdo>.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -247,10 +247,10 @@ fi
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf at gnu.org and
-$0: https://code.zmaw.de/projects/cdo about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
+$0: http://mpimet.mpg.de/cdo about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
   fi
   exit 1
 fi
@@ -570,9 +570,9 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdo'
 PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.6.7'
-PACKAGE_STRING='cdo 1.6.7'
-PACKAGE_BUGREPORT='https://code.zmaw.de/projects/cdo'
+PACKAGE_VERSION='1.6.9'
+PACKAGE_STRING='cdo 1.6.9'
+PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdo'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
@@ -657,6 +657,7 @@ JASPER_LIBS
 NETCDF_LIBS
 NETCDF_INCLUDE
 NETCDF_ROOT
+ENABLE_NC4HDF5
 ENABLE_NC4
 ENABLE_NC2
 ENABLE_NETCDF
@@ -695,8 +696,6 @@ NMEDIT
 DSYMUTIL
 MANIFEST_TOOL
 RANLIB
-ac_ct_AR
-AR
 DLLTOOL
 OBJDUMP
 LN_S
@@ -708,6 +707,7 @@ FGREP
 EGREP
 GREP
 SED
+LIBTOOL
 am__fastdepCC_FALSE
 am__fastdepCC_TRUE
 CCDEPMODE
@@ -725,7 +725,8 @@ CPPFLAGS
 LDFLAGS
 CFLAGS
 CC
-LIBTOOL
+ac_ct_AR
+AR
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
@@ -807,11 +808,11 @@ ac_user_opts='
 enable_option_checking
 enable_silent_rules
 enable_maintainer_mode
+enable_dependency_tracking
 enable_shared
 enable_static
 with_pic
 enable_fast_install
-enable_dependency_tracking
 with_gnu_ld
 with_sysroot
 enable_libtool_lock
@@ -1394,7 +1395,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cdo 1.6.7 to adapt to many kinds of systems.
+\`configure' configures cdo 1.6.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1464,7 +1465,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.6.7:";;
+     short | recursive ) echo "Configuration of cdo 1.6.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1477,14 +1478,14 @@ Optional Features:
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
                           sometimes confusing) to the casual installer
-  --enable-shared[=PKGS]  build shared libraries [default=yes]
-  --enable-static[=PKGS]  build static libraries [default=yes]
-  --enable-fast-install[=PKGS]
-                          optimize for fast installation [default=yes]
   --enable-dependency-tracking
                           do not reject slow dependency extractors
   --disable-dependency-tracking
                           speeds up one-time build
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --disable-openmp        do not use OpenMP
   --disable-largefile     omit support for large files
@@ -1555,7 +1556,7 @@ Some influential environment variables:
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <https://code.zmaw.de/projects/cdo>.
+Report bugs to <http://mpimet.mpg.de/cdo>.
 _ACEOF
 ac_status=$?
 fi
@@ -1618,7 +1619,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.6.7
+cdo configure 1.6.9
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2141,9 +2142,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------------ ##
-## Report this to https://code.zmaw.de/projects/cdo ##
-## ------------------------------------------------ ##"
+( $as_echo "## --------------------------------------- ##
+## Report this to http://mpimet.mpg.de/cdo ##
+## --------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -2211,7 +2212,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cdo $as_me 1.6.7, which was
+It was created by cdo $as_me 1.6.9, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2563,6 +2564,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
+
+cat >>confdefs.h <<_ACEOF
+#define CDO "$PACKAGE_VERSION"
+_ACEOF
+
+
 CONFIG_ABORT=yes
 ac_aux_dir=
 for ac_dir in config "$srcdir"/config; do
@@ -3154,7 +3161,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.6.7'
+ VERSION='1.6.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3273,102 +3280,6 @@ fi
 
 
 # Set up libtool.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: setting up libtool" >&5
-$as_echo "$as_me: setting up libtool" >&6;}
-case `pwd` in
-  *\ * | *\	*)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
-$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
-esac
-
-
-
-macro_version='2.4.2'
-macro_revision='1.3337'
-
-
-
-
-
-
-
-
-
-
-
-
-
-ltmain="$ac_aux_dir/ltmain.sh"
-
-# Backslashify metacharacters that are still active within
-# double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
-ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
-$as_echo_n "checking how to print strings... " >&6; }
-# Test print first, because it will be a builtin if present.
-if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
-   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
-  ECHO='print -r --'
-elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
-  ECHO='printf %s\n'
-else
-  # Use this function as a fallback that always works.
-  func_fallback_echo ()
-  {
-    eval 'cat <<_LTECHO_EOF
-$1
-_LTECHO_EOF'
-  }
-  ECHO='func_fallback_echo'
-fi
-
-# func_echo_all arg...
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
-    $ECHO ""
-}
-
-case "$ECHO" in
-  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
-$as_echo "printf" >&6; } ;;
-  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
-$as_echo "print -r" >&6; } ;;
-  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
-$as_echo "cat" >&6; } ;;
-esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
@@ -4409,6 +4320,275 @@ else
 fi
 
 
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: setting up libtool" >&5
+$as_echo "$as_me: setting up libtool" >&6;}
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
 $as_echo_n "checking for a sed that does not truncate output... " >&6; }
 if ${ac_cv_path_SED+:} false; then :
@@ -5834,7 +6014,6 @@ test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
 
 
 
-
 if test -n "$ac_tool_prefix"; then
   for ac_prog in ar
   do
@@ -12098,6 +12277,52 @@ fi
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_restrict=no
+   # The order here caters to the fact that C++ does not require restrict.
+   for ac_kw in __restrict __restrict__ _Restrict restrict; do
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+typedef int * int_ptr;
+	int foo (int_ptr $ac_kw ip) {
+	return ip[0];
+       }
+int
+main ()
+{
+int s[1];
+	int * $ac_kw t = s;
+	t[0] = 0;
+	return foo(t)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+     test "$ac_cv_c_restrict" != no && break
+   done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+   restrict) ;;
+   no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+   *)  cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
 
   OPENMP_CFLAGS=
   # Check whether --enable-openmp was given.
@@ -17183,6 +17408,30 @@ fi
 
 done
 
+for ac_header in fnmatch.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default"
+if test "x$ac_cv_header_fnmatch_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FNMATCH_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in wordexp.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "wordexp.h" "ac_cv_header_wordexp_h" "$ac_includes_default"
+if test "x$ac_cv_header_wordexp_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WORDEXP_H 1
+_ACEOF
+
+fi
+
+done
+
 #  ----------------------------------------------------------------------
 # Checks for the availability of functions
 for ac_func in mallinfo
@@ -17198,19 +17447,6 @@ done
 
 #  ----------------------------------------------------------------------
 # Checks for the availability of ANSI-C99 functions
-ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "$ac_includes_default
-#include <math.h>
-"
-if test "x$ac_cv_have_decl_isnan" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ISNAN $ac_have_decl
-_ACEOF
-
 for ac_func in getrlimit
 do :
   ac_fn_c_check_func "$LINENO" "getrlimit" "ac_cv_func_getrlimit"
@@ -17338,6 +17574,32 @@ _ACEOF
 fi
 
 #  ----------------------------------------------------------------------
+# Checks for the availability of ANSI-C99 math functions
+ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "$ac_includes_default
+#include <math.h>
+"
+if test "x$ac_cv_have_decl_isnan" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ISNAN $ac_have_decl
+_ACEOF
+
+for ac_func in sqrtl
+do :
+  ac_fn_c_check_func "$LINENO" "sqrtl" "ac_cv_func_sqrtl"
+if test "x$ac_cv_func_sqrtl" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SQRTL 1
+_ACEOF
+
+fi
+done
+
+#  ----------------------------------------------------------------------
 #  Enable DATA support
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DATA support" >&5
 $as_echo_n "checking for DATA support... " >&6; }
@@ -18652,6 +18914,7 @@ NETCDF_LIBS=''
 ENABLE_NETCDF=no
 ENABLE_NC2=no
 ENABLE_NC4=no
+ENABLE_NC4HDF5=no
 
 # Check whether --with-netcdf was given.
 if test "${with_netcdf+set}" = set; then :
@@ -18736,6 +18999,7 @@ else
 fi
 
                             NETCDF_LIBS=" -lnetcdf"
+
                             # Extract the first word of "nc-config", so it can be a program name with args.
 set dummy nc-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -18800,6 +19064,19 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
+			           { $as_echo "$as_me:${as_lineno-$LINENO}: checking netcdf's nc4/hdf5 support" >&5
+$as_echo_n "checking netcdf's nc4/hdf5 support... " >&6; }
+                                   if test "x$($NC_CONFIG --has-hdf5)" = "xyes"; then :
+
+$as_echo "#define HAVE_NC4HDF5 1" >>confdefs.h
+
+                                          ENABLE_NC4HDF5=yes
+                                          { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 else
   $as_echo Could not find nc-config! go on with default configuration
 fi ;; #(
@@ -18962,6 +19239,19 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
+			           { $as_echo "$as_me:${as_lineno-$LINENO}: checking netcdf's nc4/hdf5 support" >&5
+$as_echo_n "checking netcdf's nc4/hdf5 support... " >&6; }
+                                   if test "x$($NC_CONFIG --has-hdf5)" = "xyes"; then :
+
+$as_echo "#define HAVE_NC4HDF5 1" >>confdefs.h
+
+                                          ENABLE_NC4HDF5=yes
+                                          { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: Could not find nc-config! go on with default configuration" >&5
 $as_echo "Could not find nc-config! go on with default configuration" >&6; }
@@ -18981,6 +19271,69 @@ $as_echo "suppressed" >&6; }
 fi
 
 
+if test "x$ENABLE_NC4HDF5" = "xyes"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing H5TS_mutex_lock" >&5
+$as_echo_n "checking for library containing H5TS_mutex_lock... " >&6; }
+if ${ac_cv_search_H5TS_mutex_lock+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char H5TS_mutex_lock ();
+int
+main ()
+{
+return H5TS_mutex_lock ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' netcdf; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib -lhdf5_hl -lhdf5 $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_H5TS_mutex_lock=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_H5TS_mutex_lock+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_H5TS_mutex_lock+:} false; then :
+
+else
+  ac_cv_search_H5TS_mutex_lock=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_H5TS_mutex_lock" >&5
+$as_echo "$ac_cv_search_H5TS_mutex_lock" >&6; }
+ac_res=$ac_cv_search_H5TS_mutex_lock
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_NC4HDF5_THREADSAFE 1" >>confdefs.h
+
+fi
+
+fi
+
+
+
 
 
 
@@ -20786,7 +21139,9 @@ ac_config_files="$ac_config_files test/Cat.test test/Gridarea.test test/Genweigh
 
 ac_config_files="$ac_config_files test/Select.test test/Spectral.test test/Timstat.test test/Vertint.test"
 
-ac_config_files="$ac_config_files test/Detrend.test test/Arith.test"
+ac_config_files="$ac_config_files test/Afterburner.test test/Detrend.test test/Arith.test test/Gradsdes.test"
+
+ac_config_files="$ac_config_files test/wildcard.test"
 
 ac_config_files="$ac_config_files Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings"
 
@@ -21364,7 +21719,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdo $as_me 1.6.7, which was
+This file was extended by cdo $as_me 1.6.9, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21424,13 +21779,13 @@ $config_headers
 Configuration commands:
 $config_commands
 
-Report bugs to <https://code.zmaw.de/projects/cdo>."
+Report bugs to <http://mpimet.mpg.de/cdo>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdo config.status 1.6.7
+cdo config.status 1.6.9
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
@@ -21949,8 +22304,11 @@ do
     "test/Spectral.test") CONFIG_FILES="$CONFIG_FILES test/Spectral.test" ;;
     "test/Timstat.test") CONFIG_FILES="$CONFIG_FILES test/Timstat.test" ;;
     "test/Vertint.test") CONFIG_FILES="$CONFIG_FILES test/Vertint.test" ;;
+    "test/Afterburner.test") CONFIG_FILES="$CONFIG_FILES test/Afterburner.test" ;;
     "test/Detrend.test") CONFIG_FILES="$CONFIG_FILES test/Detrend.test" ;;
     "test/Arith.test") CONFIG_FILES="$CONFIG_FILES test/Arith.test" ;;
+    "test/Gradsdes.test") CONFIG_FILES="$CONFIG_FILES test/Gradsdes.test" ;;
+    "test/wildcard.test") CONFIG_FILES="$CONFIG_FILES test/wildcard.test" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;;
@@ -23455,8 +23813,11 @@ _LT_EOF
     "test/Spectral.test":F) chmod a+x "$ac_file" ;;
     "test/Timstat.test":F) chmod a+x "$ac_file" ;;
     "test/Vertint.test":F) chmod a+x "$ac_file" ;;
+    "test/Afterburner.test":F) chmod a+x "$ac_file" ;;
     "test/Detrend.test":F) chmod a+x "$ac_file" ;;
     "test/Arith.test":F) chmod a+x "$ac_file" ;;
+    "test/Gradsdes.test":F) chmod a+x "$ac_file" ;;
+    "test/wildcard.test":F) chmod a+x "$ac_file" ;;
 
   esac
 done # for ac_tag
diff --git a/configure.ac b/configure.ac
index ae80214..a56f200 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,9 @@
 #  autoconf 2.68
 #  libtool  2.4.2
 
-AC_INIT([cdo], [1.6.7], [https://code.zmaw.de/projects/cdo])
+AC_INIT([cdo], [1.6.9], [http://mpimet.mpg.de/cdo])
+
+AC_DEFINE_UNQUOTED(CDO, ["$PACKAGE_VERSION"], [CDO version])
 
 CONFIG_ABORT=yes
 AC_CONFIG_AUX_DIR(config)
@@ -18,6 +20,8 @@ AC_CONFIG_HEADERS([src/config.h])
 AM_MAINTAINER_MODE([disable])
 
 # Set up libtool.
+AM_PROG_AR
+#
 AC_MSG_NOTICE([setting up libtool])
 LT_INIT
 
@@ -25,6 +29,7 @@ LT_INIT
 AC_CHECK_TOOL([CC],[gcc],[:])
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
+AC_C_RESTRICT
 AC_OPENMP
 AC_CHECK_TOOL([AR],[ar],[:])
 AC_CHECK_TOOL([CPP],[cpp],[:])
@@ -59,13 +64,13 @@ AC_CHECK_HEADERS(sys/resource.h)
 AC_CHECK_HEADERS(sys/times.h)
 AC_CHECK_HEADERS(malloc.h)
 AC_CHECK_HEADERS(glob.h)
+AC_CHECK_HEADERS(fnmatch.h)
+AC_CHECK_HEADERS(wordexp.h)
 #  ----------------------------------------------------------------------
 # Checks for the availability of functions
 AC_CHECK_FUNCS(mallinfo)
 #  ----------------------------------------------------------------------
 # Checks for the availability of ANSI-C99 functions
-AC_CHECK_DECLS([isnan],,,[AC_INCLUDES_DEFAULT
-@%:@include <math.h>])
 AC_CHECK_FUNCS(getrlimit)
 AC_CHECK_FUNCS(gethostname)
 
@@ -105,6 +110,11 @@ AC_SUBST([SYSTEM_TYPE],["$ac_cv_build"])
 #  Check for math library
 AC_CHECK_LIB([m],[floor])
 #  ----------------------------------------------------------------------
+# Checks for the availability of ANSI-C99 math functions
+AC_CHECK_DECLS([isnan],,,[AC_INCLUDES_DEFAULT
+@%:@include <math.h>])
+AC_CHECK_FUNCS(sqrtl)
+#  ----------------------------------------------------------------------
 #  Enable DATA support
 AC_MSG_CHECKING([for DATA support])
 AC_ARG_ENABLE([data],
@@ -217,7 +227,8 @@ AC_PROG_AWK
 AC_CONFIG_FILES([test/File.test test/Read_grib.test test/Read_netcdf.test test/Copy_netcdf.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([test/Cat.test test/Gridarea.test test/Genweights.test test/Remap.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([test/Select.test test/Spectral.test test/Timstat.test test/Vertint.test],[chmod a+x "$ac_file"])
-AC_CONFIG_FILES([test/Detrend.test test/Arith.test],[chmod a+x "$ac_file"])
+AC_CONFIG_FILES([test/Afterburner.test test/Detrend.test test/Arith.test test/Gradsdes.test],[chmod a+x "$ac_file"])
+AC_CONFIG_FILES([test/wildcard.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([Makefile src/Makefile contrib/Makefile test/Makefile test/data/Makefile cdo.spec cdo.settings])
 AC_OUTPUT
 
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
index 68f1539..e867279 100644
--- a/contrib/Makefile.in
+++ b/contrib/Makefile.in
@@ -156,6 +156,7 @@ ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
 ENABLE_IEG = @ENABLE_IEG@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
+ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
 ENABLE_NETCDF = @ENABLE_NETCDF@
 ENABLE_SERVICE = @ENABLE_SERVICE@
 EXEEXT = @EXEEXT@
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index 4be65ed..2a24f5c 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -31,7 +31,13 @@ adipot -adipot \
 adisit -adisit \
 aexpr -aexpr \
 aexprf -aexprf \
+after -after \
+afterburner -afterburner \
 anomaly -anomaly \
+ap2pl -ap2pl \
+ap2pl_lp -ap2pl_lp \
+ap2plx -ap2plx \
+ap2plx_lp -ap2plx_lp \
 asin -asin \
 atan -atan \
 atan2 -atan2 \
@@ -214,6 +220,7 @@ gencon2 -gencon2 \
 gendis -gendis \
 gengrid -gengrid \
 genlaf -genlaf \
+genlevelbounds -genlevelbounds \
 gennn -gennn \
 genycon -genycon \
 geopotheight -geopotheight \
@@ -592,6 +599,7 @@ splitsel -splitsel \
 splittabnum -splittabnum \
 splitvar -splitvar \
 splityear -splityear \
+splityearmon -splityearmon \
 splitzaxis -splitzaxis \
 sqr -sqr \
 sqrt -sqrt \
@@ -659,6 +667,7 @@ varrms -varrms \
 vct -vct \
 vct2 -vct2 \
 vertavg -vertavg \
+vertint -vertint \
 vertmax -vertmax \
 vertmean -vertmean \
 vertmin -vertmin \
@@ -738,12 +747,16 @@ ymonsub -ymonsub \
 ymonsum -ymonsum \
 ymonvar -ymonvar \
 ymonvar1 -ymonvar1 \
+yseasadd -yseasadd \
 yseasavg -yseasavg \
+yseasdiv -yseasdiv \
 yseasmax -yseasmax \
 yseasmean -yseasmean \
 yseasmin -yseasmin \
+yseasmul -yseasmul \
 yseaspctl -yseaspctl \
 yseasstd -yseasstd \
+yseassub -yseassub \
 yseassum -yseassum \
 yseasvar -yseasvar \
 zaxisdes -zaxisdes \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index 86932e0..d040bc9 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -31,7 +31,13 @@ adipot \
 adisit \
 aexpr \
 aexprf \
+after \
+afterburner \
 anomaly \
+ap2pl \
+ap2pl_lp \
+ap2plx \
+ap2plx_lp \
 asin \
 atan \
 atan2 \
@@ -214,6 +220,7 @@ gencon2 \
 gendis \
 gengrid \
 genlaf \
+genlevelbounds \
 gennn \
 genycon \
 geopotheight \
@@ -592,6 +599,7 @@ splitsel \
 splittabnum \
 splitvar \
 splityear \
+splityearmon \
 splitzaxis \
 sqr \
 sqrt \
@@ -659,6 +667,7 @@ varrms \
 vct \
 vct2 \
 vertavg \
+vertint \
 vertmax \
 vertmean \
 vertmin \
@@ -738,12 +747,16 @@ ymonsub \
 ymonsum \
 ymonvar \
 ymonvar1 \
+yseasadd \
 yseasavg \
+yseasdiv \
 yseasmax \
 yseasmean \
 yseasmin \
+yseasmul \
 yseaspctl \
 yseasstd \
+yseassub \
 yseassum \
 yseasvar \
 zaxisdes \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index 8154886..2373dfe 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -31,7 +31,13 @@ adipot -adipot \
 adisit -adisit \
 aexpr -aexpr \
 aexprf -aexprf \
+after -after \
+afterburner -afterburner \
 anomaly -anomaly \
+ap2pl -ap2pl \
+ap2pl_lp -ap2pl_lp \
+ap2plx -ap2plx \
+ap2plx_lp -ap2plx_lp \
 asin -asin \
 atan -atan \
 atan2 -atan2 \
@@ -214,6 +220,7 @@ gencon2 -gencon2 \
 gendis -gendis \
 gengrid -gengrid \
 genlaf -genlaf \
+genlevelbounds -genlevelbounds \
 gennn -gennn \
 genycon -genycon \
 geopotheight -geopotheight \
@@ -592,6 +599,7 @@ splitsel -splitsel \
 splittabnum -splittabnum \
 splitvar -splitvar \
 splityear -splityear \
+splityearmon -splityearmon \
 splitzaxis -splitzaxis \
 sqr -sqr \
 sqrt -sqrt \
@@ -659,6 +667,7 @@ varrms -varrms \
 vct -vct \
 vct2 -vct2 \
 vertavg -vertavg \
+vertint -vertint \
 vertmax -vertmax \
 vertmean -vertmean \
 vertmin -vertmin \
@@ -738,12 +747,16 @@ ymonsub -ymonsub \
 ymonsum -ymonsum \
 ymonvar -ymonvar \
 ymonvar1 -ymonvar1 \
+yseasadd -yseasadd \
 yseasavg -yseasavg \
+yseasdiv -yseasdiv \
 yseasmax -yseasmax \
 yseasmean -yseasmean \
 yseasmin -yseasmin \
+yseasmul -yseasmul \
 yseaspctl -yseaspctl \
 yseasstd -yseasstd \
+yseassub -yseassub \
 yseassum -yseassum \
 yseasvar -yseasvar \
 zaxisdes -zaxisdes \
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index fd7e3c7..2bf841f 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index 3ddd244..7327f94 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/AUTHORS b/libcdi/AUTHORS
index fe473fb..06ecddb 100644
--- a/libcdi/AUTHORS
+++ b/libcdi/AUTHORS
@@ -1 +1 @@
-Uwe Schulzweida <Uwe.Schulzweida at zmaw.de>
+Uwe Schulzweida <uwe.schulzweida AT mpimet.mpg.de>
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index ddae508..795319a 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,69 @@
+2015-04-28  Uwe Schulzweida
+
+	* Version 1.6.9 released
+        * using CGRIBEX library version 1.7.2
+
+2015-04-22  Uwe Schulzweida
+
+	* gribapiDefParam: use cfName to find parameter ids
+	* cgribex rotated grids: added support for parameter >angle< (bug fix)
+	* netcdf rotated grids: bug fix for negative angles
+
+2015-04-21  Uwe Schulzweida
+
+	* dmemory.c: merge changes from branches/cdi-tilesAndFileDrivenInput
+
+2015-03-30  Uwe Schulzweida
+
+	* gribapiDefLevel: use function grib2DefLevel() to write grib2 levels
+
+2015-03-29  Uwe Schulzweida
+
+	* vlistMerge: compare size of grids (bug fix)
+
+2015-03-27  Uwe Schulzweida
+
+	* gribapiScanTimestep1: fixed bug from previous merge of branches/cdi_fileDrivenInput (GRIB2 read failed)
+
+2015-03-26  Uwe Schulzweida
+
+        * merged changes from branches/cdi_fileDrivenInput
+
+2015-03-26  Uwe Schulzweida
+
+	* Version 1.6.8 released
+        * using CGRIBEX library version 1.7.1
+
+2015-02-18  Uwe Schulzweida
+
+	* cdiDecodeTimevalue: fix rounding error for negativ timevalue
+
+2015-02-12  Uwe Schulzweida
+
+	* scan netcdf time units attribute (bug fix)
+
+2015-02-02  Uwe Schulzweida
+
+	* gribapiDefDateTimeRel: forecastTime [Bug #5435]
+	* cdfCopyRecord: incorrect checksum for freed object [Bug #5461]
+
+2015-01-16  Uwe Schulzweida
+
+	* cdiDecodeTimevalue: round seconds for TUNIT_SECOND (bug fix)
+
+2015-01-12  Uwe Schulzweida
+
+	* cdfCreateRecords: call cdfCreateRecords(streamptr, 1) if not done before (bug fix)
+
+2015-01-09  Uwe Schulzweida
+
+	* cdi_create_records: the contents of unused records must not be interpreted (bug fix) [patch from Nathanael Huebbe]
+
+2014-12-19  Uwe Schulzweida
+
+	* netCDF: renamed coordinate bounds dimension from nv2 to bnds
+	* netCDF: renamed time bounds dimension from nb2 to bnds
+
 2014-12-11  Uwe Schulzweida
 
 	* Version 1.6.7 released
diff --git a/libcdi/Makefile.in b/libcdi/Makefile.in
index c65dca1..66cd526 100644
--- a/libcdi/Makefile.in
+++ b/libcdi/Makefile.in
@@ -96,17 +96,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -249,6 +258,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -296,6 +306,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
diff --git a/libcdi/NEWS b/libcdi/NEWS
index 17fc3c3..2f1232d 100644
--- a/libcdi/NEWS
+++ b/libcdi/NEWS
@@ -1,6 +1,14 @@
 CDI NEWS
 --------
 
+Version 1.6.8 (26 March 2015):
+
+   Fixed bugs:
+     * cdfCopyRecord: incorrect checksum for freed object [Bug #5461]
+     * scan netcdf time units attribute
+     * fixed rounding error for negativ timevalue
+     * time unit second rounding error
+
 Version 1.6.7 (5 December 2014):
 
    Fixed bugs:
diff --git a/libcdi/README b/libcdi/README
index de23134..f69880e 100644
--- a/libcdi/README
+++ b/libcdi/README
@@ -52,5 +52,5 @@ Porting:
      
 Contact:
 
-     Send questions, comments and bug reports to <http://code.zmaw.de/projects/cdi>
+     Send questions, comments and bug reports to <http://mpimet.mpg.de/cdi>
 
diff --git a/libcdi/acinclude.m4 b/libcdi/acinclude.m4
index 68f06df..b886306 100644
--- a/libcdi/acinclude.m4
+++ b/libcdi/acinclude.m4
@@ -14,6 +14,9 @@ AC_DEFUN([ACX_CHECK_CFINT],
      [AC_DEFINE(HAVE_CF_INTERFACE, [1],
         [Define if C / Fortran interface cfortran.h works])])
   ])
+m4_include([m4/ac_lang_program_fortran.m4])
+m4_include([m4/acx_lang_fortran_check_include.m4])
+m4_include([m4/acx_lang_c_check_include.m4])
 dnl
 dnl Local Variables:
 dnl mode: autoconf
diff --git a/libcdi/aclocal.m4 b/libcdi/aclocal.m4
index 31d3d16..3f8b4f3 100644
--- a/libcdi/aclocal.m4
+++ b/libcdi/aclocal.m4
@@ -1184,12 +1184,18 @@ AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
 m4_include([m4/acx_assert_lang_is_fortran_variant.m4])
+m4_include([m4/acx_c_package.m4])
 m4_include([m4/acx_check_strptr_convert.m4])
 m4_include([m4/acx_execinfo.m4])
+m4_include([m4/acx_fortran_package.m4])
+m4_include([m4/acx_lang_check_include.m4])
 m4_include([m4/acx_lang_other_suffix_conftest.m4])
+m4_include([m4/acx_lang_package.m4])
+m4_include([m4/acx_option_search_libs.m4])
 m4_include([m4/acx_options.m4])
 m4_include([m4/acx_sl_fc_mod_path_flag.m4])
 m4_include([m4/acx_sl_mod_suffix.m4])
+m4_include([m4/asx_tr_arg.m4])
 m4_include([m4/asx_unset.m4])
 m4_include([m4/ax_pthread.m4])
 m4_include([m4/libtool.m4])
diff --git a/libcdi/app/Makefile.in b/libcdi/app/Makefile.in
index dab9325..b130d30 100644
--- a/libcdi/app/Makefile.in
+++ b/libcdi/app/Makefile.in
@@ -89,17 +89,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -222,6 +231,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -269,6 +279,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
diff --git a/libcdi/app/cdi.c b/libcdi/app/cdi.c
index 1df9da2..3174b06 100644
--- a/libcdi/app/cdi.c
+++ b/libcdi/app/cdi.c
@@ -33,13 +33,6 @@ int      vlistInqVarMissvalUsed(int vlistID, int varID);
 #endif
 
 
-static inline int
-cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
-{
-  static unsigned char uuid_nil[CDI_UUID_SIZE];
-  return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
-}
-
 #include "printinfo.h"
 
 void cdiDefTableID(int tableID);
@@ -141,7 +134,7 @@ void version(void)
 static
 void usage(void)
 {
-  char *name;
+  const char *name;
   int id;
 
   fprintf(stderr, "usage : %s  [Option]  [ifile]  [ofile]\n", Progname);
@@ -298,14 +291,15 @@ const char* calendar2str(int calendar)
 }
 
 static
-void limit_string_length(char* string)
+void limit_string_length(char* string, size_t maxlen)
 {
+  string[maxlen-1] = 0;
   size_t len = strlen(string);
 
   if ( len > 10 )
     {
       for ( size_t i = 3; i < len; ++i )
-	if ( string[i] == ' ' )
+	if ( string[i] == ' ' || string[i] == ',' || (i>10 && string[i] == '.') )
 	  {
 	    string[i] = 0;
 	    break;
@@ -355,15 +349,15 @@ void printShortinfo(int streamID, int vlistID, int vardis)
 	  /* institute info */
 	  instptr = institutInqNamePtr(vlistInqVarInstitut(vlistID, varID));
 	  strcpy(tmpname, "unknown");
-	  if ( instptr ) strcpy(tmpname, instptr);
-	  limit_string_length(tmpname);
+	  if ( instptr ) strncpy(tmpname, instptr, CDI_MAX_NAME);
+	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
 	  /* source info */
 	  modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
 	  strcpy(tmpname, "unknown");
-	  if ( modelptr ) strcpy(tmpname, modelptr);
-	  limit_string_length(tmpname);
+	  if ( modelptr ) strncpy(tmpname, modelptr, CDI_MAX_NAME);
+	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
 	  /* tsteptype */
@@ -843,8 +837,8 @@ int main(int argc, char *argv[])
 	  vlistPrint(vlistID1);
 	  ngrids = vlistNgrids(vlistID1);
 	  nzaxis = vlistNzaxis(vlistID1);
-	  for ( gridID = 0; gridID < ngrids; gridID++ ) gridPrint(gridID, 1);
-	  for ( zaxisID = 0; zaxisID < nzaxis; zaxisID++ ) zaxisPrint(zaxisID);
+	  for ( gridID = 0; gridID < ngrids; gridID++ ) gridPrint(gridID, gridID, 1);
+	  for ( zaxisID = 0; zaxisID < nzaxis; zaxisID++ ) zaxisPrint(zaxisID, zaxisID);
 	}
 
       nvars   = vlistNvars(vlistID1);
diff --git a/libcdi/app/printinfo.h b/libcdi/app/printinfo.h
index 20611fa..997f893 100644
--- a/libcdi/app/printinfo.h
+++ b/libcdi/app/printinfo.h
@@ -3,6 +3,30 @@
 
 void uuid2str(const unsigned char uuid[CDI_UUID_SIZE], char *uuidstr);
 
+static inline
+int cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+{
+  static unsigned char uuid_nil[CDI_UUID_SIZE];
+  return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
+}
+
+
+void datetime2str(int date, int time, char *datetimestr, int maxlen)
+{
+  int year, month, day;
+  int hour, minute, second;
+  int len;
+
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
+
+  len = sprintf(datetimestr, DATE_FORMAT "T" TIME_FORMAT, year, month, day, hour, minute, second);
+
+  if ( len > ( maxlen-1) )
+    fprintf(stderr, "Internal problem (%s): sizeof input string is too small!\n", __func__);
+}
+
+
 void date2str(int date, char *datestr, int maxlen)
 {
   int year, month, day;
@@ -222,7 +246,7 @@ void printGridInfo(int vlistID)
 	      latpole = gridInqYpole(gridID);
 	      angle   = gridInqAngle(gridID);
 	      fprintf(stdout, "%33s : lon=%g  lat=%g", "northpole", lonpole, latpole);
-	      if ( angle > 0 ) fprintf(stdout, "  angle=%g", angle);
+	      if ( IS_NOT_EQUAL(angle, 0) ) fprintf(stdout, "  angle=%g", angle);
 	      fprintf(stdout, "\n");
 	    }
 
diff --git a/libcdi/cdi.settings.in b/libcdi/cdi.settings.in
index d1ea566..cc0877f 100644
--- a/libcdi/cdi.settings.in
+++ b/libcdi/cdi.settings.in
@@ -1,59 +1,76 @@
 {
-   "CC"       : "@CC@",
-   "CPP"      : "@CPP@",
-   "CPPFLAGS" : "@CPPFLAGS@",
-   "CFLAGS"   : "@CFLAGS@",
-   "LDFLAGS"  : "@LDFLAGS@",
-   "LIBS"     : "@LIBS@",
-   "FC"       : "@FC@",
-   "F77"      : "@F77@",
-   "FCFLAGS"  : "@FCFLAGS@",
-   "LD"       : "@LD@",
-   "NM"       : "@NM@",
-   "AR"       : "@AR@",
-   "AS"       : "@AS@",
-   "DLLTOOL"  : "@DLLTOOL@",
-   "OBJDUMP"  : "@OBJDUMP@",
-   "STRIP"    : "@STRIP@",
-   "RANLIB"   : "@RANLIB@",
-   "INSTALL"  : "@INSTALL@",
+  "build" : {
+    "tools" : {
+      "CC"       : "@CC@",
+      "CPP"      : "@CPP@",
+      "CPPFLAGS" : "@CPPFLAGS@",
+      "CFLAGS"   : "@CFLAGS@",
+      "LDFLAGS"  : "@LDFLAGS@",
+      "LIBS"     : "@LIBS@",
+      "FC"       : "@FC@",
+      "F77"      : "@F77@",
+      "FCFLAGS"  : "@FCFLAGS@",
+      "LD"       : "@LD@",
+      "NM"       : "@NM@",
+      "AR"       : "@AR@",
+      "AS"       : "@AS@",
+      "DLLTOOL"  : "@DLLTOOL@",
+      "OBJDUMP"  : "@OBJDUMP@",
+      "STRIP"    : "@STRIP@",
+      "RANLIB"   : "@RANLIB@",
+      "INSTALL"  : "@INSTALL@"
+    },
+    "platform" : {
+      "USER_NAME"   : "@USER_NAME@",
+      "HOST_NAME"   : "@HOST_NAME@",
+      "SYSTEM_TYPE" : "@SYSTEM_TYPE@"
+    },
+    "libraries" : {
+      "threads"    : {
+        "lib"      : "@THREADS_LIBS@",
+        "include"  : "@THREADS_INCLUDE@"
+      },
+      "mpi"        : {
+        "libs"     : "@MPI_C_LIB@",
+        "cflags"   : "@MPI_C_INCLUDE@",
+        "fclibs"   : "@MPI_FC_LIB@",
+        "fcflags"  : "@MPI_FC_INCLUDE@"
+      },
+      "zlib"     : {
+        "lib"      : "@ZLIB_LIBS@",
+        "include"  : "@ZLIB_INCLUDE@"
+      },
+      "szlib"    : {
+        "lib"      : "@SZLIB_LIBS@",
+        "include"  : "@SZLIB_INCLUDE@"
+      },
+      "hdf5"     : {
+        "lib"      : "@HDF5_LIBS@",
+        "include"  : "@HDF5_INCLUDE@"
+      },
+      "netcdf"   : {
+        "lib"      : "@NETCDF_LIBS@",
+        "include"  : "@NETCDF_INCLUDE@"
+      },
+      "grib_api" : {
+        "lib"      : "@GRIB_API_LIBS@",
+        "include"  : "@GRIB_API_INCLUDE@"
+      },
+      "jasper" : {
+        "lib"      : "@JASPER_LIBS@"
+      }
+    }
   },
-  "enable_cdi_lib" : @ENABLE_CDI_LIB@,
-  "grib"           : "@ENABLE_GRIB@",
-  "cgribex"        : "@ENABLE_CGRIBEX@",
-  "service"        : "@ENABLE_SERVICE@",
-  "extra"          : "@ENABLE_EXTRA@",
-  "ieg"            : "@ENABLE_IEG@",
-  "threads"    : {
-    "lib"      : "@THREADS_LIBS@",
-    "include"  : "@THREADS_INCLUDE@"
-  },
-  "zlib"     : {
-    "lib"      : "@ZLIB_LIBS@",
-    "include"  : "@ZLIB_INCLUDE@",
-  },
-  "szlib"    : {
-    "lib"      : "@SZLIB_LIBS@",
-    "include"  : "@SZLIB_INCLUDE@"
-  },
-  "hdf5"     : {
-    "lib"      : "@HDF5_LIBS@",
-    "include"  : "@HDF5_INCLUDE@"
-  },
-  "netcdf"   : {
-    "lib"      : "@NETCDF_LIBS@",
-    "include"  : "@NETCDF_INCLUDE@"
-  },
-  "grib_api" : {
-    "lib"      : "@GRIB_API_LIBS@",
-    "include"  : "@GRIB_API_INCLUDE@"
-  },
-  "jasper" : {
-    "lib"      : "@JASPER_LIBS@"
-  },
-  "enable_python" : @ENABLE_PYTHON@,
-  "enable_ruby"   : @ENABLE_RUBY@,
-  "USER_NAME"   : "@USER_NAME@",
-  "HOST_NAME"   : "@HOST_NAME@",
-  "SYSTEM_TYPE" : "@SYSTEM_TYPE@"
+  "features" : {
+    "enable_cdi_lib" : @ENABLE_CDI_LIB@,
+    "grib"           : "@ENABLE_GRIB@",
+    "cgribex"        : "@ENABLE_CGRIBEX@",
+    "service"        : "@ENABLE_SERVICE@",
+    "extra"          : "@ENABLE_EXTRA@",
+    "ieg"            : "@ENABLE_IEG@",
+    "enable_mpi"    : @ENABLE_MPI@,
+    "parallel_nc4"  : @HAVE_PARALLEL_NC4@,
+    "enable_python" : @ENABLE_PYTHON@,
+    "enable_ruby"   : @ENABLE_RUBY@
+  }
 }
diff --git a/libcdi/config/default b/libcdi/config/default
index 1a63f9c..9570e32 100755
--- a/libcdi/config/default
+++ b/libcdi/config/default
@@ -57,11 +57,9 @@ case "${HOSTNAME}" in
                     --enable-iso-c-interface \
                     --enable-swig \
                     --enable-python \
-                    --with-jasper=/opt/local \
-                    --with-grib_api=$HOME/local/gribapi-1.9.16 \
-                    --with-netcdf=/opt/local \
-                    --with-szlib=$HOME/local \
-	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -Df2cFortran"
+                    --with-grib_api=$HOME/local/gribapi-1.13.0 \
+                    --with-netcdf=$HOME/local \
+	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -Df2cFortran"
 	;;
 # ia64-nec-linux
     ds*)
diff --git a/libcdi/configure b/libcdi/configure
index 1467627..0d5b1d6 100755
--- a/libcdi/configure
+++ b/libcdi/configure
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdi 1.6.7.
+# Generated by GNU Autoconf 2.68 for cdi 1.6.9.
 #
-# Report bugs to <https://code.zmaw.de/projects/cdi>.
+# Report bugs to <http://mpimet.mpg.de/cdi>.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -247,10 +247,10 @@ fi
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf at gnu.org and
-$0: https://code.zmaw.de/projects/cdi about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
+$0: http://mpimet.mpg.de/cdi about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
   fi
   exit 1
 fi
@@ -570,9 +570,9 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdi'
 PACKAGE_TARNAME='cdi'
-PACKAGE_VERSION='1.6.7'
-PACKAGE_STRING='cdi 1.6.7'
-PACKAGE_BUGREPORT='https://code.zmaw.de/projects/cdi'
+PACKAGE_VERSION='1.6.9'
+PACKAGE_STRING='cdi 1.6.9'
+PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdi'
 PACKAGE_URL=''
 
 # Factoring default headers for most tests.
@@ -620,6 +620,10 @@ BUILD_F77
 BUILD_FC
 BUILD_CXX
 BUILD_CC
+BUILD_FC_INCLUDE
+BUILD_C_INCLUDE
+BUILD_MPI_FC_LIB
+BUILD_MPI_C_LIB
 BUILD_LIBS
 BUILD_LDFLAGS
 BUILD_FCFLAGS
@@ -646,6 +650,7 @@ FC_MOD_FLAG
 ENABLE_F2003_ISOC
 CREATE_ISOC_FALSE
 CREATE_ISOC_TRUE
+ENABLE_MPI
 USE_MPI
 USE_PPM_CORE_FALSE
 USE_PPM_CORE_TRUE
@@ -660,6 +665,11 @@ PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 PKG_CONFIG
 MPI_LAUNCH
+MPI_FC_LIB
+MPI_FC_INCLUDE
+MPI_C_LIB
+MPI_C_INCLUDE
+MPIROOT
 ENABLE_NETCDF_FALSE
 ENABLE_NETCDF_TRUE
 ENABLE_ALL_STATIC_FALSE
@@ -672,6 +682,8 @@ ENABLE_EXTRA
 ENABLE_SERVICE
 ENABLE_CGRIBEX
 ENABLE_GRIB
+HAVE_LIBGRIB_API_FALSE
+HAVE_LIBGRIB_API_TRUE
 GRIB_API_LIBS
 GRIB_API_INCLUDE
 LIBPNG_LIBS
@@ -866,6 +878,9 @@ enable_extra
 enable_ieg
 enable_all_static
 enable_mpi
+with_mpi_root
+with_mpi_include
+with_mpi_lib
 enable_iso_c_interface
 enable_swig
 enable_ruby
@@ -890,6 +905,10 @@ CXX
 CXXFLAGS
 CCC
 CXXCPP
+MPI_C_INCLUDE
+MPI_C_LIB
+MPI_FC_INCLUDE
+MPI_FC_LIB
 PKG_CONFIG
 PKG_CONFIG_PATH
 PKG_CONFIG_LIBDIR
@@ -902,6 +921,10 @@ BUILD_CFLAGS
 BUILD_FCFLAGS
 BUILD_LDFLAGS
 BUILD_LIBS
+BUILD_MPI_C_LIB
+BUILD_MPI_FC_LIB
+BUILD_C_INCLUDE
+BUILD_FC_INCLUDE
 BUILD_CC
 BUILD_CXX
 BUILD_FC
@@ -1448,7 +1471,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cdi 1.6.7 to adapt to many kinds of systems.
+\`configure' configures cdi 1.6.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1518,7 +1541,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdi 1.6.7:";;
+     short | recursive ) echo "Configuration of cdi 1.6.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1592,6 +1615,11 @@ Optional Packages:
                           library for grib2 compression; if a directory is
                           given, it will be used as a value for
                           --with-jasper-root
+  --with-mpi-root         set directory to search for MPI headers and library
+  --with-mpi-include      specifically set directory to search for MPI
+                          headers, [default=$with_mpi_root/include]
+  --with-mpi-lib          specifically set directory to search for MPI
+                          library, [default=$with_mpi_root/lib]
 
 Some influential environment variables:
   CC          C compiler command
@@ -1611,6 +1639,14 @@ Some influential environment variables:
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
   CXXCPP      C++ preprocessor
+  MPI_C_INCLUDE
+              specifically set flags to use when compiling sources using MPI
+              includes.
+  MPI_C_LIB   specifically set flags to use when linking MPI.
+  MPI_FC_INCLUDE
+              specifically set flags to use when compiling sources using MPI
+              includes.
+  MPI_FC_LIB  specifically set flags to use when linking MPI.
   PKG_CONFIG  path to pkg-config utility
   PKG_CONFIG_PATH
               directories to add to pkg-config's search path
@@ -1630,6 +1666,14 @@ Some influential environment variables:
   BUILD_LDFLAGS
               append to LDFLAGS during build but not in configure phase
   BUILD_LIBS  append to LIBS during build but not in configure phase
+  BUILD_MPI_C_LIB
+              append to MPI_C_LIB during build but not in configure phase
+  BUILD_MPI_FC_LIB
+              append to MPI_FC_LIB during build but not in configure phase
+  BUILD_C_INCLUDE
+              append to C_INCLUDE during build but not in configure phase
+  BUILD_FC_INCLUDE
+              append to FC_INCLUDE during build but not in configure phase
   BUILD_CC    replace CC with expansion of $BUILD_CC during build but not in
               configure phase
   BUILD_CXX   replace CXX with expansion of $BUILD_CXX during build but not in
@@ -1642,7 +1686,7 @@ Some influential environment variables:
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <https://code.zmaw.de/projects/cdi>.
+Report bugs to <http://mpimet.mpg.de/cdi>.
 _ACEOF
 ac_status=$?
 fi
@@ -1705,7 +1749,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdi configure 1.6.7
+cdi configure 1.6.9
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2396,9 +2440,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------------------------ ##
-## Report this to https://code.zmaw.de/projects/cdi ##
-## ------------------------------------------------ ##"
+( $as_echo "## --------------------------------------- ##
+## Report this to http://mpimet.mpg.de/cdi ##
+## --------------------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
@@ -2466,7 +2510,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cdi $as_me 1.6.7, which was
+It was created by cdi $as_me 1.6.9, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2851,6 +2895,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
 
+
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
   as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
@@ -3411,7 +3456,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.6.7'
+ VERSION='1.6.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -9410,6 +9455,8 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec=
 	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
@@ -12354,6 +12401,52 @@ fi
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_restrict=no
+   # The order here caters to the fact that C++ does not require restrict.
+   for ac_kw in __restrict __restrict__ _Restrict restrict; do
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+typedef int * int_ptr;
+	int foo (int_ptr $ac_kw ip) {
+	return ip[0];
+       }
+int
+main ()
+{
+int s[1];
+	int * $ac_kw t = s;
+	t[0] = 0;
+	return foo(t)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+     test "$ac_cv_c_restrict" != no && break
+   done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+   restrict) ;;
+   no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+   *)  cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
 ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
 ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
@@ -12495,7 +12588,7 @@ if ${ac_cv_fc_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 #ifndef __GNUC__
        choke me
 #endif
@@ -12524,7 +12617,7 @@ if ${ac_cv_prog_fc_g+:} false; then :
 else
   FCFLAGS=-g
 cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 
       end
 _ACEOF
@@ -13674,6 +13767,8 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec_FC=
 	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
@@ -13927,7 +14022,7 @@ else
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 
       end
 _ACEOF
@@ -13974,7 +14069,7 @@ else
   $as_echo_n "(cached) " >&6
 else
   cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 
       end
 _ACEOF
@@ -15117,7 +15212,7 @@ else
     eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_FC\"; \
 	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_FC\""
     cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 
       end
 _ACEOF
@@ -15471,7 +15566,7 @@ ac_cv_fc_srcext_f90=unknown
 for ac_flag in none -qsuffix=f=f90 -Tf; do
   test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
   cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 
       end
 _ACEOF
@@ -15523,8 +15618,8 @@ fi
 
 
 
-     acx_sl_fpp_srcext=${ac_fc_srcext-F}
-   as_acx_sl_prog_fpp=`$as_echo "     acx_sl_cv_prog_fpp_fc_${ac_fc_srcext-f}" | $as_tr_sh`
+   acx_sl_fpp_srcext=${ac_fc_srcext-F}
+   as_acx_sl_prog_fpp=`$as_echo "acx_sl_cv_prog_fpp_fc_${ac_fc_srcext-f}" | $as_tr_sh`
 
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to preprocess Fortran files with suffix $acx_sl_fpp_srcext" >&5
 $as_echo_n "checking how to preprocess Fortran files with suffix $acx_sl_fpp_srcext... " >&6; }
@@ -15537,14 +15632,13 @@ else
   rm -f conftest*
 
    cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 #define OK
 #ifdef OK
       REAL A
 #else
       syntax error
 #endif
-
       end
 _ACEOF
    ac_tmp=conftest.fppout
@@ -15569,9 +15663,9 @@ $as_echo "$ac_try_echo"; } >&5
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-                       eval "$as_acx_sl_prog_fpp=\"\$FPP\""
+            eval "$as_acx_sl_prog_fpp=\"\$FPP\""
 else
-             $as_echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
             { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: user-specified \$FPP ($FPP) does not work" >&5
@@ -15580,7 +15674,7 @@ $as_echo "$as_me: WARNING: user-specified \$FPP ($FPP) does not work" >&2;}
 fi
 rm -f core conftest.err conftest.$ac_objext
 else
-          mv $ac_tmp conftest.$ac_ext
+  mv $ac_tmp conftest.$ac_ext
          $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
@@ -15597,21 +15691,23 @@ fi
            `cd $srcdir ; pwd`/util/xlfpreproc-wrapper \
            `cd $srcdir ; pwd`/util/sunf95preproc-wrapper \
            `cd $srcdir ; pwd`/util/crayftnpreproc-wrapper \
-           "$FC -F" "$FC -F -fpp" "$FC -E" "$FC -E -cpp" \
+           "$FC -F" "$FC -F -fpp" "$FC -E" "$FC -E" "$FC -E -cpp" \
            "$FC $FCFLAGS -F" "$FC $FCFLAGS -E" "$FC $FCFLAGS -E" \
-           "$FC $FCFLAGS -E -cpp" "$FC $FCFLAGS -x f95-cpp-input -E -P"
+           "$FC $FCFLAGS -E -cpp" "$FC $FCFLAGS -x f95-cpp-input -E -P" \
+           "${F77-f77} -F" "${F77-f77} -E" 'fpp' \
+           "$CPP" "$CPP -x c" 'cpp' '/lib/cpp' \
+           '/usr/ccs/lib/cpp' 'g77 -E' '${CC-cc} -E'
          do
            rm -f conftest*
 
    cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 #define OK
 #ifdef OK
       REAL A
 #else
       syntax error
 #endif
-
       end
 _ACEOF
    ac_tmp=conftest.fppout
@@ -15639,14 +15735,14 @@ sed 's/^/| /' conftest.$ac_ext >&5
             FPP="$ac_fpp"
               break
 else
-             $as_echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 
 fi
 rm -f core conftest.err conftest.$ac_objext
 else
-          mv $ac_tmp conftest.$ac_ext
+  mv $ac_tmp conftest.$ac_ext
          $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
@@ -15658,14 +15754,13 @@ fi
            rm -f conftest*
 
    cat > conftest.$ac_ext <<_ACEOF
-      program main
+      program conftest
 #define OK
 #ifdef OK
       REAL A
 #else
       syntax error
 #endif
-
       end
 _ACEOF
    ac_tmp=conftest.fppout
@@ -15693,14 +15788,14 @@ sed 's/^/| /' conftest.$ac_ext >&5
             FPP="$ac_fpp -P"
               break
 else
-             $as_echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 
 fi
 rm -f core conftest.err conftest.$ac_objext
 else
-          mv $ac_tmp conftest.$ac_ext
+  mv $ac_tmp conftest.$ac_ext
          $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
@@ -15736,7 +15831,7 @@ $as_echo_n "checking if preprocessing with $FPP of Fortran source supports requi
 if ${acx_sl_cv_fc_indirect_ok+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-       acx_sl_cv_fc_indirect_ok=yes
+  acx_sl_cv_fc_indirect_ok=yes
       # Set up ac_fpp_need_* flags based on features in
       acx_sl_fpp_srcext=${ac_fc_srcext-F}
       # defaults for needed features
@@ -15819,12 +15914,10 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 program main
-
+      program conftest
 #ifndef OK
       syntax error
 #endif
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -15842,7 +15935,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
          do
            if test x"$FPP_DEFOPT" != x ; then :
   cp conftest.${acx_sl_fpp_srcext}.bak conftest.$acx_sl_fpp_srcext
-                     { { echo Running preprocessor $FPP $FPPFLAGS ${FPP_DEFOPT}OK conftest.$acx_sl_fpp_srcext; } >&5
+              { { echo Running preprocessor $FPP $FPPFLAGS ${FPP_DEFOPT}OK conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS ${FPP_DEFOPT}OK conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -15851,7 +15944,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-                  acx_sl_prog_fc_cpp_d=yes; break
+  acx_sl_prog_fc_cpp_d=yes; break
 fi
 rm -f core conftest.err conftest.$ac_objext
 fi
@@ -15881,9 +15974,8 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="inc"
    cat > conftest.$ac_ext <<_ACEOF
-           !     This statement overrides the IMPLICIT statement in the program
-         REAL cc
-
+       !     This statement overrides the IMPLICIT statement in the program
+      REAL cc
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
@@ -15901,14 +15993,12 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-      program main
-
+      program conftest
       IMPLICIT CHARACTER (c)
-!     Comments in test programs should be freeform compliant just in case.
-!     conftest.inc contains the Fortran statement "REAL cc"
+       !     Comments in test programs should be freeform compliant just in case.
+       !     conftest.inc contains the Fortran statement "REAL cc"
 #include "conftest.inc"
       cc=1.
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -15923,7 +16013,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
          do
            if test x"$FPP_INCOPT" != x ; then :
   cp conftest.${acx_sl_fpp_srcext}.bak conftest.$acx_sl_fpp_srcext
-                     { { echo Running preprocessor $FPP $FPPFLAGS ${FPP_INCOPT}conftst conftest.$acx_sl_fpp_srcext; } >&5
+              { { echo Running preprocessor $FPP $FPPFLAGS ${FPP_INCOPT}conftst conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS ${FPP_INCOPT}conftst conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -15932,7 +16022,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-                  acx_sl_prog_fc_cpp_i=yes
+  acx_sl_prog_fc_cpp_i=yes
                  break
 fi
 rm -f core conftest.err conftest.$ac_objext
@@ -15960,13 +16050,11 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-      program main
-
+      program conftest
 #define NM xxxx
       IMPLICIT CHARACTER (n)
       REAL xxxx
       NM=1.
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -15976,7 +16064,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -15985,7 +16073,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_subs=yes
+  acx_sl_prog_fc_cpp_subs=yes
 else
   acx_sl_cv_fc_indirect_ok=no
 fi
@@ -16008,11 +16096,10 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 program main
+      program conftest
 #define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
       CHARACTER(LEN=80) :: A
       A=LONG
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -16022,7 +16109,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -16031,7 +16118,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_wrap=yes
+  acx_sl_prog_fc_cpp_wrap=yes
 else
   acx_sl_cv_fc_indirect_ok=no
 fi
@@ -16053,10 +16140,8 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 program main
-
+      program conftest
       A=1. /* C-style comment */
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -16066,7 +16151,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -16075,7 +16160,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_CSTYLE=yes
+  acx_sl_prog_fc_cpp_CSTYLE=yes
 else
   acx_sl_cv_fc_indirect_ok=no
 fi
@@ -16097,10 +16182,8 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 program main
-
+      program conftest
       A=1. /* C-style comment */
-
       end
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
@@ -16110,7 +16193,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -16119,7 +16202,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_CSTYLE=yes
+  acx_sl_prog_fc_cpp_CSTYLE=yes
 else
   acx_sl_cv_fc_indirect_ok=no
 fi
@@ -16141,11 +16224,9 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 PROGRAM MAIN
+      PROGRAM MAIN
       CHARACTER(LEN=10) :: C
       C = "abcde" // "fghij"; END PROGRAM
-
-
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
@@ -16154,7 +16235,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -16163,7 +16244,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_cxxstyle=yes
+  acx_sl_prog_fc_cpp_cxxstyle=yes
 else
   acx_sl_cv_fc_indirect_ok=no
 fi
@@ -16185,11 +16266,9 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
-                 PROGRAM MAIN
+      PROGRAM MAIN
       CHARACTER(LEN=10) :: C
       C = "abcde" // "fghij"; END PROGRAM
-
-
 _ACEOF
    ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
@@ -16198,7 +16277,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
 
 
-                { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
+         { { echo Running preprocessor $FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext; } >&5
   ($FPP $FPPFLAGS conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp) 2>&5
   ac_status=$?
@@ -16207,9 +16286,9 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    if ac_fn_fc_try_compile "$LINENO"; then :
-             acx_sl_prog_fc_cpp_cxxstyle=yes
+  acx_sl_prog_fc_cpp_cxxstyle=yes
 else
-             acx_sl_cv_fc_indirect_ok=no
+  acx_sl_cv_fc_indirect_ok=no
 fi
 rm -f core conftest.err conftest.$ac_objext
          if test x$acx_sl_cv_fc_indirect_ok = xyes; then :
@@ -16224,7 +16303,7 @@ fi
       if test x$acx_sl_cv_fc_indirect_ok = xyes; then :
 
 else
-        { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "required Fortran preprocessor not available
 See \`config.log' for more details" "$LINENO" 5; }
@@ -17395,6 +17474,8 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  whole_archive_flag_spec_F77=
 	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
 	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
@@ -27006,6 +27087,14 @@ fi
 
 
 
+ if test "x$with_grib_api" != 'x' -a "x$with_grib_api" != 'xno' ; then
+  HAVE_LIBGRIB_API_TRUE=
+  HAVE_LIBGRIB_API_FALSE='#'
+else
+  HAVE_LIBGRIB_API_TRUE='#'
+  HAVE_LIBGRIB_API_FALSE=
+fi
+
 #  ----------------------------------------------------------------------
 #  Enable GRIB support
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GRIB support" >&5
@@ -27183,9 +27272,499 @@ fi
 
 #  ----------------------------------------------------------------------
 # Compile with MPI support
+# Sed expression to map a string onto a valid argument string part.
+asx_tr_arg="eval sed 'y%*+%pp%;s%[^-$as_cr_alnum]%-%g'"
+
 # Check whether --enable-mpi was given.
 if test "${enable_mpi+set}" = set; then :
   enableval=$enable_mpi; enable_mpi=yes
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+   have_MPI_c_bindings=yes
+
+
+# Check whether --with-mpi-root was given.
+if test "${with_mpi_root+set}" = set; then :
+  withval=$with_mpi_root; MPIROOT="$with_mpi_root"
+fi
+
+   if ${MPIROOT+:} false; then :
+  if ${MPI_C_LIB+:} false; then :
+
+else
+  acx_temp=$MPIROOT
+         MPI_C_LIB="-L$acx_temp/lib"
+fi
+      if ${MPI_C_INCLUDE+:} false; then :
+
+else
+  acx_temp=$MPIROOT
+         MPI_C_INCLUDE="-I$acx_temp/include"
+fi
+fi
+
+# Check whether --with-mpi-include was given.
+if test "${with_mpi_include+set}" = set; then :
+  withval=$with_mpi_include; MPI_C_INCLUDE="-I$with_mpi_include"
+fi
+
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi.h extra include path" >&5
+$as_echo_n "checking for mpi.h extra include path... " >&6; }
+   if ${acx_cv_c_include_mpi_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+       ac_include_search_mpi_h_SAVE="$CPPFLAGS"
+      while :; do
+        for ac_incdir in ''; do
+             if test -z "$ac_incdir"; then :
+  ac_res="none required"
+                CPPFLAGS="$MPI_C_INCLUDE $ac_include_search_mpi_h_SAVE"
+else
+  ac_res="-I$ac_incdir"
+                CPPFLAGS="$MPI_C_INCLUDE $ac_res $ac_include_search_mpi_h_SAVE"
+fi
+             cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+#include <mpi.h>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  acx_cv_c_include_mpi_h=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   if ${acx_cv_c_include_mpi_h+:} false; then :
+                 if test -z "$ac_incdir"; then :
+                    acx_cv_c_include_mpi_h="$MPI_C_INCLUDE"
+else
+                    acx_cv_c_include_mpi_h="$MPI_C_INCLUDE -I$ac_incdir"
+fi
+fi
+             if ${acx_cv_c_include_mpi_h+:} false; then :
+  break
+fi
+           done
+           if ${acx_cv_c_include_mpi_h+:} false; then :
+  break
+fi
+
+        break
+      done
+      CPPFLAGS=$ac_include_search_mpi_h_SAVE
+fi
+
+   if ${acx_cv_c_include_mpi_h+:} false; then :
+  acx_temp=$acx_cv_c_include_mpi_h
+      if test x"$acx_temp" = x; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (none required)" >&5
+$as_echo "(none required)" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_temp" >&5
+$as_echo "$acx_temp" >&6; }
+fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+   if ${acx_cv_c_include_mpi_h+:} false; then :
+  acx_temp=$acx_cv_c_include_mpi_h
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         MPI_C_INCLUDE=$acx_temp
+else
+  have_MPI_c_bindings=no
+         { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Required header mpi.h not found or not compilable.
+See \`config.log' for more details" "$LINENO" 5; }
+        enable_MPI=no
+fi
+
+
+# Check whether --with-mpi-lib was given.
+if test "${with_mpi_lib+set}" = set; then :
+  withval=$with_mpi_lib; MPI_C_LIB="-L$with_mpi_lib"
+fi
+
+
+
+      if test "x$have_MPI_c_bindings" = xyes; then :
+              { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MPI_Waitall" >&5
+$as_echo_n "checking for library containing MPI_Waitall... " >&6; }
+   if ${acx_cv_option_search_MPI_Waitall_c+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+       while :; do
+        acx_option_func_search_save_LIBS="$LIBS"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char MPI_Waitall ();
+int
+main ()
+{
+return MPI_Waitall ();
+  ;
+  return 0;
+}
+_ACEOF
+   for ac_lib in '' mpi mpich; do
+     if test -z "$ac_lib"; then :
+  ac_res="none required"
+        LIBS="$MPI_C_LIB $acx_option_func_search_save_LIBS"
+else
+  ac_res="-l$ac_lib"
+        LIBS="$MPI_C_LIB $ac_res $acx_option_func_search_save_LIBS"
+fi
+     if ac_fn_c_try_link "$LINENO"; then :
+  if test x"$ac_res" = x"none required"; then :
+          acx_cv_option_search_MPI_Waitall_c="$MPI_C_LIB "
+else
+          acx_cv_option_search_MPI_Waitall_c="$MPI_C_LIB -l$ac_lib "
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+     if ${acx_cv_option_search_MPI_Waitall_c+:} false; then :
+  break
+fi
+   done
+   rm conftest.$ac_ext
+   LIBS="$acx_option_func_search_save_LIBS"
+        if ${acx_cv_option_search_MPI_Waitall_c+:} false; then :
+  break
+fi
+
+        break
+      done
+fi
+
+   if ${acx_cv_option_search_MPI_Waitall_c+:} false; then :
+       if test x"$acx_cv_option_search_MPI_Waitall_c" = x; then :
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: (none required)" >&5
+$as_echo "(none required)" >&6; }
+else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_option_search_MPI_Waitall_c" >&5
+$as_echo "$acx_cv_option_search_MPI_Waitall_c" >&6; }
+fi
+else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+   if ${acx_cv_option_search_MPI_Waitall_c+:} false; then :
+
+else
+             have_MPI_c_bindings=no
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Cannot link C MPI programs.
+See \`config.log' for more details" "$LINENO" 5; }
+        enable_MPI=no
+fi
+
+         acx_temp=$acx_cv_option_search_MPI_Waitall_c
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         MPI_C_LIB=$acx_temp
+
+fi
+
+
+
+
+
+
+   ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     if test -n "$FC" && test "X$FC" != "Xno"; then :
+  ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+
+
+
+
+
+
+
+   have_MPI_fc_bindings=yes
+
+
+# Check whether --with-mpi-root was given.
+if test "${with_mpi_root+set}" = set; then :
+  withval=$with_mpi_root; MPIROOT="$with_mpi_root"
+fi
+
+   if ${MPIROOT+:} false; then :
+  if ${MPI_FC_LIB+:} false; then :
+
+else
+  acx_temp=$MPIROOT
+         MPI_FC_LIB="-L$acx_temp/lib"
+fi
+      if ${MPI_FC_INCLUDE+:} false; then :
+
+else
+  acx_temp=$MPIROOT
+         MPI_FC_INCLUDE="$FPP_INCOPT$acx_temp/include"
+fi
+fi
+
+# Check whether --with-mpi-include was given.
+if test "${with_mpi_include+set}" = set; then :
+  withval=$with_mpi_include; MPI_FC_INCLUDE="$FPP_INCOPT$with_mpi_include"
+fi
+
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpif.h extra include path" >&5
+$as_echo_n "checking for mpif.h extra include path... " >&6; }
+   if ${acx_cv_fc_include_mpif_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+       ac_include_search_mpif_h_SAVE="$FCFLAGS"
+      while :; do
+        for ac_incdir in ''; do
+             if test -z "$ac_incdir"; then :
+  ac_res="none required"
+                FCFLAGS="$MPI_FC_INCLUDE $ac_include_search_mpif_h_SAVE"
+else
+  ac_res="$FPP_INCOPT$ac_incdir"
+                FCFLAGS="$MPI_FC_INCLUDE $ac_res $ac_include_search_mpif_h_SAVE"
+fi
+             cat > conftest.$ac_ext <<_ACEOF
+      program conftest
+      include 'mpif.h'
+      end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+  acx_cv_fc_include_mpif_h=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   if ${acx_cv_fc_include_mpif_h+:} false; then :
+                 if test -z "$ac_incdir"; then :
+                    acx_cv_fc_include_mpif_h="$MPI_FC_INCLUDE"
+else
+                    acx_cv_fc_include_mpif_h="$MPI_FC_INCLUDE $FPP_INCOPT$ac_incdir"
+fi
+fi
+             if ${acx_cv_fc_include_mpif_h+:} false; then :
+  break
+fi
+           done
+           if ${acx_cv_fc_include_mpif_h+:} false; then :
+  break
+fi
+
+        break
+      done
+      FCFLAGS=$ac_include_search_mpif_h_SAVE
+fi
+
+   if ${acx_cv_fc_include_mpif_h+:} false; then :
+  acx_temp=$acx_cv_fc_include_mpif_h
+      if test x"$acx_temp" = x; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: (none required)" >&5
+$as_echo "(none required)" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_temp" >&5
+$as_echo "$acx_temp" >&6; }
+fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+   if ${acx_cv_fc_include_mpif_h+:} false; then :
+  acx_temp=$acx_cv_fc_include_mpif_h
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         MPI_FC_INCLUDE=$acx_temp
+else
+  have_MPI_fc_bindings=no
+         { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Required include mpif.h not found or not compilable.
+See \`config.log' for more details" "$LINENO" 5; }
+           enable_MPI=no
+fi
+
+
+# Check whether --with-mpi-lib was given.
+if test "${with_mpi_lib+set}" = set; then :
+  withval=$with_mpi_lib; MPI_FC_LIB="-L$with_mpi_lib"
+fi
+
+
+
+      if test "x$have_MPI_fc_bindings" = xyes; then :
+              { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing mpi_waitall" >&5
+$as_echo_n "checking for library containing mpi_waitall... " >&6; }
+   if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+       while :; do
+        acx_option_func_search_save_LIBS="$LIBS"
+   cat > conftest.$ac_ext <<_ACEOF
+      program conftest
+      call mpi_waitall
+      end
+_ACEOF
+   for ac_lib in '' mpi mpi_f90 mpi_f77 mpich; do
+     if test -z "$ac_lib"; then :
+  ac_res="none required"
+        LIBS="$MPI_FC_LIB $acx_option_func_search_save_LIBS"
+else
+  ac_res="-l$ac_lib"
+        LIBS="$MPI_FC_LIB $ac_res $acx_option_func_search_save_LIBS"
+fi
+     if ac_fn_fc_try_link "$LINENO"; then :
+  if test x"$ac_res" = x"none required"; then :
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB "
+else
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB -l$ac_lib "
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+     if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+   done
+   rm conftest.$ac_ext
+   LIBS="$acx_option_func_search_save_LIBS"
+        if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+                  acx_option_func_search_save_LIBS="$LIBS"
+   cat > conftest.$ac_ext <<_ACEOF
+      program conftest
+      call mpi_waitall
+      end
+_ACEOF
+   for ac_lib in '' mpi mpi_f90 mpi_f77 mpich; do
+     if test -z "$ac_lib"; then :
+  ac_res="none required"
+        LIBS="$MPI_FC_LIB -lmpi_f77 -lmpi $acx_option_func_search_save_LIBS"
+else
+  ac_res="-l$ac_lib"
+        LIBS="$MPI_FC_LIB $ac_res -lmpi_f77 -lmpi $acx_option_func_search_save_LIBS"
+fi
+     if ac_fn_fc_try_link "$LINENO"; then :
+  if test x"$ac_res" = x"none required"; then :
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB -lmpi_f77 -lmpi"
+else
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB -l$ac_lib -lmpi_f77 -lmpi"
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+     if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+   done
+   rm conftest.$ac_ext
+   LIBS="$acx_option_func_search_save_LIBS"
+           if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+                    acx_option_func_search_save_LIBS="$LIBS"
+   cat > conftest.$ac_ext <<_ACEOF
+      program conftest
+      call mpi_waitall
+      end
+_ACEOF
+   for ac_lib in '' mpi mpi_f90 mpi_f77 mpich; do
+     if test -z "$ac_lib"; then :
+  ac_res="none required"
+        LIBS="$MPI_FC_LIB -lmpi $acx_option_func_search_save_LIBS"
+else
+  ac_res="-l$ac_lib"
+        LIBS="$MPI_FC_LIB $ac_res -lmpi $acx_option_func_search_save_LIBS"
+fi
+     if ac_fn_fc_try_link "$LINENO"; then :
+  if test x"$ac_res" = x"none required"; then :
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB -lmpi"
+else
+          acx_cv_option_search_mpi_waitall_fc="$MPI_FC_LIB -l$ac_lib -lmpi"
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+     if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+   done
+   rm conftest.$ac_ext
+   LIBS="$acx_option_func_search_save_LIBS"
+           if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+  break
+fi
+
+        break
+      done
+fi
+
+   if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+       if test x"$acx_cv_option_search_mpi_waitall_fc" = x; then :
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: (none required)" >&5
+$as_echo "(none required)" >&6; }
+else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_option_search_mpi_waitall_fc" >&5
+$as_echo "$acx_cv_option_search_mpi_waitall_fc" >&6; }
+fi
+else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+   if ${acx_cv_option_search_mpi_waitall_fc+:} false; then :
+
+else
+             have_MPI_fc_bindings=no
+            { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Cannot link Fortran MPI programs.
+See \`config.log' for more details" "$LINENO" 5; }
+           enable_MPI=no
+fi
+
+         acx_temp=$acx_cv_option_search_mpi_waitall_fc
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         MPI_FC_LIB=$acx_temp
+
+fi
+
+
+
+
+
+
+   ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
 else
   enable_mpi=no
 fi
@@ -27650,6 +28229,8 @@ else
 fi
 
 
+ENABLE_MPI=`test x"$enable_mpi" = xyes && echo true || echo false`
+
 #  ----------------------------------------------------------------------
 #  Create the Fortran Interface via iso_c_binding module (Fortran 2003 Standard)
 # Check whether --enable-iso-c-interface was given.
@@ -27765,8 +28346,8 @@ else
       cd conftestdir
       cat > conftest.$ac_ext <<_ACEOF
       module cnftst
-       implicit none
-       integer :: i
+      implicit none
+      integer :: i
       end module cnftst
 _ACEOF
 if ac_fn_fc_try_compile "$LINENO"; then :
@@ -27780,13 +28361,11 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
         FCFLAGS_save=$FCFLAGS
         FCFLAGS="$FCFLAGS ${i}conftestdir"
         cat > conftest.$ac_ext <<_ACEOF
-      program main
-       use cnftst
-       implicit none
-       i = 0
-
+      program conftest
+      use cnftst
+      implicit none
+      i = 0
       end
-
 _ACEOF
 if ac_fn_fc_try_compile "$LINENO"; then :
   acx_sl_cv_fc_mod_path_flag_fc=$i ; FCFLAGS=$FCFLAGS_save ; break
@@ -27830,12 +28409,10 @@ ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest
 ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 
    cat > conftest.$ac_ext <<_ACEOF
-
       module conftest
-       implicit none
-       integer :: i
+      implicit none
+      integer :: i
       end module conftest
-
 _ACEOF
 if ac_fn_fc_try_compile "$LINENO"; then :
 
@@ -28192,7 +28769,6 @@ else
   USE_FC_FALSE=
 fi
 
-
 # Checks for compiler
 COMPILER="$CC $CFLAGS"
 
@@ -28348,6 +28924,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
+if test -z "${HAVE_LIBGRIB_API_TRUE}" && test -z "${HAVE_LIBGRIB_API_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_LIBGRIB_API\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${ENABLE_CDI_LIB_TRUE}" && test -z "${ENABLE_CDI_LIB_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_CDI_LIB\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -28396,6 +28976,10 @@ CFLAGS="$CFLAGS${BUILD_CFLAGS+ $BUILD_CFLAGS}"
 FCFLAGS="$FCFLAGS${BUILD_FCFLAGS+ $BUILD_FCFLAGS}"
 LDFLAGS="$LDFLAGS${BUILD_LDFLAGS+ $BUILD_LDFLAGS}"
 LIBS="$LIBS${BUILD_LIBS+ $BUILD_LIBS}"
+MPI_C_LIB="$MPI_C_LIB${BUILD_MPI_C_LIB+ $BUILD_MPI_C_LIB}"
+MPI_FC_LIB="$MPI_FC_LIB${BUILD_MPI_FC_LIB+ $BUILD_MPI_FC_LIB}"
+C_INCLUDE="$C_INCLUDE${BUILD_C_INCLUDE+ $BUILD_C_INCLUDE}"
+FC_INCLUDE="$FC_INCLUDE${BUILD_FC_INCLUDE+ $BUILD_FC_INCLUDE}"
 CC="${BUILD_CC-$CC}"
 CXX="${BUILD_CXX-$CXX}"
 FC="${BUILD_FC-$FC}"
@@ -28809,7 +29393,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdi $as_me 1.6.7, which was
+This file was extended by cdi $as_me 1.6.9, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -28869,13 +29453,13 @@ $config_headers
 Configuration commands:
 $config_commands
 
-Report bugs to <https://code.zmaw.de/projects/cdi>."
+Report bugs to <http://mpimet.mpg.de/cdi>."
 
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdi config.status 1.6.7
+cdi config.status 1.6.9
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/libcdi/configure.ac b/libcdi/configure.ac
index 094cc38..0dee0b8 100644
--- a/libcdi/configure.ac
+++ b/libcdi/configure.ac
@@ -4,13 +4,15 @@
 #  autoconf 2.68
 #  libtool  2.4.2
 
-AC_INIT([cdi], [1.6.7], [https://code.zmaw.de/projects/cdi])
+AC_INIT([cdi], [1.6.9], [http://mpimet.mpg.de/cdi])
 
 echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}"
 
 CONFIG_ABORT=yes
 AC_CONFIG_AUX_DIR([config])
 AC_CONFIG_MACRO_DIR([m4])
+dnl forbid acx macro names from remaining unexpanded
+m4_pattern_forbid([^ACX_])
 AC_CANONICAL_HOST
 AC_CANONICAL_BUILD
 
@@ -27,6 +29,7 @@ LT_INIT([pic-only])
 AC_CHECK_TOOL([CC],[gcc],[:])
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
+AC_C_RESTRICT
 AC_PROG_FC
 AS_IF([test -n "$FC" && test "X$FC" != "Xno"],
   [AC_FC_SRCEXT([f90])
@@ -128,7 +131,23 @@ ACX_OPTIONS
 AM_CONDITIONAL([ENABLE_NETCDF],[test x$ENABLE_NETCDF = xyes])
 #  ----------------------------------------------------------------------
 # Compile with MPI support
-AC_ARG_ENABLE(mpi,AS_HELP_STRING([--enable-mpi],[Compile with MPI compiler [default=no]]),enable_mpi=yes,enable_mpi=no)
+AC_ARG_ENABLE([mpi],
+  AS_HELP_STRING([--enable-mpi],
+    [Compile with MPI compiler @<:@default=no@:>@]),
+    [enable_mpi=yes
+     ACX_C_PACKAGE([MPI],[mpi.h],,,
+       [AC_MSG_FAILURE([Required header mpi.h not found or not compilable.])
+        enable_MPI=no],[MPI_Waitall],[mpi mpich],,,
+       [AC_MSG_FAILURE([Cannot link C MPI programs.])
+        enable_MPI=no])
+     AS_IF([test -n "$FC" && test "X$FC" != "Xno"],
+       [ACX_FORTRAN_PACKAGE([MPI], [mpif.h],,,
+          [AC_MSG_FAILURE([Required include mpif.h not found or not compilable.])
+           enable_MPI=no],[mpi_waitall],
+          [mpi mpi_f90 mpi_f77 mpich],[[-lmpi_f77 -lmpi],[-lmpi]],,
+          [AC_MSG_FAILURE([Cannot link Fortran MPI programs.])
+           enable_MPI=no],[])])],
+    [enable_mpi=no])
 AS_IF([test x"${enable_mpi}" = x"yes"],
       [USE_MPI=yes])
 HAVE_PARALLEL_NC4=0
@@ -217,6 +236,7 @@ AC_SUBST([HAVE_PARALLEL_NC4])
 AM_CONDITIONAL([USE_MPI],[test x"$USE_MPI" = xyes])
 AM_CONDITIONAL([USE_PPM_CORE],[test $enable_ppm = yes])
 AC_SUBST([USE_MPI])
+AC_SUBST([ENABLE_MPI],[`test x"$enable_mpi" = xyes && echo true || echo false`])
 #  ----------------------------------------------------------------------
 #  Create the Fortran Interface via iso_c_binding module (Fortran 2003 Standard)
 AC_ARG_ENABLE([iso-c-interface],
@@ -306,40 +326,20 @@ AM_CONDITIONAL([USE_FC],[test -n "$FC" && test "X$FC" != "Xno" && test x$acx_cv_
 dnl
 AC_SUBST([CPPFLAGS])dnl
 dnl
-AC_ARG_VAR([BUILD_CFLAGS],
-  [append to CFLAGS during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([CFLAGS="$CFLAGS${BUILD_CFLAGS+ $BUILD_CFLAGS}"])dnl
-AM_SUBST_NOTMAKE([BUILD_CFLAGS])dnl
-AC_ARG_VAR([BUILD_FCFLAGS],
-  [append to FCFLAGS during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([FCFLAGS="$FCFLAGS${BUILD_FCFLAGS+ $BUILD_FCFLAGS}"])dnl
-AM_SUBST_NOTMAKE([BUILD_FCFLAGS])dnl
-AC_ARG_VAR([BUILD_LDFLAGS],
-  [append to LDFLAGS during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([LDFLAGS="$LDFLAGS${BUILD_LDFLAGS+ $BUILD_LDFLAGS}"])dnl
-AM_SUBST_NOTMAKE([BUILD_LDFLAGS])dnl
-AC_ARG_VAR([BUILD_LIBS],
-  [append to LIBS during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([LIBS="$LIBS${BUILD_LIBS+ $BUILD_LIBS}"])dnl
-AM_SUBST_NOTMAKE([BUILD_LIBS])dnl
-AC_ARG_VAR([BUILD_CC],
-  [replace CC with expansion of $BUILD_CC during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([CC="${BUILD_CC-$CC}"])dnl
-AM_SUBST_NOTMAKE([BUILD_CC])dnl
-AC_ARG_VAR([BUILD_CXX],
-  [replace CXX with expansion of $BUILD_CXX during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([CXX="${BUILD_CXX-$CXX}"])dnl
-AM_SUBST_NOTMAKE([BUILD_CXX])dnl
-AC_ARG_VAR([BUILD_FC],
-  [replace FC with expansion of $BUILD_FC during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([FC="${BUILD_FC-$FC}"])dnl
-AM_SUBST_NOTMAKE([BUILD_FC])dnl
-AC_ARG_VAR([BUILD_F77],
-  [replace F77 with expansion of $BUILD_F77 during build but not in configure phase])dnl
-AC_CONFIG_COMMANDS_PRE([F77="${BUILD_F77-$F77}"])dnl
-AM_SUBST_NOTMAKE([BUILD_F77])dnl
-
+m4_foreach([build_flag_var],[[BUILD_CFLAGS],[BUILD_FCFLAGS],[BUILD_LDFLAGS],[BUILD_LIBS],[BUILD_MPI_C_LIB],[BUILD_MPI_FC_LIB],[BUILD_C_INCLUDE],[BUILD_FC_INCLUDE]],
+  [AC_ARG_VAR(build_flag_var,
+     [append to ]m4_bpatsubst(build_flag_var, [BUILD_], [])[ during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_flag_var, [BUILD_], [])[="$]m4_bpatsubst(build_flag_var, [BUILD_], [])[$]{build_flag_var+ $build_flag_var[}"])dnl
+AM_SUBST_NOTMAKE(build_flag_var)])dnl
 
+m4_foreach([build_tool_var],[[BUILD_CC],[BUILD_CXX],[BUILD_FC],[BUILD_F77]],
+  [AC_ARG_VAR(build_tool_var,
+     [replace ]m4_bpatsubst(build_tool_var, [BUILD_], [])[ with expansion of $]build_tool_var[ during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE(m4_bpatsubst(build_tool_var, [BUILD_], [])[="$]{build_tool_var-$[]m4_bpatsubst(build_tool_var, [BUILD_], [])}["])dnl
+AM_SUBST_NOTMAKE(build_tool_var)])dnl
+dnl
+dnl
+dnl
 # Checks for compiler
 COMPILER="$CC $CFLAGS"
 AC_DEFINE_UNQUOTED(COMPILER, ["$COMPILER"], [Compiler])
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 75b630c..5ff9873 100644
Binary files a/libcdi/doc/cdi_cman.pdf and b/libcdi/doc/cdi_cman.pdf differ
diff --git a/libcdi/doc/cdi_fman.pdf b/libcdi/doc/cdi_fman.pdf
index 1e69024..8b936e7 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/examples/Makefile.in b/libcdi/examples/Makefile.in
index 33c054c..e7ec26b 100644
--- a/libcdi/examples/Makefile.in
+++ b/libcdi/examples/Makefile.in
@@ -89,17 +89,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -270,6 +279,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -317,6 +327,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
diff --git a/libcdi/examples/cdi_read_f2003.f90 b/libcdi/examples/cdi_read_f2003.f90
index 9128712..1281e1b 100644
--- a/libcdi/examples/cdi_read_f2003.f90
+++ b/libcdi/examples/cdi_read_f2003.f90
@@ -11,7 +11,7 @@ PROGRAM CDIREADF2003
   DOUBLE PRECISION, ALLOCATABLE :: field(:,:)
   CHARACTER(kind=c_char), POINTER, DIMENSION(:) :: &
        msg, cdi_version
-  CHARACTER(kind=c_char), DIMENSION(cdi_max_name + 1) :: &
+  CHARACTER(kind=c_char, LEN = cdi_max_name + 1) :: &
        name, longname, units
   INTEGER :: name_c_len, longname_c_len, units_c_len
 
diff --git a/libcdi/examples/pio/Makefile.am b/libcdi/examples/pio/Makefile.am
index 5f28c90..88bbc1a 100644
--- a/libcdi/examples/pio/Makefile.am
+++ b/libcdi/examples/pio/Makefile.am
@@ -1,7 +1,8 @@
 noinst_PROGRAMS=collectData collectDataNStreams
 
 AM_CPPFLAGS = -I$(top_srcdir)/src $(YAXT_CFLAGS)
-AM_FCFLAGS  = $(FPP_INCOPT)$(top_srcdir)/src
+AM_FCFLAGS  = $(FPP_INCOPT)$(top_srcdir)/src $(MPI_FC_INCLUDE)
+AM_CFLAGS = $(MPI_C_INCLUDE)
 
 if USE_MPI
 noinst_PROGRAMS+=compareResourcesArray
@@ -15,14 +16,15 @@ endif
 collectData_SOURCES=collectData.c
 
 if USE_MPI
-LDADD=$(top_builddir)/src/libcdipio.la
+LDADD=$(top_builddir)/src/libcdipio.la $(MPI_C_LIB)
+collectData2003_LDADD=$(top_builddir)/src/libcdipio.la $(MPI_FC_LIB)
 else
-LDADD=
+LDADD=$(top_builddir)/src/libcdi.la
+collectData2003_LDADD=$(top_builddir)/src/libcdi.la
 endif
-LDADD+=$(top_builddir)/src/libcdi.la
 
 collectData2003_SOURCES=collectData2003.F90
 
-collectDataNStreams_SOURCES=collectDataNStreams.c
+collectDataNStreams_SOURCES = collectDataNStreams.c
 
-compareResourcesArray_SOURCES=compareResourcesArray.c
+compareResourcesArray_SOURCES = compareResourcesArray.c
diff --git a/libcdi/examples/pio/Makefile.in b/libcdi/examples/pio/Makefile.in
index ec6029c..dee19ea 100644
--- a/libcdi/examples/pio/Makefile.in
+++ b/libcdi/examples/pio/Makefile.in
@@ -90,17 +90,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -114,23 +123,23 @@ PROGRAMS = $(noinst_PROGRAMS)
 am_collectData_OBJECTS = collectData.$(OBJEXT)
 collectData_OBJECTS = $(am_collectData_OBJECTS)
 collectData_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
 @USE_MPI_FALSE at collectData_DEPENDENCIES =  \
 @USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
 @USE_MPI_TRUE at collectData_DEPENDENCIES =  \
 @USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
- at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_1)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
 am_collectData2003_OBJECTS = collectData2003.$(OBJEXT)
 collectData2003_OBJECTS = $(am_collectData2003_OBJECTS)
-collectData2003_LDADD = $(LDADD)
 @USE_MPI_FALSE at collectData2003_DEPENDENCIES =  \
 @USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
 @USE_MPI_TRUE at collectData2003_DEPENDENCIES =  \
 @USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
- at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_1)
 am_collectDataNStreams_OBJECTS = collectDataNStreams.$(OBJEXT)
 collectDataNStreams_OBJECTS = $(am_collectDataNStreams_OBJECTS)
 collectDataNStreams_LDADD = $(LDADD)
@@ -138,7 +147,7 @@ collectDataNStreams_LDADD = $(LDADD)
 @USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
 @USE_MPI_TRUE at collectDataNStreams_DEPENDENCIES =  \
 @USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
- at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_1)
 am_compareResourcesArray_OBJECTS = compareResourcesArray.$(OBJEXT)
 compareResourcesArray_OBJECTS = $(am_compareResourcesArray_OBJECTS)
 compareResourcesArray_LDADD = $(LDADD)
@@ -146,7 +155,7 @@ compareResourcesArray_LDADD = $(LDADD)
 @USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
 @USE_MPI_TRUE at compareResourcesArray_DEPENDENCIES =  \
 @USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
- at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_1)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -264,6 +273,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -311,6 +321,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
@@ -418,11 +433,14 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(top_srcdir)/src $(YAXT_CFLAGS)
-AM_FCFLAGS = $(FPP_INCOPT)$(top_srcdir)/src $(am__append_2)
+AM_FCFLAGS = $(FPP_INCOPT)$(top_srcdir)/src $(MPI_FC_INCLUDE) \
+	$(am__append_2)
+AM_CFLAGS = $(MPI_C_INCLUDE)
 collectData_SOURCES = collectData.c
 @USE_MPI_FALSE at LDADD = $(top_builddir)/src/libcdi.la
- at USE_MPI_TRUE@LDADD = $(top_builddir)/src/libcdipio.la \
- at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@LDADD = $(top_builddir)/src/libcdipio.la $(MPI_C_LIB)
+ at USE_MPI_FALSE@collectData2003_LDADD = $(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@collectData2003_LDADD = $(top_builddir)/src/libcdipio.la $(MPI_FC_LIB)
 collectData2003_SOURCES = collectData2003.F90
 collectDataNStreams_SOURCES = collectDataNStreams.c
 compareResourcesArray_SOURCES = compareResourcesArray.c
diff --git a/libcdi/examples/pio/compareResourcesArray.c b/libcdi/examples/pio/compareResourcesArray.c
index 53dc0f5..1cd4459 100644
--- a/libcdi/examples/pio/compareResourcesArray.c
+++ b/libcdi/examples/pio/compareResourcesArray.c
@@ -4,7 +4,6 @@
 
 #include <stdio.h>
 
-#ifdef USE_MPI
 #include <mpi.h>
 #include <yaxt.h>
 #include "cdi.h"
@@ -223,23 +222,20 @@ static void modelRun ( MPI_Comm comm )
   return;
 }
 
-#endif 
-
-int main (int argc, char *argv[]) 
+int main (int argc, char *argv[])
 {
-#ifdef USE_MPI
   int sizeGlob, pioNamespace;
   MPI_Comm commGlob, commModel;
 
-  MPI_Init(&argc, &argv);           
+  MPI_Init(&argc, &argv);
   commGlob = MPI_COMM_WORLD;
   xt_initialize(commGlob);
   xmpi ( MPI_Comm_set_errhandler ( commGlob, MPI_ERRORS_RETURN ));
-  xmpi ( MPI_Comm_size ( commGlob, &sizeGlob )); 
+  xmpi ( MPI_Comm_size ( commGlob, &sizeGlob ));
 
-  if ( sizeGlob != 1 )                                         
+  if ( sizeGlob != 1 )
       xabort ( "test transition of resource array only with 1 PE." );
-                                         
+
   if ( nProcsIO != 1 )
     xabort ( "bad distribution of tasks on PEs" );
 
@@ -250,10 +246,7 @@ int main (int argc, char *argv[])
   modelRun ( commModel );
 
   xt_finalize();
-  MPI_Finalize (); 
-#else
-  printf ( "Use MPI for this testprogram.\n" );
-#endif
+  MPI_Finalize ();
 
   return 0;
 }
diff --git a/libcdi/interfaces/Makefile.in b/libcdi/interfaces/Makefile.in
index 40faeee..646a909 100644
--- a/libcdi/interfaces/Makefile.in
+++ b/libcdi/interfaces/Makefile.in
@@ -96,17 +96,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -248,6 +257,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -295,6 +305,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
diff --git a/libcdi/interfaces/cdi.hpp b/libcdi/interfaces/cdi.hpp
index a248568..96bdbb0 100644
--- a/libcdi/interfaces/cdi.hpp
+++ b/libcdi/interfaces/cdi.hpp
@@ -40,7 +40,8 @@ class CdiTaxis {
     int ntsteps, unit;
     int rdate, rtime, vdate, vtime;
     int type, calendar, hasBounds;
-    char name[CHARSIZE], *unitname;
+    char name[CHARSIZE];
+    const char *unitname;
 };
 
 class CdiZaxis {
diff --git a/libcdi/interfaces/f2003/bindGen.rb b/libcdi/interfaces/f2003/bindGen.rb
index 6cff430..b643f47 100755
--- a/libcdi/interfaces/f2003/bindGen.rb
+++ b/libcdi/interfaces/f2003/bindGen.rb
@@ -1,508 +1,780 @@
 #!/usr/bin/env ruby
-require 'optparse'
-################################################################
-# CONFIGURATION:
-CFTypeInfo             = {
-  'int'                  => {:namedConst       => 'c_int'                , :ftype => 'integer'},
-  'short int'            => {:namedConst       => 'c_short'              , :ftype => 'integer'},
-  'long int'             => {:namedConst       => 'c_long'               , :ftype => 'integer'},
-  'long long int'        => {:namedConst       => 'c_long_long'          , :ftype => 'integer'},
-  'signed char'          => {:namedConst       => 'c_signed_char'        , :ftype => 'integer'},
-  'unsigned char'        => {:namedConst       => 'c_signed_char'        , :ftype => 'integer'},
-  'size_t'               => {:namedConst       => 'c_size_t'             , :ftype => 'integer'},
-  'int8_t'               => {:namedConst       => 'c_int8_t'             , :ftype => 'integer'},
-  'int16_t'              => {:namedConst       => 'c_int16_t'            , :ftype => 'integer'},
-  'int32_t'              => {:namedConst       => 'c_int32_t'            , :ftype => 'integer'},
-  'int64_t'              => {:namedConst       => 'c_int64_t'            , :ftype => 'integer'},
-  'int_fast8_t'          => {:namedConst       => 'c_int_fast8_t'        , :ftype => 'integer'},
-  'int_fast16_t'         => {:namedConst       => 'c_int_fast16_t'       , :ftype => 'integer'},
-  'int_fast32_t'         => {:namedConst       => 'c_int_fast32_t'       , :ftype => 'integer'},
-  'int_fast64_t'         => {:namedConst       => 'c_int_fast64_t'       , :ftype => 'integer'},
-  'int_least8_t'         => {:namedConst       => 'c_int_least8_t'       , :ftype => 'integer'},
-  'int_least16_t'        => {:namedConst       => 'c_int_least16_t'      , :ftype => 'integer'},
-  'int_least32_t'        => {:namedConst       => 'c_int_least32_t'      , :ftype => 'integer'},
-  'int_least64_t'        => {:namedConst       => 'c_int_least64_t'      , :ftype => 'integer'},
-  'intmax_t'             => {:namedConst       => 'c_intmax_t'           , :ftype => 'integer'},
-  'intptr_t'             => {:namedConst       => 'c_intptr_t'           , :ftype => 'integer'},
-
-  'float'                => {:namedConst       => 'c_float'              , :ftype => 'real'},
-  'double'               => {:namedConst       => 'c_double'             , :ftype => 'real'},
-  'long double'          => {:namedConst       => 'c_long_double'        , :ftype => 'real'},
-
-  'float _Complex'       => {:namedConst       => 'c_float_complex'      , :ftype => 'complex'},
-  'double _Complex'      => {:namedConst       => 'c_double_complex'     , :ftype => 'complex'},
-  'long double _Complex' => {:namedConst       => 'c_long_double_complex', :ftype => 'complex'},
-  '_Bool'                => {:namedConst       => 'c_bool'               , :ftype => 'logical'},
-  'char'                 => {:namedConst       => 'c_char'               , :ftype => 'character'}
-}
-# how the module should be invoked from fortran
-ModuleName    = 'mo_cdi'
-# which conversion is to use generating the fortran routine names, this could
-# be any ruby String method.
-FNameMethod   = :noop
-# FNameMethod = :downcase
-# FNameMethod = :noop
-# FNameMethod = :upcase
-class String;def noop;self;end;end
-# fortran subroutines are not allowed to have a parameters with the same name,
-# so in case of a match, these parameters have to get an new name
-FParamExtension = 'v'
-# Naming convention from above: 
-# all non scalar variables should have the postfix '_vec' in there name
-Vectors = /_vec$/i
-################################################################################
-FortranMaxLineLength = 132
-# read the c header file and grep out name, return type and paramterlist of
-# each function
-def getFuncInfo(filename)
-  typelist = %w[char int float double void]
-  cppflags = ENV['CPPFLAGS'].nil? ? '' : ENV['CPPFLAGS']
-  funclist = IO.popen("cpp #{cppflags} #{filename} | cpp -fpreprocessed").readlines.delete_if {|line| line.include?('#')}.collect {|line| line.chomp}
-  # delete everything, that do not look like a function prototype
-  typeRegexp = /^.*(#{typelist.join('|')}) \**\w+\s*\(.*\)/
-  funclist.delete_if {|line|
-    not typeRegexp.match(line.lstrip)
-  }
-  funclist.collect! {|line|
-    md = /(\w+)+ +(\**)(\w+)\s*\((.*)\)/.match(line)
-    returnType, returnPointer, funcName, paramList = md[1,4]
-    paramList = paramList.split(',').collect {|p| p.split(' ').each {|_p| _p.strip}}
-    [funcName, returnType, returnPointer, paramList]
-  }
-  funclist
-end
 
-# grep the #define C-Constants, which should be available within the fortran CDI API
-def getDefines(filename)
-  defines = File.open(filename,'r').readlines.grep(/^#define/).collect {|line|
-    md = / +(\w+) +(-*\d+)/.match(line)
-  }.select {|item| not item.nil?}.collect {|match| match[1..2]}
+# This script generates a fortran source file that uses the ISO_C_BINDINGS to interface to the functions defined in the given C header file.
+# The basic approach is, that every C function is wrapped in a fortran function/subroutine, which internally uses a bind(c) interface to the C code.
+# This wrapper based approach has the advantage that the wrapper is free to provide a true fortran interface
+# that enables full type checking of its arguments; the pure bind(c) interface would not be able to distinguish
+# between different opaque pointer types, for instance, nor would it be able to infer the size of a static string returned by a C function.
+#
+# Within this header file, the following constructs are recognized:
+#
+#   * #define FOO 123
+#   * typedef struct foo foo;
+#   * typedef struct foo { ... } foo;
+#   * ... foo(...);
+#
+# These constructs are used to divide a source line into parts that are recognizable by the templates defined below.
+# A function definition, for instance, is divided into a return type, a function name, and a number of argument definitions,
+# the return type and argument descriptions are matched against templates which define the translation of these parts into fortran code.
+# Note that all these constructs must be one-liners since processing in this script is line based.
+#
+# Every template is a hash that contains an entry :regex, which is used to match it against the corresponding C declaration.
+# There are a couple of placeholders that may be used within these regex strings, they are expanded by matchTemplate() before a Regexp object is constructed from the string in :regex.
+# These placeholders are:
+#	<integerTypes>	matches the C integer types that can be used within Fortran by prefixing 'c_' to the type
+#	<floatTypes>	matches the C floating point types that can be used within Fortran by prefixing 'c_' to the type
+#	<opaqueTypes>	matches all the opaque types defined within the header
+#	<publicTypes>	matches all the public types defined within the header
+#
+# In the case of argument and type templates, this :regex may contain one or more named subexpressions /(?<name>...)/,
+# which can be included in the other fields by means of a corresponding placeholder "<name>".
+# The names of the subexpressions that are to be substituted in this way need to be listed in the :placeholders key.
+# This is usually used to capture the variable name, and then use "<name>_foo" to derive fortran variable names from the argument name,
+# but it may also be used to capture the size of an array declaration.
+# Since fortran uses so many keywords that can easily conflict with C argument names, it is a good idea not to use a naked "<name>";
+# always append something to it as in "<name>_dummy"
+#
+# Argument templates must provide the following fields:
+#	:regex	A regex that matches the whole definition of a C argument. Make sure it only matches the cases that the template can actually handle!
+#	:placeholders	An array of the name of the named subexpressions used in the regex. For the :regex => /(?<foo>.),(?<bar>.)/ you would use :placeholders => %w[foo bar]
+#	:dummyName	The name of the fortran dummy argument. Both the wrapper function and the `bind(c)` interface use the same name.
+#	:acceptAs	The declaration of the dummy argument in the fortran wrapper.
+#	:helperVars	Declarations of additional variables needed to provide the desired functionality in the wrapper function.
+#	:precallStatements	Code that needs to be executed before the C function is called.
+#	:callExpression	The actual argument that the wrapper passes to the C function.
+#	:passAs	The declaration of the dummy argument in the `bind(c)` interface.
+#	:postcallStatements	Code that needs to be executed after the C function returns.
+#
+#
+#
+# Return type templates are similar to argument templates, but they have to deal with the fact that fortran differentiates between subroutines and functions. Because of this, return type templates add the :isVoid key which is only true if the C function returns `void`.
+#
+# Return type templates must provide the following fields:
+#	:regex	A regex that matches the whole definition of a C return type. Make sure it only matches the cases that the template can actually handle!
+#	:isVoid	Always false, except for the template for `void`.
+#	:returnAs	The type of the fortran wrapper function.
+#	:helperVars	Declarations of additional variables needed to provide the desired functionality in the wrapper function.
+#	:precallStatements	Code that needs to be executed before the C function is called.
+#	:recieveAs	The type of the `bind(c)` interface function.
+#	:assignVariable	The expression that the result of the C function is assigned to.
+#	:postcallStatements	Code that needs to be executed after the C function returns.
+#
+#
+#
+# Type templates are used for the variables in public `struct` definitions. These are much simpler as they only have to translate a C variable declaration into an interoperable fortran variable declaration.
+#
+# Type templates must provide the following fields:
+#	:regex	A regex that matches the whole C variable definition. Make sure it only matches the cases that the template can actually handle!
+#	:placeholders	An array of the name of the named subexpressions used in the regex. Same semantics as in an argument template.
+#	:declareAs	The declaration of the corresponding fortran derived type member.
+#
+#
+#
+# The wrapper that is generated for a non-void C function looks like this:
+#
+#	function fname(:dummyName...) result(result)
+#		:returnAs :: result
+#		:acceptAs...
+#		:helperVars...
+#		interface
+#			:recieveAs function lib_fname(:dummyName...) bind(c, name = 'fname')
+#				import <importConstants>
+#				:passAs...
+#			end function lib_fname
+#		end interface
+#		:precallStatements
+#		:assignVariable = lib_fname(:callExpression)
+#		:postcallStatements
+#	end function fname
+#
+#
+#
+# The wrapper that is generated for a void C function looks like this:
+#
+#	subroutine fname(:dummyName...)
+#		:acceptAs...
+#		:helperVars...
+#		interface
+#			subroutine lib_fname(:dummyName...) bind(c, name = 'fname')
+#				import <importConstants>
+#				:passAs...
+#			end subroutine lib_fname
+#		end interface
+#		:precallStatements
+#		call lib_fname(:callExpression)
+#		:postcallStatements
+#	end subroutine fname
+
+####################################################################################################
+# Template definitions #############################################################################
+####################################################################################################
+
+$argumentTemplates = [
+	{	#Dummy for declarations using foo(void).
+		:regex => '^\s*void\s*$',
+		:placeholders => %w[],
+		:dummyName => '',
+		:acceptAs => '',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '',
+		:passAs => '',
+		:postcallStatements => ''
+	}, {	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s+(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), value :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), value :: <name>_dummy',
+		:postcallStatements => ''
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s+(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), value :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), value :: <name>_dummy',
+		:postcallStatements => ''
+	},
+	#Array arguments. These are marked by a `_vec` suffix by convention.
+	#Since it's near impossible to write regexs that only match names that do *not* end in a given suffix,
+	#these templates must precede the more general templates for pointer arguments.
+	#That way, we can override the more general template with the more special one if both match.
+	{	#<integerTypes>* <name>_vec
+		:regex => '^\s*(?<type><integerTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#<floatTypes>* <name>_vec
+		:regex => '^\s*(?<type><floatTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#unsigned char <name>[<size>]
+		:regex => '^\s*unsigned\s+char\s+(?<name>\w+)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char), intent(inout) :: <name>_dummy(<size>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'character(kind = c_char), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <integerTypes>* <name>_vec
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <floatTypes>* <name>_vec
+		:regex => '^\s*const\s+(?<type><floatTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), intent(in) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const unsigned char <name>[<size>]
+		:regex => '^\s*(const\s+unsigned\s+char|unsigned\s+char\s+const)\s+(?<name>\w+)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char), intent(in) :: <name>_dummy(<size>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'character(kind = c_char), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <integerTypes> <name>[<lineCount>][<lineSize>]
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s+(?<name>\w+)\s*\[\s*(?<lineCount>[^\]]+)\s*\]\s*\[\s*(?<lineSize>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name type lineCount lineSize],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(in) :: <name>_dummy(<lineSize>, <lineCount>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	},
+	#Pointer arguments. These match both pointers and arrays, so they must appear after the more special array templates.
+	#Most of these are wrapped by optional arguments which have to be named in calling code, which is why we don't use the _dummy suffix for them.
+	{	#<integerTypes>*
+		:regex => '^\s*(?<type><integerTypes>)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>',
+		:acceptAs => 'integer(c_<type>), optional, intent(inout) :: <name>',
+		:helperVars => "integer(c_<type>), target :: <name>_temp\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	}, {	#<floatTypes>*
+		:regex => '^\s*(?<type><floatTypes>)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>',
+		:acceptAs => 'real(c_<type>), optional, intent(inout) :: <name>',
+		:helperVars => "real(c_<type>), target :: <name>_temp\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	}, {	#unsigned char (*<name>)[<size>]
+		:regex => '^\s*unsigned\s+char\s*\(\s*\*\s*(?<name>\w+)\s*\)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>',
+		:acceptAs => 'character(kind = c_char), optional, intent(inout) :: <name>(<size>)',
+		:helperVars => "character(kind = c_char), target :: <name>_temp(<size>)\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	},
+	#String arguments.
+	{	#char*	Unsafe buffer passing
+		:regex => '^\s*char\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char, len = *), intent(inout) :: <name>_dummy',
+		:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy))\n" +
+		               "integer :: <name>_i\n" +
+		               "logical :: <name>_padding = .true.",
+		:precallStatements => "do <name>_i = len(<name>_dummy), 1, -1\n" +
+		                      "\tif(<name>_dummy(<name>_i:<name>_i) /= ' ') <name>_padding = .false.\n" +
+		                      "\tif(<name>_padding) then\n" +
+		                      "\t\t<name>_temp(<name>_i) = c_null_char\n" +
+		                      "\telse\n" +
+		                      "\t\t<name>_temp(<name>_i) = <name>_dummy(<name>_i:<name>_i)\n" +
+		                      "\tend if\n" +
+		                      "end do",
+		:callExpression => '<name>_temp',
+		:passAs => 'character(kind = c_char) :: <name>_dummy(*)',
+		:postcallStatements => "<name>_padding = .false.\n" +
+		                       "do <name>_i = 1, len(<name>_dummy)\n" +
+		                       "\tif(<name>_temp(<name>_i) == c_null_char) <name>_padding = .true.\n" +
+		                       "\tif(<name>_padding) then\n" +
+		                       "\t\t<name>_dummy(<name>_i:<name>_i) = ' '\n" +
+		                       "\telse\n" +
+		                       "\t\t<name>_dummy(<name>_i:<name>_i) = <name>_temp(<name>_i)\n" +
+		                       "\tend if\n" +
+		                       "end do"
+	}, {	#const char*	Safe passing of an input string.
+		:regex => '^\s*(const\s+char|char\sconst)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char, len = *), intent(in) :: <name>_dummy',
+		:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy) + 1)\ninteger :: <name>_i",
+		:precallStatements => "do <name>_i = 1, len(<name>_dummy)\n<name>_temp(<name>_i) = <name>_dummy(<name>_i:<name>_i)\nend do\n<name>_temp(len(<name>_dummy) + 1) = c_null_char",
+		:callExpression => '<name>_temp',
+		:passAs => 'character(kind = c_char) :: <name>_dummy(*)',
+		:postcallStatements => ''
+	}, {	#char**	Safe returning of an output string.
+		:regex => '^\s*char\s*\*\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>',
+		:acceptAs => 'character(kind = c_char), pointer, optional, intent(inout) :: <name>(:)',
+		:helperVars => "type(c_ptr), target :: <name>_ptr\n" +
+		               "type(c_ptr) :: <name>_handle\n" +
+		               "integer :: <name>_shape(1)\n" +
+		               "character(kind = c_char), pointer :: <name>_fptr(:)",
+		:precallStatements => "<name>_handle = c_null_ptr\n" +
+		                      "if(present(<name>)) <name>_handle = c_loc(<name>_ptr)",
+		:callExpression => '<name>_handle',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) then\n" +
+		                       "\tif(c_associated(<name>_ptr)) then\n" +
+		                       "\t\t<name>_shape(1) = int(lib_strlen(<name>_ptr))\n" +
+		                       "\t\tcall c_f_pointer(<name>_ptr, <name>_fptr, <name>_shape)\n" +
+		                       "\t\tallocate(<name>(<name>_shape(1)))\n" +
+		                       "\t\t<name> = <name>_fptr\n" +
+		                       "\t\tcall lib_free(<name>_ptr)\n" +
+		                       "\telse\n" +
+		                       "\t\t<name> => null()\n" +
+		                       "\tend if\n" +
+		                       "end if"
+	},
+	#Public and opaque types
+	{	#[const] <opaqueTypes>*
+		:regex => '^\s*(const\s+|)(?<type><opaqueTypes>)(\s+const|)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'type(t_<type>), intent(in) :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy%ptr',
+		:passAs => 'type(c_ptr), value :: <name>_dummy',
+		:postcallStatements => ''
+	}
+]
+
+$returnTypeTemplates = [
+	{	#void
+		:regex => '^\s*void\s*$',
+		:placeholders => %w[],
+		:isVoid => true
+	}, {	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'integer(c_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'integer(c_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'real(c_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'real(c_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#char*
+		:regex => '^\s*char\s*\*\s*$',
+		:placeholders => %w[],
+		:isVoid => false,
+		:returnAs => 'character(kind = c_char), dimension(:), pointer',
+		:helperVars => "type(c_ptr) :: cString\n" +
+		               "integer :: shape(1)\n" +
+		               "character(kind = c_char), dimension(:), pointer :: temp",
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'cString',
+		:postcallStatements => "if(c_associated(cString)) then\n" +
+		                       "\tshape(1) = int(lib_strlen(cString))\n" +
+		                       "\tcall c_f_pointer(cString, temp, shape)\n" +
+		                       "\tallocate(result(shape(1)))\n" +
+		                       "\tresult = temp\n" +
+		                       "\tcall lib_free(cString)\n" +
+		                       "else\n" +
+		                       "\tresult => null()\n" +
+		                       "end if"
+	}, {	#const char*
+		:regex => '^\s*const\s+char\s*\*\s*$',
+		:placeholders => %w[],
+		:isVoid => false,
+		:returnAs => 'character(kind = c_char), dimension(:), pointer',
+		:helperVars => "type(c_ptr) :: ptr\ninteger :: shape(1)",
+		:precallStatements => 'result => null()',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'ptr',
+		:postcallStatements => "if(c_associated(ptr)) then\n" +
+		                       "\tshape(1) = int(lib_strlen(ptr))\n" +
+		                       "\tcall c_f_pointer(ptr, result, shape)\n" +
+		                       "end if"
+	}, {	#const int*	This returns the naked pointer because we can't know the length of the returned array within the wrapper. The user has to call c_f_pointer() himself.
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(c_ptr)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#const double*	This returns the naked pointer because we can't know the length of the returned array within the wrapper. The user has to call c_f_pointer() himself.
+		:regex => '^\s*const\s+(?<type><floatTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(c_ptr)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	},
+	#Public and opaque types.
+	{	#<publicTypes>
+		:regex => '^\s*(?<type><publicTypes>)\s+$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(t_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(t_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#<opaqueTypes>*
+		:regex => '^\s*(?<type><opaqueTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(t_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result%ptr',
+		:postcallStatements => ''
+	}
+]
+
+$typeTemplates = [
+	{	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s+(?<name>\w+)\s*;$',
+		:placeholders => %w[name type],
+		:declareAs => "integer(c_<type>) :: <name>"
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s+(?<name>\w+)\s*;$',
+		:placeholders => %w[name type],
+		:declareAs => "real(c_<type>) :: <name>"
+	}
+]
+
+####################################################################################################
+# Verbatim Fortran Code ############################################################################
+####################################################################################################
+
+$verbatimDeclarations = '
+	public ctrim
+	public c_len
+
+	interface
+		integer(c_size_t) function lib_strlen(charPtr) bind(c, name = "strlen")
+			import c_size_t, c_ptr
+			type(c_ptr), value :: charPtr
+		end function lib_strlen
+
+		subroutine lib_free(pointer) bind(c, name = "free")
+			import c_ptr
+			type(c_ptr), value :: pointer
+		end subroutine lib_free
+	end interface
+'
+
+$verbatimDefinitions = "
+	subroutine ctrim(str)
+		character(kind = c_char, len = *), intent(inout) :: str
+		integer :: i
+
+		do i=1,len(str)
+			if (str(i:i) == c_null_char) then
+				str(i:len(str)) = ' '
+				exit
+			end if
+		end do
+	end subroutine ctrim
+
+	function c_len(s) result(i)
+		character(kind = c_char, len = *), intent(in) :: s
+		integer :: i
+
+		do i = 1, len(s)
+			if (s(i:i) == c_null_char) exit
+		end do
+		i = i - 1
+	end function
+"
+
+####################################################################################################
+# Code to interpret the templates ##################################################################
+####################################################################################################
+
+$declarationLines = []
+$definitionLines = []
+$opaqueTypes = []
+$publicTypes = []
+
+#This substitutes the placeholders <opaqueTypes> and <publicTypes> in the regexString prior to constructing a Regexp out of it.
+def matchTemplate(regexString, matchString)
+	opaqueTypesString = "(#{ $opaqueTypes.collect{ |type| type }.join('|') })"
+	regexString = regexString.gsub("<opaqueTypes>", opaqueTypesString)
+	publicTypesString = "(#{ $publicTypes.collect{ |type| type }.join('|') })"
+	regexString = regexString.gsub("<publicTypes>", publicTypesString)
+	regexString = regexString.gsub("<integerTypes>", '(short|int|long|size_t|intmax_t|int_(least|fast)(8|16|32|64)_t)')
+	regexString = regexString.gsub("<floatTypes>",  '(float|double)')
+	return Regexp.new(regexString).match(matchString)
 end
 
-# create continuation for lines longer that 132 sign, which would create an
-# error with some fortran compilers
-def genContinuation(iline)
-  # leave the input untouched
-  line = iline
-  # try to create readable line breaks, i.e. do not split name, labels or keywords
-  regexp = /,[^,]*$/
-
-  matchIndex = line[0,FortranMaxLineLength] =~ regexp
-
-  if matchIndex.nil?
-    line[FortranMaxLineLength-2] = "&\n"+line[FortranMaxLineLength-2,1]+"&"
-  else
-    line[matchIndex] = ",&\n" + ' '*7
-  end
-  line
+class TemplateInstanciation
+	def initialize(argumentString, template)
+		@template = template
+		@matchData = matchTemplate(template[:regex], argumentString)
+		@placeholders = []
+		template[:placeholders].each { |placeholder|
+			@placeholders.push({ :name => placeholder, :regex => Regexp.new("<#{placeholder}>") })
+		}
+	end
+
+	def expandTemplate(templateKey)
+		result = @template[templateKey]
+		#Replace all placeholders with their expansion.
+		@placeholders.each { |current|
+			result = result.gsub(current[:regex], @matchData[current[:name]])
+		}
+		return result
+	end
 end
 
-
-# create fortran module variables
-def genModParams(vars)
-  vars.collect {|var, value|
-    "      integer, parameter :: #{var} = #{value}"
-  }.join("\n")
+def formatLines(lineArray, indentation, string)
+	if string == "" && indentation == 0
+		lineArray.push("")	#split() does not return anything if the string is empty, killing our empty lines
+	end
+	string.split("\n").each { |line|
+		lineArray.push("\t"*indentation + line)
+	}
 end
 
-# return the fortran version of the c parameters (name, named constant within
-# iso-c-bindig, fortran type)
-def fortranParamsWithTypes(paramList)
-  paramList.collect {|paramInfo|
-    ctype, param = paramInfo[-2,2]
-    ftype, nc    = CFTypeInfo[ctype][:ftype], CFTypeInfo[ctype][:namedConst]
-    # fortran parameters can be configured out of the c parameters
-    [param.send(FNameMethod),nc,ftype, paramInfo.include?('const')]
-  }
+def dumpStatements(indentation, argumentArray, templateKey)
+	argumentArray.each{ |argument|
+		formatLines($definitionLines, indentation, argument.expandTemplate(templateKey))
+	}
 end
-def startMod(name)
-  "
-module #{name}
-      use, intrinsic :: iso_c_binding
-
-      implicit none
 
-      private
-  "
+def defineConstant(name, value)
+	if /^(\+|-|)\d+$/.match(value)
+		formatLines($declarationLines, 1, "integer(c_int), public, parameter :: #{name} = #{value}")
+	else
+		puts("Error: value '#{value}' of constant '#{name}' is not an integer literal")
+	end
 end
-def endMod(name)
-  "\nend module #{name}\n"
-end
-def isBadFunction(returnType, returnPointer, paramList)
-  return true if (
-    # external return type
-    (returnType != 'void' and not CFTypeInfo.keys.include?(returnType)) or
-    # pointer2pointer return type
-    returnPointer.length > 1
-  )
-  paramList.each {|paramInfo|
-    next if paramInfo == ['void']
-    next if paramInfo[0] == 'void' and /^\*\w+$/.match(paramInfo[1])
-    ctype, param = paramInfo[-2,2]
-    # TJ: unnamed arguments shouldn't be matched at all but because
-    # pointer * is parsed as part of the name those need to be rejected here
-    return true if (
-      CFTypeInfo[ctype].nil? or                        # derived data type
-      param == '*' or                                  # unnamed pointer
-      param[0,2] == '**' or                            # pointer2pointer
-      (param[0,1] == '*' and /\w\[\w*\]/.match(param)) # array of pointers
-    )
-  }
-  return false
+
+def defineOpaqueType(name)
+	formatLines($declarationLines, 0, "")
+	formatLines($declarationLines, 1, "public t_#{name}")
+	formatLines($declarationLines, 1, "type t_#{name}")
+	formatLines($declarationLines, 2, "type(c_ptr) :: ptr")
+	formatLines($declarationLines, 1, "end type t_#{name}")
+	$opaqueTypes.push(name)
 end
 
-def hasDimension(paramName, paramFType)
-  return true if paramFType == 'character'
-  return true if ( %w[integer real].include?(paramFType) and Vectors.match(paramName) )
-  return false
+def findTemplate(string, templateArray)
+	templateArray.each do |template|
+		if matchTemplate(template[:regex], string)
+			return template
+		end
+	end
+	return nil
 end
 
-# collect further information about the original c type of the params and
-# in case of a match between param name and function name, the parameter name
-# is changed
-def setFortranParams(paramswithtypes,fFuncname)
-  # special treatment of empty parameter list
-  return [[],[]] if paramswithtypes == [[]]
-
-  originalParameters = paramswithtypes.transpose[0]
-  paramswithtypes.collect {|param, paramCType, fType, isConstant|
-    # test for pointers/arrays
-    isPointer, isArray, arraySize = false, false, nil
-    if param[0,1] == '*'
-      isPointer = true
-      # remove '*' from funcnames and paramnames
-      param.sub!('*','')
-    end
-    if ( md = /\w\[(\w*)\]/.match(param); not md.nil? )
-      isArray   = true
-      arraySize = md[1] == '' ? '*' : md[1]
-      param[md.begin(1)-1,md.end(1)-1] = ''
-    end
-
-    # change param name if it equals the funcname
-    if param == fFuncname or param.downcase == fFuncname.downcase
-      param += FParamExtension
-      # but maybe the result is the name of another parameter. -> play it again sam...
-      param += FParamExtension while ( originalParameters.include?(param) )
-    end
-    if param[0,1] == '_'
-      param = 'p' + param
-    end
-
-    [param,paramCType,fType,isPointer,isArray,arraySize,isConstant]
-  }
+def definePublicType(name, body)
+	formatLines($declarationLines, 0, "")
+	formatLines($declarationLines, 1, "public t_#{name}")
+	formatLines($declarationLines, 1, "type, bind(c) :: t_#{name}")
+	body.gsub(/[^;]+;/) do |variableDeclaration|
+		if template = findTemplate(variableDeclaration, $typeTemplates)
+			variable = TemplateInstanciation.new(variableDeclaration, template)
+			formatLines($declarationLines, 2, "#{variable.expandTemplate(:declareAs)}")
+		else
+			puts("Error: Can't translate the declaration '#{variableDeclaration}'")
+		end
+	end
+	formatLines($declarationLines, 1, "end type t_#{name}")
+	$publicTypes.push(name)
 end
 
-def printParams(fParams, indent)
-  out = ''
-  fParams.each {|param,paramType,ftype,ispointer,isarray,arraysize,isconstant|
-    dimension     = isarray ? "dimension(#{arraysize})" : ( (ispointer and hasDimension(param, ftype) ) ? 'dimension(*)' : nil)
-    intent, value = nil, nil
-    if (ispointer or isarray)
-      if not isconstant
-        intent = 'intent(out)'
-      else
-        intent = 'intent(in)'
-      end unless paramType == 'c_char'
-    else
-      #intent = 'intent(in)'
-      value  = 'value'
-    end
-
-    typeinfo = [value,intent,dimension].select {|s| ! s.nil?}.join(', ')
-    out << "  #{indent}#{ftype}"
-    out << (paramType == 'c_ptr' ? '' : "(kind=#{paramType})")
-    out << ", #{typeinfo} :: #{param}\n"
-  }
-  return out
+def collectImportConstants(importConstantsArray, typeString)
+	if importConstant = typeString[/\b[ct]_\w+\b/]
+		importConstantsArray.push(importConstant)
+	end
 end
 
-# creates the actual binding within the module for the given c function
-# unsupported types of function a ignored, see RESTRICTIONS (top) for details
-def genInterface(cFuncname, returnType, returnPointer, paramList, debug)
-
-  # do not create interfaces for unsupported functions
-  if isBadFunction( returnType, returnPointer, paramList)
-    warn "parameterlist of '#{cFuncname}' is not supported -> function ignored."
-    return ['','']
-  end
-  return ['', ''] if (cFuncname[0,1] == '_')
-  # the void argument type can be left out: if 'void' occurs in the
-  # parameterlist (which is only the case, if it is the only parameter
-  # information), it is simply removed and a empty paramter list is left.
-  paramList = [[],[]] if paramList.flatten == [ 'void' ] or paramList.flatten.empty?
-
-  out = ''
-  isWrapper = false
-
-  # create new names for the fortran routines, see CONFIGURATION (top)
-  fFuncname = cFuncname.send(FNameMethod)
-
-  paramsWithTypes = []
-  # divide between empty and non empty parameter lists
-  if paramList == [[],[]]
-    fParams, fParams4Import, fTypes4Import = [], [],[]
-  else
-    # collect information for setting the correct fortran type for each parameter
-    paramsWithTypes = paramList.collect {|paramInfo|
-      ctype, param = paramInfo[-2,2]
-      integral_type = /^(:?char|int|long|short)$/.match(ctype);
-      if (integral_type)
-        while (/^(:?un)?signed/.match(paramInfo[-3]))
-          ctype = paramInfo[-3] << ' ' << ctype
-          paramInfo.delete_at(-3)
-          paramInfo[-2] = ctype
-          pp [paramInfo] if debug
-        end
-      end
-      ptr_match = /^\*(\w+)$/.match(param)
-      if (/^(:?const)? *void$/.match(ctype) and ptr_match)
-        param = ptr_match[1]
-        ftype = 'type(c_ptr)'
-        nc = 'c_ptr'
-      else
-        ftype, nc    = CFTypeInfo[ctype][:ftype], CFTypeInfo[ctype][:namedConst]
-      end
-      # fortran parameters can be configured out of the c parameters
-      [param.send(FNameMethod),nc,ftype, paramInfo.include?('const')]
-    }
-
-    # get deeper information about parameterlists and filter out functions with
-    # non supported parameters
-    fParams = setFortranParams(paramsWithTypes,fFuncname)
-    fParams4Import, fTypes4Import, = fParams.transpose
-  end
-
-  fReturnInfo                    = CFTypeInfo[returnType]
-  indent = '      '
-  if not fReturnInfo.nil?
-    fReturnString = "function"
-    fEnd    = ["#{fReturnInfo[:ftype]}(kind=#{fReturnInfo[:namedConst]}) :: #{fFuncname}\n", "end function" ]
-    fTypes4Import << fReturnInfo[:namedConst]
-  elsif returnType == 'void'
-    fReturnString = "subroutine"
-    fEnd    = ["end subroutine"]
-  end
-  fFuncname_suffix = ''
-
-  if (returnType == 'char' and returnPointer == '*')
-    out << "#{indent}function #{fFuncname}(#{fParams4Import.join(',')})\n"
-    out << printParams(fParams, indent)
-    fTypes4Import.unshift('c_ptr') unless fTypes4Import.include?('c_ptr')
-    isWrapper = true
-    fwEnd = [ "end function" ]
-    fFuncname_suffix = '_c'
-    indent = '        '
-    fEnd = [ "type(c_ptr) :: #{fFuncname}#{fFuncname_suffix}\n",
-             "end function" ]
-  end
-  out << "#{indent}interface
-#{indent}  #{fReturnString} #{fFuncname}#{fFuncname_suffix}(#{fParams4Import.join(',')}) bind(c,name='#{cFuncname}')\n"
-  out << "#{indent}    import :: #{fTypes4Import.uniq.join(',')}\n" unless fTypes4Import.empty?
-
-  out << printParams(fParams, indent + '  ')
-
-  fEnd.each_with_index do |line, i|
-    extra_indent = '    '
-    if i == fEnd.length - 1
-      extra_indent = '  '
-    end
-    out << indent + extra_indent + line
-  end
-  out << " #{fFuncname}#{fFuncname_suffix}\n#{indent}end interface\n"
-  if (returnType == 'char' and returnPointer == '*')
-    indent = '      '
-    out << "#{indent}  character(len=1, kind=c_char), pointer :: #{fFuncname}(:)
-#{indent}  type(c_ptr) :: cptr
-#{indent}  integer :: slen(1)
-
-#{indent}  cptr = #{fFuncname}#{fFuncname_suffix}("
-    out << fParams4Import.join(",&
-#{indent}    ") << ")\n"
-    out << "#{indent}  #{fFuncname} => null()\n"
-    out << "#{indent}  slen(1) = int(strlen(cptr))\n"
-    out << "#{indent}  call c_f_pointer(cptr, #{fFuncname}, slen)\n"
-    fwEnd.each_with_index do |line,i|
-      extra_indent = '  '
-      if i == fwEnd.length - 1
-        extra_indent = ''
-      end
-      out << indent + extra_indent + line
-    end
-    out << " #{fFuncname}\n"
-  end
-  [out, makePublic(fFuncname), isWrapper]
+#Collect the c_* and t_* constants/types from the arguments and the return type and build the corresponding `import` statement from them.
+def importStatement(returnType, argumentArray)
+	importConstants = []
+	collectImportConstants(importConstants, returnType)
+	argumentArray.each { |arg|
+		collectImportConstants(importConstants, arg.expandTemplate(:passAs))
+	}
+	return (importConstants.length != 0) ? "import #{importConstants.sort.uniq.join(", ")}" : ""
 end
-def makePublic(*fFuncnameList)
-  fFuncnameList.collect {|fname| 
-    "      public :: #{fname.tr('*','')}"
-  }.join("\n") << "\n"
+
+def defineFunction(name, arguments, returnType)
+	#Find the relevant templates.
+	if returnTemplate = findTemplate(returnType, $returnTypeTemplates)
+		returnData = TemplateInstanciation.new(returnType, returnTemplate)
+		argArray = []
+		arguments.gsub(/[^,]+/) do |argument|
+			if template = findTemplate(argument, $argumentTemplates)
+				argArray.push(TemplateInstanciation.new(argument, template))
+			else
+				puts("Error: type of argument '#{argument}' to function #{name}() is not supported")
+				return
+			end
+		end
+	else
+		puts("Error: Can't translate return type '#{returnType}' of function #{name}()")
+		return
+	end
+
+	#Generate the wrapper function.
+	dummyArguments = argArray.collect{ |arg|
+		arg.expandTemplate(:dummyName)
+	}.join(", ")
+	if returnTemplate[:isVoid]
+		formatLines($definitionLines, 1, "subroutine #{name}(#{dummyArguments})")
+		dumpStatements(               2, argArray, :acceptAs)
+		dumpStatements(               2, argArray, :helperVars)
+		formatLines($definitionLines, 2, "interface")
+		formatLines($definitionLines, 3, "subroutine lib_#{name}(#{dummyArguments}) bind(c, name = '#{name}')")
+		formatLines($definitionLines, 4, "#{importStatement("", argArray)}")
+		dumpStatements(               4, argArray, :passAs)
+		formatLines($definitionLines, 3, "end subroutine lib_#{name}")
+		formatLines($definitionLines, 2, "end interface")
+		dumpStatements(               2, argArray, :precallStatements)
+		formatLines($definitionLines, 2, "call lib_#{name}(#{argArray.collect{ |arg|
+			arg.expandTemplate(:callExpression)
+		}.join(", ")})")
+		dumpStatements(               2, argArray, :postcallStatements)
+		formatLines($definitionLines, 1, "end subroutine #{name}")
+	else
+		formatLines($definitionLines, 1, "function #{name}(#{dummyArguments}) result(result)")
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:returnAs)} :: result")
+		dumpStatements(               2, argArray, :acceptAs)
+		dumpStatements(               2, argArray, :helperVars)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:helperVars)}")
+		formatLines($definitionLines, 2, "interface")
+		formatLines($definitionLines, 3, "#{returnData.expandTemplate(:recieveAs)} function lib_#{name}(#{dummyArguments}) bind(c, name = '#{name}')")
+		formatLines($definitionLines, 4, "#{importStatement(returnData.expandTemplate(:recieveAs), argArray)}")
+		dumpStatements(               4, argArray, :passAs)
+		formatLines($definitionLines, 3, "end function lib_#{name}")
+		formatLines($definitionLines, 2, "end interface")
+		dumpStatements(               2, argArray, :precallStatements)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:precallStatements)}")
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:assignVariable)} = lib_#{name}(#{argArray.collect{ |arg|
+			arg.expandTemplate(:callExpression)
+		}.join(", ")})")
+		dumpStatements(               2, argArray, :postcallStatements)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:postcallStatements)}")
+		formatLines($definitionLines, 1, "end function #{name}")
+	end
+	formatLines($definitionLines, 0, "")
+	formatLines($declarationLines, 1, "public #{name}")
+
 end
-def ctrim
-  "
-    subroutine ctrim(str)
-    character(kind=c_char), intent(inout) :: str(:)
-    character(kind=c_char) :: c
-    integer :: i
-
-    do i=1,size(str)
-      c = str(i)
-      if (c == c_null_char) then
-        str(i:size(str)) = ' '
-        exit
-      end if
-    end do
-
-    end subroutine ctrim\n"
+
+#Scan the given header and collect the interface information in the global variables.
+def scanHeader(headerPath)
+	#Scan the given header.
+	headerLines = IO.popen("cpp -fpreprocessed -dD #{headerPath}").readlines	#The options cause the preprocessor to strip all comments, but retain all #defines, and ignore #includes.
+	headerLines.each do |line|
+		line.chomp!
+
+		if /^\s*$/.match(line)
+			#Empty lines are ignored.
+
+		#Preprocessor stuff
+		elsif matchedLine = /^\s*#\s*define\s+(?<symbol>\w+)\s+(?<value>.+)$/.match(line)
+			defineConstant(matchedLine['symbol'], matchedLine['value'])
+		elsif /^\s*#/.match(line)
+			#All other preprocessor directives are ignored.
+
+		#User defined types
+		elsif matchedLine = /^\s*typedef\s+struct\s+(?<typeName>\w+)\s+\k<typeName>\s*;\s*$/.match(line)
+			defineOpaqueType(matchedLine['typeName'])
+		elsif matchedLine = /^\s*typedef\s+struct\s+(?<typeName>\w+)\s*{(?<body>.*)}\s*\k<typeName>\s*;\s*$/.match(line)
+			definePublicType(matchedLine['typeName'], matchedLine['body'])
+
+		#Function declarations
+		elsif matchedLine = /^\s*(?<returnType>[^()]+)\b(?<functionName>\w+)\s*\((?<arguments>.*)\)\s*;\s*$/.match(line)
+			defineFunction(matchedLine['functionName'], matchedLine['arguments'], matchedLine['returnType'])
+
+		else
+			puts("Warning: Unrecognized line '#{line}'")
+		end
+	end
 end
 
-def clen
-  "
-    function c_len(s) result(i)
-      character(kind=c_char), intent(in) :: s(:)
-      integer :: i
-      do i = 1, size(s)
-        if (s(i) == c_null_char) then
-          exit
-        end if
-      end do
-      i = i - 1
-    end function\n"
+#Prints the line if it does not consist only of indentation, adding continuation lines as necessary.
+def fortranLine(file, line)
+	unless /^\t+$/.match(line)	#Intentionally empty lines don't contain indentation, so we preserve totally empty lines while throwing away the ones with leading tabs.
+		indentation = /^\t*/.match(line)[0]
+		while line.length > 131
+			file.puts(line[0...131] + "&")
+			line = indentation + "&" + line[131...line.length]
+		end
+		file.puts(line)
+	end
 end
 
-################################################################################
-if __FILE__ == $0
-require 'optparse'
-require 'pp'
-
-debug = false
-OptionParser.new do |opts|
-  opts.on("-d","--debug") {debug = true}
-  opts.on_tail("--help","-h","-H","Display this help message.") do
-    puts <<-'END'
-#== Synopsis
-# Create Fortran iso-c-bindings form a given c header file
-# 
-#== Usage
-#   binGen.rb <headerFile> <fortranLibraryFile> [<modName>] [--help|--debug]  
-#
-# headerFile:
-#   A general c header file: function prototypes and '#defines' with numerical
-#   value will be taken for the fortran module construction. Furthermore there
-#   are some restrictions to what is provided in fortran: Currently internal
-#   datatypes and (arrays|pointers) to internal datatypes are supported, i.e.
-#   no arrays of pointers, no pointer to pointers, no typedefs
-#
-# fortranLibraryFile:
-#   file name for generated bindings
-#
-# modName:
-#   This will be the name of the Fortran module, so it has to obey the fortran 
-#   restriction for module names. default: mo_cdi
-#  
-#== Author
-# Ralf Mueller, ralf.mueller at zmaw.de
-#
-#== RESTRICTIONS:
-# ONLY SUPPORT FOR INTERNAL DATATYPES AND (ARRAYS|POINTERS) TO INTERNAL
-# DATATYPES, I.E. NO ARRAYS OF POINTERS, NO POINTER TO POINTERS, NO TYPEDEFS
-#
-#=== Special: naming convention
-# Pointers can have different sizes, which cannot be detetermined by parsing a
-# function prototype. Therefor a convention according the parameter names can
-# be used to take this decision precisely:
-# * Pointers to numbers are expected to be scalars unless the name of the
-#   parameter end with '_vec'
-# * Pointers to char are allways referenced as vectors
-#
-#== LICENSE: 
-# BSD License
-#
-#  Copyright (c) 2009-2012, Ralf Mueller (ralf.mueller at zmaw.de)
-#  All rights reserved.
-#  
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  
-#      * Redistributions of source code must retain the above copyright notice,
-#        this list of conditions and the following disclaimer.
-#  
-#      * Redistributions in binary form must reproduce the above copyright
-#        notice, this list of conditions and the following disclaimer in the
-#        documentation and/or other materials provided with the distribution.
-#  
-#      * The names of its contributors may not be used to endorse or promote
-#        products derived from this software without specific prior written
-#        permission.
-#  
-#  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.
-#
-END
-  exit
-  end
-end.parse!
-
-  if ARGV[1] == nil
-    warn 'no outputile given'
-    exit
-  end
-
-  outputString      = ''
-  modname           = ARGV[2].nil? ? ModuleName : ARGV[2]
-
-  cDefines          = getDefines(ARGV[0])
-  pp cDefines if debug
-  unless cDefines.empty?
-    makeModVarsPublic = makePublic(*cDefines.transpose[0]) 
-    moduleVariables   = genModParams(cDefines)
-  end
-
-  interfaces, makepublics, subroutines = '', '', "contains\n"
-  indent = '    '
-
-  funcdecls = [ [ 'strlen', 'size_t', '', [ [ 'void', '*s' ] ] ] ]
-  funcdecls.concat(getFuncInfo(ARGV[0]))
-
-  funcdecls.each {| funcName, returnType, returnPointer, paramList|
-    pp [funcName, returnType, returnPointer, paramList] if debug
-    interface, makepublic, isWrapper = genInterface(funcName,returnType, returnPointer, paramList, debug)
-    if isWrapper
-      subroutines << interface
-    else
-      interfaces  << interface
-    end
-    makepublics << makepublic
-  }
-
-  # add a specialized trim for wierd c strings
-  makepublics << makePublic('ctrim') << makePublic('c_len')
-  subroutines << ctrim << clen
-
-  File.open(ARGV[1],"w") {|f|
-    [ startMod(modname),
-      moduleVariables ||= '',
-      interfaces,
-      makepublics,
-      makeModVarsPublic ||= '',
-      subroutines,
-      endMod(modname)
-    ].join("\n").split("\n").each {|line| 
-      # check the length of each line before writing to file
-      if line.length > FortranMaxLineLength
-        f << genContinuation(line) << "\n"
-      else
-        f << line << "\n"
-      end
-    }
-  }
+#Output the interface information in the global variables to a fortran file.
+def writeFortranModule(scriptPath, headerPath, modulePath, moduleName)
+	file = File.new(modulePath, "w")
+	fortranLine(file, "! >>> Warning: This is a generated file. If you modify it, you get what you deserve. <<<")
+	fortranLine(file, "!")
+	fortranLine(file, "! Generated by \"#{scriptPath}\" from input file \"#{headerPath}\".")
+	fortranLine(file, "");
+
+	fortranLine(file, "module #{moduleName}")
+	fortranLine(file, "\tuse iso_c_binding")
+	fortranLine(file, "\timplicit none")
+	fortranLine(file, "\tprivate")
+
+	file.puts($verbatimDeclarations)
+	fortranLine(file, "")
+	$declarationLines.each do |line|
+		fortranLine(file, line)
+	end
+	fortranLine(file, "")
+
+	fortranLine(file, "contains")
+	file.puts($verbatimDefinitions)
+	fortranLine(file, "")
+	$definitionLines.each do |line|
+		fortranLine(file, line)
+	end
+
+	fortranLine(file, "end module #{moduleName}")
+end
 
+def main
+	printUsage = false
+	ARGV.each { |argument|
+		if argument == "-h" || argument == "--help"
+			printUsage = true
+		end
+	}
+	unless printUsage
+		case ARGV.length
+			when 0
+				puts("Error: no input file given")
+				printUsage = true
+			when 1
+				puts("Error: no output file given")
+				printUsage = true
+			when 2
+				moduleName = /(?<basename>[^.\/]+)\.[^\/]+/.match(ARGV[1])['basename']
+			when 3
+				moduleName = ARGV[2]
+			else
+				puts("Error: too many arguments")
+				printUsage = true
+		end
+	end
+	unless printUsage
+		headerPath = ARGV[0]
+		outputPath = ARGV[1]
+		scanHeader(headerPath)
+		writeFortranModule($0, headerPath, outputPath, moduleName)
+	else
+		puts("Usage:")
+		puts("#{$0} cHeader outputPath [ moduleName ]")
+		puts("#{$0} ( -h | --help )")
+		puts("")
+		puts("\tcHeader:    input C header file")
+		puts("\toutputPath: output fortran file name")
+		puts("\tmoduleName: name of the resulting fortran module, defaults to the basename of outputPath")
+	end
 end
+
+main()
diff --git a/libcdi/interfaces/python/CdiObj.py b/libcdi/interfaces/python/CdiObj.py
index 6f1c3bd..35d483a 100644
--- a/libcdi/interfaces/python/CdiObj.py
+++ b/libcdi/interfaces/python/CdiObj.py
@@ -1,12 +1,35 @@
 # This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.31
+# Version 3.0.2
 #
-# Don't modify this file, modify the SWIG interface instead.
-# This file is compatible with both classic and new-style classes.
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+
 
-import _CdiObj
-import new
-new_instancemethod = new.instancemethod
+
+
+from sys import version_info
+if version_info >= (2,6,0):
+    def swig_import_helper():
+        from os.path import dirname
+        import imp
+        fp = None
+        try:
+            fp, pathname, description = imp.find_module('_CdiObj', [dirname(__file__)])
+        except ImportError:
+            import _CdiObj
+            return _CdiObj
+        if fp is not None:
+            try:
+                _mod = imp.load_module('_CdiObj', fp, pathname, description)
+            finally:
+                fp.close()
+            return _mod
+    _CdiObj = swig_import_helper()
+    del swig_import_helper
+else:
+    import _CdiObj
+del version_info
 try:
     _swig_property = property
 except NameError:
@@ -14,12 +37,12 @@ except NameError:
 def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
     if (name == "thisown"): return self.this.own(value)
     if (name == "this"):
-        if type(value).__name__ == 'PySwigObject':
+        if type(value).__name__ == 'SwigPyObject':
             self.__dict__[name] = value
             return
     method = class_type.__swig_setmethods__.get(name,None)
     if method: return method(self,value)
-    if (not static) or hasattr(self,name):
+    if (not static):
         self.__dict__[name] = value
     else:
         raise AttributeError("You cannot add attributes to %s" % self)
@@ -31,50 +54,49 @@ def _swig_getattr(self,class_type,name):
     if (name == "thisown"): return self.this.own()
     method = class_type.__swig_getmethods__.get(name,None)
     if method: return method(self)
-    raise AttributeError,name
+    raise AttributeError(name)
 
 def _swig_repr(self):
     try: strthis = "proxy of " + self.this.__repr__()
     except: strthis = ""
     return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
 
-import types
 try:
-    _object = types.ObjectType
+    _object = object
     _newclass = 1
 except AttributeError:
     class _object : pass
     _newclass = 0
-del types
 
 
-class PySwigIterator(_object):
+class SwigPyIterator(_object):
     __swig_setmethods__ = {}
-    __setattr__ = lambda self, name, value: _swig_setattr(self, PySwigIterator, name, value)
+    __setattr__ = lambda self, name, value: _swig_setattr(self, SwigPyIterator, name, value)
     __swig_getmethods__ = {}
-    __getattr__ = lambda self, name: _swig_getattr(self, PySwigIterator, name)
-    def __init__(self): raise AttributeError, "No constructor defined"
+    __getattr__ = lambda self, name: _swig_getattr(self, SwigPyIterator, name)
+    def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined - class is abstract")
     __repr__ = _swig_repr
-    __swig_destroy__ = _CdiObj.delete_PySwigIterator
+    __swig_destroy__ = _CdiObj.delete_SwigPyIterator
     __del__ = lambda self : None;
-    def value(*args): return _CdiObj.PySwigIterator_value(*args)
-    def incr(*args): return _CdiObj.PySwigIterator_incr(*args)
-    def decr(*args): return _CdiObj.PySwigIterator_decr(*args)
-    def distance(*args): return _CdiObj.PySwigIterator_distance(*args)
-    def equal(*args): return _CdiObj.PySwigIterator_equal(*args)
-    def copy(*args): return _CdiObj.PySwigIterator_copy(*args)
-    def next(*args): return _CdiObj.PySwigIterator_next(*args)
-    def previous(*args): return _CdiObj.PySwigIterator_previous(*args)
-    def advance(*args): return _CdiObj.PySwigIterator_advance(*args)
-    def __eq__(*args): return _CdiObj.PySwigIterator___eq__(*args)
-    def __ne__(*args): return _CdiObj.PySwigIterator___ne__(*args)
-    def __iadd__(*args): return _CdiObj.PySwigIterator___iadd__(*args)
-    def __isub__(*args): return _CdiObj.PySwigIterator___isub__(*args)
-    def __add__(*args): return _CdiObj.PySwigIterator___add__(*args)
-    def __sub__(*args): return _CdiObj.PySwigIterator___sub__(*args)
+    def value(self): return _CdiObj.SwigPyIterator_value(self)
+    def incr(self, n=1): return _CdiObj.SwigPyIterator_incr(self, n)
+    def decr(self, n=1): return _CdiObj.SwigPyIterator_decr(self, n)
+    def distance(self, *args): return _CdiObj.SwigPyIterator_distance(self, *args)
+    def equal(self, *args): return _CdiObj.SwigPyIterator_equal(self, *args)
+    def copy(self): return _CdiObj.SwigPyIterator_copy(self)
+    def next(self): return _CdiObj.SwigPyIterator_next(self)
+    def __next__(self): return _CdiObj.SwigPyIterator___next__(self)
+    def previous(self): return _CdiObj.SwigPyIterator_previous(self)
+    def advance(self, *args): return _CdiObj.SwigPyIterator_advance(self, *args)
+    def __eq__(self, *args): return _CdiObj.SwigPyIterator___eq__(self, *args)
+    def __ne__(self, *args): return _CdiObj.SwigPyIterator___ne__(self, *args)
+    def __iadd__(self, *args): return _CdiObj.SwigPyIterator___iadd__(self, *args)
+    def __isub__(self, *args): return _CdiObj.SwigPyIterator___isub__(self, *args)
+    def __add__(self, *args): return _CdiObj.SwigPyIterator___add__(self, *args)
+    def __sub__(self, *args): return _CdiObj.SwigPyIterator___sub__(self, *args)
     def __iter__(self): return self
-PySwigIterator_swigregister = _CdiObj.PySwigIterator_swigregister
-PySwigIterator_swigregister(PySwigIterator)
+SwigPyIterator_swigregister = _CdiObj.SwigPyIterator_swigregister
+SwigPyIterator_swigregister(SwigPyIterator)
 
 class IntVector(_object):
     __swig_setmethods__ = {}
@@ -82,41 +104,42 @@ class IntVector(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, IntVector, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.IntVector_iterator(*args)
+    def iterator(self): return _CdiObj.IntVector_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.IntVector___nonzero__(*args)
-    def __len__(*args): return _CdiObj.IntVector___len__(*args)
-    def pop(*args): return _CdiObj.IntVector_pop(*args)
-    def __getslice__(*args): return _CdiObj.IntVector___getslice__(*args)
-    def __setslice__(*args): return _CdiObj.IntVector___setslice__(*args)
-    def __delslice__(*args): return _CdiObj.IntVector___delslice__(*args)
-    def __delitem__(*args): return _CdiObj.IntVector___delitem__(*args)
-    def __getitem__(*args): return _CdiObj.IntVector___getitem__(*args)
-    def __setitem__(*args): return _CdiObj.IntVector___setitem__(*args)
-    def append(*args): return _CdiObj.IntVector_append(*args)
-    def empty(*args): return _CdiObj.IntVector_empty(*args)
-    def size(*args): return _CdiObj.IntVector_size(*args)
-    def clear(*args): return _CdiObj.IntVector_clear(*args)
-    def swap(*args): return _CdiObj.IntVector_swap(*args)
-    def get_allocator(*args): return _CdiObj.IntVector_get_allocator(*args)
-    def begin(*args): return _CdiObj.IntVector_begin(*args)
-    def end(*args): return _CdiObj.IntVector_end(*args)
-    def rbegin(*args): return _CdiObj.IntVector_rbegin(*args)
-    def rend(*args): return _CdiObj.IntVector_rend(*args)
-    def pop_back(*args): return _CdiObj.IntVector_pop_back(*args)
-    def erase(*args): return _CdiObj.IntVector_erase(*args)
+    def __nonzero__(self): return _CdiObj.IntVector___nonzero__(self)
+    def __bool__(self): return _CdiObj.IntVector___bool__(self)
+    def __len__(self): return _CdiObj.IntVector___len__(self)
+    def pop(self): return _CdiObj.IntVector_pop(self)
+    def __getslice__(self, *args): return _CdiObj.IntVector___getslice__(self, *args)
+    def __setslice__(self, *args): return _CdiObj.IntVector___setslice__(self, *args)
+    def __delslice__(self, *args): return _CdiObj.IntVector___delslice__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.IntVector___delitem__(self, *args)
+    def __getitem__(self, *args): return _CdiObj.IntVector___getitem__(self, *args)
+    def __setitem__(self, *args): return _CdiObj.IntVector___setitem__(self, *args)
+    def append(self, *args): return _CdiObj.IntVector_append(self, *args)
+    def empty(self): return _CdiObj.IntVector_empty(self)
+    def size(self): return _CdiObj.IntVector_size(self)
+    def clear(self): return _CdiObj.IntVector_clear(self)
+    def swap(self, *args): return _CdiObj.IntVector_swap(self, *args)
+    def get_allocator(self): return _CdiObj.IntVector_get_allocator(self)
+    def begin(self): return _CdiObj.IntVector_begin(self)
+    def end(self): return _CdiObj.IntVector_end(self)
+    def rbegin(self): return _CdiObj.IntVector_rbegin(self)
+    def rend(self): return _CdiObj.IntVector_rend(self)
+    def pop_back(self): return _CdiObj.IntVector_pop_back(self)
+    def erase(self, *args): return _CdiObj.IntVector_erase(self, *args)
     def __init__(self, *args): 
         this = _CdiObj.new_IntVector(*args)
         try: self.this.append(this)
         except: self.this = this
-    def push_back(*args): return _CdiObj.IntVector_push_back(*args)
-    def front(*args): return _CdiObj.IntVector_front(*args)
-    def back(*args): return _CdiObj.IntVector_back(*args)
-    def assign(*args): return _CdiObj.IntVector_assign(*args)
-    def resize(*args): return _CdiObj.IntVector_resize(*args)
-    def insert(*args): return _CdiObj.IntVector_insert(*args)
-    def reserve(*args): return _CdiObj.IntVector_reserve(*args)
-    def capacity(*args): return _CdiObj.IntVector_capacity(*args)
+    def push_back(self, *args): return _CdiObj.IntVector_push_back(self, *args)
+    def front(self): return _CdiObj.IntVector_front(self)
+    def back(self): return _CdiObj.IntVector_back(self)
+    def assign(self, *args): return _CdiObj.IntVector_assign(self, *args)
+    def resize(self, *args): return _CdiObj.IntVector_resize(self, *args)
+    def insert(self, *args): return _CdiObj.IntVector_insert(self, *args)
+    def reserve(self, *args): return _CdiObj.IntVector_reserve(self, *args)
+    def capacity(self): return _CdiObj.IntVector_capacity(self)
     __swig_destroy__ = _CdiObj.delete_IntVector
     __del__ = lambda self : None;
 IntVector_swigregister = _CdiObj.IntVector_swigregister
@@ -128,41 +151,42 @@ class DoubleVector(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, DoubleVector, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.DoubleVector_iterator(*args)
+    def iterator(self): return _CdiObj.DoubleVector_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.DoubleVector___nonzero__(*args)
-    def __len__(*args): return _CdiObj.DoubleVector___len__(*args)
-    def pop(*args): return _CdiObj.DoubleVector_pop(*args)
-    def __getslice__(*args): return _CdiObj.DoubleVector___getslice__(*args)
-    def __setslice__(*args): return _CdiObj.DoubleVector___setslice__(*args)
-    def __delslice__(*args): return _CdiObj.DoubleVector___delslice__(*args)
-    def __delitem__(*args): return _CdiObj.DoubleVector___delitem__(*args)
-    def __getitem__(*args): return _CdiObj.DoubleVector___getitem__(*args)
-    def __setitem__(*args): return _CdiObj.DoubleVector___setitem__(*args)
-    def append(*args): return _CdiObj.DoubleVector_append(*args)
-    def empty(*args): return _CdiObj.DoubleVector_empty(*args)
-    def size(*args): return _CdiObj.DoubleVector_size(*args)
-    def clear(*args): return _CdiObj.DoubleVector_clear(*args)
-    def swap(*args): return _CdiObj.DoubleVector_swap(*args)
-    def get_allocator(*args): return _CdiObj.DoubleVector_get_allocator(*args)
-    def begin(*args): return _CdiObj.DoubleVector_begin(*args)
-    def end(*args): return _CdiObj.DoubleVector_end(*args)
-    def rbegin(*args): return _CdiObj.DoubleVector_rbegin(*args)
-    def rend(*args): return _CdiObj.DoubleVector_rend(*args)
-    def pop_back(*args): return _CdiObj.DoubleVector_pop_back(*args)
-    def erase(*args): return _CdiObj.DoubleVector_erase(*args)
+    def __nonzero__(self): return _CdiObj.DoubleVector___nonzero__(self)
+    def __bool__(self): return _CdiObj.DoubleVector___bool__(self)
+    def __len__(self): return _CdiObj.DoubleVector___len__(self)
+    def pop(self): return _CdiObj.DoubleVector_pop(self)
+    def __getslice__(self, *args): return _CdiObj.DoubleVector___getslice__(self, *args)
+    def __setslice__(self, *args): return _CdiObj.DoubleVector___setslice__(self, *args)
+    def __delslice__(self, *args): return _CdiObj.DoubleVector___delslice__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.DoubleVector___delitem__(self, *args)
+    def __getitem__(self, *args): return _CdiObj.DoubleVector___getitem__(self, *args)
+    def __setitem__(self, *args): return _CdiObj.DoubleVector___setitem__(self, *args)
+    def append(self, *args): return _CdiObj.DoubleVector_append(self, *args)
+    def empty(self): return _CdiObj.DoubleVector_empty(self)
+    def size(self): return _CdiObj.DoubleVector_size(self)
+    def clear(self): return _CdiObj.DoubleVector_clear(self)
+    def swap(self, *args): return _CdiObj.DoubleVector_swap(self, *args)
+    def get_allocator(self): return _CdiObj.DoubleVector_get_allocator(self)
+    def begin(self): return _CdiObj.DoubleVector_begin(self)
+    def end(self): return _CdiObj.DoubleVector_end(self)
+    def rbegin(self): return _CdiObj.DoubleVector_rbegin(self)
+    def rend(self): return _CdiObj.DoubleVector_rend(self)
+    def pop_back(self): return _CdiObj.DoubleVector_pop_back(self)
+    def erase(self, *args): return _CdiObj.DoubleVector_erase(self, *args)
     def __init__(self, *args): 
         this = _CdiObj.new_DoubleVector(*args)
         try: self.this.append(this)
         except: self.this = this
-    def push_back(*args): return _CdiObj.DoubleVector_push_back(*args)
-    def front(*args): return _CdiObj.DoubleVector_front(*args)
-    def back(*args): return _CdiObj.DoubleVector_back(*args)
-    def assign(*args): return _CdiObj.DoubleVector_assign(*args)
-    def resize(*args): return _CdiObj.DoubleVector_resize(*args)
-    def insert(*args): return _CdiObj.DoubleVector_insert(*args)
-    def reserve(*args): return _CdiObj.DoubleVector_reserve(*args)
-    def capacity(*args): return _CdiObj.DoubleVector_capacity(*args)
+    def push_back(self, *args): return _CdiObj.DoubleVector_push_back(self, *args)
+    def front(self): return _CdiObj.DoubleVector_front(self)
+    def back(self): return _CdiObj.DoubleVector_back(self)
+    def assign(self, *args): return _CdiObj.DoubleVector_assign(self, *args)
+    def resize(self, *args): return _CdiObj.DoubleVector_resize(self, *args)
+    def insert(self, *args): return _CdiObj.DoubleVector_insert(self, *args)
+    def reserve(self, *args): return _CdiObj.DoubleVector_reserve(self, *args)
+    def capacity(self): return _CdiObj.DoubleVector_capacity(self)
     __swig_destroy__ = _CdiObj.delete_DoubleVector
     __del__ = lambda self : None;
 DoubleVector_swigregister = _CdiObj.DoubleVector_swigregister
@@ -174,41 +198,42 @@ class DoubleDoubleVector(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, DoubleDoubleVector, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.DoubleDoubleVector_iterator(*args)
+    def iterator(self): return _CdiObj.DoubleDoubleVector_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.DoubleDoubleVector___nonzero__(*args)
-    def __len__(*args): return _CdiObj.DoubleDoubleVector___len__(*args)
-    def pop(*args): return _CdiObj.DoubleDoubleVector_pop(*args)
-    def __getslice__(*args): return _CdiObj.DoubleDoubleVector___getslice__(*args)
-    def __setslice__(*args): return _CdiObj.DoubleDoubleVector___setslice__(*args)
-    def __delslice__(*args): return _CdiObj.DoubleDoubleVector___delslice__(*args)
-    def __delitem__(*args): return _CdiObj.DoubleDoubleVector___delitem__(*args)
-    def __getitem__(*args): return _CdiObj.DoubleDoubleVector___getitem__(*args)
-    def __setitem__(*args): return _CdiObj.DoubleDoubleVector___setitem__(*args)
-    def append(*args): return _CdiObj.DoubleDoubleVector_append(*args)
-    def empty(*args): return _CdiObj.DoubleDoubleVector_empty(*args)
-    def size(*args): return _CdiObj.DoubleDoubleVector_size(*args)
-    def clear(*args): return _CdiObj.DoubleDoubleVector_clear(*args)
-    def swap(*args): return _CdiObj.DoubleDoubleVector_swap(*args)
-    def get_allocator(*args): return _CdiObj.DoubleDoubleVector_get_allocator(*args)
-    def begin(*args): return _CdiObj.DoubleDoubleVector_begin(*args)
-    def end(*args): return _CdiObj.DoubleDoubleVector_end(*args)
-    def rbegin(*args): return _CdiObj.DoubleDoubleVector_rbegin(*args)
-    def rend(*args): return _CdiObj.DoubleDoubleVector_rend(*args)
-    def pop_back(*args): return _CdiObj.DoubleDoubleVector_pop_back(*args)
-    def erase(*args): return _CdiObj.DoubleDoubleVector_erase(*args)
+    def __nonzero__(self): return _CdiObj.DoubleDoubleVector___nonzero__(self)
+    def __bool__(self): return _CdiObj.DoubleDoubleVector___bool__(self)
+    def __len__(self): return _CdiObj.DoubleDoubleVector___len__(self)
+    def pop(self): return _CdiObj.DoubleDoubleVector_pop(self)
+    def __getslice__(self, *args): return _CdiObj.DoubleDoubleVector___getslice__(self, *args)
+    def __setslice__(self, *args): return _CdiObj.DoubleDoubleVector___setslice__(self, *args)
+    def __delslice__(self, *args): return _CdiObj.DoubleDoubleVector___delslice__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.DoubleDoubleVector___delitem__(self, *args)
+    def __getitem__(self, *args): return _CdiObj.DoubleDoubleVector___getitem__(self, *args)
+    def __setitem__(self, *args): return _CdiObj.DoubleDoubleVector___setitem__(self, *args)
+    def append(self, *args): return _CdiObj.DoubleDoubleVector_append(self, *args)
+    def empty(self): return _CdiObj.DoubleDoubleVector_empty(self)
+    def size(self): return _CdiObj.DoubleDoubleVector_size(self)
+    def clear(self): return _CdiObj.DoubleDoubleVector_clear(self)
+    def swap(self, *args): return _CdiObj.DoubleDoubleVector_swap(self, *args)
+    def get_allocator(self): return _CdiObj.DoubleDoubleVector_get_allocator(self)
+    def begin(self): return _CdiObj.DoubleDoubleVector_begin(self)
+    def end(self): return _CdiObj.DoubleDoubleVector_end(self)
+    def rbegin(self): return _CdiObj.DoubleDoubleVector_rbegin(self)
+    def rend(self): return _CdiObj.DoubleDoubleVector_rend(self)
+    def pop_back(self): return _CdiObj.DoubleDoubleVector_pop_back(self)
+    def erase(self, *args): return _CdiObj.DoubleDoubleVector_erase(self, *args)
     def __init__(self, *args): 
         this = _CdiObj.new_DoubleDoubleVector(*args)
         try: self.this.append(this)
         except: self.this = this
-    def push_back(*args): return _CdiObj.DoubleDoubleVector_push_back(*args)
-    def front(*args): return _CdiObj.DoubleDoubleVector_front(*args)
-    def back(*args): return _CdiObj.DoubleDoubleVector_back(*args)
-    def assign(*args): return _CdiObj.DoubleDoubleVector_assign(*args)
-    def resize(*args): return _CdiObj.DoubleDoubleVector_resize(*args)
-    def insert(*args): return _CdiObj.DoubleDoubleVector_insert(*args)
-    def reserve(*args): return _CdiObj.DoubleDoubleVector_reserve(*args)
-    def capacity(*args): return _CdiObj.DoubleDoubleVector_capacity(*args)
+    def push_back(self, *args): return _CdiObj.DoubleDoubleVector_push_back(self, *args)
+    def front(self): return _CdiObj.DoubleDoubleVector_front(self)
+    def back(self): return _CdiObj.DoubleDoubleVector_back(self)
+    def assign(self, *args): return _CdiObj.DoubleDoubleVector_assign(self, *args)
+    def resize(self, *args): return _CdiObj.DoubleDoubleVector_resize(self, *args)
+    def insert(self, *args): return _CdiObj.DoubleDoubleVector_insert(self, *args)
+    def reserve(self, *args): return _CdiObj.DoubleDoubleVector_reserve(self, *args)
+    def capacity(self): return _CdiObj.DoubleDoubleVector_capacity(self)
     __swig_destroy__ = _CdiObj.delete_DoubleDoubleVector
     __del__ = lambda self : None;
 DoubleDoubleVector_swigregister = _CdiObj.DoubleDoubleVector_swigregister
@@ -220,41 +245,42 @@ class StringVector(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, StringVector, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.StringVector_iterator(*args)
+    def iterator(self): return _CdiObj.StringVector_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.StringVector___nonzero__(*args)
-    def __len__(*args): return _CdiObj.StringVector___len__(*args)
-    def pop(*args): return _CdiObj.StringVector_pop(*args)
-    def __getslice__(*args): return _CdiObj.StringVector___getslice__(*args)
-    def __setslice__(*args): return _CdiObj.StringVector___setslice__(*args)
-    def __delslice__(*args): return _CdiObj.StringVector___delslice__(*args)
-    def __delitem__(*args): return _CdiObj.StringVector___delitem__(*args)
-    def __getitem__(*args): return _CdiObj.StringVector___getitem__(*args)
-    def __setitem__(*args): return _CdiObj.StringVector___setitem__(*args)
-    def append(*args): return _CdiObj.StringVector_append(*args)
-    def empty(*args): return _CdiObj.StringVector_empty(*args)
-    def size(*args): return _CdiObj.StringVector_size(*args)
-    def clear(*args): return _CdiObj.StringVector_clear(*args)
-    def swap(*args): return _CdiObj.StringVector_swap(*args)
-    def get_allocator(*args): return _CdiObj.StringVector_get_allocator(*args)
-    def begin(*args): return _CdiObj.StringVector_begin(*args)
-    def end(*args): return _CdiObj.StringVector_end(*args)
-    def rbegin(*args): return _CdiObj.StringVector_rbegin(*args)
-    def rend(*args): return _CdiObj.StringVector_rend(*args)
-    def pop_back(*args): return _CdiObj.StringVector_pop_back(*args)
-    def erase(*args): return _CdiObj.StringVector_erase(*args)
+    def __nonzero__(self): return _CdiObj.StringVector___nonzero__(self)
+    def __bool__(self): return _CdiObj.StringVector___bool__(self)
+    def __len__(self): return _CdiObj.StringVector___len__(self)
+    def pop(self): return _CdiObj.StringVector_pop(self)
+    def __getslice__(self, *args): return _CdiObj.StringVector___getslice__(self, *args)
+    def __setslice__(self, *args): return _CdiObj.StringVector___setslice__(self, *args)
+    def __delslice__(self, *args): return _CdiObj.StringVector___delslice__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.StringVector___delitem__(self, *args)
+    def __getitem__(self, *args): return _CdiObj.StringVector___getitem__(self, *args)
+    def __setitem__(self, *args): return _CdiObj.StringVector___setitem__(self, *args)
+    def append(self, *args): return _CdiObj.StringVector_append(self, *args)
+    def empty(self): return _CdiObj.StringVector_empty(self)
+    def size(self): return _CdiObj.StringVector_size(self)
+    def clear(self): return _CdiObj.StringVector_clear(self)
+    def swap(self, *args): return _CdiObj.StringVector_swap(self, *args)
+    def get_allocator(self): return _CdiObj.StringVector_get_allocator(self)
+    def begin(self): return _CdiObj.StringVector_begin(self)
+    def end(self): return _CdiObj.StringVector_end(self)
+    def rbegin(self): return _CdiObj.StringVector_rbegin(self)
+    def rend(self): return _CdiObj.StringVector_rend(self)
+    def pop_back(self): return _CdiObj.StringVector_pop_back(self)
+    def erase(self, *args): return _CdiObj.StringVector_erase(self, *args)
     def __init__(self, *args): 
         this = _CdiObj.new_StringVector(*args)
         try: self.this.append(this)
         except: self.this = this
-    def push_back(*args): return _CdiObj.StringVector_push_back(*args)
-    def front(*args): return _CdiObj.StringVector_front(*args)
-    def back(*args): return _CdiObj.StringVector_back(*args)
-    def assign(*args): return _CdiObj.StringVector_assign(*args)
-    def resize(*args): return _CdiObj.StringVector_resize(*args)
-    def insert(*args): return _CdiObj.StringVector_insert(*args)
-    def reserve(*args): return _CdiObj.StringVector_reserve(*args)
-    def capacity(*args): return _CdiObj.StringVector_capacity(*args)
+    def push_back(self, *args): return _CdiObj.StringVector_push_back(self, *args)
+    def front(self): return _CdiObj.StringVector_front(self)
+    def back(self): return _CdiObj.StringVector_back(self)
+    def assign(self, *args): return _CdiObj.StringVector_assign(self, *args)
+    def resize(self, *args): return _CdiObj.StringVector_resize(self, *args)
+    def insert(self, *args): return _CdiObj.StringVector_insert(self, *args)
+    def reserve(self, *args): return _CdiObj.StringVector_reserve(self, *args)
+    def capacity(self): return _CdiObj.StringVector_capacity(self)
     __swig_destroy__ = _CdiObj.delete_StringVector
     __del__ = lambda self : None;
 StringVector_swigregister = _CdiObj.StringVector_swigregister
@@ -266,41 +292,42 @@ class VarsVector(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, VarsVector, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.VarsVector_iterator(*args)
+    def iterator(self): return _CdiObj.VarsVector_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.VarsVector___nonzero__(*args)
-    def __len__(*args): return _CdiObj.VarsVector___len__(*args)
-    def pop(*args): return _CdiObj.VarsVector_pop(*args)
-    def __getslice__(*args): return _CdiObj.VarsVector___getslice__(*args)
-    def __setslice__(*args): return _CdiObj.VarsVector___setslice__(*args)
-    def __delslice__(*args): return _CdiObj.VarsVector___delslice__(*args)
-    def __delitem__(*args): return _CdiObj.VarsVector___delitem__(*args)
-    def __getitem__(*args): return _CdiObj.VarsVector___getitem__(*args)
-    def __setitem__(*args): return _CdiObj.VarsVector___setitem__(*args)
-    def append(*args): return _CdiObj.VarsVector_append(*args)
-    def empty(*args): return _CdiObj.VarsVector_empty(*args)
-    def size(*args): return _CdiObj.VarsVector_size(*args)
-    def clear(*args): return _CdiObj.VarsVector_clear(*args)
-    def swap(*args): return _CdiObj.VarsVector_swap(*args)
-    def get_allocator(*args): return _CdiObj.VarsVector_get_allocator(*args)
-    def begin(*args): return _CdiObj.VarsVector_begin(*args)
-    def end(*args): return _CdiObj.VarsVector_end(*args)
-    def rbegin(*args): return _CdiObj.VarsVector_rbegin(*args)
-    def rend(*args): return _CdiObj.VarsVector_rend(*args)
-    def pop_back(*args): return _CdiObj.VarsVector_pop_back(*args)
-    def erase(*args): return _CdiObj.VarsVector_erase(*args)
+    def __nonzero__(self): return _CdiObj.VarsVector___nonzero__(self)
+    def __bool__(self): return _CdiObj.VarsVector___bool__(self)
+    def __len__(self): return _CdiObj.VarsVector___len__(self)
+    def pop(self): return _CdiObj.VarsVector_pop(self)
+    def __getslice__(self, *args): return _CdiObj.VarsVector___getslice__(self, *args)
+    def __setslice__(self, *args): return _CdiObj.VarsVector___setslice__(self, *args)
+    def __delslice__(self, *args): return _CdiObj.VarsVector___delslice__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.VarsVector___delitem__(self, *args)
+    def __getitem__(self, *args): return _CdiObj.VarsVector___getitem__(self, *args)
+    def __setitem__(self, *args): return _CdiObj.VarsVector___setitem__(self, *args)
+    def append(self, *args): return _CdiObj.VarsVector_append(self, *args)
+    def empty(self): return _CdiObj.VarsVector_empty(self)
+    def size(self): return _CdiObj.VarsVector_size(self)
+    def clear(self): return _CdiObj.VarsVector_clear(self)
+    def swap(self, *args): return _CdiObj.VarsVector_swap(self, *args)
+    def get_allocator(self): return _CdiObj.VarsVector_get_allocator(self)
+    def begin(self): return _CdiObj.VarsVector_begin(self)
+    def end(self): return _CdiObj.VarsVector_end(self)
+    def rbegin(self): return _CdiObj.VarsVector_rbegin(self)
+    def rend(self): return _CdiObj.VarsVector_rend(self)
+    def pop_back(self): return _CdiObj.VarsVector_pop_back(self)
+    def erase(self, *args): return _CdiObj.VarsVector_erase(self, *args)
     def __init__(self, *args): 
         this = _CdiObj.new_VarsVector(*args)
         try: self.this.append(this)
         except: self.this = this
-    def push_back(*args): return _CdiObj.VarsVector_push_back(*args)
-    def front(*args): return _CdiObj.VarsVector_front(*args)
-    def back(*args): return _CdiObj.VarsVector_back(*args)
-    def assign(*args): return _CdiObj.VarsVector_assign(*args)
-    def resize(*args): return _CdiObj.VarsVector_resize(*args)
-    def insert(*args): return _CdiObj.VarsVector_insert(*args)
-    def reserve(*args): return _CdiObj.VarsVector_reserve(*args)
-    def capacity(*args): return _CdiObj.VarsVector_capacity(*args)
+    def push_back(self, *args): return _CdiObj.VarsVector_push_back(self, *args)
+    def front(self): return _CdiObj.VarsVector_front(self)
+    def back(self): return _CdiObj.VarsVector_back(self)
+    def assign(self, *args): return _CdiObj.VarsVector_assign(self, *args)
+    def resize(self, *args): return _CdiObj.VarsVector_resize(self, *args)
+    def insert(self, *args): return _CdiObj.VarsVector_insert(self, *args)
+    def reserve(self, *args): return _CdiObj.VarsVector_reserve(self, *args)
+    def capacity(self): return _CdiObj.VarsVector_capacity(self)
     __swig_destroy__ = _CdiObj.delete_VarsVector
     __del__ = lambda self : None;
 VarsVector_swigregister = _CdiObj.VarsVector_swigregister
@@ -312,42 +339,44 @@ class VarsMap(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, VarsMap, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.VarsMap_iterator(*args)
+    def iterator(self): return _CdiObj.VarsMap_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.VarsMap___nonzero__(*args)
-    def __len__(*args): return _CdiObj.VarsMap___len__(*args)
-    def __getitem__(*args): return _CdiObj.VarsMap___getitem__(*args)
-    def __delitem__(*args): return _CdiObj.VarsMap___delitem__(*args)
-    def has_key(*args): return _CdiObj.VarsMap_has_key(*args)
-    def keys(*args): return _CdiObj.VarsMap_keys(*args)
-    def values(*args): return _CdiObj.VarsMap_values(*args)
-    def items(*args): return _CdiObj.VarsMap_items(*args)
-    def __contains__(*args): return _CdiObj.VarsMap___contains__(*args)
-    def key_iterator(*args): return _CdiObj.VarsMap_key_iterator(*args)
-    def value_iterator(*args): return _CdiObj.VarsMap_value_iterator(*args)
+    def __nonzero__(self): return _CdiObj.VarsMap___nonzero__(self)
+    def __bool__(self): return _CdiObj.VarsMap___bool__(self)
+    def __len__(self): return _CdiObj.VarsMap___len__(self)
     def __iter__(self): return self.key_iterator()
     def iterkeys(self): return self.key_iterator()
     def itervalues(self): return self.value_iterator()
     def iteritems(self): return self.iterator()
-    def __setitem__(*args): return _CdiObj.VarsMap___setitem__(*args)
+    def __getitem__(self, *args): return _CdiObj.VarsMap___getitem__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.VarsMap___delitem__(self, *args)
+    def has_key(self, *args): return _CdiObj.VarsMap_has_key(self, *args)
+    def keys(self): return _CdiObj.VarsMap_keys(self)
+    def values(self): return _CdiObj.VarsMap_values(self)
+    def items(self): return _CdiObj.VarsMap_items(self)
+    def __contains__(self, *args): return _CdiObj.VarsMap___contains__(self, *args)
+    def key_iterator(self): return _CdiObj.VarsMap_key_iterator(self)
+    def value_iterator(self): return _CdiObj.VarsMap_value_iterator(self)
+    def __setitem__(self, *args): return _CdiObj.VarsMap___setitem__(self, *args)
+    def asdict(self): return _CdiObj.VarsMap_asdict(self)
     def __init__(self, *args): 
         this = _CdiObj.new_VarsMap(*args)
         try: self.this.append(this)
         except: self.this = this
-    def empty(*args): return _CdiObj.VarsMap_empty(*args)
-    def size(*args): return _CdiObj.VarsMap_size(*args)
-    def clear(*args): return _CdiObj.VarsMap_clear(*args)
-    def swap(*args): return _CdiObj.VarsMap_swap(*args)
-    def get_allocator(*args): return _CdiObj.VarsMap_get_allocator(*args)
-    def begin(*args): return _CdiObj.VarsMap_begin(*args)
-    def end(*args): return _CdiObj.VarsMap_end(*args)
-    def rbegin(*args): return _CdiObj.VarsMap_rbegin(*args)
-    def rend(*args): return _CdiObj.VarsMap_rend(*args)
-    def count(*args): return _CdiObj.VarsMap_count(*args)
-    def erase(*args): return _CdiObj.VarsMap_erase(*args)
-    def find(*args): return _CdiObj.VarsMap_find(*args)
-    def lower_bound(*args): return _CdiObj.VarsMap_lower_bound(*args)
-    def upper_bound(*args): return _CdiObj.VarsMap_upper_bound(*args)
+    def empty(self): return _CdiObj.VarsMap_empty(self)
+    def size(self): return _CdiObj.VarsMap_size(self)
+    def clear(self): return _CdiObj.VarsMap_clear(self)
+    def swap(self, *args): return _CdiObj.VarsMap_swap(self, *args)
+    def get_allocator(self): return _CdiObj.VarsMap_get_allocator(self)
+    def begin(self): return _CdiObj.VarsMap_begin(self)
+    def end(self): return _CdiObj.VarsMap_end(self)
+    def rbegin(self): return _CdiObj.VarsMap_rbegin(self)
+    def rend(self): return _CdiObj.VarsMap_rend(self)
+    def count(self, *args): return _CdiObj.VarsMap_count(self, *args)
+    def erase(self, *args): return _CdiObj.VarsMap_erase(self, *args)
+    def find(self, *args): return _CdiObj.VarsMap_find(self, *args)
+    def lower_bound(self, *args): return _CdiObj.VarsMap_lower_bound(self, *args)
+    def upper_bound(self, *args): return _CdiObj.VarsMap_upper_bound(self, *args)
     __swig_destroy__ = _CdiObj.delete_VarsMap
     __del__ = lambda self : None;
 VarsMap_swigregister = _CdiObj.VarsMap_swigregister
@@ -359,42 +388,44 @@ class VarsByCode(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, VarsByCode, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.VarsByCode_iterator(*args)
+    def iterator(self): return _CdiObj.VarsByCode_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.VarsByCode___nonzero__(*args)
-    def __len__(*args): return _CdiObj.VarsByCode___len__(*args)
-    def __getitem__(*args): return _CdiObj.VarsByCode___getitem__(*args)
-    def __delitem__(*args): return _CdiObj.VarsByCode___delitem__(*args)
-    def has_key(*args): return _CdiObj.VarsByCode_has_key(*args)
-    def keys(*args): return _CdiObj.VarsByCode_keys(*args)
-    def values(*args): return _CdiObj.VarsByCode_values(*args)
-    def items(*args): return _CdiObj.VarsByCode_items(*args)
-    def __contains__(*args): return _CdiObj.VarsByCode___contains__(*args)
-    def key_iterator(*args): return _CdiObj.VarsByCode_key_iterator(*args)
-    def value_iterator(*args): return _CdiObj.VarsByCode_value_iterator(*args)
+    def __nonzero__(self): return _CdiObj.VarsByCode___nonzero__(self)
+    def __bool__(self): return _CdiObj.VarsByCode___bool__(self)
+    def __len__(self): return _CdiObj.VarsByCode___len__(self)
     def __iter__(self): return self.key_iterator()
     def iterkeys(self): return self.key_iterator()
     def itervalues(self): return self.value_iterator()
     def iteritems(self): return self.iterator()
-    def __setitem__(*args): return _CdiObj.VarsByCode___setitem__(*args)
+    def __getitem__(self, *args): return _CdiObj.VarsByCode___getitem__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.VarsByCode___delitem__(self, *args)
+    def has_key(self, *args): return _CdiObj.VarsByCode_has_key(self, *args)
+    def keys(self): return _CdiObj.VarsByCode_keys(self)
+    def values(self): return _CdiObj.VarsByCode_values(self)
+    def items(self): return _CdiObj.VarsByCode_items(self)
+    def __contains__(self, *args): return _CdiObj.VarsByCode___contains__(self, *args)
+    def key_iterator(self): return _CdiObj.VarsByCode_key_iterator(self)
+    def value_iterator(self): return _CdiObj.VarsByCode_value_iterator(self)
+    def __setitem__(self, *args): return _CdiObj.VarsByCode___setitem__(self, *args)
+    def asdict(self): return _CdiObj.VarsByCode_asdict(self)
     def __init__(self, *args): 
         this = _CdiObj.new_VarsByCode(*args)
         try: self.this.append(this)
         except: self.this = this
-    def empty(*args): return _CdiObj.VarsByCode_empty(*args)
-    def size(*args): return _CdiObj.VarsByCode_size(*args)
-    def clear(*args): return _CdiObj.VarsByCode_clear(*args)
-    def swap(*args): return _CdiObj.VarsByCode_swap(*args)
-    def get_allocator(*args): return _CdiObj.VarsByCode_get_allocator(*args)
-    def begin(*args): return _CdiObj.VarsByCode_begin(*args)
-    def end(*args): return _CdiObj.VarsByCode_end(*args)
-    def rbegin(*args): return _CdiObj.VarsByCode_rbegin(*args)
-    def rend(*args): return _CdiObj.VarsByCode_rend(*args)
-    def count(*args): return _CdiObj.VarsByCode_count(*args)
-    def erase(*args): return _CdiObj.VarsByCode_erase(*args)
-    def find(*args): return _CdiObj.VarsByCode_find(*args)
-    def lower_bound(*args): return _CdiObj.VarsByCode_lower_bound(*args)
-    def upper_bound(*args): return _CdiObj.VarsByCode_upper_bound(*args)
+    def empty(self): return _CdiObj.VarsByCode_empty(self)
+    def size(self): return _CdiObj.VarsByCode_size(self)
+    def clear(self): return _CdiObj.VarsByCode_clear(self)
+    def swap(self, *args): return _CdiObj.VarsByCode_swap(self, *args)
+    def get_allocator(self): return _CdiObj.VarsByCode_get_allocator(self)
+    def begin(self): return _CdiObj.VarsByCode_begin(self)
+    def end(self): return _CdiObj.VarsByCode_end(self)
+    def rbegin(self): return _CdiObj.VarsByCode_rbegin(self)
+    def rend(self): return _CdiObj.VarsByCode_rend(self)
+    def count(self, *args): return _CdiObj.VarsByCode_count(self, *args)
+    def erase(self, *args): return _CdiObj.VarsByCode_erase(self, *args)
+    def find(self, *args): return _CdiObj.VarsByCode_find(self, *args)
+    def lower_bound(self, *args): return _CdiObj.VarsByCode_lower_bound(self, *args)
+    def upper_bound(self, *args): return _CdiObj.VarsByCode_upper_bound(self, *args)
     __swig_destroy__ = _CdiObj.delete_VarsByCode
     __del__ = lambda self : None;
 VarsByCode_swigregister = _CdiObj.VarsByCode_swigregister
@@ -406,42 +437,44 @@ class TaxesMap(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, TaxesMap, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.TaxesMap_iterator(*args)
+    def iterator(self): return _CdiObj.TaxesMap_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.TaxesMap___nonzero__(*args)
-    def __len__(*args): return _CdiObj.TaxesMap___len__(*args)
-    def __getitem__(*args): return _CdiObj.TaxesMap___getitem__(*args)
-    def __delitem__(*args): return _CdiObj.TaxesMap___delitem__(*args)
-    def has_key(*args): return _CdiObj.TaxesMap_has_key(*args)
-    def keys(*args): return _CdiObj.TaxesMap_keys(*args)
-    def values(*args): return _CdiObj.TaxesMap_values(*args)
-    def items(*args): return _CdiObj.TaxesMap_items(*args)
-    def __contains__(*args): return _CdiObj.TaxesMap___contains__(*args)
-    def key_iterator(*args): return _CdiObj.TaxesMap_key_iterator(*args)
-    def value_iterator(*args): return _CdiObj.TaxesMap_value_iterator(*args)
+    def __nonzero__(self): return _CdiObj.TaxesMap___nonzero__(self)
+    def __bool__(self): return _CdiObj.TaxesMap___bool__(self)
+    def __len__(self): return _CdiObj.TaxesMap___len__(self)
     def __iter__(self): return self.key_iterator()
     def iterkeys(self): return self.key_iterator()
     def itervalues(self): return self.value_iterator()
     def iteritems(self): return self.iterator()
-    def __setitem__(*args): return _CdiObj.TaxesMap___setitem__(*args)
+    def __getitem__(self, *args): return _CdiObj.TaxesMap___getitem__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.TaxesMap___delitem__(self, *args)
+    def has_key(self, *args): return _CdiObj.TaxesMap_has_key(self, *args)
+    def keys(self): return _CdiObj.TaxesMap_keys(self)
+    def values(self): return _CdiObj.TaxesMap_values(self)
+    def items(self): return _CdiObj.TaxesMap_items(self)
+    def __contains__(self, *args): return _CdiObj.TaxesMap___contains__(self, *args)
+    def key_iterator(self): return _CdiObj.TaxesMap_key_iterator(self)
+    def value_iterator(self): return _CdiObj.TaxesMap_value_iterator(self)
+    def __setitem__(self, *args): return _CdiObj.TaxesMap___setitem__(self, *args)
+    def asdict(self): return _CdiObj.TaxesMap_asdict(self)
     def __init__(self, *args): 
         this = _CdiObj.new_TaxesMap(*args)
         try: self.this.append(this)
         except: self.this = this
-    def empty(*args): return _CdiObj.TaxesMap_empty(*args)
-    def size(*args): return _CdiObj.TaxesMap_size(*args)
-    def clear(*args): return _CdiObj.TaxesMap_clear(*args)
-    def swap(*args): return _CdiObj.TaxesMap_swap(*args)
-    def get_allocator(*args): return _CdiObj.TaxesMap_get_allocator(*args)
-    def begin(*args): return _CdiObj.TaxesMap_begin(*args)
-    def end(*args): return _CdiObj.TaxesMap_end(*args)
-    def rbegin(*args): return _CdiObj.TaxesMap_rbegin(*args)
-    def rend(*args): return _CdiObj.TaxesMap_rend(*args)
-    def count(*args): return _CdiObj.TaxesMap_count(*args)
-    def erase(*args): return _CdiObj.TaxesMap_erase(*args)
-    def find(*args): return _CdiObj.TaxesMap_find(*args)
-    def lower_bound(*args): return _CdiObj.TaxesMap_lower_bound(*args)
-    def upper_bound(*args): return _CdiObj.TaxesMap_upper_bound(*args)
+    def empty(self): return _CdiObj.TaxesMap_empty(self)
+    def size(self): return _CdiObj.TaxesMap_size(self)
+    def clear(self): return _CdiObj.TaxesMap_clear(self)
+    def swap(self, *args): return _CdiObj.TaxesMap_swap(self, *args)
+    def get_allocator(self): return _CdiObj.TaxesMap_get_allocator(self)
+    def begin(self): return _CdiObj.TaxesMap_begin(self)
+    def end(self): return _CdiObj.TaxesMap_end(self)
+    def rbegin(self): return _CdiObj.TaxesMap_rbegin(self)
+    def rend(self): return _CdiObj.TaxesMap_rend(self)
+    def count(self, *args): return _CdiObj.TaxesMap_count(self, *args)
+    def erase(self, *args): return _CdiObj.TaxesMap_erase(self, *args)
+    def find(self, *args): return _CdiObj.TaxesMap_find(self, *args)
+    def lower_bound(self, *args): return _CdiObj.TaxesMap_lower_bound(self, *args)
+    def upper_bound(self, *args): return _CdiObj.TaxesMap_upper_bound(self, *args)
     __swig_destroy__ = _CdiObj.delete_TaxesMap
     __del__ = lambda self : None;
 TaxesMap_swigregister = _CdiObj.TaxesMap_swigregister
@@ -453,42 +486,44 @@ class ZaxesMap(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, ZaxesMap, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.ZaxesMap_iterator(*args)
+    def iterator(self): return _CdiObj.ZaxesMap_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.ZaxesMap___nonzero__(*args)
-    def __len__(*args): return _CdiObj.ZaxesMap___len__(*args)
-    def __getitem__(*args): return _CdiObj.ZaxesMap___getitem__(*args)
-    def __delitem__(*args): return _CdiObj.ZaxesMap___delitem__(*args)
-    def has_key(*args): return _CdiObj.ZaxesMap_has_key(*args)
-    def keys(*args): return _CdiObj.ZaxesMap_keys(*args)
-    def values(*args): return _CdiObj.ZaxesMap_values(*args)
-    def items(*args): return _CdiObj.ZaxesMap_items(*args)
-    def __contains__(*args): return _CdiObj.ZaxesMap___contains__(*args)
-    def key_iterator(*args): return _CdiObj.ZaxesMap_key_iterator(*args)
-    def value_iterator(*args): return _CdiObj.ZaxesMap_value_iterator(*args)
+    def __nonzero__(self): return _CdiObj.ZaxesMap___nonzero__(self)
+    def __bool__(self): return _CdiObj.ZaxesMap___bool__(self)
+    def __len__(self): return _CdiObj.ZaxesMap___len__(self)
     def __iter__(self): return self.key_iterator()
     def iterkeys(self): return self.key_iterator()
     def itervalues(self): return self.value_iterator()
     def iteritems(self): return self.iterator()
-    def __setitem__(*args): return _CdiObj.ZaxesMap___setitem__(*args)
+    def __getitem__(self, *args): return _CdiObj.ZaxesMap___getitem__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.ZaxesMap___delitem__(self, *args)
+    def has_key(self, *args): return _CdiObj.ZaxesMap_has_key(self, *args)
+    def keys(self): return _CdiObj.ZaxesMap_keys(self)
+    def values(self): return _CdiObj.ZaxesMap_values(self)
+    def items(self): return _CdiObj.ZaxesMap_items(self)
+    def __contains__(self, *args): return _CdiObj.ZaxesMap___contains__(self, *args)
+    def key_iterator(self): return _CdiObj.ZaxesMap_key_iterator(self)
+    def value_iterator(self): return _CdiObj.ZaxesMap_value_iterator(self)
+    def __setitem__(self, *args): return _CdiObj.ZaxesMap___setitem__(self, *args)
+    def asdict(self): return _CdiObj.ZaxesMap_asdict(self)
     def __init__(self, *args): 
         this = _CdiObj.new_ZaxesMap(*args)
         try: self.this.append(this)
         except: self.this = this
-    def empty(*args): return _CdiObj.ZaxesMap_empty(*args)
-    def size(*args): return _CdiObj.ZaxesMap_size(*args)
-    def clear(*args): return _CdiObj.ZaxesMap_clear(*args)
-    def swap(*args): return _CdiObj.ZaxesMap_swap(*args)
-    def get_allocator(*args): return _CdiObj.ZaxesMap_get_allocator(*args)
-    def begin(*args): return _CdiObj.ZaxesMap_begin(*args)
-    def end(*args): return _CdiObj.ZaxesMap_end(*args)
-    def rbegin(*args): return _CdiObj.ZaxesMap_rbegin(*args)
-    def rend(*args): return _CdiObj.ZaxesMap_rend(*args)
-    def count(*args): return _CdiObj.ZaxesMap_count(*args)
-    def erase(*args): return _CdiObj.ZaxesMap_erase(*args)
-    def find(*args): return _CdiObj.ZaxesMap_find(*args)
-    def lower_bound(*args): return _CdiObj.ZaxesMap_lower_bound(*args)
-    def upper_bound(*args): return _CdiObj.ZaxesMap_upper_bound(*args)
+    def empty(self): return _CdiObj.ZaxesMap_empty(self)
+    def size(self): return _CdiObj.ZaxesMap_size(self)
+    def clear(self): return _CdiObj.ZaxesMap_clear(self)
+    def swap(self, *args): return _CdiObj.ZaxesMap_swap(self, *args)
+    def get_allocator(self): return _CdiObj.ZaxesMap_get_allocator(self)
+    def begin(self): return _CdiObj.ZaxesMap_begin(self)
+    def end(self): return _CdiObj.ZaxesMap_end(self)
+    def rbegin(self): return _CdiObj.ZaxesMap_rbegin(self)
+    def rend(self): return _CdiObj.ZaxesMap_rend(self)
+    def count(self, *args): return _CdiObj.ZaxesMap_count(self, *args)
+    def erase(self, *args): return _CdiObj.ZaxesMap_erase(self, *args)
+    def find(self, *args): return _CdiObj.ZaxesMap_find(self, *args)
+    def lower_bound(self, *args): return _CdiObj.ZaxesMap_lower_bound(self, *args)
+    def upper_bound(self, *args): return _CdiObj.ZaxesMap_upper_bound(self, *args)
     __swig_destroy__ = _CdiObj.delete_ZaxesMap
     __del__ = lambda self : None;
 ZaxesMap_swigregister = _CdiObj.ZaxesMap_swigregister
@@ -500,42 +535,44 @@ class GridsMap(_object):
     __swig_getmethods__ = {}
     __getattr__ = lambda self, name: _swig_getattr(self, GridsMap, name)
     __repr__ = _swig_repr
-    def iterator(*args): return _CdiObj.GridsMap_iterator(*args)
+    def iterator(self): return _CdiObj.GridsMap_iterator(self)
     def __iter__(self): return self.iterator()
-    def __nonzero__(*args): return _CdiObj.GridsMap___nonzero__(*args)
-    def __len__(*args): return _CdiObj.GridsMap___len__(*args)
-    def __getitem__(*args): return _CdiObj.GridsMap___getitem__(*args)
-    def __delitem__(*args): return _CdiObj.GridsMap___delitem__(*args)
-    def has_key(*args): return _CdiObj.GridsMap_has_key(*args)
-    def keys(*args): return _CdiObj.GridsMap_keys(*args)
-    def values(*args): return _CdiObj.GridsMap_values(*args)
-    def items(*args): return _CdiObj.GridsMap_items(*args)
-    def __contains__(*args): return _CdiObj.GridsMap___contains__(*args)
-    def key_iterator(*args): return _CdiObj.GridsMap_key_iterator(*args)
-    def value_iterator(*args): return _CdiObj.GridsMap_value_iterator(*args)
+    def __nonzero__(self): return _CdiObj.GridsMap___nonzero__(self)
+    def __bool__(self): return _CdiObj.GridsMap___bool__(self)
+    def __len__(self): return _CdiObj.GridsMap___len__(self)
     def __iter__(self): return self.key_iterator()
     def iterkeys(self): return self.key_iterator()
     def itervalues(self): return self.value_iterator()
     def iteritems(self): return self.iterator()
-    def __setitem__(*args): return _CdiObj.GridsMap___setitem__(*args)
+    def __getitem__(self, *args): return _CdiObj.GridsMap___getitem__(self, *args)
+    def __delitem__(self, *args): return _CdiObj.GridsMap___delitem__(self, *args)
+    def has_key(self, *args): return _CdiObj.GridsMap_has_key(self, *args)
+    def keys(self): return _CdiObj.GridsMap_keys(self)
+    def values(self): return _CdiObj.GridsMap_values(self)
+    def items(self): return _CdiObj.GridsMap_items(self)
+    def __contains__(self, *args): return _CdiObj.GridsMap___contains__(self, *args)
+    def key_iterator(self): return _CdiObj.GridsMap_key_iterator(self)
+    def value_iterator(self): return _CdiObj.GridsMap_value_iterator(self)
+    def __setitem__(self, *args): return _CdiObj.GridsMap___setitem__(self, *args)
+    def asdict(self): return _CdiObj.GridsMap_asdict(self)
     def __init__(self, *args): 
         this = _CdiObj.new_GridsMap(*args)
         try: self.this.append(this)
         except: self.this = this
-    def empty(*args): return _CdiObj.GridsMap_empty(*args)
-    def size(*args): return _CdiObj.GridsMap_size(*args)
-    def clear(*args): return _CdiObj.GridsMap_clear(*args)
-    def swap(*args): return _CdiObj.GridsMap_swap(*args)
-    def get_allocator(*args): return _CdiObj.GridsMap_get_allocator(*args)
-    def begin(*args): return _CdiObj.GridsMap_begin(*args)
-    def end(*args): return _CdiObj.GridsMap_end(*args)
-    def rbegin(*args): return _CdiObj.GridsMap_rbegin(*args)
-    def rend(*args): return _CdiObj.GridsMap_rend(*args)
-    def count(*args): return _CdiObj.GridsMap_count(*args)
-    def erase(*args): return _CdiObj.GridsMap_erase(*args)
-    def find(*args): return _CdiObj.GridsMap_find(*args)
-    def lower_bound(*args): return _CdiObj.GridsMap_lower_bound(*args)
-    def upper_bound(*args): return _CdiObj.GridsMap_upper_bound(*args)
+    def empty(self): return _CdiObj.GridsMap_empty(self)
+    def size(self): return _CdiObj.GridsMap_size(self)
+    def clear(self): return _CdiObj.GridsMap_clear(self)
+    def swap(self, *args): return _CdiObj.GridsMap_swap(self, *args)
+    def get_allocator(self): return _CdiObj.GridsMap_get_allocator(self)
+    def begin(self): return _CdiObj.GridsMap_begin(self)
+    def end(self): return _CdiObj.GridsMap_end(self)
+    def rbegin(self): return _CdiObj.GridsMap_rbegin(self)
+    def rend(self): return _CdiObj.GridsMap_rend(self)
+    def count(self, *args): return _CdiObj.GridsMap_count(self, *args)
+    def erase(self, *args): return _CdiObj.GridsMap_erase(self, *args)
+    def find(self, *args): return _CdiObj.GridsMap_find(self, *args)
+    def lower_bound(self, *args): return _CdiObj.GridsMap_lower_bound(self, *args)
+    def upper_bound(self, *args): return _CdiObj.GridsMap_upper_bound(self, *args)
     __swig_destroy__ = _CdiObj.delete_GridsMap
     __del__ = lambda self : None;
 GridsMap_swigregister = _CdiObj.GridsMap_swigregister
@@ -623,12 +660,12 @@ class CdiGrid(_object):
     __swig_setmethods__["name"] = _CdiObj.CdiGrid_name_set
     __swig_getmethods__["name"] = _CdiObj.CdiGrid_name_get
     if _newclass:name = _swig_property(_CdiObj.CdiGrid_name_get, _CdiObj.CdiGrid_name_set)
-    def getValues(*args): return _CdiObj.CdiGrid_getValues(*args)
-    def getBounds(*args): return _CdiObj.CdiGrid_getBounds(*args)
-    def getValuesAsPointer(*args): return _CdiObj.CdiGrid_getValuesAsPointer(*args)
-    def getBoundsAsPointer(*args): return _CdiObj.CdiGrid_getBoundsAsPointer(*args)
-    def getFloatVals(*args): return _CdiObj.CdiGrid_getFloatVals(*args)
-    def getFloatBounds(*args): return _CdiObj.CdiGrid_getFloatBounds(*args)
+    def getValues(self): return _CdiObj.CdiGrid_getValues(self)
+    def getBounds(self): return _CdiObj.CdiGrid_getBounds(self)
+    def getValuesAsPointer(self, *args): return _CdiObj.CdiGrid_getValuesAsPointer(self, *args)
+    def getBoundsAsPointer(self, *args): return _CdiObj.CdiGrid_getBoundsAsPointer(self, *args)
+    def getFloatVals(self, *args): return _CdiObj.CdiGrid_getFloatVals(self, *args)
+    def getFloatBounds(self, *args): return _CdiObj.CdiGrid_getFloatBounds(self, *args)
 CdiGrid_swigregister = _CdiObj.CdiGrid_swigregister
 CdiGrid_swigregister(CdiGrid)
 
@@ -818,13 +855,13 @@ class CdiVariable(_object):
     __swig_setmethods__["taxis"] = _CdiObj.CdiVariable_taxis_set
     __swig_getmethods__["taxis"] = _CdiObj.CdiVariable_taxis_get
     if _newclass:taxis = _swig_property(_CdiObj.CdiVariable_taxis_get, _CdiObj.CdiVariable_taxis_set)
-    def sinfo(*args): return _CdiObj.CdiVariable_sinfo(*args)
-    def getValues(*args): return _CdiObj.CdiVariable_getValues(*args)
-    def getValuesWithLevel(*args): return _CdiObj.CdiVariable_getValuesWithLevel(*args)
-    def getFValues(*args): return _CdiObj.CdiVariable_getFValues(*args)
-    def getFValuesWithLevel(*args): return _CdiObj.CdiVariable_getFValuesWithLevel(*args)
-    def getValuesAsPointer(*args): return _CdiObj.CdiVariable_getValuesAsPointer(*args)
-    def getValuesWithLevelAsPointer(*args): return _CdiObj.CdiVariable_getValuesWithLevelAsPointer(*args)
+    def sinfo(self): return _CdiObj.CdiVariable_sinfo(self)
+    def getValues(self): return _CdiObj.CdiVariable_getValues(self)
+    def getValuesWithLevel(self, tsID=0): return _CdiObj.CdiVariable_getValuesWithLevel(self, tsID)
+    def getFValues(self): return _CdiObj.CdiVariable_getFValues(self)
+    def getFValuesWithLevel(self, tsID=0): return _CdiObj.CdiVariable_getFValuesWithLevel(self, tsID)
+    def getValuesAsPointer(self): return _CdiObj.CdiVariable_getValuesAsPointer(self)
+    def getValuesWithLevelAsPointer(self, tsID=0): return _CdiObj.CdiVariable_getValuesWithLevelAsPointer(self, tsID)
 CdiVariable_swigregister = _CdiObj.CdiVariable_swigregister
 CdiVariable_swigregister(CdiVariable)
 
@@ -885,9 +922,10 @@ class Cdi(_object):
     __swig_setmethods__["grids"] = _CdiObj.Cdi_grids_set
     __swig_getmethods__["grids"] = _CdiObj.Cdi_grids_get
     if _newclass:grids = _swig_property(_CdiObj.Cdi_grids_get, _CdiObj.Cdi_grids_set)
-    def griddes(*args): return _CdiObj.Cdi_griddes(*args)
+    def griddes(self): return _CdiObj.Cdi_griddes(self)
 Cdi_swigregister = _CdiObj.Cdi_swigregister
 Cdi_swigregister(Cdi)
 
+# This file is compatible with both classic and new-style classes.
 
 
diff --git a/libcdi/interfaces/python/cdiobj_wrap.cpp b/libcdi/interfaces/python/cdiobj_wrap.cpp
index 726bb4b..cf41afa 100644
--- a/libcdi/interfaces/python/cdiobj_wrap.cpp
+++ b/libcdi/interfaces/python/cdiobj_wrap.cpp
@@ -1,30 +1,38 @@
 /* ----------------------------------------------------------------------------
  * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.31
- * 
- * This file is not intended to be easily readable and contains a number of 
+ * Version 3.0.2
+ *
+ * This file is not intended to be easily readable and contains a number of
  * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG 
- * interface file instead. 
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
  * ----------------------------------------------------------------------------- */
 
 #define SWIGPYTHON
 #define SWIG_PYTHON_DIRECTOR_NO_VTABLE
 
+
 #ifdef __cplusplus
-template<class T> class SwigValueWrapper {
-    T *tt;
+/* SwigValueWrapper is described in swig.swg */
+template<typename T> class SwigValueWrapper {
+  struct SwigMovePointer {
+    T *ptr;
+    SwigMovePointer(T *p) : ptr(p) { }
+    ~SwigMovePointer() { delete ptr; }
+    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+  } pointer;
+  SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+  SwigValueWrapper(const SwigValueWrapper<T>& rhs);
 public:
-    SwigValueWrapper() : tt(0) { }
-    SwigValueWrapper(const SwigValueWrapper<T>& rhs) : tt(new T(*rhs.tt)) { }
-    SwigValueWrapper(const T& t) : tt(new T(t)) { }
-    ~SwigValueWrapper() { delete tt; } 
-    SwigValueWrapper& operator=(const T& t) { delete tt; tt = new T(t); return *this; }
-    operator T&() const { return *tt; }
-    T *operator&() { return tt; }
-private:
-    SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+  SwigValueWrapper() : pointer(0) { }
+  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+  operator T&() const { return *pointer.ptr; }
+  T *operator&() { return pointer.ptr; }
 };
+
+template <typename T> T SwigValueInit() {
+  return T();
+}
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -34,14 +42,14 @@ private:
 
 /* template workaround for compilers that cannot correctly implement the C++ standard */
 #ifndef SWIGTEMPLATEDISAMBIGUATOR
-# if defined(__SUNPRO_CC)
-#   if (__SUNPRO_CC <= 0x560)
-#     define SWIGTEMPLATEDISAMBIGUATOR template
-#   else
-#     define SWIGTEMPLATEDISAMBIGUATOR 
-#   endif
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+#  define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+#  define SWIGTEMPLATEDISAMBIGUATOR template
 # else
-#   define SWIGTEMPLATEDISAMBIGUATOR 
+#  define SWIGTEMPLATEDISAMBIGUATOR
 # endif
 #endif
 
@@ -58,14 +66,20 @@ private:
 #ifndef SWIGUNUSED
 # if defined(__GNUC__)
 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-#     define SWIGUNUSED __attribute__ ((__unused__)) 
+#     define SWIGUNUSED __attribute__ ((__unused__))
 #   else
 #     define SWIGUNUSED
 #   endif
 # elif defined(__ICC)
-#   define SWIGUNUSED __attribute__ ((__unused__)) 
+#   define SWIGUNUSED __attribute__ ((__unused__))
 # else
-#   define SWIGUNUSED 
+#   define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+#   pragma warning(disable : 4505) /* unreferenced local function has been removed */
 # endif
 #endif
 
@@ -73,7 +87,7 @@ private:
 # ifdef __cplusplus
 #   define SWIGUNUSEDPARM(p)
 # else
-#   define SWIGUNUSEDPARM(p) p SWIGUNUSED 
+#   define SWIGUNUSEDPARM(p) p SWIGUNUSED
 # endif
 #endif
 
@@ -116,7 +130,7 @@ private:
 #   define SWIGSTDCALL __stdcall
 # else
 #   define SWIGSTDCALL
-# endif 
+# endif
 #endif
 
 /* Deal with Microsoft's attempt at deprecating C standard runtime functions */
@@ -124,20 +138,32 @@ private:
 # define _CRT_SECURE_NO_DEPRECATE
 #endif
 
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
 
-/* Python.h has to appear first */
-#include <Python.h>
+
+#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
+/* Use debug wrappers with the Python release dll */
+# undef _DEBUG
+# include <Python.h>
+# define _DEBUG
+#else
+# include <Python.h>
+#endif
 
 /* -----------------------------------------------------------------------------
  * swigrun.swg
  *
- * This file contains generic CAPI SWIG runtime support for pointer
+ * This file contains generic C API SWIG runtime support for pointer
  * type checking.
  * ----------------------------------------------------------------------------- */
 
 /* This should only be incremented when either the layout of swig_type_info changes,
    or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "3"
+#define SWIG_RUNTIME_VERSION "4"
 
 /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
 #ifdef SWIG_TYPE_TABLE
@@ -150,11 +176,11 @@ private:
 
 /*
   You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
-  creating a static or dynamic library from the swig runtime code.
-  In 99.9% of the cases, swig just needs to declare them as 'static'.
-  
-  But only do this if is strictly necessary, ie, if you have problems
-  with your compiler or so.
+  creating a static or dynamic library from the SWIG runtime code.
+  In 99.9% of the cases, SWIG just needs to declare them as 'static'.
+
+  But only do this if strictly necessary, ie, if you have problems
+  with your compiler or suchlike.
 */
 
 #ifndef SWIGRUNTIME
@@ -172,22 +198,23 @@ private:
 
 /* Flags for pointer conversions */
 #define SWIG_POINTER_DISOWN        0x1
+#define SWIG_CAST_NEW_MEMORY       0x2
 
 /* Flags for new pointer objects */
 #define SWIG_POINTER_OWN           0x1
 
 
-/* 
+/*
    Flags/methods for returning states.
-   
-   The swig conversion methods, as ConvertPtr, return and integer 
+
+   The SWIG conversion methods, as ConvertPtr, return an integer
    that tells if the conversion was successful or not. And if not,
    an error code can be returned (see swigerrors.swg for the codes).
-   
+
    Use the following macros/flags to set or process the returning
    states.
-   
-   In old swig versions, you usually write code as:
+
+   In old versions of SWIG, code such as the following was usually written:
 
      if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
        // success code
@@ -195,7 +222,7 @@ private:
        //fail code
      }
 
-   Now you can be more explicit as:
+   Now you can be more explicit:
 
     int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
     if (SWIG_IsOK(res)) {
@@ -204,7 +231,7 @@ private:
       // fail code
     }
 
-   that seems to be the same, but now you can also do
+   which is the same really, but now you can also do
 
     Type *ptr;
     int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
@@ -219,28 +246,28 @@ private:
     } else {
       // fail code
     }
-    
+
    I.e., now SWIG_ConvertPtr can return new objects and you can
    identify the case and take care of the deallocation. Of course that
-   requires also to SWIG_ConvertPtr to return new result values, as
-
-      int SWIG_ConvertPtr(obj, ptr,...) {         
-        if (<obj is ok>) {			       
-          if (<need new object>) {		       
-            *ptr = <ptr to new allocated object>; 
-            return SWIG_NEWOBJ;		       
-          } else {				       
-            *ptr = <ptr to old object>;	       
-            return SWIG_OLDOBJ;		       
-          } 				       
-        } else {				       
-          return SWIG_BADOBJ;		       
-        }					       
+   also requires SWIG_ConvertPtr to return new result values, such as
+
+      int SWIG_ConvertPtr(obj, ptr,...) {
+        if (<obj is ok>) {
+          if (<need new object>) {
+            *ptr = <ptr to new allocated object>;
+            return SWIG_NEWOBJ;
+          } else {
+            *ptr = <ptr to old object>;
+            return SWIG_OLDOBJ;
+          }
+        } else {
+          return SWIG_BADOBJ;
+        }
       }
 
    Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
    more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
-   swig errors code.
+   SWIG errors code.
 
    Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
    allows to return the 'cast rank', for example, if you have this
@@ -249,18 +276,17 @@ private:
        int fooi(int);
 
    and you call
- 
+
       food(1)   // cast rank '1'  (1 -> 1.0)
       fooi(1)   // cast rank '0'
 
    just use the SWIG_AddCast()/SWIG_CheckState()
+*/
 
-
- */
-#define SWIG_OK                    (0) 
+#define SWIG_OK                    (0)
 #define SWIG_ERROR                 (-1)
 #define SWIG_IsOK(r)               (r >= 0)
-#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)  
+#define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)
 
 /* The CastRankLimit says how many bits are used for the cast rank */
 #define SWIG_CASTRANKLIMIT         (1 << 8)
@@ -281,7 +307,6 @@ private:
 #define SWIG_DelTmpMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
 #define SWIG_IsTmpObj(r)           (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
 
-
 /* Cast-Rank Mode */
 #if defined(SWIG_CASTRANK_MODE)
 #  ifndef SWIG_TypeRank
@@ -292,30 +317,28 @@ private:
 #  endif
 #  define SWIG_CASTRANKMASK          ((SWIG_CASTRANKLIMIT) -1)
 #  define SWIG_CastRank(r)           (r & SWIG_CASTRANKMASK)
-SWIGINTERNINLINE int SWIG_AddCast(int r) { 
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
   return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
 }
-SWIGINTERNINLINE int SWIG_CheckState(int r) { 
-  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; 
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+  return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
 }
 #else /* no cast-rank mode */
-#  define SWIG_AddCast
+#  define SWIG_AddCast(r) (r)
 #  define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
 #endif
 
 
-
-
 #include <string.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef void *(*swig_converter_func)(void *);
+typedef void *(*swig_converter_func)(void *, int *);
 typedef struct swig_type_info *(*swig_dycast_func)(void **);
 
-/* Structure to store inforomation on one type */
+/* Structure to store information on one type */
 typedef struct swig_type_info {
   const char             *name;			/* mangled name of this type */
   const char             *str;			/* human readable name of this type */
@@ -345,7 +368,7 @@ typedef struct swig_module_info {
   void                    *clientdata;		/* Language specific module data */
 } swig_module_info;
 
-/* 
+/*
   Compare two type names skipping the space characters, therefore
   "char*" == "char *" and "Class<int>" == "Class<int >", etc.
 
@@ -360,23 +383,23 @@ SWIG_TypeNameComp(const char *f1, const char *l1,
     while ((*f2 == ' ') && (f2 != l2)) ++f2;
     if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
   }
-  return (l1 - f1) - (l2 - f2);
+  return (int)((l1 - f1) - (l2 - f2));
 }
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if not equal, 1 if equal
+  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
 */
 SWIGRUNTIME int
-SWIG_TypeEquiv(const char *nb, const char *tb) {
-  int equiv = 0;
+SWIG_TypeCmp(const char *nb, const char *tb) {
+  int equiv = 1;
   const char* te = tb + strlen(tb);
   const char* ne = nb;
-  while (!equiv && *ne) {
+  while (equiv != 0 && *ne) {
     for (nb = ne; *ne; ++ne) {
       if (*ne == '|') break;
     }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+    equiv = SWIG_TypeNameComp(nb, ne, tb, te);
     if (*ne) ++ne;
   }
   return equiv;
@@ -384,69 +407,76 @@ SWIG_TypeEquiv(const char *nb, const char *tb) {
 
 /*
   Check type equivalence in a name list like <name1>|<name2>|...
-  Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+  Return 0 if not equal, 1 if equal
 */
 SWIGRUNTIME int
-SWIG_TypeCompare(const char *nb, const char *tb) {
-  int equiv = 0;
-  const char* te = tb + strlen(tb);
-  const char* ne = nb;
-  while (!equiv && *ne) {
-    for (nb = ne; *ne; ++ne) {
-      if (*ne == '|') break;
-    }
-    equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
-    if (*ne) ++ne;
-  }
-  return equiv;
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+  return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0;
 }
 
-
-/* think of this as a c++ template<> or a scheme macro */
-#define SWIG_TypeCheck_Template(comparison, ty)         \
-  if (ty) {                                             \
-    swig_cast_info *iter = ty->cast;                    \
-    while (iter) {                                      \
-      if (comparison) {                                 \
-        if (iter == ty->cast) return iter;              \
-        /* Move iter to the top of the linked list */   \
-        iter->prev->next = iter->next;                  \
-        if (iter->next)                                 \
-          iter->next->prev = iter->prev;                \
-        iter->next = ty->cast;                          \
-        iter->prev = 0;                                 \
-        if (ty->cast) ty->cast->prev = iter;            \
-        ty->cast = iter;                                \
-        return iter;                                    \
-      }                                                 \
-      iter = iter->next;                                \
-    }                                                   \
-  }                                                     \
-  return 0
-
 /*
   Check the typename
 */
 SWIGRUNTIME swig_cast_info *
 SWIG_TypeCheck(const char *c, swig_type_info *ty) {
-  SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty);
+  if (ty) {
+    swig_cast_info *iter = ty->cast;
+    while (iter) {
+      if (strcmp(iter->type->name, c) == 0) {
+        if (iter == ty->cast)
+          return iter;
+        /* Move iter to the top of the linked list */
+        iter->prev->next = iter->next;
+        if (iter->next)
+          iter->next->prev = iter->prev;
+        iter->next = ty->cast;
+        iter->prev = 0;
+        if (ty->cast) ty->cast->prev = iter;
+        ty->cast = iter;
+        return iter;
+      }
+      iter = iter->next;
+    }
+  }
+  return 0;
 }
 
-/* Same as previous function, except strcmp is replaced with a pointer comparison */
+/*
+  Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
+*/
 SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
-  SWIG_TypeCheck_Template(iter->type == from, into);
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+  if (ty) {
+    swig_cast_info *iter = ty->cast;
+    while (iter) {
+      if (iter->type == from) {
+        if (iter == ty->cast)
+          return iter;
+        /* Move iter to the top of the linked list */
+        iter->prev->next = iter->next;
+        if (iter->next)
+          iter->next->prev = iter->prev;
+        iter->next = ty->cast;
+        iter->prev = 0;
+        if (ty->cast) ty->cast->prev = iter;
+        ty->cast = iter;
+        return iter;
+      }
+      iter = iter->next;
+    }
+  }
+  return 0;
 }
 
 /*
   Cast a pointer up an inheritance hierarchy
 */
 SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
-  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+  return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
 }
 
-/* 
+/*
    Dynamic pointer casting. Down an inheritance hierarchy
 */
 SWIGRUNTIME swig_type_info *
@@ -490,7 +520,7 @@ SWIG_TypePrettyName(const swig_type_info *type) {
     return type->name;
 }
 
-/* 
+/*
    Set the clientdata field for a type
 */
 SWIGRUNTIME void
@@ -498,14 +528,14 @@ SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
   swig_cast_info *cast = ti->cast;
   /* if (ti->clientdata == clientdata) return; */
   ti->clientdata = clientdata;
-  
+
   while (cast) {
     if (!cast->converter) {
       swig_type_info *tc = cast->type;
       if (!tc->clientdata) {
 	SWIG_TypeClientData(tc, clientdata);
       }
-    }    
+    }
     cast = cast->next;
   }
 }
@@ -514,31 +544,31 @@ SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
   SWIG_TypeClientData(ti, clientdata);
   ti->owndata = 1;
 }
-  
+
 /*
   Search for a swig_type_info structure only by mangled name
   Search is a O(log #types)
-  
-  We start searching at module start, and finish searching when start == end.  
+
+  We start searching at module start, and finish searching when start == end.
   Note: if start == end at the beginning of the function, we go all the way around
   the circular list.
 */
 SWIGRUNTIME swig_type_info *
-SWIG_MangledTypeQueryModule(swig_module_info *start, 
-                            swig_module_info *end, 
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+                            swig_module_info *end,
 		            const char *name) {
   swig_module_info *iter = start;
   do {
     if (iter->size) {
-      register size_t l = 0;
-      register size_t r = iter->size - 1;
+      size_t l = 0;
+      size_t r = iter->size - 1;
       do {
 	/* since l+r >= 0, we can (>> 1) instead (/ 2) */
-	register size_t i = (l + r) >> 1; 
+	size_t i = (l + r) >> 1;
 	const char *iname = iter->types[i]->name;
 	if (iname) {
-	  register int compare = strcmp(name, iname);
-	  if (compare == 0) {	    
+	  int compare = strcmp(name, iname);
+	  if (compare == 0) {
 	    return iter->types[i];
 	  } else if (compare < 0) {
 	    if (i) {
@@ -563,14 +593,14 @@ SWIG_MangledTypeQueryModule(swig_module_info *start,
   Search for a swig_type_info structure for either a mangled name or a human readable name.
   It first searches the mangled names of the types, which is a O(log #types)
   If a type is not found it then searches the human readable names, which is O(#types).
-  
-  We start searching at module start, and finish searching when start == end.  
+
+  We start searching at module start, and finish searching when start == end.
   Note: if start == end at the beginning of the function, we go all the way around
   the circular list.
 */
 SWIGRUNTIME swig_type_info *
-SWIG_TypeQueryModule(swig_module_info *start, 
-                     swig_module_info *end, 
+SWIG_TypeQueryModule(swig_module_info *start,
+                     swig_module_info *end,
 		     const char *name) {
   /* STEP 1: Search the name field using binary search */
   swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
@@ -581,7 +611,7 @@ SWIG_TypeQueryModule(swig_module_info *start,
        of the str field (the human readable name) */
     swig_module_info *iter = start;
     do {
-      register size_t i = 0;
+      size_t i = 0;
       for (; i < iter->size; ++i) {
 	if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
 	  return iter->types[i];
@@ -589,56 +619,56 @@ SWIG_TypeQueryModule(swig_module_info *start,
       iter = iter->next;
     } while (iter != end);
   }
-  
+
   /* neither found a match */
   return 0;
 }
 
-/* 
+/*
    Pack binary data into a string
 */
 SWIGRUNTIME char *
 SWIG_PackData(char *c, void *ptr, size_t sz) {
   static const char hex[17] = "0123456789abcdef";
-  register const unsigned char *u = (unsigned char *) ptr;
-  register const unsigned char *eu =  u + sz;
+  const unsigned char *u = (unsigned char *) ptr;
+  const unsigned char *eu =  u + sz;
   for (; u != eu; ++u) {
-    register unsigned char uu = *u;
+    unsigned char uu = *u;
     *(c++) = hex[(uu & 0xf0) >> 4];
     *(c++) = hex[uu & 0xf];
   }
   return c;
 }
 
-/* 
+/*
    Unpack binary data from a string
 */
 SWIGRUNTIME const char *
 SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
-  register unsigned char *u = (unsigned char *) ptr;
-  register const unsigned char *eu = u + sz;
+  unsigned char *u = (unsigned char *) ptr;
+  const unsigned char *eu = u + sz;
   for (; u != eu; ++u) {
-    register char d = *(c++);
-    register unsigned char uu;
+    char d = *(c++);
+    unsigned char uu;
     if ((d >= '0') && (d <= '9'))
       uu = ((d - '0') << 4);
     else if ((d >= 'a') && (d <= 'f'))
       uu = ((d - ('a'-10)) << 4);
-    else 
+    else
       return (char *) 0;
     d = *(c++);
     if ((d >= '0') && (d <= '9'))
       uu |= (d - '0');
     else if ((d >= 'a') && (d <= 'f'))
       uu |= (d - ('a'-10));
-    else 
+    else
       return (char *) 0;
     *u = uu;
   }
   return c;
 }
 
-/* 
+/*
    Pack 'void *' into a string buffer.
 */
 SWIGRUNTIME char *
@@ -698,22 +728,92 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
 #endif
 
 /*  Errors in SWIG */
-#define  SWIG_UnknownError    	   -1 
-#define  SWIG_IOError        	   -2 
-#define  SWIG_RuntimeError   	   -3 
-#define  SWIG_IndexError     	   -4 
-#define  SWIG_TypeError      	   -5 
-#define  SWIG_DivisionByZero 	   -6 
-#define  SWIG_OverflowError  	   -7 
-#define  SWIG_SyntaxError    	   -8 
-#define  SWIG_ValueError     	   -9 
+#define  SWIG_UnknownError    	   -1
+#define  SWIG_IOError        	   -2
+#define  SWIG_RuntimeError   	   -3
+#define  SWIG_IndexError     	   -4
+#define  SWIG_TypeError      	   -5
+#define  SWIG_DivisionByZero 	   -6
+#define  SWIG_OverflowError  	   -7
+#define  SWIG_SyntaxError    	   -8
+#define  SWIG_ValueError     	   -9
 #define  SWIG_SystemError    	   -10
 #define  SWIG_AttributeError 	   -11
-#define  SWIG_MemoryError    	   -12 
+#define  SWIG_MemoryError    	   -12
 #define  SWIG_NullReferenceError   -13
 
 
 
+/* Compatibility macros for Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+
+#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
+#define PyInt_Check(x) PyLong_Check(x)
+#define PyInt_AsLong(x) PyLong_AsLong(x)
+#define PyInt_FromLong(x) PyLong_FromLong(x)
+#define PyInt_FromSize_t(x) PyLong_FromSize_t(x)
+#define PyString_Check(name) PyBytes_Check(name)
+#define PyString_FromString(x) PyUnicode_FromString(x)
+#define PyString_Format(fmt, args)  PyUnicode_Format(fmt, args)
+#define PyString_AsString(str) PyBytes_AsString(str)
+#define PyString_Size(str) PyBytes_Size(str)	
+#define PyString_InternFromString(key) PyUnicode_InternFromString(key)
+#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
+#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
+#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
+
+#endif
+
+#ifndef Py_TYPE
+#  define Py_TYPE(op) ((op)->ob_type)
+#endif
+
+/* SWIG APIs for compatibility of both Python 2 & 3 */
+
+#if PY_VERSION_HEX >= 0x03000000
+#  define SWIG_Python_str_FromFormat PyUnicode_FromFormat
+#else
+#  define SWIG_Python_str_FromFormat PyString_FromFormat
+#endif
+
+
+/* Warning: This function will allocate a new string in Python 3,
+ * so please call SWIG_Python_str_DelForPy3(x) to free the space.
+ */
+SWIGINTERN char*
+SWIG_Python_str_AsChar(PyObject *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+  char *cstr;
+  char *newstr;
+  Py_ssize_t len;
+  str = PyUnicode_AsUTF8String(str);
+  PyBytes_AsStringAndSize(str, &cstr, &len);
+  newstr = (char *) malloc(len+1);
+  memcpy(newstr, cstr, len+1);
+  Py_XDECREF(str);
+  return newstr;
+#else
+  return PyString_AsString(str);
+#endif
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
+#else
+#  define SWIG_Python_str_DelForPy3(x) 
+#endif
+
+
+SWIGINTERN PyObject*
+SWIG_Python_str_FromChar(const char *c)
+{
+#if PY_VERSION_HEX >= 0x03000000
+  return PyUnicode_FromString(c); 
+#else
+  return PyString_FromString(c);
+#endif
+}
 
 /* Add PyOS_snprintf for old Pythons */
 #if PY_VERSION_HEX < 0x02020000
@@ -760,6 +860,7 @@ PyString_FromFormat(const char *fmt, ...) {
 #  define PyObject_GenericGetAttr 0
 # endif
 #endif
+
 /* Py_NotImplemented is defined in 2.1 and up. */
 #if PY_VERSION_HEX < 0x02010000
 # ifndef Py_NotImplemented
@@ -767,7 +868,6 @@ PyString_FromFormat(const char *fmt, ...) {
 # endif
 #endif
 
-
 /* A crude PyString_AsStringAndSize implementation for old Pythons */
 #if PY_VERSION_HEX < 0x02010000
 # ifndef PyString_AsStringAndSize
@@ -782,7 +882,6 @@ PyString_FromFormat(const char *fmt, ...) {
 # endif
 #endif
 
-
 /* PyBool_FromLong for old Pythons */
 #if PY_VERSION_HEX < 0x02030000
 static
@@ -801,6 +900,67 @@ PyObject *PyBool_FromLong(long ok)
 typedef int Py_ssize_t;
 # define PY_SSIZE_T_MAX INT_MAX
 # define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+typedef intargfunc ssizeargfunc;
+typedef intintargfunc ssizessizeargfunc;
+typedef intobjargproc ssizeobjargproc;
+typedef intintobjargproc ssizessizeobjargproc;
+typedef getreadbufferproc readbufferproc;
+typedef getwritebufferproc writebufferproc;
+typedef getsegcountproc segcountproc;
+typedef getcharbufferproc charbufferproc;
+static long PyNumber_AsSsize_t (PyObject *x, void *SWIGUNUSEDPARM(exc))
+{
+  long result = 0;
+  PyObject *i = PyNumber_Int(x);
+  if (i) {
+    result = PyInt_AsLong(i);
+    Py_DECREF(i);
+  }
+  return result;
+}
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+#define PyInt_FromSize_t(x) PyInt_FromLong((long)x)
+#endif
+
+#if PY_VERSION_HEX < 0x02040000
+#define Py_VISIT(op)				\
+  do { 						\
+    if (op) {					\
+      int vret = visit((op), arg);		\
+      if (vret)					\
+        return vret;				\
+    }						\
+  } while (0)
+#endif
+
+#if PY_VERSION_HEX < 0x02030000
+typedef struct {
+  PyTypeObject type;
+  PyNumberMethods as_number;
+  PyMappingMethods as_mapping;
+  PySequenceMethods as_sequence;
+  PyBufferProcs as_buffer;
+  PyObject *name, *slots;
+} PyHeapTypeObject;
+#endif
+
+#if PY_VERSION_HEX < 0x02030000
+typedef destructor freefunc;
+#endif
+
+#if ((PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 6) || \
+     (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION > 0) || \
+     (PY_MAJOR_VERSION > 3))
+# define SWIGPY_USE_CAPSULE
+# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
+#endif
+
+#if PY_VERSION_HEX < 0x03020000
+#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
+#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -860,19 +1020,20 @@ SWIG_Python_AddErrorMsg(const char* mesg)
 
   if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
   if (value) {
+    char *tmp;
     PyObject *old_str = PyObject_Str(value);
     PyErr_Clear();
     Py_XINCREF(type);
-    PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+
+    PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+    SWIG_Python_str_DelForPy3(tmp);
     Py_DECREF(old_str);
     Py_DECREF(value);
   } else {
-    PyErr_Format(PyExc_RuntimeError, mesg);
+    PyErr_SetString(PyExc_RuntimeError, mesg);
   }
 }
 
-
-
 #if defined(SWIG_PYTHON_NO_THREADS)
 #  if defined(SWIG_PYTHON_THREADS)
 #    undef SWIG_PYTHON_THREADS
@@ -946,9 +1107,6 @@ SWIG_Python_AddErrorMsg(const char* mesg)
 
 #ifdef __cplusplus
 extern "C" {
-#if 0
-} /* cc-mode */
-#endif
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -969,18 +1127,29 @@ typedef struct swig_const_info {
   swig_type_info **ptype;
 } swig_const_info;
 
-#ifdef __cplusplus
-#if 0
-{ /* cc-mode */
+
+/* -----------------------------------------------------------------------------
+ * Wrapper of PyInstanceMethod_New() used in Python 3
+ * It is exported to the generated module, used for -fastproxy
+ * ----------------------------------------------------------------------------- */
+#if PY_VERSION_HEX >= 0x03000000
+SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func)
+{
+  return PyInstanceMethod_New(func);
+}
+#else
+SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(func))
+{
+  return NULL;
+}
 #endif
+
+#ifdef __cplusplus
 }
 #endif
 
 
 /* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
- *
  * pyrun.swg
  *
  * This file contains the runtime support for Python modules
@@ -995,7 +1164,15 @@ typedef struct swig_const_info {
 #define SWIG_Python_ConvertPtr(obj, pptr, type, flags)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
 #define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_Python_ConvertPtr(obj, pptr, type, flags)
 #define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
-#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(ptr, type, flags)
+
+#ifdef SWIGPYTHON_BUILTIN
+#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(self, ptr, type, flags)
+#else
+#define SWIG_NewPointerObj(ptr, type, flags)            SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
+#endif
+
+#define SWIG_InternalNewPointerObj(ptr, type, flags)	SWIG_Python_NewPointerObj(NULL, ptr, type, flags)
+
 #define SWIG_CheckImplicit(ty)                          SWIG_Python_CheckImplicit(ty) 
 #define SWIG_AcquirePtr(ptr, src)                       SWIG_Python_AcquirePtr(ptr, src)
 #define swig_owntype                                    int
@@ -1010,7 +1187,7 @@ typedef struct swig_const_info {
 
 /* for C or C++ function pointers */
 #define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
-#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(ptr, type, 0)
+#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_Python_NewPointerObj(NULL, ptr, type, 0)
 
 /* for C++ member pointers, ie, member methods */
 #define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
@@ -1019,9 +1196,9 @@ typedef struct swig_const_info {
 
 /* Runtime API */
 
-#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule()
+#define SWIG_GetModule(clientdata)                      SWIG_Python_GetModule(clientdata)
 #define SWIG_SetModule(clientdata, pointer)             SWIG_Python_SetModule(pointer)
-#define SWIG_NewClientData(obj)                         PySwigClientData_New(obj)
+#define SWIG_NewClientData(obj)                         SwigPyClientData_New(obj)
 
 #define SWIG_SetErrorObj                                SWIG_Python_SetErrorObj                            
 #define SWIG_SetErrorMsg                        	SWIG_Python_SetErrorMsg				   
@@ -1045,7 +1222,7 @@ SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
 SWIGINTERN void 
 SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
   SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-  PyErr_SetString(errtype, (char *) msg);
+  PyErr_SetString(errtype, msg);
   SWIG_PYTHON_THREAD_END_BLOCK;
 }
 
@@ -1053,12 +1230,41 @@ SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
 
 /* Set a constant value */
 
+#if defined(SWIGPYTHON_BUILTIN)
+
+SWIGINTERN void
+SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) {
+  PyObject *s = PyString_InternFromString(key);
+  PyList_Append(seq, s);
+  Py_DECREF(s);
+}
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) {   
+#if PY_VERSION_HEX < 0x02030000
+  PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
+  Py_DECREF(obj);
+  if (public_interface)
+    SwigPyBuiltin_AddPublicSymbol(public_interface, name);
+}
+
+#else
+
 SWIGINTERN void
 SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {   
-  PyDict_SetItemString(d, (char*) name, obj);
+#if PY_VERSION_HEX < 0x02030000
+  PyDict_SetItemString(d, (char *)name, obj);
+#else
+  PyDict_SetItemString(d, name, obj);
+#endif
   Py_DECREF(obj);                            
 }
 
+#endif
+
 /* Append a value to the result obj */
 
 SWIGINTERN PyObject*
@@ -1107,32 +1313,40 @@ SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
 /* Unpack the argument tuple */
 
 SWIGINTERN int
-SWIG_Python_UnpackTuple(PyObject *args, const char *name, int min, int max, PyObject **objs)
+SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
 {
   if (!args) {
     if (!min && !max) {
       return 1;
     } else {
       PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", 
-		   name, (min == max ? "" : "at least "), min);
+		   name, (min == max ? "" : "at least "), (int)min);
       return 0;
     }
   }  
   if (!PyTuple_Check(args)) {
+    if (min <= 1 && max >= 1) {
+      int i;
+      objs[0] = args;
+      for (i = 1; i < max; ++i) {
+	objs[i] = 0;
+      }
+      return 2;
+    }
     PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
     return 0;
   } else {
-    register int l = PyTuple_GET_SIZE(args);
+    Py_ssize_t l = PyTuple_GET_SIZE(args);
     if (l < min) {
       PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
-		   name, (min == max ? "" : "at least "), min, l);
+		   name, (min == max ? "" : "at least "), (int)min, (int)l);
       return 0;
     } else if (l > max) {
       PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", 
-		   name, (min == max ? "" : "at most "), max, l);
+		   name, (min == max ? "" : "at most "), (int)max, (int)l);
       return 0;
     } else {
-      register int i;
+      int i;
       for (i = 0; i < l; ++i) {
 	objs[i] = PyTuple_GET_ITEM(args, i);
       }
@@ -1171,11 +1385,11 @@ SWIG_Python_UnpackTuple(PyObject *args, const char *name, int min, int max, PyOb
 
 #define SWIG_POINTER_IMPLICIT_CONV  (SWIG_POINTER_DISOWN   << 1)
 
+#define SWIG_BUILTIN_TP_INIT	    (SWIG_POINTER_OWN << 2)
+#define SWIG_BUILTIN_INIT	    (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN)
+
 #ifdef __cplusplus
 extern "C" {
-#if 0
-} /* cc-mode */
-#endif
 #endif
 
 /*  How to access Py_None */
@@ -1217,7 +1431,7 @@ SWIG_Py_Void(void)
   return none;
 }
 
-/* PySwigClientData */
+/* SwigPyClientData */
 
 typedef struct {
   PyObject *klass;
@@ -1226,30 +1440,31 @@ typedef struct {
   PyObject *destroy;
   int delargs;
   int implicitconv;
-} PySwigClientData;
+  PyTypeObject *pytype;
+} SwigPyClientData;
 
 SWIGRUNTIMEINLINE int 
 SWIG_Python_CheckImplicit(swig_type_info *ty)
 {
-  PySwigClientData *data = (PySwigClientData *)ty->clientdata;
+  SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
   return data ? data->implicitconv : 0;
 }
 
 SWIGRUNTIMEINLINE PyObject *
 SWIG_Python_ExceptionType(swig_type_info *desc) {
-  PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0;
+  SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
   PyObject *klass = data ? data->klass : 0;
   return (klass ? klass : PyExc_RuntimeError);
 }
 
 
-SWIGRUNTIME PySwigClientData * 
-PySwigClientData_New(PyObject* obj)
+SWIGRUNTIME SwigPyClientData * 
+SwigPyClientData_New(PyObject* obj)
 {
   if (!obj) {
     return 0;
   } else {
-    PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData));
+    SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
     /* the klass element */
     data->klass = obj;
     Py_INCREF(data->klass);
@@ -1292,19 +1507,19 @@ PySwigClientData_New(PyObject* obj)
       data->delargs = 0;
     }
     data->implicitconv = 0;
+    data->pytype = 0;
     return data;
   }
 }
 
 SWIGRUNTIME void 
-PySwigClientData_Del(PySwigClientData* data)
-{
+SwigPyClientData_Del(SwigPyClientData *data) {
   Py_XDECREF(data->newraw);
   Py_XDECREF(data->newargs);
   Py_XDECREF(data->destroy);
 }
 
-/* =============== PySwigObject =====================*/
+/* =============== SwigPyObject =====================*/
 
 typedef struct {
   PyObject_HEAD
@@ -1312,24 +1527,31 @@ typedef struct {
   swig_type_info *ty;
   int own;
   PyObject *next;
-} PySwigObject;
+#ifdef SWIGPYTHON_BUILTIN
+  PyObject *dict;
+#endif
+} SwigPyObject;
 
 SWIGRUNTIME PyObject *
-PySwigObject_long(PySwigObject *v)
+SwigPyObject_long(SwigPyObject *v)
 {
   return PyLong_FromVoidPtr(v->ptr);
 }
 
 SWIGRUNTIME PyObject *
-PySwigObject_format(const char* fmt, PySwigObject *v)
+SwigPyObject_format(const char* fmt, SwigPyObject *v)
 {
   PyObject *res = NULL;
   PyObject *args = PyTuple_New(1);
   if (args) {
-    if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) {
-      PyObject *ofmt = PyString_FromString(fmt);
+    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
+      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
       if (ofmt) {
+#if PY_VERSION_HEX >= 0x03000000
+	res = PyUnicode_Format(ofmt,args);
+#else
 	res = PyString_Format(ofmt,args);
+#endif
 	Py_DECREF(ofmt);
       }
       Py_DECREF(args);
@@ -1339,104 +1561,118 @@ PySwigObject_format(const char* fmt, PySwigObject *v)
 }
 
 SWIGRUNTIME PyObject *
-PySwigObject_oct(PySwigObject *v)
+SwigPyObject_oct(SwigPyObject *v)
 {
-  return PySwigObject_format("%o",v);
+  return SwigPyObject_format("%o",v);
 }
 
 SWIGRUNTIME PyObject *
-PySwigObject_hex(PySwigObject *v)
+SwigPyObject_hex(SwigPyObject *v)
 {
-  return PySwigObject_format("%x",v);
+  return SwigPyObject_format("%x",v);
 }
 
 SWIGRUNTIME PyObject *
 #ifdef METH_NOARGS
-PySwigObject_repr(PySwigObject *v)
+SwigPyObject_repr(SwigPyObject *v)
 #else
-PySwigObject_repr(PySwigObject *v, PyObject *args)
+SwigPyObject_repr(SwigPyObject *v, PyObject *args)
 #endif
 {
   const char *name = SWIG_TypePrettyName(v->ty);
-  PyObject *hex = PySwigObject_hex(v);    
-  PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
-  Py_DECREF(hex);
+  PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
   if (v->next) {
-#ifdef METH_NOARGS
-    PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next);
-#else
-    PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args);
-#endif
+# ifdef METH_NOARGS
+    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
+# else
+    PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
+# endif
+# if PY_VERSION_HEX >= 0x03000000
+    PyObject *joined = PyUnicode_Concat(repr, nrep);
+    Py_DecRef(repr);
+    Py_DecRef(nrep);
+    repr = joined;
+# else
     PyString_ConcatAndDel(&repr,nrep);
+# endif
   }
   return repr;  
 }
 
 SWIGRUNTIME int
-PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
 {
-#ifdef METH_NOARGS
-  PyObject *repr = PySwigObject_repr(v);
-#else
-  PyObject *repr = PySwigObject_repr(v, NULL);
-#endif
-  if (repr) {
-    fputs(PyString_AsString(repr), fp);
-    Py_DECREF(repr);
-    return 0; 
-  } else {
-    return 1; 
-  }
+  void *i = v->ptr;
+  void *j = w->ptr;
+  return (i < j) ? -1 : ((i > j) ? 1 : 0);
 }
 
-SWIGRUNTIME PyObject *
-PySwigObject_str(PySwigObject *v)
+/* Added for Python 3.x, would it also be useful for Python 2.x? */
+SWIGRUNTIME PyObject*
+SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
 {
-  char result[SWIG_BUFFER_SIZE];
-  return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
-    PyString_FromString(result) : 0;
+  PyObject* res;
+  if( op != Py_EQ && op != Py_NE ) {
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+  }
+  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
+  return res;  
 }
 
-SWIGRUNTIME int
-PySwigObject_compare(PySwigObject *v, PySwigObject *w)
-{
-  void *i = v->ptr;
-  void *j = w->ptr;
-  return (i < j) ? -1 : ((i > j) ? 1 : 0);
-}
 
-SWIGRUNTIME PyTypeObject* _PySwigObject_type(void);
+SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void);
 
+#ifdef SWIGPYTHON_BUILTIN
+static swig_type_info *SwigPyObject_stype = 0;
+SWIGRUNTIME PyTypeObject*
+SwigPyObject_type(void) {
+    SwigPyClientData *cd;
+    assert(SwigPyObject_stype);
+    cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
+    assert(cd);
+    assert(cd->pytype);
+    return cd->pytype;
+}
+#else
 SWIGRUNTIME PyTypeObject*
-PySwigObject_type(void) {
-  static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type();
+SwigPyObject_type(void) {
+  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce();
   return type;
 }
+#endif
 
 SWIGRUNTIMEINLINE int
-PySwigObject_Check(PyObject *op) {
-  return ((op)->ob_type == PySwigObject_type())
-    || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
+SwigPyObject_Check(PyObject *op) {
+#ifdef SWIGPYTHON_BUILTIN
+  PyTypeObject *target_tp = SwigPyObject_type();
+  if (PyType_IsSubtype(op->ob_type, target_tp))
+    return 1;
+  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
+#else
+  return (Py_TYPE(op) == SwigPyObject_type())
+    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
+#endif
 }
 
 SWIGRUNTIME PyObject *
-PySwigObject_New(void *ptr, swig_type_info *ty, int own);
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
 
 SWIGRUNTIME void
-PySwigObject_dealloc(PyObject *v)
+SwigPyObject_dealloc(PyObject *v)
 {
-  PySwigObject *sobj = (PySwigObject *) v;
+  SwigPyObject *sobj = (SwigPyObject *) v;
   PyObject *next = sobj->next;
-  if (sobj->own) {
+  if (sobj->own == SWIG_POINTER_OWN) {
     swig_type_info *ty = sobj->ty;
-    PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
+    SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
     PyObject *destroy = data ? data->destroy : 0;
     if (destroy) {
       /* destroy is always a VARARGS method */
       PyObject *res;
       if (data->delargs) {
-	/* we need to create a temporal object to carry the destroy operation */
-	PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0);
+	/* we need to create a temporary object to carry the destroy operation */
+	PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
 	res = SWIG_Python_CallFunctor(destroy, tmp);
 	Py_DECREF(tmp);
       } else {
@@ -1445,27 +1681,28 @@ PySwigObject_dealloc(PyObject *v)
 	res = ((*meth)(mself, v));
       }
       Py_XDECREF(res);
-    } else {
-      const char *name = SWIG_TypePrettyName(ty);
+    } 
 #if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
-      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name);
-#endif
+    else {
+      const char *name = SWIG_TypePrettyName(ty);
+      printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
     }
+#endif
   } 
   Py_XDECREF(next);
   PyObject_DEL(v);
 }
 
 SWIGRUNTIME PyObject* 
-PySwigObject_append(PyObject* v, PyObject* next)
+SwigPyObject_append(PyObject* v, PyObject* next)
 {
-  PySwigObject *sobj = (PySwigObject *) v;
+  SwigPyObject *sobj = (SwigPyObject *) v;
 #ifndef METH_O
   PyObject *tmp = 0;
   if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
   next = tmp;
 #endif
-  if (!PySwigObject_Check(next)) {
+  if (!SwigPyObject_Check(next)) {
     return NULL;
   }
   sobj->next = next;
@@ -1475,12 +1712,12 @@ PySwigObject_append(PyObject* v, PyObject* next)
 
 SWIGRUNTIME PyObject* 
 #ifdef METH_NOARGS
-PySwigObject_next(PyObject* v)
+SwigPyObject_next(PyObject* v)
 #else
-PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
 #endif
 {
-  PySwigObject *sobj = (PySwigObject *) v;
+  SwigPyObject *sobj = (SwigPyObject *) v;
   if (sobj->next) {    
     Py_INCREF(sobj->next);
     return sobj->next;
@@ -1491,56 +1728,58 @@ PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
 
 SWIGINTERN PyObject*
 #ifdef METH_NOARGS
-PySwigObject_disown(PyObject *v)
+SwigPyObject_disown(PyObject *v)
 #else
-PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
 #endif
 {
-  PySwigObject *sobj = (PySwigObject *)v;
+  SwigPyObject *sobj = (SwigPyObject *)v;
   sobj->own = 0;
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject*
 #ifdef METH_NOARGS
-PySwigObject_acquire(PyObject *v)
+SwigPyObject_acquire(PyObject *v)
 #else
-PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
 #endif
 {
-  PySwigObject *sobj = (PySwigObject *)v;
+  SwigPyObject *sobj = (SwigPyObject *)v;
   sobj->own = SWIG_POINTER_OWN;
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject*
-PySwigObject_own(PyObject *v, PyObject *args)
+SwigPyObject_own(PyObject *v, PyObject *args)
 {
   PyObject *val = 0;
 #if (PY_VERSION_HEX < 0x02020000)
   if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
-#else
+#elif (PY_VERSION_HEX < 0x02050000)
   if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) 
+#else
+  if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) 
 #endif
     {
       return NULL;
     } 
   else
     {
-      PySwigObject *sobj = (PySwigObject *)v;
+      SwigPyObject *sobj = (SwigPyObject *)v;
       PyObject *obj = PyBool_FromLong(sobj->own);
       if (val) {
 #ifdef METH_NOARGS
 	if (PyObject_IsTrue(val)) {
-	  PySwigObject_acquire(v);
+	  SwigPyObject_acquire(v);
 	} else {
-	  PySwigObject_disown(v);
+	  SwigPyObject_disown(v);
 	}
 #else
 	if (PyObject_IsTrue(val)) {
-	  PySwigObject_acquire(v,args);
+	  SwigPyObject_acquire(v,args);
 	} else {
-	  PySwigObject_disown(v,args);
+	  SwigPyObject_disown(v,args);
 	}
 #endif
       } 
@@ -1551,44 +1790,47 @@ PySwigObject_own(PyObject *v, PyObject *args)
 #ifdef METH_O
 static PyMethodDef
 swigobject_methods[] = {
-  {(char *)"disown",  (PyCFunction)PySwigObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
-  {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS,  (char *)"aquires ownership of the pointer"},
-  {(char *)"own",     (PyCFunction)PySwigObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
-  {(char *)"append",  (PyCFunction)PySwigObject_append,  METH_O,       (char *)"appends another 'this' object"},
-  {(char *)"next",    (PyCFunction)PySwigObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
-  {(char *)"__repr__",(PyCFunction)PySwigObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
+  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_NOARGS,  (char *)"releases ownership of the pointer"},
+  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS,  (char *)"acquires ownership of the pointer"},
+  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_O,       (char *)"appends another 'this' object"},
+  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_NOARGS,  (char *)"returns the next 'this' object"},
+  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,    METH_NOARGS,  (char *)"returns object representation"},
   {0, 0, 0, 0}  
 };
 #else
 static PyMethodDef
 swigobject_methods[] = {
-  {(char *)"disown",  (PyCFunction)PySwigObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
-  {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
-  {(char *)"own",     (PyCFunction)PySwigObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
-  {(char *)"append",  (PyCFunction)PySwigObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
-  {(char *)"next",    (PyCFunction)PySwigObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
-  {(char *)"__repr__",(PyCFunction)PySwigObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
+  {(char *)"disown",  (PyCFunction)SwigPyObject_disown,  METH_VARARGS,  (char *)"releases ownership of the pointer"},
+  {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS,  (char *)"aquires ownership of the pointer"},
+  {(char *)"own",     (PyCFunction)SwigPyObject_own,     METH_VARARGS,  (char *)"returns/sets ownership of the pointer"},
+  {(char *)"append",  (PyCFunction)SwigPyObject_append,  METH_VARARGS,  (char *)"appends another 'this' object"},
+  {(char *)"next",    (PyCFunction)SwigPyObject_next,    METH_VARARGS,  (char *)"returns the next 'this' object"},
+  {(char *)"__repr__",(PyCFunction)SwigPyObject_repr,   METH_VARARGS,  (char *)"returns object representation"},
   {0, 0, 0, 0}  
 };
 #endif
 
 #if PY_VERSION_HEX < 0x02020000
 SWIGINTERN PyObject *
-PySwigObject_getattr(PySwigObject *sobj,char *name)
+SwigPyObject_getattr(SwigPyObject *sobj,char *name)
 {
   return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
 }
 #endif
 
 SWIGRUNTIME PyTypeObject*
-_PySwigObject_type(void) {
+SwigPyObject_TypeOnce(void) {
   static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
-  
-  static PyNumberMethods PySwigObject_as_number = {
+
+  static PyNumberMethods SwigPyObject_as_number = {
     (binaryfunc)0, /*nb_add*/
     (binaryfunc)0, /*nb_subtract*/
     (binaryfunc)0, /*nb_multiply*/
+    /* nb_divide removed in Python 3 */
+#if PY_VERSION_HEX < 0x03000000
     (binaryfunc)0, /*nb_divide*/
+#endif
     (binaryfunc)0, /*nb_remainder*/
     (binaryfunc)0, /*nb_divmod*/
     (ternaryfunc)0,/*nb_power*/
@@ -1602,94 +1844,122 @@ _PySwigObject_type(void) {
     0,		   /*nb_and*/
     0,		   /*nb_xor*/
     0,		   /*nb_or*/
-    (coercion)0,   /*nb_coerce*/
-    (unaryfunc)PySwigObject_long, /*nb_int*/
-    (unaryfunc)PySwigObject_long, /*nb_long*/
+#if PY_VERSION_HEX < 0x03000000
+    0,   /*nb_coerce*/
+#endif
+    (unaryfunc)SwigPyObject_long, /*nb_int*/
+#if PY_VERSION_HEX < 0x03000000
+    (unaryfunc)SwigPyObject_long, /*nb_long*/
+#else
+    0, /*nb_reserved*/
+#endif
     (unaryfunc)0,                 /*nb_float*/
-    (unaryfunc)PySwigObject_oct,  /*nb_oct*/
-    (unaryfunc)PySwigObject_hex,  /*nb_hex*/
-#if PY_VERSION_HEX >= 0x02020000
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ 
-#elif PY_VERSION_HEX >= 0x02000000
+#if PY_VERSION_HEX < 0x03000000
+    (unaryfunc)SwigPyObject_oct,  /*nb_oct*/
+    (unaryfunc)SwigPyObject_hex,  /*nb_hex*/
+#endif
+#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
+#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
+#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
+#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
     0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
 #endif
   };
 
-  static PyTypeObject pyswigobject_type;  
+  static PyTypeObject swigpyobject_type;
   static int type_init = 0;
   if (!type_init) {
-    const PyTypeObject tmp
-      = {
-	PyObject_HEAD_INIT(NULL)
-	0,				    /* ob_size */
-	(char *)"PySwigObject",		    /* tp_name */
-	sizeof(PySwigObject),		    /* tp_basicsize */
-	0,			            /* tp_itemsize */
-	(destructor)PySwigObject_dealloc,   /* tp_dealloc */
-	(printfunc)PySwigObject_print,	    /* tp_print */
+    const PyTypeObject tmp = {
+      /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+      PyVarObject_HEAD_INIT(NULL, 0)
+#else
+      PyObject_HEAD_INIT(NULL)
+      0,                                    /* ob_size */
+#endif
+      (char *)"SwigPyObject",               /* tp_name */
+      sizeof(SwigPyObject),                 /* tp_basicsize */
+      0,                                    /* tp_itemsize */
+      (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
+      0,				    /* tp_print */
 #if PY_VERSION_HEX < 0x02020000
-	(getattrfunc)PySwigObject_getattr,  /* tp_getattr */ 
+      (getattrfunc)SwigPyObject_getattr,    /* tp_getattr */
+#else
+      (getattrfunc)0,                       /* tp_getattr */
+#endif
+      (setattrfunc)0,                       /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+    0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
 #else
-	(getattrfunc)0,			    /* tp_getattr */ 
+      (cmpfunc)SwigPyObject_compare,        /* tp_compare */
 #endif
-	(setattrfunc)0,			    /* tp_setattr */ 
-	(cmpfunc)PySwigObject_compare,	    /* tp_compare */ 
-	(reprfunc)PySwigObject_repr,	    /* tp_repr */    
-	&PySwigObject_as_number,	    /* tp_as_number */
-	0,				    /* tp_as_sequence */
-	0,				    /* tp_as_mapping */
-	(hashfunc)0,			    /* tp_hash */
-	(ternaryfunc)0,			    /* tp_call */
-	(reprfunc)PySwigObject_str,	    /* tp_str */
-	PyObject_GenericGetAttr,            /* tp_getattro */
-	0,				    /* tp_setattro */
-	0,		                    /* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,	            /* tp_flags */
-	swigobject_doc, 	            /* tp_doc */        
-	0,                                  /* tp_traverse */
-	0,                                  /* tp_clear */
-	0,                                  /* tp_richcompare */
-	0,                                  /* tp_weaklistoffset */
+      (reprfunc)SwigPyObject_repr,          /* tp_repr */
+      &SwigPyObject_as_number,              /* tp_as_number */
+      0,                                    /* tp_as_sequence */
+      0,                                    /* tp_as_mapping */
+      (hashfunc)0,                          /* tp_hash */
+      (ternaryfunc)0,                       /* tp_call */
+      0,				    /* tp_str */
+      PyObject_GenericGetAttr,              /* tp_getattro */
+      0,                                    /* tp_setattro */
+      0,                                    /* tp_as_buffer */
+      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
+      swigobject_doc,                       /* tp_doc */
+      0,                                    /* tp_traverse */
+      0,                                    /* tp_clear */
+      (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */
+      0,                                    /* tp_weaklistoffset */
 #if PY_VERSION_HEX >= 0x02020000
-	0,                                  /* tp_iter */
-	0,                                  /* tp_iternext */
-	swigobject_methods,		    /* tp_methods */ 
-	0,			            /* tp_members */
-	0,				    /* tp_getset */	    	
-	0,			            /* tp_base */	        
-	0,				    /* tp_dict */	    	
-	0,				    /* tp_descr_get */  	
-	0,				    /* tp_descr_set */  	
-	0,				    /* tp_dictoffset */ 	
-	0,				    /* tp_init */	    	
-	0,				    /* tp_alloc */	    	
-	0,			            /* tp_new */	    	
-	0,	                            /* tp_free */	   
-        0,                                  /* tp_is_gc */  
-	0,				    /* tp_bases */   
-	0,				    /* tp_mro */
-	0,				    /* tp_cache */   
- 	0,				    /* tp_subclasses */
-	0,				    /* tp_weaklist */
+      0,                                    /* tp_iter */
+      0,                                    /* tp_iternext */
+      swigobject_methods,                   /* tp_methods */
+      0,                                    /* tp_members */
+      0,                                    /* tp_getset */
+      0,                                    /* tp_base */
+      0,                                    /* tp_dict */
+      0,                                    /* tp_descr_get */
+      0,                                    /* tp_descr_set */
+      0,                                    /* tp_dictoffset */
+      0,                                    /* tp_init */
+      0,                                    /* tp_alloc */
+      0,                                    /* tp_new */
+      0,                                    /* tp_free */
+      0,                                    /* tp_is_gc */
+      0,                                    /* tp_bases */
+      0,                                    /* tp_mro */
+      0,                                    /* tp_cache */
+      0,                                    /* tp_subclasses */
+      0,                                    /* tp_weaklist */
 #endif
 #if PY_VERSION_HEX >= 0x02030000
-	0,                                  /* tp_del */
+      0,                                    /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+      0,                                    /* tp_version */
 #endif
 #ifdef COUNT_ALLOCS
-	0,0,0,0                             /* tp_alloc -> tp_next */
+      0,0,0,0                               /* tp_alloc -> tp_next */
 #endif
-      };
-    pyswigobject_type = tmp;
-    pyswigobject_type.ob_type = &PyType_Type;
+    };
+    swigpyobject_type = tmp;
     type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+    swigpyobject_type.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&swigpyobject_type) < 0)
+      return NULL;
+#endif
   }
-  return &pyswigobject_type;
+  return &swigpyobject_type;
 }
 
 SWIGRUNTIME PyObject *
-PySwigObject_New(void *ptr, swig_type_info *ty, int own)
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
 {
-  PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type());
+  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
   if (sobj) {
     sobj->ptr  = ptr;
     sobj->ty   = ty;
@@ -1708,10 +1978,10 @@ typedef struct {
   void *pack;
   swig_type_info *ty;
   size_t size;
-} PySwigPacked;
+} SwigPyPacked;
 
 SWIGRUNTIME int
-PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
 {
   char result[SWIG_BUFFER_SIZE];
   fputs("<Swig Packed ", fp); 
@@ -1725,29 +1995,29 @@ PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
 }
   
 SWIGRUNTIME PyObject *
-PySwigPacked_repr(PySwigPacked *v)
+SwigPyPacked_repr(SwigPyPacked *v)
 {
   char result[SWIG_BUFFER_SIZE];
   if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
-    return PyString_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
+    return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
   } else {
-    return PyString_FromFormat("<Swig Packed %s>", v->ty->name);
+    return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
   }  
 }
 
 SWIGRUNTIME PyObject *
-PySwigPacked_str(PySwigPacked *v)
+SwigPyPacked_str(SwigPyPacked *v)
 {
   char result[SWIG_BUFFER_SIZE];
   if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
-    return PyString_FromFormat("%s%s", result, v->ty->name);
+    return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
   } else {
-    return PyString_FromString(v->ty->name);
+    return SWIG_Python_str_FromChar(v->ty->name);
   }  
 }
 
 SWIGRUNTIME int
-PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w)
+SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
 {
   size_t i = v->size;
   size_t j = w->size;
@@ -1755,104 +2025,120 @@ PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w)
   return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
 }
 
-SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void);
+SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void);
 
 SWIGRUNTIME PyTypeObject*
-PySwigPacked_type(void) {
-  static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type();
+SwigPyPacked_type(void) {
+  static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce();
   return type;
 }
 
 SWIGRUNTIMEINLINE int
-PySwigPacked_Check(PyObject *op) {
-  return ((op)->ob_type == _PySwigPacked_type()) 
-    || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0);
+SwigPyPacked_Check(PyObject *op) {
+  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
+    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
 }
 
 SWIGRUNTIME void
-PySwigPacked_dealloc(PyObject *v)
+SwigPyPacked_dealloc(PyObject *v)
 {
-  if (PySwigPacked_Check(v)) {
-    PySwigPacked *sobj = (PySwigPacked *) v;
+  if (SwigPyPacked_Check(v)) {
+    SwigPyPacked *sobj = (SwigPyPacked *) v;
     free(sobj->pack);
   }
   PyObject_DEL(v);
 }
 
 SWIGRUNTIME PyTypeObject*
-_PySwigPacked_type(void) {
+SwigPyPacked_TypeOnce(void) {
   static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
-  static PyTypeObject pyswigpacked_type;
-  static int type_init = 0;  
+  static PyTypeObject swigpypacked_type;
+  static int type_init = 0;
   if (!type_init) {
-    const PyTypeObject tmp
-      = {
-	PyObject_HEAD_INIT(NULL)
-	0,				    /* ob_size */	
-	(char *)"PySwigPacked",		    /* tp_name */	
-	sizeof(PySwigPacked),		    /* tp_basicsize */	
-	0,				    /* tp_itemsize */	
-	(destructor)PySwigPacked_dealloc,   /* tp_dealloc */	
-	(printfunc)PySwigPacked_print,	    /* tp_print */   	
-	(getattrfunc)0,			    /* tp_getattr */ 	
-	(setattrfunc)0,			    /* tp_setattr */ 	
-	(cmpfunc)PySwigPacked_compare,	    /* tp_compare */ 	
-	(reprfunc)PySwigPacked_repr,	    /* tp_repr */    	
-	0,	                            /* tp_as_number */	
-	0,				    /* tp_as_sequence */
-	0,				    /* tp_as_mapping */	
-	(hashfunc)0,			    /* tp_hash */	
-	(ternaryfunc)0,			    /* tp_call */	
-	(reprfunc)PySwigPacked_str,	    /* tp_str */	
-	PyObject_GenericGetAttr,            /* tp_getattro */
-	0,				    /* tp_setattro */
-	0,		                    /* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,	            /* tp_flags */
-	swigpacked_doc, 	            /* tp_doc */
-	0,                                  /* tp_traverse */
-	0,                                  /* tp_clear */
-	0,                                  /* tp_richcompare */
-	0,                                  /* tp_weaklistoffset */
+    const PyTypeObject tmp = {
+      /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX>=0x03000000
+      PyVarObject_HEAD_INIT(NULL, 0)
+#else
+      PyObject_HEAD_INIT(NULL)
+      0,                                    /* ob_size */
+#endif
+      (char *)"SwigPyPacked",               /* tp_name */
+      sizeof(SwigPyPacked),                 /* tp_basicsize */
+      0,                                    /* tp_itemsize */
+      (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
+      (printfunc)SwigPyPacked_print,        /* tp_print */
+      (getattrfunc)0,                       /* tp_getattr */
+      (setattrfunc)0,                       /* tp_setattr */
+#if PY_VERSION_HEX>=0x03000000
+      0, /* tp_reserved in 3.0.1 */
+#else
+      (cmpfunc)SwigPyPacked_compare,        /* tp_compare */
+#endif
+      (reprfunc)SwigPyPacked_repr,          /* tp_repr */
+      0,                                    /* tp_as_number */
+      0,                                    /* tp_as_sequence */
+      0,                                    /* tp_as_mapping */
+      (hashfunc)0,                          /* tp_hash */
+      (ternaryfunc)0,                       /* tp_call */
+      (reprfunc)SwigPyPacked_str,           /* tp_str */
+      PyObject_GenericGetAttr,              /* tp_getattro */
+      0,                                    /* tp_setattro */
+      0,                                    /* tp_as_buffer */
+      Py_TPFLAGS_DEFAULT,                   /* tp_flags */
+      swigpacked_doc,                       /* tp_doc */
+      0,                                    /* tp_traverse */
+      0,                                    /* tp_clear */
+      0,                                    /* tp_richcompare */
+      0,                                    /* tp_weaklistoffset */
 #if PY_VERSION_HEX >= 0x02020000
-	0,                                  /* tp_iter */
-	0,                                  /* tp_iternext */
-	0,		                    /* tp_methods */ 
-	0,			            /* tp_members */
-	0,				    /* tp_getset */	    	
-	0,			            /* tp_base */	        
-	0,				    /* tp_dict */	    	
-	0,				    /* tp_descr_get */  	
-	0,				    /* tp_descr_set */  	
-	0,				    /* tp_dictoffset */ 	
-	0,				    /* tp_init */	    	
-	0,				    /* tp_alloc */	    	
-	0,			            /* tp_new */	    	
-	0, 	                            /* tp_free */	   
-        0,                                  /* tp_is_gc */  
-	0,				    /* tp_bases */   
-	0,				    /* tp_mro */
-	0,				    /* tp_cache */   
- 	0,				    /* tp_subclasses */
-	0,				    /* tp_weaklist */
+      0,                                    /* tp_iter */
+      0,                                    /* tp_iternext */
+      0,                                    /* tp_methods */
+      0,                                    /* tp_members */
+      0,                                    /* tp_getset */
+      0,                                    /* tp_base */
+      0,                                    /* tp_dict */
+      0,                                    /* tp_descr_get */
+      0,                                    /* tp_descr_set */
+      0,                                    /* tp_dictoffset */
+      0,                                    /* tp_init */
+      0,                                    /* tp_alloc */
+      0,                                    /* tp_new */
+      0,                                    /* tp_free */
+      0,                                    /* tp_is_gc */
+      0,                                    /* tp_bases */
+      0,                                    /* tp_mro */
+      0,                                    /* tp_cache */
+      0,                                    /* tp_subclasses */
+      0,                                    /* tp_weaklist */
 #endif
 #if PY_VERSION_HEX >= 0x02030000
-	0,                                  /* tp_del */
+      0,                                    /* tp_del */
+#endif
+#if PY_VERSION_HEX >= 0x02060000
+      0,                                    /* tp_version */
 #endif
 #ifdef COUNT_ALLOCS
-	0,0,0,0                             /* tp_alloc -> tp_next */
+      0,0,0,0                               /* tp_alloc -> tp_next */
 #endif
-      };
-    pyswigpacked_type = tmp;
-    pyswigpacked_type.ob_type = &PyType_Type;
+    };
+    swigpypacked_type = tmp;
     type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+    swigpypacked_type.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&swigpypacked_type) < 0)
+      return NULL;
+#endif
   }
-  return &pyswigpacked_type;
+  return &swigpypacked_type;
 }
 
 SWIGRUNTIME PyObject *
-PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
+SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
 {
-  PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type());
+  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
   if (sobj) {
     void *pack = malloc(size);
     if (pack) {
@@ -1869,10 +2155,10 @@ PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
 }
 
 SWIGRUNTIME swig_type_info *
-PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
+SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
 {
-  if (PySwigPacked_Check(obj)) {
-    PySwigPacked *sobj = (PySwigPacked *)obj;
+  if (SwigPyPacked_Check(obj)) {
+    SwigPyPacked *sobj = (SwigPyPacked *)obj;
     if (sobj->size != size) return 0;
     memcpy(ptr, sobj->pack, size);
     return sobj->ty;
@@ -1888,73 +2174,96 @@ PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
 SWIGRUNTIMEINLINE PyObject *
 _SWIG_This(void)
 {
-  return PyString_FromString("this");
+    return SWIG_Python_str_FromChar("this");
 }
 
+static PyObject *swig_this = NULL;
+
 SWIGRUNTIME PyObject *
 SWIG_This(void)
 {
-  static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
+  if (swig_this == NULL)
+    swig_this = _SWIG_This();
   return swig_this;
 }
 
 /* #define SWIG_PYTHON_SLOW_GETSET_THIS */
 
-SWIGRUNTIME PySwigObject *
+/* TODO: I don't know how to implement the fast getset in Python 3 right now */
+#if PY_VERSION_HEX>=0x03000000
+#define SWIG_PYTHON_SLOW_GETSET_THIS 
+#endif
+
+SWIGRUNTIME SwigPyObject *
 SWIG_Python_GetSwigThis(PyObject *pyobj) 
 {
-  if (PySwigObject_Check(pyobj)) {
-    return (PySwigObject *) pyobj;
-  } else {
-    PyObject *obj = 0;
+  PyObject *obj;
+
+  if (SwigPyObject_Check(pyobj))
+    return (SwigPyObject *) pyobj;
+
+#ifdef SWIGPYTHON_BUILTIN
+  (void)obj;
+# ifdef PyWeakref_CheckProxy
+  if (PyWeakref_CheckProxy(pyobj)) {
+    pyobj = PyWeakref_GET_OBJECT(pyobj);
+    if (pyobj && SwigPyObject_Check(pyobj))
+      return (SwigPyObject*) pyobj;
+  }
+# endif
+  return NULL;
+#else
+
+  obj = 0;
+
 #if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
-    if (PyInstance_Check(pyobj)) {
-      obj = _PyInstance_Lookup(pyobj, SWIG_This());      
+  if (PyInstance_Check(pyobj)) {
+    obj = _PyInstance_Lookup(pyobj, SWIG_This());      
+  } else {
+    PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
+    if (dictptr != NULL) {
+      PyObject *dict = *dictptr;
+      obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
     } else {
-      PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
-      if (dictptr != NULL) {
-	PyObject *dict = *dictptr;
-	obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
-      } else {
 #ifdef PyWeakref_CheckProxy
-	if (PyWeakref_CheckProxy(pyobj)) {
-	  PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
-	  return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
-	}
+      if (PyWeakref_CheckProxy(pyobj)) {
+	PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
+	return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
+      }
 #endif
-	obj = PyObject_GetAttr(pyobj,SWIG_This());
-	if (obj) {
-	  Py_DECREF(obj);
-	} else {
-	  if (PyErr_Occurred()) PyErr_Clear();
-	  return 0;
-	}
+      obj = PyObject_GetAttr(pyobj,SWIG_This());
+      if (obj) {
+	Py_DECREF(obj);
+      } else {
+	if (PyErr_Occurred()) PyErr_Clear();
+	return 0;
       }
     }
+  }
 #else
-    obj = PyObject_GetAttr(pyobj,SWIG_This());
-    if (obj) {
-      Py_DECREF(obj);
-    } else {
-      if (PyErr_Occurred()) PyErr_Clear();
-      return 0;
-    }
+  obj = PyObject_GetAttr(pyobj,SWIG_This());
+  if (obj) {
+    Py_DECREF(obj);
+  } else {
+    if (PyErr_Occurred()) PyErr_Clear();
+    return 0;
+  }
 #endif
-    if (obj && !PySwigObject_Check(obj)) {
-      /* a PyObject is called 'this', try to get the 'real this'
-	 PySwigObject from it */ 
-      return SWIG_Python_GetSwigThis(obj);
-    }
-    return (PySwigObject *)obj;
+  if (obj && !SwigPyObject_Check(obj)) {
+    /* a PyObject is called 'this', try to get the 'real this'
+       SwigPyObject from it */ 
+    return SWIG_Python_GetSwigThis(obj);
   }
+  return (SwigPyObject *)obj;
+#endif
 }
 
 /* Acquire a pointer value */
 
 SWIGRUNTIME int
 SWIG_Python_AcquirePtr(PyObject *obj, int own) {
-  if (own) {
-    PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+  if (own == SWIG_POINTER_OWN) {
+    SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
     if (sobj) {
       int oldown = sobj->own;
       sobj->own = own;
@@ -1968,80 +2277,105 @@ SWIG_Python_AcquirePtr(PyObject *obj, int own) {
 
 SWIGRUNTIME int
 SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
-  if (!obj) return SWIG_ERROR;
-  if (obj == Py_None) {
-    if (ptr) *ptr = 0;
+  int res;
+  SwigPyObject *sobj;
+  int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0;
+
+  if (!obj)
+    return SWIG_ERROR;
+  if (obj == Py_None && !implicit_conv) {
+    if (ptr)
+      *ptr = 0;
     return SWIG_OK;
-  } else {
-    PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
-    while (sobj) {
-      void *vptr = sobj->ptr;
-      if (ty) {
-	swig_type_info *to = sobj->ty;
-	if (to == ty) {
-	  /* no type cast needed */
-	  if (ptr) *ptr = vptr;
-	  break;
-	} else {
-	  swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
-	  if (!tc) {
-	    sobj = (PySwigObject *)sobj->next;
-	  } else {
-	    if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
-	    break;
-	  }
-	}
+  }
+
+  res = SWIG_ERROR;
+
+  sobj = SWIG_Python_GetSwigThis(obj);
+  if (own)
+    *own = 0;
+  while (sobj) {
+    void *vptr = sobj->ptr;
+    if (ty) {
+      swig_type_info *to = sobj->ty;
+      if (to == ty) {
+        /* no type cast needed */
+        if (ptr) *ptr = vptr;
+        break;
       } else {
-	if (ptr) *ptr = vptr;
-	break;
-      }
-    }
-    if (sobj) {
-      if (own) *own = sobj->own;
-      if (flags & SWIG_POINTER_DISOWN) {
-	sobj->own = 0;
+        swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+        if (!tc) {
+          sobj = (SwigPyObject *)sobj->next;
+        } else {
+          if (ptr) {
+            int newmemory = 0;
+            *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+            if (newmemory == SWIG_CAST_NEW_MEMORY) {
+              assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+              if (own)
+                *own = *own | SWIG_CAST_NEW_MEMORY;
+            }
+          }
+          break;
+        }
       }
-      return SWIG_OK;
     } else {
-      int res = SWIG_ERROR;
-      if (flags & SWIG_POINTER_IMPLICIT_CONV) {
-	PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
-	if (data && !data->implicitconv) {
-	  PyObject *klass = data->klass;
-	  if (klass) {
-	    PyObject *impconv;
-	    data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
-	    impconv = SWIG_Python_CallFunctor(klass, obj);
-	    data->implicitconv = 0;
-	    if (PyErr_Occurred()) {
-	      PyErr_Clear();
-	      impconv = 0;
-	    }
-	    if (impconv) {
-	      PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv);
-	      if (iobj) {
-		void *vptr;
-		res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
-		if (SWIG_IsOK(res)) {
-		  if (ptr) {
-		    *ptr = vptr;
-		    /* transfer the ownership to 'ptr' */
-		    iobj->own = 0;
-		    res = SWIG_AddCast(res);
-		    res = SWIG_AddNewMask(res);
-		  } else {
-		    res = SWIG_AddCast(res);		    
-		  }
-		}
-	      }
-	      Py_DECREF(impconv);
-	    }
-	  }
-	}
+      if (ptr) *ptr = vptr;
+      break;
+    }
+  }
+  if (sobj) {
+    if (own)
+      *own = *own | sobj->own;
+    if (flags & SWIG_POINTER_DISOWN) {
+      sobj->own = 0;
+    }
+    res = SWIG_OK;
+  } else {
+    if (implicit_conv) {
+      SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
+      if (data && !data->implicitconv) {
+        PyObject *klass = data->klass;
+        if (klass) {
+          PyObject *impconv;
+          data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
+          impconv = SWIG_Python_CallFunctor(klass, obj);
+          data->implicitconv = 0;
+          if (PyErr_Occurred()) {
+            PyErr_Clear();
+            impconv = 0;
+          }
+          if (impconv) {
+            SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
+            if (iobj) {
+              void *vptr;
+              res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
+              if (SWIG_IsOK(res)) {
+                if (ptr) {
+                  *ptr = vptr;
+                  /* transfer the ownership to 'ptr' */
+                  iobj->own = 0;
+                  res = SWIG_AddCast(res);
+                  res = SWIG_AddNewMask(res);
+                } else {
+                  res = SWIG_AddCast(res);		    
+                }
+              }
+            }
+            Py_DECREF(impconv);
+          }
+        }
       }
-      return res;
+    }
+    if (!SWIG_IsOK(res) && obj == Py_None) {
+      if (ptr)
+        *ptr = 0;
+      if (PyErr_Occurred())
+        PyErr_Clear();
+      res = SWIG_OK;
     }
   }
+  return res;
 }
 
 /* Convert a function ptr value */
@@ -2056,14 +2390,19 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
     /* here we get the method pointer for callbacks */
     const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
     const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
-    if (desc) {
+    if (desc)
       desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
-      if (!desc) return SWIG_ERROR;
-    }
+    if (!desc) 
+      return SWIG_ERROR;
     if (ty) {
       swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
-      if (!tc) return SWIG_ERROR;
-      *ptr = SWIG_TypeCast(tc,vptr);
+      if (tc) {
+        int newmemory = 0;
+        *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+        assert(!newmemory); /* newmemory handling not yet implemented */
+      } else {
+        return SWIG_ERROR;
+      }
     } else {
       *ptr = vptr;
     }
@@ -2075,7 +2414,7 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
 
 SWIGRUNTIME int
 SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
-  swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz);
+  swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
   if (!to) return SWIG_ERROR;
   if (ty) {
     if (to != ty) {
@@ -2092,12 +2431,12 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t
  * ----------------------------------------------------------------------------- */
 
 /*
-  Create a new instance object, whitout calling __init__, and set the
+  Create a new instance object, without calling __init__, and set the
   'this' attribute.
 */
 
 SWIGRUNTIME PyObject* 
-SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
+SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
 {
 #if (PY_VERSION_HEX >= 0x02020000)
   PyObject *inst = 0;
@@ -2121,19 +2460,31 @@ SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
 #endif
     }
   } else {
+#if PY_VERSION_HEX >= 0x03000000
+    inst = ((PyTypeObject*) data->newargs)->tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
+    if (inst) {
+      PyObject_SetAttr(inst, SWIG_This(), swig_this);
+      Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+    }
+#else
     PyObject *dict = PyDict_New();
-    PyDict_SetItem(dict, SWIG_This(), swig_this);
-    inst = PyInstance_NewRaw(data->newargs, dict);
-    Py_DECREF(dict);
+    if (dict) {
+      PyDict_SetItem(dict, SWIG_This(), swig_this);
+      inst = PyInstance_NewRaw(data->newargs, dict);
+      Py_DECREF(dict);
+    }
+#endif
   }
   return inst;
 #else
 #if (PY_VERSION_HEX >= 0x02010000)
-  PyObject *inst;
+  PyObject *inst = 0;
   PyObject *dict = PyDict_New();
-  PyDict_SetItem(dict, SWIG_This(), swig_this);
-  inst = PyInstance_NewRaw(data->newargs, dict);
-  Py_DECREF(dict);
+  if (dict) {
+    PyDict_SetItem(dict, SWIG_This(), swig_this);
+    inst = PyInstance_NewRaw(data->newargs, dict);
+    Py_DECREF(dict);
+  }
   return (PyObject *) inst;
 #else
   PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
@@ -2184,12 +2535,12 @@ SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
 SWIGINTERN PyObject *
 SWIG_Python_InitShadowInstance(PyObject *args) {
   PyObject *obj[2];
-  if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+  if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) {
     return NULL;
   } else {
-    PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
+    SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
     if (sthis) {
-      PySwigObject_append((PyObject*) sthis, obj[1]);
+      SwigPyObject_append((PyObject*) sthis, obj[1]);
     } else {
       SWIG_Python_SetSwigThis(obj[0], obj[1]);
     }
@@ -2200,29 +2551,59 @@ SWIG_Python_InitShadowInstance(PyObject *args) {
 /* Create a new pointer object */
 
 SWIGRUNTIME PyObject *
-SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
-  if (!ptr) {
+SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) {
+  SwigPyClientData *clientdata;
+  PyObject * robj;
+  int own;
+
+  if (!ptr)
     return SWIG_Py_Void();
-  } else {
-    int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
-    PyObject *robj = PySwigObject_New(ptr, type, own);
-    PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0;
-    if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
-      PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
-      if (inst) {
-	Py_DECREF(robj);
-	robj = inst;
+
+  clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
+  own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+  if (clientdata && clientdata->pytype) {
+    SwigPyObject *newobj;
+    if (flags & SWIG_BUILTIN_TP_INIT) {
+      newobj = (SwigPyObject*) self;
+      if (newobj->ptr) {
+        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
+        while (newobj->next)
+	  newobj = (SwigPyObject *) newobj->next;
+        newobj->next = next_self;
+        newobj = (SwigPyObject *)next_self;
       }
+    } else {
+      newobj = PyObject_New(SwigPyObject, clientdata->pytype);
+    }
+    if (newobj) {
+      newobj->ptr = ptr;
+      newobj->ty = type;
+      newobj->own = own;
+      newobj->next = 0;
+#ifdef SWIGPYTHON_BUILTIN
+      newobj->dict = 0;
+#endif
+      return (PyObject*) newobj;
     }
-    return robj;
+    return SWIG_Py_Void();
+  }
+
+  assert(!(flags & SWIG_BUILTIN_TP_INIT));
+
+  robj = SwigPyObject_New(ptr, type, own);
+  if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+    PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
+    Py_DECREF(robj);
+    robj = inst;
   }
+  return robj;
 }
 
 /* Create a new packed object */
 
 SWIGRUNTIMEINLINE PyObject *
 SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
-  return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
+  return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
 }
 
 /* -----------------------------------------------------------------------------*
@@ -2234,15 +2615,19 @@ void *SWIG_ReturnGlobalTypeList(void *);
 #endif
 
 SWIGRUNTIME swig_module_info *
-SWIG_Python_GetModule(void) {
+SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
   static void *type_pointer = (void *)0;
   /* first check if module already created */
   if (!type_pointer) {
 #ifdef SWIG_LINK_RUNTIME
     type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
 #else
+# ifdef SWIGPY_USE_CAPSULE
+    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
+# else
     type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
 				    (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
+# endif
     if (PyErr_Occurred()) {
       PyErr_Clear();
       type_pointer = (void *)0;
@@ -2285,33 +2670,54 @@ PyModule_AddObject(PyObject *m, char *name, PyObject *o)
 #endif
 
 SWIGRUNTIME void
+#ifdef SWIGPY_USE_CAPSULE
+SWIG_Python_DestroyModule(PyObject *obj)
+#else
 SWIG_Python_DestroyModule(void *vptr)
+#endif
 {
+#ifdef SWIGPY_USE_CAPSULE
+  swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
+#else
   swig_module_info *swig_module = (swig_module_info *) vptr;
+#endif
   swig_type_info **types = swig_module->types;
   size_t i;
   for (i =0; i < swig_module->size; ++i) {
     swig_type_info *ty = types[i];
     if (ty->owndata) {
-      PySwigClientData *data = (PySwigClientData *) ty->clientdata;
-      if (data) PySwigClientData_Del(data);
+      SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
+      if (data) SwigPyClientData_Del(data);
     }
   }
   Py_DECREF(SWIG_This());
+  swig_this = NULL;
 }
 
 SWIGRUNTIME void
 SWIG_Python_SetModule(swig_module_info *swig_module) {
-  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */
-
-  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
-				   swig_empty_runtime_method_table);
+#if PY_VERSION_HEX >= 0x03000000
+ /* Add a dummy module object into sys.modules */
+  PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
+#else
+  static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */
+  PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table);
+#endif
+#ifdef SWIGPY_USE_CAPSULE
+  PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
+  if (pointer && module) {
+    PyModule_AddObject(module, (char*)"type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
+  } else {
+    Py_XDECREF(pointer);
+  }
+#else
   PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
   if (pointer && module) {
     PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
   } else {
     Py_XDECREF(pointer);
   }
+#endif
 }
 
 /* The python cached type query */
@@ -2325,16 +2731,24 @@ SWIGRUNTIME swig_type_info *
 SWIG_Python_TypeQuery(const char *type)
 {
   PyObject *cache = SWIG_Python_TypeCache();
-  PyObject *key = PyString_FromString(type); 
+  PyObject *key = SWIG_Python_str_FromChar(type); 
   PyObject *obj = PyDict_GetItem(cache, key);
   swig_type_info *descriptor;
   if (obj) {
+#ifdef SWIGPY_USE_CAPSULE
+    descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL);
+#else
     descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
+#endif
   } else {
-    swig_module_info *swig_module = SWIG_Python_GetModule();
+    swig_module_info *swig_module = SWIG_GetModule(0);
     descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
     if (descriptor) {
+#ifdef SWIGPY_USE_CAPSULE
+      obj = PyCapsule_New((void*) descriptor, NULL, NULL);
+#else
       obj = PyCObject_FromVoidPtr(descriptor, NULL);
+#endif
       PyDict_SetItem(cache, key, obj);
       Py_DECREF(obj);
     }
@@ -2352,21 +2766,23 @@ SWIG_Python_TypeQuery(const char *type)
 
 SWIGRUNTIME int
 SWIG_Python_AddErrMesg(const char* mesg, int infront)
-{
+{  
   if (PyErr_Occurred()) {
     PyObject *type = 0;
     PyObject *value = 0;
     PyObject *traceback = 0;
     PyErr_Fetch(&type, &value, &traceback);
     if (value) {
+      char *tmp;
       PyObject *old_str = PyObject_Str(value);
       Py_XINCREF(type);
       PyErr_Clear();
       if (infront) {
-	PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str));
+	PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
       } else {
-	PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+	PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
       }
+      SWIG_Python_str_DelForPy3(tmp);
       Py_DECREF(old_str);
     }
     return 1;
@@ -2389,11 +2805,11 @@ SWIG_Python_ArgFail(int argnum)
 }
 
 SWIGRUNTIMEINLINE const char *
-PySwigObject_GetDesc(PyObject *self)
+SwigPyObject_GetDesc(PyObject *self)
 {
-  PySwigObject *v = (PySwigObject *)self;
+  SwigPyObject *v = (SwigPyObject *)self;
   swig_type_info *ty = v ? v->ty : 0;
-  return ty ? ty->str : (char*)"";
+  return ty ? ty->str : "";
 }
 
 SWIGRUNTIME void
@@ -2401,10 +2817,10 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
 {
   if (type) {
 #if defined(SWIG_COBJECT_TYPES)
-    if (obj && PySwigObject_Check(obj)) {
-      const char *otype = (const char *) PySwigObject_GetDesc(obj);
+    if (obj && SwigPyObject_Check(obj)) {
+      const char *otype = (const char *) SwigPyObject_GetDesc(obj);
       if (otype) {
-	PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received",
+	PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
 		     type, otype);
 	return;
       }
@@ -2414,10 +2830,11 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
       const char *otype = (obj ? obj->ob_type->tp_name : 0); 
       if (otype) {
 	PyObject *str = PyObject_Str(obj);
-	const char *cstr = str ? PyString_AsString(str) : 0;
+	const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
 	if (cstr) {
 	  PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
 		       type, otype, cstr);
+          SWIG_Python_str_DelForPy3(cstr);
 	} else {
 	  PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
 		       type, otype);
@@ -2435,23 +2852,75 @@ SWIG_Python_TypeError(const char *type, PyObject *obj)
 
 /* Convert a pointer value, signal an exception on a type mismatch */
 SWIGRUNTIME void *
-SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) {
+SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) {
   void *result;
   if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
     PyErr_Clear();
-    if (flags & SWIG_POINTER_EXCEPTION) {
+#if SWIG_POINTER_EXCEPTION
+    if (flags) {
       SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
       SWIG_Python_ArgFail(argnum);
     }
+#endif
   }
   return result;
 }
 
+#ifdef SWIGPYTHON_BUILTIN
+SWIGRUNTIME int
+SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
+  PyTypeObject *tp = obj->ob_type;
+  PyObject *descr;
+  PyObject *encoded_name;
+  descrsetfunc f;
+  int res = -1;
+
+# ifdef Py_USING_UNICODE
+  if (PyString_Check(name)) {
+    name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL);
+    if (!name)
+      return -1;
+  } else if (!PyUnicode_Check(name))
+# else
+  if (!PyString_Check(name))
+# endif
+  {
+    PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name);
+    return -1;
+  } else {
+    Py_INCREF(name);
+  }
+
+  if (!tp->tp_dict) {
+    if (PyType_Ready(tp) < 0)
+      goto done;
+  }
+
+  descr = _PyType_Lookup(tp, name);
+  f = NULL;
+  if (descr != NULL)
+    f = descr->ob_type->tp_descr_set;
+  if (!f) {
+    if (PyString_Check(name)) {
+      encoded_name = name;
+      Py_INCREF(name);
+    } else {
+      encoded_name = PyUnicode_AsUTF8String(name);
+    }
+    PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
+    Py_DECREF(encoded_name);
+  } else {
+    res = f(descr, obj, value);
+  }
+  
+  done:
+  Py_DECREF(name);
+  return res;
+}
+#endif
+
 
 #ifdef __cplusplus
-#if 0
-{ /* cc-mode */
-#endif
 }
 #endif
 
@@ -2483,39 +2952,36 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
 #define SWIGTYPE_p_p_PyObject swig_types[12]
 #define SWIGTYPE_p_p_double swig_types[13]
 #define SWIGTYPE_p_size_type swig_types[14]
-#define SWIGTYPE_p_std__invalid_argument swig_types[15]
-#define SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t swig_types[16]
-#define SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type swig_types[17]
-#define SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type swig_types[18]
-#define SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t swig_types[19]
-#define SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type swig_types[20]
-#define SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type swig_types[21]
-#define SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t swig_types[22]
-#define SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type swig_types[23]
-#define SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type swig_types[24]
-#define SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t swig_types[25]
-#define SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type swig_types[26]
-#define SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type swig_types[27]
-#define SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t swig_types[28]
-#define SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type swig_types[29]
-#define SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type swig_types[30]
-#define SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t swig_types[31]
-#define SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type swig_types[32]
-#define SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type swig_types[33]
-#define SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t swig_types[34]
-#define SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type swig_types[35]
-#define SWIGTYPE_p_std__vectorTfloat_std__allocatorTfloat_t_t swig_types[36]
-#define SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t swig_types[37]
-#define SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t__allocator_type swig_types[38]
-#define SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t swig_types[39]
-#define SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type swig_types[40]
-#define SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t swig_types[41]
-#define SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type swig_types[42]
-#define SWIGTYPE_p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t swig_types[43]
-#define SWIGTYPE_p_swig__PySwigIterator swig_types[44]
-#define SWIGTYPE_p_value_type swig_types[45]
-static swig_type_info *swig_types[47];
-static swig_module_info swig_module = {swig_types, 46, 0, 0, 0, 0};
+#define SWIGTYPE_p_std__allocatorT_CdiVariable_t swig_types[15]
+#define SWIGTYPE_p_std__allocatorT_double_t swig_types[16]
+#define SWIGTYPE_p_std__allocatorT_int_t swig_types[17]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t swig_types[18]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t swig_types[19]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t swig_types[20]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t swig_types[21]
+#define SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t swig_types[22]
+#define SWIGTYPE_p_std__allocatorT_std__string_t swig_types[23]
+#define SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t swig_types[24]
+#define SWIGTYPE_p_std__invalid_argument swig_types[25]
+#define SWIGTYPE_p_std__lessT_int_t swig_types[26]
+#define SWIGTYPE_p_std__lessT_std__string_t swig_types[27]
+#define SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t swig_types[28]
+#define SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t swig_types[29]
+#define SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t swig_types[30]
+#define SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t swig_types[31]
+#define SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t swig_types[32]
+#define SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t swig_types[33]
+#define SWIGTYPE_p_std__vectorT__Tp__Alloc_t swig_types[34]
+#define SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t swig_types[35]
+#define SWIGTYPE_p_std__vectorT_float_std__allocatorT_float_t_t swig_types[36]
+#define SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t swig_types[37]
+#define SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t swig_types[38]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t swig_types[39]
+#define SWIGTYPE_p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t swig_types[40]
+#define SWIGTYPE_p_swig__SwigPyIterator swig_types[41]
+#define SWIGTYPE_p_value_type swig_types[42]
+static swig_type_info *swig_types[44];
+static swig_module_info swig_module = {swig_types, 43, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -2530,11 +2996,16 @@ static swig_module_info swig_module = {swig_types, 46, 0, 0, 0, 0};
 /*-----------------------------------------------
               @(target):= _CdiObj.so
   ------------------------------------------------*/
-#define SWIG_init    init_CdiObj
+#if PY_VERSION_HEX >= 0x03000000
+#  define SWIG_init    PyInit__CdiObj
+
+#else
+#  define SWIG_init    init_CdiObj
 
+#endif
 #define SWIG_name    "_CdiObj"
 
-#define SWIGVERSION 0x010331 
+#define SWIGVERSION 0x030002 
 #define SWIG_VERSION SWIGVERSION
 
 
@@ -2546,26 +3017,28 @@ static swig_module_info swig_module = {swig_types, 46, 0, 0, 0, 0};
 
 
 namespace swig {
-  class PyObject_ptr {
+  class SwigPtr_PyObject {
   protected:
     PyObject *_obj;
 
   public:
-    PyObject_ptr() :_obj(0)
+    SwigPtr_PyObject() :_obj(0)
     {
     }
 
-    PyObject_ptr(const PyObject_ptr& item) : _obj(item._obj)
+    SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
     {
       Py_XINCREF(_obj);      
     }
     
-    PyObject_ptr(PyObject *obj, bool initial_ref = true) :_obj(obj)
+    SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
     {
-      if (initial_ref) Py_XINCREF(_obj);
+      if (initial_ref) {
+        Py_XINCREF(_obj);
+      }
     }
     
-    PyObject_ptr & operator=(const PyObject_ptr& item) 
+    SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) 
     {
       Py_XINCREF(item._obj);
       Py_XDECREF(_obj);
@@ -2573,7 +3046,7 @@ namespace swig {
       return *this;      
     }
     
-    ~PyObject_ptr() 
+    ~SwigPtr_PyObject() 
     {
       Py_XDECREF(_obj);
     }
@@ -2592,10 +3065,10 @@ namespace swig {
 
 
 namespace swig {
-  struct PyObject_var : PyObject_ptr {
-    PyObject_var(PyObject* obj = 0) : PyObject_ptr(obj, false) { }
+  struct SwigVar_PyObject : SwigPtr_PyObject {
+    SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
     
-    PyObject_var & operator = (PyObject* obj)
+    SwigVar_PyObject & operator = (PyObject* obj)
     {
       Py_XDECREF(_obj);
       _obj = obj;
@@ -2612,13 +3085,6 @@ namespace swig {
 #include <stdexcept>
 
 
-  
-#if defined(__SUNPRO_CC) && defined(_RWSTD_VER)
-#  define SWIG_STD_NOASSIGN_STL
-#  define SWIG_STD_NOINSERT_TEMPLATE_STL
-#  define SWIG_STD_NOITERATOR_TRAITS_STL
-#endif
-
 #if defined(__GNUC__)
 #  if __GNUC__ == 2 && __GNUC_MINOR <= 96
 #     define SWIG_STD_NOMODERN_STL
@@ -2626,109 +3092,123 @@ namespace swig {
 #endif
 
 
-
-
 #include <string>
-#include <stdexcept>
 
 
-#include <string>
+#include <stddef.h>
 
 
 #include <iostream>
 
-  
+#if PY_VERSION_HEX >= 0x03020000
+# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
+#else
+# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
+#endif
+
+
 namespace swig {
   struct stop_iteration {
   };
 
-  struct PySwigIterator {
+  struct SwigPyIterator {
   private:
-    PyObject_ptr _seq;
+    SwigPtr_PyObject _seq;
 
   protected:
-    PySwigIterator(PyObject *seq) : _seq(seq)
+    SwigPyIterator(PyObject *seq) : _seq(seq)
     {
     }
       
   public:
-    virtual ~PySwigIterator() {}
+    virtual ~SwigPyIterator() {}
 
     // Access iterator method, required by Python
     virtual PyObject *value() const = 0;
 
     // Forward iterator method, required by Python
-    virtual PySwigIterator *incr(size_t n = 1) = 0;
+    virtual SwigPyIterator *incr(size_t n = 1) = 0;
     
     // Backward iterator method, very common in C++, but not required in Python
-    virtual PySwigIterator *decr(size_t n = 1)
+    virtual SwigPyIterator *decr(size_t /*n*/ = 1)
     {
       throw stop_iteration();
     }
 
     // Random access iterator methods, but not required in Python
-    virtual ptrdiff_t distance(const PySwigIterator &x) const
+    virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const
     {
       throw std::invalid_argument("operation not supported");
     }
 
-    virtual bool equal (const PySwigIterator &x) const
+    virtual bool equal (const SwigPyIterator &/*x*/) const
     {
       throw std::invalid_argument("operation not supported");
     }
     
     // C++ common/needed methods
-    virtual PySwigIterator *copy() const = 0;
+    virtual SwigPyIterator *copy() const = 0;
 
-    PyObject *next()
+    PyObject *next()     
     {
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
       PyObject *obj = value();
-      incr();
-      return obj;
+      incr();       
+      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
+      return obj;     
+    }
+
+    /* Make an alias for Python 3.x */
+    PyObject *__next__()
+    {
+      return next();
     }
 
     PyObject *previous()
     {
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads       
       decr();
-      return value();
+      PyObject *obj = value();
+      SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads       
+      return obj;
     }
 
-    PySwigIterator *advance(ptrdiff_t n)
+    SwigPyIterator *advance(ptrdiff_t n)
     {
       return  (n > 0) ?  incr(n) : decr(-n);
     }
       
-    bool operator == (const PySwigIterator& x)  const
+    bool operator == (const SwigPyIterator& x)  const
     {
       return equal(x);
     }
       
-    bool operator != (const PySwigIterator& x) const
+    bool operator != (const SwigPyIterator& x) const
     {
       return ! operator==(x);
     }
       
-    PySwigIterator& operator += (ptrdiff_t n)
+    SwigPyIterator& operator += (ptrdiff_t n)
     {
       return *advance(n);
     }
 
-    PySwigIterator& operator -= (ptrdiff_t n)
+    SwigPyIterator& operator -= (ptrdiff_t n)
     {
       return *advance(-n);
     }
       
-    PySwigIterator* operator + (ptrdiff_t n) const
+    SwigPyIterator* operator + (ptrdiff_t n) const
     {
       return copy()->advance(n);
     }
 
-    PySwigIterator* operator - (ptrdiff_t n) const
+    SwigPyIterator* operator - (ptrdiff_t n) const
     {
       return copy()->advance(-n);
     }
       
-    ptrdiff_t operator - (const PySwigIterator& x) const
+    ptrdiff_t operator - (const SwigPyIterator& x) const
     {
       return x.distance(*this);
     }
@@ -2737,12 +3217,20 @@ namespace swig {
       static int init = 0;
       static swig_type_info* desc = 0;
       if (!init) {
-	desc = SWIG_TypeQuery("swig::PySwigIterator *");
+	desc = SWIG_TypeQuery("swig::SwigPyIterator *");
 	init = 1;
       }	
       return desc;
     }    
   };
+
+#if defined(SWIGPYTHON_BUILTIN)
+  inline PyObject* make_output_iterator_builtin (PyObject *pyself)
+  {
+    Py_INCREF(pyself);
+    return pyself;
+  }
+#endif
 }
 
 
@@ -2829,6 +3317,7 @@ SWIG_CanCastAsInteger(double *d, double min, double max) {
 SWIGINTERN int
 SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) 
 {
+#if PY_VERSION_HEX < 0x03000000
   if (PyInt_Check(obj)) {
     long v = PyInt_AsLong(obj);
     if (v >= 0) {
@@ -2837,13 +3326,27 @@ SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val)
     } else {
       return SWIG_OverflowError;
     }
-  } else if (PyLong_Check(obj)) {
+  } else
+#endif
+  if (PyLong_Check(obj)) {
     unsigned long v = PyLong_AsUnsignedLong(obj);
     if (!PyErr_Occurred()) {
       if (val) *val = v;
       return SWIG_OK;
     } else {
       PyErr_Clear();
+#if PY_VERSION_HEX >= 0x03000000
+      {
+        long v = PyLong_AsLong(obj);
+        if (!PyErr_Occurred()) {
+          if (v < 0) {
+            return SWIG_OverflowError;
+          }
+        } else {
+          PyErr_Clear();
+        }
+      }
+#endif
     }
   }
 #ifdef SWIG_PYTHON_CAST_MODE
@@ -2880,7 +3383,7 @@ SWIG_AsVal_size_t (PyObject * obj, size_t *val)
 }
 
 
-  #define SWIG_From_long   PyInt_FromLong 
+  #define SWIG_From_long   PyLong_FromLong 
 
 
 SWIGINTERNINLINE PyObject *
@@ -2946,9 +3449,6 @@ SWIG_AsVal_ptrdiff_t (PyObject * obj, ptrdiff_t *val)
 }
 
 
-#include <stdexcept>
-
-
 #include <algorithm>
 
 
@@ -2959,8 +3459,9 @@ SWIG_AsVal_ptrdiff_t (PyObject * obj, ptrdiff_t *val)
 
 
 #include <map>
+
+
 #include <algorithm>
-#include <stdexcept>
 
 
 namespace swig {  
@@ -3038,7 +3539,7 @@ namespace swig {
   */
   template <class Type> struct traits_from_ptr {
     static PyObject *from(Type *val, int owner = 0) {
-      return SWIG_NewPointerObj(val, type_info<Type>(), owner);
+      return SWIG_InternalNewPointerObj(val, type_info<Type>(), owner);
     }
   };
 
@@ -3078,7 +3579,7 @@ namespace swig {
   struct traits_asptr {   
     static int asptr(PyObject *obj, Type **val) {
       Type *p;
-      int res = (SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0) == SWIG_OK) ? SWIG_OLDOBJ : 0;
+      int res = SWIG_ConvertPtr(obj, (void**)&p, type_info<Type>(), 0);
       if (SWIG_IsOK(res)) {
 	if (val) *val = p;
       }
@@ -3143,7 +3644,7 @@ namespace swig {
       int res = asval(obj, &v);
       if (!obj || !SWIG_IsOK(res)) {
 	if (!PyErr_Occurred()) {
-	  SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
+	  ::SWIG_Error(SWIG_TypeError,  swig::type_name<Type>());
 	}
 	if (throw_error) throw std::invalid_argument("bad type");
       }
@@ -3233,27 +3734,38 @@ namespace std {
     { 
       bool res;
       SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-      res = PyObject_Compare(v, w) < 0;
+      res = PyObject_RichCompareBool(v, w, Py_LT) ? true : false;
+      /* This may fall into a case of inconsistent
+               eg. ObjA > ObjX > ObjB
+               but ObjA < ObjB
+      */
+      if( PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_TypeError) )
+      {
+        /* Objects can't be compared, this mostly occurred in Python 3.0 */
+        /* Compare their ptr directly for a workaround */
+        res = (v < w);
+        PyErr_Clear();
+      }
       SWIG_PYTHON_THREAD_END_BLOCK;
       return res;
     }
   };
 
   template <>
-  struct less <swig::PyObject_ptr>: public binary_function<swig::PyObject_ptr, swig::PyObject_ptr, bool>
+  struct less <swig::SwigPtr_PyObject>: public binary_function<swig::SwigPtr_PyObject, swig::SwigPtr_PyObject, bool>
   {
     bool
-    operator()(const swig::PyObject_ptr& v, const swig::PyObject_ptr& w) const
+    operator()(const swig::SwigPtr_PyObject& v, const swig::SwigPtr_PyObject& w) const
     {
       return std::less<PyObject *>()(v, w);
     }
   };
 
   template <>
-  struct less <swig::PyObject_var>: public binary_function<swig::PyObject_var, swig::PyObject_var, bool>
+  struct less <swig::SwigVar_PyObject>: public binary_function<swig::SwigVar_PyObject, swig::SwigVar_PyObject, bool>
   {
     bool
-    operator()(const swig::PyObject_var& v, const swig::PyObject_var& w) const
+    operator()(const swig::SwigVar_PyObject& v, const swig::SwigVar_PyObject& w) const
     {
       return std::less<PyObject *>()(v, w);
     }
@@ -3293,8 +3805,9 @@ namespace swig {
 }
 
 namespace swig {
+  template <class Difference>
   inline size_t
-  check_index(ptrdiff_t i, size_t size, bool insert = false) {
+  check_index(Difference i, size_t size, bool insert = false) {
     if ( i < 0 ) {
       if ((size_t) (-i) <= size)
 	return (size_t) (i + size);
@@ -3303,20 +3816,42 @@ namespace swig {
     } else if (insert && ((size_t) i == size)) {
       return size;
     }
-    
     throw std::out_of_range("index out of range");
   }
 
-  inline size_t
-  slice_index(ptrdiff_t i, size_t size) {
-    if ( i < 0 ) {
-      if ((size_t) (-i) <= size) {
-	return (size_t) (i + size);
+  template <class Difference>
+  void
+  slice_adjust(Difference i, Difference j, Py_ssize_t step, size_t size, Difference &ii, Difference &jj, bool insert = false) {
+    if (step == 0) {
+      throw std::invalid_argument("slice step cannot be zero");
+    } else if (step > 0) {
+      // Required range: 0 <= i < size, 0 <= j < size
+      if (i < 0) {
+        ii = 0;
+      } else if (i < (Difference)size) {
+        ii = i;
+      } else if (insert && (i >= (Difference)size)) {
+        ii = (Difference)size;
+      }
+      if ( j < 0 ) {
+        jj = 0;
       } else {
-	throw std::out_of_range("index out of range");
+        jj = (j < (Difference)size) ? j : (Difference)size;
       }
     } else {
-      return ( (size_t) i < size ) ? ((size_t) i) : size;
+      // Required range: -1 <= i < size-1, -1 <= j < size-1
+      if (i < -1) {
+        ii = -1;
+      } else if (i < (Difference) size) {
+        ii = i;
+      } else if (i >= (Difference)(size-1)) {
+        ii = (Difference)(size-1);
+      }
+      if (j < -1) {
+        jj = -1;
+      } else {
+        jj = (j < (Difference)size ) ? j : (Difference)(size-1);
+      }
     }
   }
 
@@ -3338,80 +3873,178 @@ namespace swig {
 
   template <class Sequence, class Difference>
   inline Sequence*
-  getslice(const Sequence* self, Difference i, Difference j) {
+  getslice(const Sequence* self, Difference i, Difference j, Py_ssize_t step) {
     typename Sequence::size_type size = self->size();
-    typename Sequence::size_type ii = swig::check_index(i, size);
-    typename Sequence::size_type jj = swig::slice_index(j, size);
-
-    if (jj > ii) {
-      typename Sequence::const_iterator vb = self->begin();
-      typename Sequence::const_iterator ve = self->begin();
-      std::advance(vb,ii);
-      std::advance(ve,jj);
-      return new Sequence(vb, ve);
+    Difference ii = 0;
+    Difference jj = 0;
+    swig::slice_adjust(i, j, step, size, ii, jj);
+
+    if (step > 0) {
+      typename Sequence::const_iterator sb = self->begin();
+      typename Sequence::const_iterator se = self->begin();
+      std::advance(sb,ii);
+      std::advance(se,jj);
+      if (step == 1) {
+        return new Sequence(sb, se);
+      } else {
+        Sequence *sequence = new Sequence();
+        typename Sequence::const_iterator it = sb;
+        while (it!=se) {
+          sequence->push_back(*it);
+          for (Py_ssize_t c=0; c<step && it!=se; ++c)
+            it++;
+        }
+        return sequence;
+      } 
     } else {
-      return new Sequence();
+      Sequence *sequence = new Sequence();
+      if (ii > jj) {
+        typename Sequence::const_reverse_iterator sb = self->rbegin();
+        typename Sequence::const_reverse_iterator se = self->rbegin();
+        std::advance(sb,size-ii-1);
+        std::advance(se,size-jj-1);
+        typename Sequence::const_reverse_iterator it = sb;
+        while (it!=se) {
+          sequence->push_back(*it);
+          for (Py_ssize_t c=0; c<-step && it!=se; ++c)
+            it++;
+        }
+      }
+      return sequence;
     }
   }
 
   template <class Sequence, class Difference, class InputSeq>
   inline void
-  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
+  setslice(Sequence* self, Difference i, Difference j, Py_ssize_t step, const InputSeq& is = InputSeq()) {
     typename Sequence::size_type size = self->size();
-    typename Sequence::size_type ii = swig::check_index(i, size, true);
-    typename Sequence::size_type jj = swig::slice_index(j, size);
-    if (jj < ii) jj = ii;
-    size_t ssize = jj - ii;
-    if (ssize <= v.size()) {
-      typename Sequence::iterator sb = self->begin();
-      typename InputSeq::const_iterator vmid = v.begin();
-      std::advance(sb,ii);
-      std::advance(vmid, jj - ii);
-      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
+    Difference ii = 0;
+    Difference jj = 0;
+    swig::slice_adjust(i, j, step, size, ii, jj, true);
+    if (step > 0) {
+      if (jj < ii)
+        jj = ii;
+      if (step == 1) {
+        size_t ssize = jj - ii;
+        if (ssize <= is.size()) {
+          // expanding/staying the same size
+          typename Sequence::iterator sb = self->begin();
+          typename InputSeq::const_iterator isit = is.begin();
+          std::advance(sb,ii);
+          std::advance(isit, jj - ii);
+          self->insert(std::copy(is.begin(), isit, sb), isit, is.end());
+        } else {
+          // shrinking
+          typename Sequence::iterator sb = self->begin();
+          typename Sequence::iterator se = self->begin();
+          std::advance(sb,ii);
+          std::advance(se,jj);
+          self->erase(sb,se);
+          sb = self->begin();
+          std::advance(sb,ii);
+          self->insert(sb, is.begin(), is.end());
+        }
+      } else {
+        size_t replacecount = (jj - ii + step - 1) / step;
+        if (is.size() != replacecount) {
+          char msg[1024];
+          sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
+          throw std::invalid_argument(msg);
+        }
+        typename Sequence::const_iterator isit = is.begin();
+        typename Sequence::iterator it = self->begin();
+        std::advance(it,ii);
+        for (size_t rc=0; rc<replacecount; ++rc) {
+          *it++ = *isit++;
+          for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
+            it++;
+        }
+      }
     } else {
-      typename Sequence::iterator sb = self->begin();
-      typename Sequence::iterator se = self->begin();
-      std::advance(sb,ii);
-      std::advance(se,jj);
-      self->erase(sb,se);
-      self->insert(sb, v.begin(), v.end());
+      if (jj > ii)
+        jj = ii;
+      size_t replacecount = (ii - jj - step - 1) / -step;
+      if (is.size() != replacecount) {
+        char msg[1024];
+        sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
+        throw std::invalid_argument(msg);
+      }
+      typename Sequence::const_iterator isit = is.begin();
+      typename Sequence::reverse_iterator it = self->rbegin();
+      std::advance(it,size-ii-1);
+      for (size_t rc=0; rc<replacecount; ++rc) {
+        *it++ = *isit++;
+        for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
+          it++;
+      }
     }
   }
 
   template <class Sequence, class Difference>
   inline void
-  delslice(Sequence* self, Difference i, Difference j) {
+  delslice(Sequence* self, Difference i, Difference j, Py_ssize_t step) {
     typename Sequence::size_type size = self->size();
-    typename Sequence::size_type ii = swig::check_index(i, size, true);
-    typename Sequence::size_type jj = swig::slice_index(j, size);
-    if (jj > ii) {
-      typename Sequence::iterator sb = self->begin();
-      typename Sequence::iterator se = self->begin();
-      std::advance(sb,ii);
-      std::advance(se,jj);
-      self->erase(sb,se);
+    Difference ii = 0;
+    Difference jj = 0;
+    swig::slice_adjust(i, j, step, size, ii, jj, true);
+    if (step > 0) {
+      if (jj > ii) {
+        typename Sequence::iterator sb = self->begin();
+        std::advance(sb,ii);
+        if (step == 1) {
+          typename Sequence::iterator se = self->begin();
+          std::advance(se,jj);
+          self->erase(sb,se);
+        } else {
+          typename Sequence::iterator it = sb;
+          size_t delcount = (jj - ii + step - 1) / step;
+          while (delcount) {
+            it = self->erase(it);
+            for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c)
+              it++;
+            delcount--;
+          }
+        }
+      }
+    } else {
+      if (ii > jj) {
+        typename Sequence::reverse_iterator sb = self->rbegin();
+        std::advance(sb,size-ii-1);
+        typename Sequence::reverse_iterator it = sb;
+        size_t delcount = (ii - jj - step - 1) / -step;
+        while (delcount) {
+          it = typename Sequence::reverse_iterator(self->erase((++it).base()));
+          for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c)
+            it++;
+          delcount--;
+        }
+      }
     }
   }
 }
 
 
+#if defined(__SUNPRO_CC) && defined(_RWSTD_VER)
+#  if !defined(SWIG_NO_STD_NOITERATOR_TRAITS_STL)
+#    define SWIG_STD_NOITERATOR_TRAITS_STL
+#  endif
+#endif
+
 #if !defined(SWIG_STD_NOITERATOR_TRAITS_STL)
 #include <iterator>
 #else
-namespace std  {
+namespace std {
   template <class Iterator>
   struct iterator_traits {
     typedef ptrdiff_t difference_type;
     typedef typename Iterator::value_type value_type;
   };
 
-#if defined(__SUNPRO_CC) && defined(_RWSTD_VER)
   template <class Iterator, class Category,class T, class Reference, class Pointer, class Distance>
   struct iterator_traits<__reverse_bi_iterator<Iterator,Category,T,Reference,Pointer,Distance> > {
     typedef Distance difference_type;
     typedef T value_type;
   };
-#endif  
 
   template <class T>
   struct iterator_traits<T*> {
@@ -3429,22 +4062,21 @@ namespace std  {
     }
     return __n;
   }
-
-} 
+}
 #endif
 
 
 namespace swig {
   template<typename OutIterator>
-  class PySwigIterator_T :  public PySwigIterator
+  class SwigPyIterator_T :  public SwigPyIterator
   {
   public:
     typedef OutIterator out_iterator;
     typedef typename std::iterator_traits<out_iterator>::value_type value_type;    
-    typedef PySwigIterator_T<out_iterator> self_type;
+    typedef SwigPyIterator_T<out_iterator> self_type;
 
-    PySwigIterator_T(out_iterator curr, PyObject *seq)
-      : PySwigIterator(seq), current(curr)
+    SwigPyIterator_T(out_iterator curr, PyObject *seq)
+      : SwigPyIterator(seq), current(curr)
     {
     }
 
@@ -3454,7 +4086,7 @@ namespace swig {
     }
 
     
-    bool equal (const PySwigIterator &iter) const
+    bool equal (const SwigPyIterator &iter) const
     {
       const self_type *iters = dynamic_cast<const self_type *>(&iter);
       if (iters) {
@@ -3464,7 +4096,7 @@ namespace swig {
       }
     }
     
-    ptrdiff_t distance(const PySwigIterator &iter) const
+    ptrdiff_t distance(const SwigPyIterator &iter) const
     {
       const self_type *iters = dynamic_cast<const self_type *>(&iter);
       if (iters) {
@@ -3492,17 +4124,17 @@ namespace swig {
   template<typename OutIterator, 
 	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
 	   typename FromOper = from_oper<ValueType> >
-  class PySwigIteratorOpen_T :  public PySwigIterator_T<OutIterator>
+  class SwigPyIteratorOpen_T :  public SwigPyIterator_T<OutIterator>
   {
   public:
     FromOper from;
     typedef OutIterator out_iterator;
     typedef ValueType value_type;
-    typedef PySwigIterator_T<out_iterator>  base;
-    typedef PySwigIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
+    typedef SwigPyIterator_T<out_iterator>  base;
+    typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
     
-    PySwigIteratorOpen_T(out_iterator curr, PyObject *seq)
-      : PySwigIterator_T<OutIterator>(curr, seq)
+    SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq)
+      : SwigPyIterator_T<OutIterator>(curr, seq)
     {
     }
     
@@ -3510,12 +4142,12 @@ namespace swig {
       return from(static_cast<const value_type&>(*(base::current)));
     }
     
-    PySwigIterator *copy() const
+    SwigPyIterator *copy() const
     {
       return new self_type(*this);
     }
 
-    PySwigIterator *incr(size_t n = 1)
+    SwigPyIterator *incr(size_t n = 1)
     {
       while (n--) {
 	++base::current;
@@ -3523,7 +4155,7 @@ namespace swig {
       return this;
     }
 
-    PySwigIterator *decr(size_t n = 1)
+    SwigPyIterator *decr(size_t n = 1)
     {
       while (n--) {
 	--base::current;
@@ -3535,17 +4167,17 @@ namespace swig {
   template<typename OutIterator, 
 	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
 	   typename FromOper = from_oper<ValueType> >
-  class PySwigIteratorClosed_T :  public PySwigIterator_T<OutIterator>
+  class SwigPyIteratorClosed_T :  public SwigPyIterator_T<OutIterator>
   {
   public:
     FromOper from;
     typedef OutIterator out_iterator;
     typedef ValueType value_type;
-    typedef PySwigIterator_T<out_iterator>  base;    
-    typedef PySwigIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
+    typedef SwigPyIterator_T<out_iterator>  base;    
+    typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
     
-    PySwigIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
-      : PySwigIterator_T<OutIterator>(curr, seq), begin(first), end(last)
+    SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
+      : SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
     {
     }
     
@@ -3557,12 +4189,12 @@ namespace swig {
       }
     }
     
-    PySwigIterator *copy() const
+    SwigPyIterator *copy() const
     {
       return new self_type(*this);
     }
 
-    PySwigIterator *incr(size_t n = 1)
+    SwigPyIterator *incr(size_t n = 1)
     {
       while (n--) {
 	if (base::current == end) {
@@ -3574,7 +4206,7 @@ namespace swig {
       return this;
     }
 
-    PySwigIterator *decr(size_t n = 1)
+    SwigPyIterator *decr(size_t n = 1)
     {
       while (n--) {
 	if (base::current == begin) {
@@ -3592,41 +4224,42 @@ namespace swig {
   };
 
   template<typename OutIter>
-  inline PySwigIterator*
+  inline SwigPyIterator*
   make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0)
   {
-    return new PySwigIteratorClosed_T<OutIter>(current, begin, end, seq);
+    return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq);
   }
 
   template<typename OutIter>
-  inline PySwigIterator*
+  inline SwigPyIterator*
   make_output_iterator(const OutIter& current, PyObject *seq = 0)
   {
-    return new PySwigIteratorOpen_T<OutIter>(current, seq);
+    return new SwigPyIteratorOpen_T<OutIter>(current, seq);
   }
+
 }
 
 
 namespace swig
 {
   template <class T>
-  struct PySequence_Ref
+  struct SwigPySequence_Ref
   {
-    PySequence_Ref(PyObject* seq, int index)
+    SwigPySequence_Ref(PyObject* seq, int index)
       : _seq(seq), _index(index)
     {
     }
     
     operator T () const
     {
-      swig::PyObject_var item = PySequence_GetItem(_seq, _index);
+      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
       try {
 	return swig::as<T>(item, true);
       } catch (std::exception& e) {
 	char msg[1024];
 	sprintf(msg, "in sequence element %d ", _index);
 	if (!PyErr_Occurred()) {
-	  SWIG_Error(SWIG_TypeError,  swig::type_name<T>());
+	  ::SWIG_Error(SWIG_TypeError,  swig::type_name<T>());
 	}
 	SWIG_Python_AddErrorMsg(msg);
 	SWIG_Python_AddErrorMsg(e.what());
@@ -3634,7 +4267,7 @@ namespace swig
       }
     }
 
-    PySequence_Ref& operator=(const T& v)
+    SwigPySequence_Ref& operator=(const T& v)
     {
       PySequence_SetItem(_seq, _index, swig::from<T>(v));
       return *this;
@@ -3646,18 +4279,18 @@ namespace swig
   };
 
   template <class T>
-  struct PySequence_ArrowProxy
+  struct SwigPySequence_ArrowProxy
   {
-    PySequence_ArrowProxy(const T& x): m_value(x) {}
+    SwigPySequence_ArrowProxy(const T& x): m_value(x) {}
     const T* operator->() const { return &m_value; }
     operator const T*() const { return &m_value; }
     T m_value;
   };
 
   template <class T, class Reference >
-  struct PySequence_InputIterator
+  struct SwigPySequence_InputIterator
   {
-    typedef PySequence_InputIterator<T, Reference > self;
+    typedef SwigPySequence_InputIterator<T, Reference > self;
 
     typedef std::random_access_iterator_tag iterator_category;
     typedef Reference reference;
@@ -3665,11 +4298,11 @@ namespace swig
     typedef T* pointer;
     typedef int difference_type;
 
-    PySequence_InputIterator()
+    SwigPySequence_InputIterator()
     {
     }
 
-    PySequence_InputIterator(PyObject* seq, int index)
+    SwigPySequence_InputIterator(PyObject* seq, int index)
       : _seq(seq), _index(index)
     {
     }
@@ -3679,9 +4312,9 @@ namespace swig
       return reference(_seq, _index);
     }
 
-    PySequence_ArrowProxy<T>
+    SwigPySequence_ArrowProxy<T>
     operator->() const {
-      return PySequence_ArrowProxy<T>(operator*());
+      return SwigPySequence_ArrowProxy<T>(operator*());
     }
 
     bool operator==(const self& ri) const
@@ -3750,19 +4383,19 @@ namespace swig
   };
 
   template <class T>
-  struct PySequence_Cont
+  struct SwigPySequence_Cont
   {
-    typedef PySequence_Ref<T> reference;
-    typedef const PySequence_Ref<T> const_reference;
+    typedef SwigPySequence_Ref<T> reference;
+    typedef const SwigPySequence_Ref<T> const_reference;
     typedef T value_type;
     typedef T* pointer;
     typedef int difference_type;
     typedef int size_type;
     typedef const pointer const_pointer;
-    typedef PySequence_InputIterator<T, reference> iterator;
-    typedef PySequence_InputIterator<T, const_reference> const_iterator;
+    typedef SwigPySequence_InputIterator<T, reference> iterator;
+    typedef SwigPySequence_InputIterator<T, const_reference> const_iterator;
 
-    PySequence_Cont(PyObject* seq) : _seq(0)
+    SwigPySequence_Cont(PyObject* seq) : _seq(0)
     {
       if (!PySequence_Check(seq)) {
 	throw std::invalid_argument("a sequence is expected");
@@ -3771,14 +4404,14 @@ namespace swig
       Py_INCREF(_seq);
     }
 
-    ~PySequence_Cont()
+    ~SwigPySequence_Cont()
     {
-      if (_seq) Py_DECREF(_seq);
+      Py_XDECREF(_seq);
     }
 
     size_type size() const
     {
-      return PySequence_Size(_seq);
+      return static_cast<size_type>(PySequence_Size(_seq));
     }
 
     bool empty() const
@@ -3820,7 +4453,7 @@ namespace swig
     {
       int s = size();
       for (int i = 0; i < s; ++i) {
-	swig::PyObject_var item = PySequence_GetItem(_seq, i);
+	swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
 	if (!swig::check<value_type>(item)) {
 	  if (set_err) {
 	    char msg[1024];
@@ -3841,14 +4474,12 @@ namespace swig
 
 
 #include <limits.h>
-#ifndef LLONG_MIN
-# define LLONG_MIN	LONG_LONG_MIN
-#endif
-#ifndef LLONG_MAX
-# define LLONG_MAX	LONG_LONG_MAX
-#endif
-#ifndef ULLONG_MAX
-# define ULLONG_MAX	ULONG_LONG_MAX
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+#   define LLONG_MAX __LONG_LONG_MAX__
+#   define LLONG_MIN (-LLONG_MAX - 1LL)
+#   define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
 #endif
 
 
@@ -3868,10 +4499,10 @@ SWIG_AsVal_int (PyObject * obj, int *val)
 }
 
 
-SWIGINTERNINLINE PyObject *
-SWIG_From_int  (int value)
-{    
-  return SWIG_From_long  (value);
+SWIGINTERNINLINE PyObject*
+  SWIG_From_int  (int value)
+{
+  return PyInt_FromLong((long) value);
 }
 
 
@@ -3896,18 +4527,15 @@ namespace swig {
 
 
 namespace swig {
-  template <class PySeq, class Seq>
+  template <class SwigPySeq, class Seq>
   inline void
-  assign(const PySeq& pyseq, Seq* seq) {
-#ifdef SWIG_STD_NOASSIGN_STL
-    typedef typename PySeq::value_type value_type;
-    typename PySeq::const_iterator it = pyseq.begin();
-    for (;it != pyseq.end(); ++it) {
+  assign(const SwigPySeq& swigpyseq, Seq* seq) {
+    // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
+    typedef typename SwigPySeq::value_type value_type;
+    typename SwigPySeq::const_iterator it = swigpyseq.begin();
+    for (;it != swigpyseq.end(); ++it) {
       seq->insert(seq->end(),(value_type)(*it));
     }
-#else
-    seq->assign(pyseq.begin(), pyseq.end());
-#endif
   }
 
   template <class Seq, class T = typename Seq::value_type >
@@ -3916,16 +4544,23 @@ namespace swig {
     typedef T value_type;
 
     static int asptr(PyObject *obj, sequence **seq) {
-      if (PySequence_Check(obj)) {
+      if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) {
+	sequence *p;
+	if (::SWIG_ConvertPtr(obj,(void**)&p,
+			      swig::type_info<sequence>(),0) == SWIG_OK) {
+	  if (seq) *seq = p;
+	  return SWIG_OLDOBJ;
+	}
+      } else if (PySequence_Check(obj)) {
 	try {
-	  PySequence_Cont<value_type> pyseq(obj);
+	  SwigPySequence_Cont<value_type> swigpyseq(obj);
 	  if (seq) {
 	    sequence *pseq = new sequence();
-	    assign(pyseq, pseq);
+	    assign(swigpyseq, pseq);
 	    *seq = pseq;
 	    return SWIG_NEWOBJ;
 	  } else {
-	    return pyseq.check() ? SWIG_OK : SWIG_ERROR;
+	    return swigpyseq.check() ? SWIG_OK : SWIG_ERROR;
 	  }
 	} catch (std::exception& e) {
 	  if (seq) {
@@ -3935,13 +4570,6 @@ namespace swig {
 	  }
 	  return SWIG_ERROR;
 	}
-      } else {
-	sequence *p;
-	if (SWIG_ConvertPtr(obj,(void**)&p,
-			    swig::type_info<sequence>(),0) == SWIG_OK) {
-	  if (seq) *seq = p;
-	  return SWIG_OLDOBJ;
-	}
       }
       return SWIG_ERROR;
     }
@@ -3955,12 +4583,12 @@ namespace swig {
     typedef typename sequence::const_iterator const_iterator;
 
     static PyObject *from(const sequence& seq) {
-
-
-
-
-
-
+#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS
+      swig_type_info *desc = swig::type_info<sequence>();
+      if (desc && desc->clientdata) {
+	return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN);
+      }
+#endif
       size_type size = seq.size();
       if (size <= (size_type)INT_MAX) {
 	PyObject *obj = PyTuple_New((int)size);
@@ -3997,21 +4625,24 @@ namespace swig {
 
 
       namespace swig {
-	template <>  struct traits<std::vector<int, std::allocator<int > > > {
+	template <>  struct traits<std::vector<int, std::allocator< int > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::vector<" "int" "," "std::allocator<int >" " >";
+	    return "std::vector<" "int" "," "std::allocator< int >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_vector_Sl_int_Sg__iterator(std::vector<int > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_vector_Sl_int_Sg__iterator(std::vector< int > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_vector_Sl_int_Sg____nonzero__(std::vector<int > const *self){
+SWIGINTERN bool std_vector_Sl_int_Sg____nonzero__(std::vector< int > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_vector_Sl_int_Sg____bool__(std::vector< int > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::vector<int >::size_type std_vector_Sl_int_Sg____len__(std::vector<int > const *self){
+SWIGINTERN std::vector< int >::size_type std_vector_Sl_int_Sg____len__(std::vector< int > const *self){
       return self->size();
     }
 
@@ -4019,7 +4650,7 @@ SWIGINTERNINLINE PyObject*
 SWIG_From_unsigned_SS_long  (unsigned long value)
 {
   return (value > LONG_MAX) ?
-    PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value)); 
+    PyLong_FromUnsignedLong(value) : PyLong_FromLong(static_cast< long >(value)); 
 }
 
 
@@ -4029,34 +4660,82 @@ SWIG_From_size_t  (size_t value)
   return SWIG_From_unsigned_SS_long  (static_cast< unsigned long >(value));
 }
 
-SWIGINTERN std::vector<int >::value_type std_vector_Sl_int_Sg__pop(std::vector<int > *self){
+SWIGINTERN std::vector< int >::value_type std_vector_Sl_int_Sg__pop(std::vector< int > *self){
       if (self->size() == 0)
 	throw std::out_of_range("pop from empty container");
-      std::vector<int,std::allocator<int > >::value_type x = self->back();
+      std::vector<int,std::allocator< int > >::value_type x = self->back();
       self->pop_back();
       return x;
     }
-SWIGINTERN std::vector<int,std::allocator<int > > *std_vector_Sl_int_Sg____getslice__(std::vector<int > *self,std::vector<int >::difference_type i,std::vector<int >::difference_type j){
-      return swig::getslice(self, i, j);
+SWIGINTERN std::vector< int,std::allocator< int > > *std_vector_Sl_int_Sg____getslice__(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j){
+      return swig::getslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_int_Sg____setslice__(std::vector<int > *self,std::vector<int >::difference_type i,std::vector<int >::difference_type j,std::vector<int,std::allocator<int > > const &v){
-      swig::setslice(self, i, j, v);
+SWIGINTERN void std_vector_Sl_int_Sg____setslice____SWIG_0(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j,std::vector< int,std::allocator< int > > const &v=std::vector< int,std::allocator< int > >()){
+      swig::setslice(self, i, j, 1, v);
     }
-SWIGINTERN void std_vector_Sl_int_Sg____delslice__(std::vector<int > *self,std::vector<int >::difference_type i,std::vector<int >::difference_type j){
-      swig::delslice(self, i, j);
+SWIGINTERN void std_vector_Sl_int_Sg____delslice__(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::difference_type j){
+      swig::delslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_int_Sg____delitem__(std::vector<int > *self,std::vector<int >::difference_type i){
+SWIGINTERN void std_vector_Sl_int_Sg____delitem____SWIG_0(std::vector< int > *self,std::vector< int >::difference_type i){
       self->erase(swig::getpos(self,i));
     }
-SWIGINTERN std::vector<int >::value_type const &std_vector_Sl_int_Sg____getitem__(std::vector<int > const *self,std::vector<int >::difference_type i){
+SWIGINTERN std::vector< int,std::allocator< int > > *std_vector_Sl_int_Sg____getitem____SWIG_0(std::vector< int > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return NULL;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<int,std::allocator< int > >::difference_type id = i;
+      std::vector<int,std::allocator< int > >::difference_type jd = j;
+      return swig::getslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_0(std::vector< int > *self,PySliceObject *slice,std::vector< int,std::allocator< int > > const &v){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<int,std::allocator< int > >::difference_type id = i;
+      std::vector<int,std::allocator< int > >::difference_type jd = j;
+      swig::setslice(self, id, jd, step, v);
+    }
+SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_1(std::vector< int > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<int,std::allocator< int > >::difference_type id = i;
+      std::vector<int,std::allocator< int > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_int_Sg____delitem____SWIG_1(std::vector< int > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<int,std::allocator< int > >::difference_type id = i;
+      std::vector<int,std::allocator< int > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN std::vector< int >::value_type const &std_vector_Sl_int_Sg____getitem____SWIG_1(std::vector< int > const *self,std::vector< int >::difference_type i){
       return *(swig::cgetpos(self, i));
     }
-SWIGINTERN void std_vector_Sl_int_Sg____setitem__(std::vector<int > *self,std::vector<int >::difference_type i,std::vector<int >::value_type const &x){
+SWIGINTERN void std_vector_Sl_int_Sg____setitem____SWIG_2(std::vector< int > *self,std::vector< int >::difference_type i,std::vector< int >::value_type const &x){
       *(swig::getpos(self,i)) = x;
     }
-SWIGINTERN void std_vector_Sl_int_Sg__append(std::vector<int > *self,std::vector<int >::value_type const &x){
+SWIGINTERN void std_vector_Sl_int_Sg__append(std::vector< int > *self,std::vector< int >::value_type const &x){
       self->push_back(x);
     }
+SWIGINTERN std::vector< int >::iterator std_vector_Sl_int_Sg__erase__SWIG_0(std::vector< int > *self,std::vector< int >::iterator pos){ return self->erase(pos); }
+SWIGINTERN std::vector< int >::iterator std_vector_Sl_int_Sg__erase__SWIG_1(std::vector< int > *self,std::vector< int >::iterator first,std::vector< int >::iterator last){ return self->erase(first, last); }
+SWIGINTERN std::vector< int >::iterator std_vector_Sl_int_Sg__insert__SWIG_0(std::vector< int > *self,std::vector< int >::iterator pos,std::vector< int >::value_type const &x){ return self->insert(pos, x); }
+SWIGINTERN void std_vector_Sl_int_Sg__insert__SWIG_1(std::vector< int > *self,std::vector< int >::iterator pos,std::vector< int >::size_type n,std::vector< int >::value_type const &x){ self->insert(pos, n, x); }
 
   #define SWIG_From_double   PyFloat_FromDouble 
 
@@ -4082,98 +4761,200 @@ namespace swig {
 
 
       namespace swig {
-	template <>  struct traits<std::vector<double, std::allocator<double > > > {
+	template <>  struct traits<std::vector<double, std::allocator< double > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::vector<" "double" "," "std::allocator<double >" " >";
+	    return "std::vector<" "double" "," "std::allocator< double >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_vector_Sl_double_Sg__iterator(std::vector<double > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_vector_Sl_double_Sg__iterator(std::vector< double > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_vector_Sl_double_Sg____nonzero__(std::vector<double > const *self){
+SWIGINTERN bool std_vector_Sl_double_Sg____nonzero__(std::vector< double > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_vector_Sl_double_Sg____bool__(std::vector< double > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::vector<double >::size_type std_vector_Sl_double_Sg____len__(std::vector<double > const *self){
+SWIGINTERN std::vector< double >::size_type std_vector_Sl_double_Sg____len__(std::vector< double > const *self){
       return self->size();
     }
-SWIGINTERN std::vector<double >::value_type std_vector_Sl_double_Sg__pop(std::vector<double > *self){
+SWIGINTERN std::vector< double >::value_type std_vector_Sl_double_Sg__pop(std::vector< double > *self){
       if (self->size() == 0)
 	throw std::out_of_range("pop from empty container");
-      std::vector<double,std::allocator<double > >::value_type x = self->back();
+      std::vector<double,std::allocator< double > >::value_type x = self->back();
       self->pop_back();
       return x;
     }
-SWIGINTERN std::vector<double,std::allocator<double > > *std_vector_Sl_double_Sg____getslice__(std::vector<double > *self,std::vector<double >::difference_type i,std::vector<double >::difference_type j){
-      return swig::getslice(self, i, j);
+SWIGINTERN std::vector< double,std::allocator< double > > *std_vector_Sl_double_Sg____getslice__(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j){
+      return swig::getslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_double_Sg____setslice__(std::vector<double > *self,std::vector<double >::difference_type i,std::vector<double >::difference_type j,std::vector<double,std::allocator<double > > const &v){
-      swig::setslice(self, i, j, v);
+SWIGINTERN void std_vector_Sl_double_Sg____setslice____SWIG_0(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j,std::vector< double,std::allocator< double > > const &v=std::vector< double,std::allocator< double > >()){
+      swig::setslice(self, i, j, 1, v);
     }
-SWIGINTERN void std_vector_Sl_double_Sg____delslice__(std::vector<double > *self,std::vector<double >::difference_type i,std::vector<double >::difference_type j){
-      swig::delslice(self, i, j);
+SWIGINTERN void std_vector_Sl_double_Sg____delslice__(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::difference_type j){
+      swig::delslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_double_Sg____delitem__(std::vector<double > *self,std::vector<double >::difference_type i){
+SWIGINTERN void std_vector_Sl_double_Sg____delitem____SWIG_0(std::vector< double > *self,std::vector< double >::difference_type i){
       self->erase(swig::getpos(self,i));
     }
-SWIGINTERN std::vector<double >::value_type const &std_vector_Sl_double_Sg____getitem__(std::vector<double > const *self,std::vector<double >::difference_type i){
+SWIGINTERN std::vector< double,std::allocator< double > > *std_vector_Sl_double_Sg____getitem____SWIG_0(std::vector< double > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return NULL;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<double,std::allocator< double > >::difference_type id = i;
+      std::vector<double,std::allocator< double > >::difference_type jd = j;
+      return swig::getslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_0(std::vector< double > *self,PySliceObject *slice,std::vector< double,std::allocator< double > > const &v){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<double,std::allocator< double > >::difference_type id = i;
+      std::vector<double,std::allocator< double > >::difference_type jd = j;
+      swig::setslice(self, id, jd, step, v);
+    }
+SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_1(std::vector< double > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<double,std::allocator< double > >::difference_type id = i;
+      std::vector<double,std::allocator< double > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_double_Sg____delitem____SWIG_1(std::vector< double > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<double,std::allocator< double > >::difference_type id = i;
+      std::vector<double,std::allocator< double > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN std::vector< double >::value_type const &std_vector_Sl_double_Sg____getitem____SWIG_1(std::vector< double > const *self,std::vector< double >::difference_type i){
       return *(swig::cgetpos(self, i));
     }
-SWIGINTERN void std_vector_Sl_double_Sg____setitem__(std::vector<double > *self,std::vector<double >::difference_type i,std::vector<double >::value_type const &x){
+SWIGINTERN void std_vector_Sl_double_Sg____setitem____SWIG_2(std::vector< double > *self,std::vector< double >::difference_type i,std::vector< double >::value_type const &x){
       *(swig::getpos(self,i)) = x;
     }
-SWIGINTERN void std_vector_Sl_double_Sg__append(std::vector<double > *self,std::vector<double >::value_type const &x){
+SWIGINTERN void std_vector_Sl_double_Sg__append(std::vector< double > *self,std::vector< double >::value_type const &x){
       self->push_back(x);
     }
+SWIGINTERN std::vector< double >::iterator std_vector_Sl_double_Sg__erase__SWIG_0(std::vector< double > *self,std::vector< double >::iterator pos){ return self->erase(pos); }
+SWIGINTERN std::vector< double >::iterator std_vector_Sl_double_Sg__erase__SWIG_1(std::vector< double > *self,std::vector< double >::iterator first,std::vector< double >::iterator last){ return self->erase(first, last); }
+SWIGINTERN std::vector< double >::iterator std_vector_Sl_double_Sg__insert__SWIG_0(std::vector< double > *self,std::vector< double >::iterator pos,std::vector< double >::value_type const &x){ return self->insert(pos, x); }
+SWIGINTERN void std_vector_Sl_double_Sg__insert__SWIG_1(std::vector< double > *self,std::vector< double >::iterator pos,std::vector< double >::size_type n,std::vector< double >::value_type const &x){ self->insert(pos, n, x); }
 
       namespace swig {
-	template <>  struct traits<std::vector<std::vector<double,std::allocator<double > >, std::allocator<std::vector<double,std::allocator<double > > > > > {
+	template <>  struct traits<std::vector<std::vector< double,std::allocator< double > >, std::allocator< std::vector< double,std::allocator< double > > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::vector<" "std::vector<double,std::allocator<double > >" "," "std::allocator<std::vector<double,std::allocator<double > > >" " >";
+	    return "std::vector<" "std::vector< double,std::allocator< double > >" "," "std::allocator< std::vector< double,std::allocator< double > > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_vector_Sl_std_vector_Sl_double_Sg__Sg__iterator(std::vector<std::vector<double > > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_vector_Sl_std_vector_Sl_double_Sg__Sg__iterator(std::vector< std::vector< double > > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_vector_Sl_std_vector_Sl_double_Sg__Sg____nonzero__(std::vector<std::vector<double > > const *self){
+SWIGINTERN bool std_vector_Sl_std_vector_Sl_double_Sg__Sg____nonzero__(std::vector< std::vector< double > > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_vector_Sl_std_vector_Sl_double_Sg__Sg____bool__(std::vector< std::vector< double > > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::vector<std::vector<double > >::size_type std_vector_Sl_std_vector_Sl_double_Sg__Sg____len__(std::vector<std::vector<double > > const *self){
+SWIGINTERN std::vector< std::vector< double > >::size_type std_vector_Sl_std_vector_Sl_double_Sg__Sg____len__(std::vector< std::vector< double > > const *self){
       return self->size();
     }
-SWIGINTERN std::vector<std::vector<double > >::value_type std_vector_Sl_std_vector_Sl_double_Sg__Sg__pop(std::vector<std::vector<double > > *self){
+SWIGINTERN std::vector< std::vector< double > >::value_type std_vector_Sl_std_vector_Sl_double_Sg__Sg__pop(std::vector< std::vector< double > > *self){
       if (self->size() == 0)
 	throw std::out_of_range("pop from empty container");
-      std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >::value_type x = self->back();
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::value_type x = self->back();
       self->pop_back();
       return x;
     }
-SWIGINTERN std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *std_vector_Sl_std_vector_Sl_double_Sg__Sg____getslice__(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::difference_type i,std::vector<std::vector<double > >::difference_type j){
-      return swig::getslice(self, i, j);
+SWIGINTERN std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *std_vector_Sl_std_vector_Sl_double_Sg__Sg____getslice__(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::difference_type i,std::vector< std::vector< double > >::difference_type j){
+      return swig::getslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setslice__(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::difference_type i,std::vector<std::vector<double > >::difference_type j,std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > const &v){
-      swig::setslice(self, i, j, v);
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setslice____SWIG_0(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::difference_type i,std::vector< std::vector< double > >::difference_type j,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &v=std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double >  [...]
+      swig::setslice(self, i, j, 1, v);
     }
-SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____delslice__(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::difference_type i,std::vector<std::vector<double > >::difference_type j){
-      swig::delslice(self, i, j);
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____delslice__(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::difference_type i,std::vector< std::vector< double > >::difference_type j){
+      swig::delslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem__(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::difference_type i){
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem____SWIG_0(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::difference_type i){
       self->erase(swig::getpos(self,i));
     }
-SWIGINTERN std::vector<std::vector<double > >::value_type const &std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem__(std::vector<std::vector<double > > const *self,std::vector<std::vector<double > >::difference_type i){
+SWIGINTERN std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem____SWIG_0(std::vector< std::vector< double > > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return NULL;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type id = i;
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type jd = j;
+      return swig::getslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_0(std::vector< std::vector< double > > *self,PySliceObject *slice,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &v){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type id = i;
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type jd = j;
+      swig::setslice(self, id, jd, step, v);
+    }
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_1(std::vector< std::vector< double > > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type id = i;
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem____SWIG_1(std::vector< std::vector< double > > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type id = i;
+      std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN std::vector< std::vector< double > >::value_type const &std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem____SWIG_1(std::vector< std::vector< double > > const *self,std::vector< std::vector< double > >::difference_type i){
       return *(swig::cgetpos(self, i));
     }
-SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem__(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::difference_type i,std::vector<std::vector<double > >::value_type const &x){
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_2(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::difference_type i,std::vector< std::vector< double > >::value_type const &x){
       *(swig::getpos(self,i)) = x;
     }
-SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg__append(std::vector<std::vector<double > > *self,std::vector<std::vector<double > >::value_type const &x){
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg__append(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::value_type const &x){
       self->push_back(x);
     }
+SWIGINTERN std::vector< std::vector< double > >::iterator std_vector_Sl_std_vector_Sl_double_Sg__Sg__erase__SWIG_0(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::iterator pos){ return self->erase(pos); }
+SWIGINTERN std::vector< std::vector< double > >::iterator std_vector_Sl_std_vector_Sl_double_Sg__Sg__erase__SWIG_1(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::iterator first,std::vector< std::vector< double > >::iterator last){ return self->erase(first, last); }
+SWIGINTERN std::vector< std::vector< double > >::iterator std_vector_Sl_std_vector_Sl_double_Sg__Sg__insert__SWIG_0(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::iterator pos,std::vector< std::vector< double > >::value_type const &x){ return self->insert(pos, x); }
+SWIGINTERN void std_vector_Sl_std_vector_Sl_double_Sg__Sg__insert__SWIG_1(std::vector< std::vector< double > > *self,std::vector< std::vector< double > >::iterator pos,std::vector< std::vector< double > >::size_type n,std::vector< std::vector< double > >::value_type const &x){ self->insert(pos, n, x); }
 
 SWIGINTERN swig_type_info*
 SWIG_pchar_descriptor(void)
@@ -4191,10 +4972,28 @@ SWIG_pchar_descriptor(void)
 SWIGINTERN int
 SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
 {
-  if (PyString_Check(obj)) {
+#if PY_VERSION_HEX>=0x03000000
+  if (PyUnicode_Check(obj))
+#else  
+  if (PyString_Check(obj))
+#endif
+  {
     char *cstr; Py_ssize_t len;
+#if PY_VERSION_HEX>=0x03000000
+    if (!alloc && cptr) {
+        /* We can't allow converting without allocation, since the internal
+           representation of string in Python 3 is UCS-2/UCS-4 but we require
+           a UTF-8 representation.
+           TODO(bhy) More detailed explanation */
+        return SWIG_RuntimeError;
+    }
+    obj = PyUnicode_AsUTF8String(obj);
+    PyBytes_AsStringAndSize(obj, &cstr, &len);
+    if(alloc) *alloc = SWIG_NEWOBJ;
+#else
     PyString_AsStringAndSize(obj, &cstr, &len);
-    if (cptr)  {
+#endif
+    if (cptr) {
       if (alloc) {
 	/* 
 	   In python the user should not be able to modify the inner
@@ -4219,10 +5018,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
 	  *alloc = SWIG_OLDOBJ;
 	}
       } else {
-	*cptr = PyString_AsString(obj);
+        #if PY_VERSION_HEX>=0x03000000
+        assert(0); /* Should never reach here in Python 3 */
+        #endif
+	*cptr = SWIG_Python_str_AsChar(obj);
       }
     }
     if (psize) *psize = len + 1;
+#if PY_VERSION_HEX>=0x03000000
+    Py_XDECREF(obj);
+#endif
     return SWIG_OK;
   } else {
     swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
@@ -4296,9 +5101,17 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size)
     if (size > INT_MAX) {
       swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
       return pchar_descriptor ? 
-	SWIG_NewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
+	SWIG_InternalNewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
     } else {
+#if PY_VERSION_HEX >= 0x03000000
+#if PY_VERSION_HEX >= 0x03010000
+      return PyUnicode_DecodeUTF8(carray, static_cast< int >(size), "surrogateescape");
+#else
+      return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
+#endif
+#else
       return PyString_FromStringAndSize(carray, static_cast< int >(size));
+#endif
     }
   } else {
     return SWIG_Py_Void();
@@ -4309,11 +5122,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size)
 SWIGINTERNINLINE PyObject *
 SWIG_From_std_string  (const std::string& s)
 {
-  if (s.size()) {
-    return SWIG_FromCharPtrAndSize(s.data(), s.size());
-  } else {
-    return SWIG_FromCharPtrAndSize(s.c_str(), 0);
-  }
+  return SWIG_FromCharPtrAndSize(s.data(), s.size());
 }
 
 
@@ -4338,51 +5147,102 @@ namespace swig {
 
 
       namespace swig {
-	template <>  struct traits<std::vector<std::string, std::allocator<std::string > > > {
+	template <>  struct traits<std::vector<std::string, std::allocator< std::string > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::vector<" "std::string" "," "std::allocator<std::string >" " >";
+	    return "std::vector<" "std::string" "," "std::allocator< std::string >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_vector_Sl_std_string_Sg__iterator(std::vector<std::string > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_vector_Sl_std_string_Sg__iterator(std::vector< std::string > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_vector_Sl_std_string_Sg____nonzero__(std::vector<std::string > const *self){
+SWIGINTERN bool std_vector_Sl_std_string_Sg____nonzero__(std::vector< std::string > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_vector_Sl_std_string_Sg____bool__(std::vector< std::string > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::vector<std::string >::size_type std_vector_Sl_std_string_Sg____len__(std::vector<std::string > const *self){
+SWIGINTERN std::vector< std::string >::size_type std_vector_Sl_std_string_Sg____len__(std::vector< std::string > const *self){
       return self->size();
     }
-SWIGINTERN std::vector<std::string >::value_type std_vector_Sl_std_string_Sg__pop(std::vector<std::string > *self){
+SWIGINTERN std::vector< std::string >::value_type std_vector_Sl_std_string_Sg__pop(std::vector< std::string > *self){
       if (self->size() == 0)
 	throw std::out_of_range("pop from empty container");
-      std::vector<std::string,std::allocator<std::string > >::value_type x = self->back();
+      std::vector<std::string,std::allocator< std::string > >::value_type x = self->back();
       self->pop_back();
       return x;
     }
-SWIGINTERN std::vector<std::string,std::allocator<std::string > > *std_vector_Sl_std_string_Sg____getslice__(std::vector<std::string > *self,std::vector<std::string >::difference_type i,std::vector<std::string >::difference_type j){
-      return swig::getslice(self, i, j);
+SWIGINTERN std::vector< std::string,std::allocator< std::string > > *std_vector_Sl_std_string_Sg____getslice__(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j){
+      return swig::getslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_std_string_Sg____setslice__(std::vector<std::string > *self,std::vector<std::string >::difference_type i,std::vector<std::string >::difference_type j,std::vector<std::string,std::allocator<std::string > > const &v){
-      swig::setslice(self, i, j, v);
+SWIGINTERN void std_vector_Sl_std_string_Sg____setslice____SWIG_0(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j,std::vector< std::string,std::allocator< std::string > > const &v=std::vector< std::string,std::allocator< std::string > >()){
+      swig::setslice(self, i, j, 1, v);
     }
-SWIGINTERN void std_vector_Sl_std_string_Sg____delslice__(std::vector<std::string > *self,std::vector<std::string >::difference_type i,std::vector<std::string >::difference_type j){
-      swig::delslice(self, i, j);
+SWIGINTERN void std_vector_Sl_std_string_Sg____delslice__(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::difference_type j){
+      swig::delslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_std_string_Sg____delitem__(std::vector<std::string > *self,std::vector<std::string >::difference_type i){
+SWIGINTERN void std_vector_Sl_std_string_Sg____delitem____SWIG_0(std::vector< std::string > *self,std::vector< std::string >::difference_type i){
       self->erase(swig::getpos(self,i));
     }
-SWIGINTERN std::vector<std::string >::value_type const &std_vector_Sl_std_string_Sg____getitem__(std::vector<std::string > const *self,std::vector<std::string >::difference_type i){
+SWIGINTERN std::vector< std::string,std::allocator< std::string > > *std_vector_Sl_std_string_Sg____getitem____SWIG_0(std::vector< std::string > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return NULL;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::string,std::allocator< std::string > >::difference_type id = i;
+      std::vector<std::string,std::allocator< std::string > >::difference_type jd = j;
+      return swig::getslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_0(std::vector< std::string > *self,PySliceObject *slice,std::vector< std::string,std::allocator< std::string > > const &v){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::string,std::allocator< std::string > >::difference_type id = i;
+      std::vector<std::string,std::allocator< std::string > >::difference_type jd = j;
+      swig::setslice(self, id, jd, step, v);
+    }
+SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_1(std::vector< std::string > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::string,std::allocator< std::string > >::difference_type id = i;
+      std::vector<std::string,std::allocator< std::string > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_std_string_Sg____delitem____SWIG_1(std::vector< std::string > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<std::string,std::allocator< std::string > >::difference_type id = i;
+      std::vector<std::string,std::allocator< std::string > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN std::vector< std::string >::value_type const &std_vector_Sl_std_string_Sg____getitem____SWIG_1(std::vector< std::string > const *self,std::vector< std::string >::difference_type i){
       return *(swig::cgetpos(self, i));
     }
-SWIGINTERN void std_vector_Sl_std_string_Sg____setitem__(std::vector<std::string > *self,std::vector<std::string >::difference_type i,std::vector<std::string >::value_type const &x){
+SWIGINTERN void std_vector_Sl_std_string_Sg____setitem____SWIG_2(std::vector< std::string > *self,std::vector< std::string >::difference_type i,std::vector< std::string >::value_type const &x){
       *(swig::getpos(self,i)) = x;
     }
-SWIGINTERN void std_vector_Sl_std_string_Sg__append(std::vector<std::string > *self,std::vector<std::string >::value_type const &x){
+SWIGINTERN void std_vector_Sl_std_string_Sg__append(std::vector< std::string > *self,std::vector< std::string >::value_type const &x){
       self->push_back(x);
     }
+SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__erase__SWIG_0(std::vector< std::string > *self,std::vector< std::string >::iterator pos){ return self->erase(pos); }
+SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__erase__SWIG_1(std::vector< std::string > *self,std::vector< std::string >::iterator first,std::vector< std::string >::iterator last){ return self->erase(first, last); }
+SWIGINTERN std::vector< std::string >::iterator std_vector_Sl_std_string_Sg__insert__SWIG_0(std::vector< std::string > *self,std::vector< std::string >::iterator pos,std::vector< std::string >::value_type const &x){ return self->insert(pos, x); }
+SWIGINTERN void std_vector_Sl_std_string_Sg__insert__SWIG_1(std::vector< std::string > *self,std::vector< std::string >::iterator pos,std::vector< std::string >::size_type n,std::vector< std::string >::value_type const &x){ self->insert(pos, n, x); }
 
   namespace swig {
     template <>  struct traits<CdiVariable > {
@@ -4393,51 +5253,102 @@ SWIGINTERN void std_vector_Sl_std_string_Sg__append(std::vector<std::string > *s
 
 
       namespace swig {
-	template <>  struct traits<std::vector<CdiVariable, std::allocator<CdiVariable > > > {
+	template <>  struct traits<std::vector<CdiVariable, std::allocator< CdiVariable > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::vector<" "CdiVariable" "," "std::allocator<CdiVariable >" " >";
+	    return "std::vector<" "CdiVariable" "," "std::allocator< CdiVariable >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_vector_Sl_CdiVariable_Sg__iterator(std::vector<CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_vector_Sl_CdiVariable_Sg__iterator(std::vector< CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_vector_Sl_CdiVariable_Sg____nonzero__(std::vector<CdiVariable > const *self){
+SWIGINTERN bool std_vector_Sl_CdiVariable_Sg____nonzero__(std::vector< CdiVariable > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_vector_Sl_CdiVariable_Sg____bool__(std::vector< CdiVariable > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::vector<CdiVariable >::size_type std_vector_Sl_CdiVariable_Sg____len__(std::vector<CdiVariable > const *self){
+SWIGINTERN std::vector< CdiVariable >::size_type std_vector_Sl_CdiVariable_Sg____len__(std::vector< CdiVariable > const *self){
       return self->size();
     }
-SWIGINTERN std::vector<CdiVariable >::value_type std_vector_Sl_CdiVariable_Sg__pop(std::vector<CdiVariable > *self){
+SWIGINTERN std::vector< CdiVariable >::value_type std_vector_Sl_CdiVariable_Sg__pop(std::vector< CdiVariable > *self){
       if (self->size() == 0)
 	throw std::out_of_range("pop from empty container");
-      std::vector<CdiVariable,std::allocator<CdiVariable > >::value_type x = self->back();
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::value_type x = self->back();
       self->pop_back();
       return x;
     }
-SWIGINTERN std::vector<CdiVariable,std::allocator<CdiVariable > > *std_vector_Sl_CdiVariable_Sg____getslice__(std::vector<CdiVariable > *self,std::vector<CdiVariable >::difference_type i,std::vector<CdiVariable >::difference_type j){
-      return swig::getslice(self, i, j);
+SWIGINTERN std::vector< CdiVariable,std::allocator< CdiVariable > > *std_vector_Sl_CdiVariable_Sg____getslice__(std::vector< CdiVariable > *self,std::vector< CdiVariable >::difference_type i,std::vector< CdiVariable >::difference_type j){
+      return swig::getslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setslice__(std::vector<CdiVariable > *self,std::vector<CdiVariable >::difference_type i,std::vector<CdiVariable >::difference_type j,std::vector<CdiVariable,std::allocator<CdiVariable > > const &v){
-      swig::setslice(self, i, j, v);
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setslice____SWIG_0(std::vector< CdiVariable > *self,std::vector< CdiVariable >::difference_type i,std::vector< CdiVariable >::difference_type j,std::vector< CdiVariable,std::allocator< CdiVariable > > const &v=std::vector< CdiVariable,std::allocator< CdiVariable > >()){
+      swig::setslice(self, i, j, 1, v);
     }
-SWIGINTERN void std_vector_Sl_CdiVariable_Sg____delslice__(std::vector<CdiVariable > *self,std::vector<CdiVariable >::difference_type i,std::vector<CdiVariable >::difference_type j){
-      swig::delslice(self, i, j);
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____delslice__(std::vector< CdiVariable > *self,std::vector< CdiVariable >::difference_type i,std::vector< CdiVariable >::difference_type j){
+      swig::delslice(self, i, j, 1);
     }
-SWIGINTERN void std_vector_Sl_CdiVariable_Sg____delitem__(std::vector<CdiVariable > *self,std::vector<CdiVariable >::difference_type i){
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____delitem____SWIG_0(std::vector< CdiVariable > *self,std::vector< CdiVariable >::difference_type i){
       self->erase(swig::getpos(self,i));
     }
-SWIGINTERN std::vector<CdiVariable >::value_type const &std_vector_Sl_CdiVariable_Sg____getitem__(std::vector<CdiVariable > const *self,std::vector<CdiVariable >::difference_type i){
+SWIGINTERN std::vector< CdiVariable,std::allocator< CdiVariable > > *std_vector_Sl_CdiVariable_Sg____getitem____SWIG_0(std::vector< CdiVariable > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return NULL;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type id = i;
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type jd = j;
+      return swig::getslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setitem____SWIG_0(std::vector< CdiVariable > *self,PySliceObject *slice,std::vector< CdiVariable,std::allocator< CdiVariable > > const &v){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type id = i;
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type jd = j;
+      swig::setslice(self, id, jd, step, v);
+    }
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setitem____SWIG_1(std::vector< CdiVariable > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type id = i;
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____delitem____SWIG_1(std::vector< CdiVariable > *self,PySliceObject *slice){
+      Py_ssize_t i, j, step;
+      if( !PySlice_Check(slice) ) {
+        SWIG_Error(SWIG_TypeError, "Slice object expected.");
+        return;
+      }
+      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type id = i;
+      std::vector<CdiVariable,std::allocator< CdiVariable > >::difference_type jd = j;
+      swig::delslice(self, id, jd, step);
+    }
+SWIGINTERN std::vector< CdiVariable >::value_type const &std_vector_Sl_CdiVariable_Sg____getitem____SWIG_1(std::vector< CdiVariable > const *self,std::vector< CdiVariable >::difference_type i){
       return *(swig::cgetpos(self, i));
     }
-SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setitem__(std::vector<CdiVariable > *self,std::vector<CdiVariable >::difference_type i,std::vector<CdiVariable >::value_type const &x){
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg____setitem____SWIG_2(std::vector< CdiVariable > *self,std::vector< CdiVariable >::difference_type i,std::vector< CdiVariable >::value_type const &x){
       *(swig::getpos(self,i)) = x;
     }
-SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *self,std::vector<CdiVariable >::value_type const &x){
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector< CdiVariable > *self,std::vector< CdiVariable >::value_type const &x){
       self->push_back(x);
     }
+SWIGINTERN std::vector< CdiVariable >::iterator std_vector_Sl_CdiVariable_Sg__erase__SWIG_0(std::vector< CdiVariable > *self,std::vector< CdiVariable >::iterator pos){ return self->erase(pos); }
+SWIGINTERN std::vector< CdiVariable >::iterator std_vector_Sl_CdiVariable_Sg__erase__SWIG_1(std::vector< CdiVariable > *self,std::vector< CdiVariable >::iterator first,std::vector< CdiVariable >::iterator last){ return self->erase(first, last); }
+SWIGINTERN std::vector< CdiVariable >::iterator std_vector_Sl_CdiVariable_Sg__insert__SWIG_0(std::vector< CdiVariable > *self,std::vector< CdiVariable >::iterator pos,std::vector< CdiVariable >::value_type const &x){ return self->insert(pos, x); }
+SWIGINTERN void std_vector_Sl_CdiVariable_Sg__insert__SWIG_1(std::vector< CdiVariable > *self,std::vector< CdiVariable >::iterator pos,std::vector< CdiVariable >::size_type n,std::vector< CdiVariable >::value_type const &x){ self->insert(pos, n, x); }
 
   namespace swig {
 
@@ -4525,8 +5436,8 @@ SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *
 	  }
 	} else if (PySequence_Check(obj)) {
 	  if (PySequence_Size(obj) == 2) {
-	    swig::PyObject_var first = PySequence_GetItem(obj,0);
-	    swig::PyObject_var second = PySequence_GetItem(obj,1);
+	    swig::SwigVar_PyObject first = PySequence_GetItem(obj,0);
+	    swig::SwigVar_PyObject second = PySequence_GetItem(obj,1);
 	    res = get_pair(first, second, val);
 	  }
 	} else {
@@ -4551,6 +5462,41 @@ SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *
   }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
       namespace swig {
 	template <>  struct traits<std::pair< std::string, CdiVariable > > {
 	  typedef pointer_category category;
@@ -4562,64 +5508,6 @@ SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *
     
 
   namespace swig {
-    template <class PySeq, class K, class T >
-    inline void
-    assign(const PySeq& pyseq, std::map<K,T > *map) {
-      typedef typename std::map<K,T>::value_type value_type;
-      typename PySeq::const_iterator it = pyseq.begin();
-      for (;it != pyseq.end(); ++it) {
-	map->insert(value_type(it->first, it->second));
-      }
-    }
-
-    template <class K, class T>
-    struct traits_asptr<std::map<K,T> >  {
-      typedef std::map<K,T> map_type;
-      static int asptr(PyObject *obj, map_type **val) {
-	int res = SWIG_ERROR;
-	if (PyDict_Check(obj)) {
-	  PyObject_var items = PyMapping_Items(obj);
-	  res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val);
-	} else {
-	  map_type *p;
-	  res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<map_type>(),0);
-	  if (SWIG_IsOK(res) && val)  *val = p;
-	}
-	return res;
-      }      
-    };
-      
-    template <class K, class T >
-    struct traits_from<std::map<K,T> >  {
-      typedef std::map<K,T> map_type;
-      typedef typename map_type::const_iterator const_iterator;
-      typedef typename map_type::size_type size_type;
-            
-      static PyObject *from(const map_type& map) {
-	swig_type_info *desc = swig::type_info<map_type>();
-	if (desc && desc->clientdata) {
-	  return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN);
-	} else {
-	  size_type size = map.size();
-	  int pysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
-	  if (pysize < 0) {
-	    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-	    PyErr_SetString(PyExc_OverflowError,
-			    "map size not valid in python");
-	    SWIG_PYTHON_THREAD_END_BLOCK;
-	    return NULL;
-	  }
-	  PyObject *obj = PyDict_New();
-	  for (const_iterator i= map.begin(); i!= map.end(); ++i) {
-	    swig::PyObject_var key = swig::from(i->first);
-	    swig::PyObject_var val = swig::from(i->second);
-	    PyDict_SetItem(obj, key, val);
-	  }
-	  return obj;
-	}
-      }
-    };
-
     template <class ValueType>
     struct from_key_oper 
     {
@@ -4643,10 +5531,10 @@ SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *
     };
 
     template<class OutIterator, class FromOper, class ValueType = typename OutIterator::value_type>
-    struct PyMapIterator_T : PySwigIteratorClosed_T<OutIterator, ValueType, FromOper>
+    struct SwigPyMapIterator_T : SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper>
     {
-      PyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
-	: PySwigIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
+      SwigPyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
+	: SwigPyIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
       {
       }
     };
@@ -4654,140 +5542,226 @@ SWIGINTERN void std_vector_Sl_CdiVariable_Sg__append(std::vector<CdiVariable > *
 
     template<class OutIterator,
 	     class FromOper = from_key_oper<typename OutIterator::value_type> >
-    struct PyMapKeyIterator_T : PyMapIterator_T<OutIterator, FromOper>
+    struct SwigPyMapKeyIterator_T : SwigPyMapIterator_T<OutIterator, FromOper>
     {
-      PyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
-	: PyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
+      SwigPyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
+	: SwigPyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
       {
       }
     };
 
     template<typename OutIter>
-    inline PySwigIterator*
+    inline SwigPyIterator*
     make_output_key_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
     {
-      return new PyMapKeyIterator_T<OutIter>(current, begin, end, seq);
+      return new SwigPyMapKeyIterator_T<OutIter>(current, begin, end, seq);
     }
 
     template<class OutIterator,
 	     class FromOper = from_value_oper<typename OutIterator::value_type> >
-    struct PyMapValueIterator_T : PyMapIterator_T<OutIterator, FromOper>
+    struct SwigPyMapValueITerator_T : SwigPyMapIterator_T<OutIterator, FromOper>
     {
-      PyMapValueIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
-	: PyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
+      SwigPyMapValueITerator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq)
+	: SwigPyMapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
       {
       }
     };
     
 
     template<typename OutIter>
-    inline PySwigIterator*
+    inline SwigPyIterator*
     make_output_value_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0)
     {
-      return new PyMapValueIterator_T<OutIter>(current, begin, end, seq);
+      return new SwigPyMapValueITerator_T<OutIter>(current, begin, end, seq);
+    }
+  }
+
+
+  namespace swig {
+    template <class SwigPySeq, class K, class T, class Compare, class Alloc >
+    inline void
+    assign(const SwigPySeq& swigpyseq, std::map<K,T,Compare,Alloc > *map) {
+      typedef typename std::map<K,T,Compare,Alloc >::value_type value_type;
+      typename SwigPySeq::const_iterator it = swigpyseq.begin();
+      for (;it != swigpyseq.end(); ++it) {
+	map->insert(value_type(it->first, it->second));
+      }
     }
+
+    template <class K, class T, class Compare, class Alloc>
+    struct traits_asptr<std::map<K,T,Compare,Alloc > >  {
+      typedef std::map<K,T,Compare,Alloc > map_type;
+      static int asptr(PyObject *obj, map_type **val) {
+	int res = SWIG_ERROR;
+	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+	if (PyDict_Check(obj)) {
+	  SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL);
+#if PY_VERSION_HEX >= 0x03000000
+          /* In Python 3.x the ".items()" method returns a dict_items object */
+          items = PySequence_Fast(items, ".items() didn't return a sequence!");
+#endif
+	  res = traits_asptr_stdseq<map_type, std::pair<K, T> >::asptr(items, val);
+	} else {
+	  map_type *p;
+	  res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<map_type>(),0);
+	  if (SWIG_IsOK(res) && val)  *val = p;
+	}
+	SWIG_PYTHON_THREAD_END_BLOCK;
+	return res;
+      }      
+    };
+      
+    template <class K, class T, class Compare, class Alloc >
+    struct traits_from<std::map<K,T,Compare,Alloc > >  {
+      typedef std::map<K,T,Compare,Alloc > map_type;
+      typedef typename map_type::const_iterator const_iterator;
+      typedef typename map_type::size_type size_type;
+
+      static PyObject *asdict(const map_type& map) {
+	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+	size_type size = map.size();
+	int pysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
+	if (pysize < 0) {
+	  PyErr_SetString(PyExc_OverflowError,
+			  "map size not valid in python");
+	  SWIG_PYTHON_THREAD_END_BLOCK;
+	  return NULL;
+	}
+	PyObject *obj = PyDict_New();
+	for (const_iterator i= map.begin(); i!= map.end(); ++i) {
+	  swig::SwigVar_PyObject key = swig::from(i->first);
+	  swig::SwigVar_PyObject val = swig::from(i->second);
+	  PyDict_SetItem(obj, key, val);
+	}
+	SWIG_PYTHON_THREAD_END_BLOCK;
+	return obj;
+      }
+                
+      static PyObject *from(const map_type& map) {
+	swig_type_info *desc = swig::type_info<map_type>();
+	if (desc && desc->clientdata) {
+	  return SWIG_InternalNewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN);
+	} else {
+	  return asdict(map);
+	}
+      }
+    };
   }
 
 
       namespace swig {
-	template <>  struct traits<std::map<std::string, CdiVariable, std::less<std::string >, std::allocator<std::pair<std::string const,CdiVariable > > > > {
+	template <>  struct traits<std::map<std::string, CdiVariable, std::less< std::string >, std::allocator< std::pair< std::string const,CdiVariable > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::map<" "std::string" "," "CdiVariable" "," "std::less<std::string >" "," "std::allocator<std::pair<std::string const,CdiVariable > >" " >";
+	    return "std::map<" "std::string" "," "CdiVariable" "," "std::less< std::string >" "," "std::allocator< std::pair< std::string const,CdiVariable > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__iterator(std::map<std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__iterator(std::map< std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg____nonzero__(std::map<std::string,CdiVariable > const *self){
+SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg____nonzero__(std::map< std::string,CdiVariable > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg____bool__(std::map< std::string,CdiVariable > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::map<std::string,CdiVariable >::size_type std_map_Sl_std_string_Sc_CdiVariable_Sg____len__(std::map<std::string,CdiVariable > const *self){
+SWIGINTERN std::map< std::string,CdiVariable >::size_type std_map_Sl_std_string_Sc_CdiVariable_Sg____len__(std::map< std::string,CdiVariable > const *self){
       return self->size();
     }
-SWIGINTERN std::map<std::string,CdiVariable >::mapped_type std_map_Sl_std_string_Sc_CdiVariable_Sg____getitem__(std::map<std::string,CdiVariable > const *self,std::map<std::string,CdiVariable >::key_type const &key){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::const_iterator i = self->find(key);
+SWIGINTERN std::map< std::string,CdiVariable >::mapped_type const &std_map_Sl_std_string_Sc_CdiVariable_Sg____getitem__(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::key_type const &key){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::const_iterator i = self->find(key);
       if (i != self->end())
 	return i->second;
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____delitem__(std::map<std::string,CdiVariable > *self,std::map<std::string,CdiVariable >::key_type const &key){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::iterator i = self->find(key);
+SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____delitem__(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::key_type const &key){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::iterator i = self->find(key);
       if (i != self->end())
 	self->erase(i);
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg__has_key(std::map<std::string,CdiVariable > const *self,std::map<std::string,CdiVariable >::key_type const &key){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::const_iterator i = self->find(key);
+SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg__has_key(std::map< std::string,CdiVariable > const *self,std::map< std::string,CdiVariable >::key_type const &key){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::const_iterator i = self->find(key);
       return i != self->end();
     }
-SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__keys(std::map<std::string,CdiVariable > *self){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__keys(std::map< std::string,CdiVariable > *self){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* keyList = PyList_New(pysize);
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(keyList, j, swig::from(i->first));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return keyList;
     }
-SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__values(std::map<std::string,CdiVariable > *self){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__values(std::map< std::string,CdiVariable > *self){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* valList = PyList_New(pysize);
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(valList, j, swig::from(i->second));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return valList;
     }
-SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__items(std::map<std::string,CdiVariable > *self){
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__items(std::map< std::string,CdiVariable > *self){
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }    
       PyObject* itemList = PyList_New(pysize);
-      std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(itemList, j, swig::from(*i));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return itemList;
     }
-SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg____contains__(std::map<std::string,CdiVariable > *self,std::map<std::string,CdiVariable >::key_type const &key){
+SWIGINTERN bool std_map_Sl_std_string_Sc_CdiVariable_Sg____contains__(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::key_type const &key){
       return self->find(key) != self->end();
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__key_iterator(std::map<std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__key_iterator(std::map< std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__value_iterator(std::map<std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_std_string_Sc_CdiVariable_Sg__value_iterator(std::map< std::string,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem__(std::map<std::string,CdiVariable > *self,std::map<std::string,CdiVariable >::key_type const &key,std::map<std::string,CdiVariable >::mapped_type const &x){
+SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem____SWIG_0(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::key_type const &key){
+      self->erase(key);
+    }
+SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem____SWIG_1(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::key_type const &key,std::map< std::string,CdiVariable >::mapped_type const &x){
       (*self)[key] = x;
     }
+SWIGINTERN PyObject *std_map_Sl_std_string_Sc_CdiVariable_Sg__asdict(std::map< std::string,CdiVariable > *self){
+      return swig::traits_from< std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > >::asdict(*self);
+    }
+SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg__erase__SWIG_1(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::iterator position){ self->erase(position); }
+SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg__erase__SWIG_2(std::map< std::string,CdiVariable > *self,std::map< std::string,CdiVariable >::iterator first,std::map< std::string,CdiVariable >::iterator last){ self->erase(first, last); }
 
       namespace swig {
 	template <>  struct traits<std::pair< int, CdiVariable > > {
@@ -4800,104 +5774,118 @@ SWIGINTERN void std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem__(std::map<st
     
 
       namespace swig {
-	template <>  struct traits<std::map<int, CdiVariable, std::less<int >, std::allocator<std::pair<int const,CdiVariable > > > > {
+	template <>  struct traits<std::map<int, CdiVariable, std::less< int >, std::allocator< std::pair< int const,CdiVariable > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::map<" "int" "," "CdiVariable" "," "std::less<int >" "," "std::allocator<std::pair<int const,CdiVariable > >" " >";
+	    return "std::map<" "int" "," "CdiVariable" "," "std::less< int >" "," "std::allocator< std::pair< int const,CdiVariable > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiVariable_Sg__iterator(std::map<int,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiVariable_Sg__iterator(std::map< int,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg____nonzero__(std::map<int,CdiVariable > const *self){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg____nonzero__(std::map< int,CdiVariable > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg____bool__(std::map< int,CdiVariable > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::map<int,CdiVariable >::size_type std_map_Sl_int_Sc_CdiVariable_Sg____len__(std::map<int,CdiVariable > const *self){
+SWIGINTERN std::map< int,CdiVariable >::size_type std_map_Sl_int_Sc_CdiVariable_Sg____len__(std::map< int,CdiVariable > const *self){
       return self->size();
     }
-SWIGINTERN std::map<int,CdiVariable >::mapped_type std_map_Sl_int_Sc_CdiVariable_Sg____getitem__(std::map<int,CdiVariable > const *self,std::map<int,CdiVariable >::key_type const &key){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::const_iterator i = self->find(key);
+SWIGINTERN std::map< int,CdiVariable >::mapped_type const &std_map_Sl_int_Sc_CdiVariable_Sg____getitem__(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::key_type const &key){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::const_iterator i = self->find(key);
       if (i != self->end())
 	return i->second;
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____delitem__(std::map<int,CdiVariable > *self,std::map<int,CdiVariable >::key_type const &key){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::iterator i = self->find(key);
+SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____delitem__(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::key_type const &key){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::iterator i = self->find(key);
       if (i != self->end())
 	self->erase(i);
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg__has_key(std::map<int,CdiVariable > const *self,std::map<int,CdiVariable >::key_type const &key){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::const_iterator i = self->find(key);
+SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg__has_key(std::map< int,CdiVariable > const *self,std::map< int,CdiVariable >::key_type const &key){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::const_iterator i = self->find(key);
       return i != self->end();
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__keys(std::map<int,CdiVariable > *self){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__keys(std::map< int,CdiVariable > *self){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* keyList = PyList_New(pysize);
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(keyList, j, swig::from(i->first));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return keyList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__values(std::map<int,CdiVariable > *self){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__values(std::map< int,CdiVariable > *self){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* valList = PyList_New(pysize);
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(valList, j, swig::from(i->second));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return valList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__items(std::map<int,CdiVariable > *self){
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__items(std::map< int,CdiVariable > *self){
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }    
       PyObject* itemList = PyList_New(pysize);
-      std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >::const_iterator i = self->begin();
+      std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(itemList, j, swig::from(*i));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return itemList;
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg____contains__(std::map<int,CdiVariable > *self,std::map<int,CdiVariable >::key_type const &key){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiVariable_Sg____contains__(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::key_type const &key){
       return self->find(key) != self->end();
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiVariable_Sg__key_iterator(std::map<int,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiVariable_Sg__key_iterator(std::map< int,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiVariable_Sg__value_iterator(std::map<int,CdiVariable > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiVariable_Sg__value_iterator(std::map< int,CdiVariable > *self,PyObject **PYTHON_SELF){
       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____setitem__(std::map<int,CdiVariable > *self,std::map<int,CdiVariable >::key_type const &key,std::map<int,CdiVariable >::mapped_type const &x){
+SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____setitem____SWIG_0(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::key_type const &key){
+      self->erase(key);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____setitem____SWIG_1(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::key_type const &key,std::map< int,CdiVariable >::mapped_type const &x){
       (*self)[key] = x;
     }
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiVariable_Sg__asdict(std::map< int,CdiVariable > *self){
+      return swig::traits_from< std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > >::asdict(*self);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg__erase__SWIG_1(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::iterator position){ self->erase(position); }
+SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg__erase__SWIG_2(std::map< int,CdiVariable > *self,std::map< int,CdiVariable >::iterator first,std::map< int,CdiVariable >::iterator last){ self->erase(first, last); }
 
   namespace swig {
     template <>  struct traits<CdiTaxis > {
@@ -4918,104 +5906,118 @@ SWIGINTERN void std_map_Sl_int_Sc_CdiVariable_Sg____setitem__(std::map<int,CdiVa
     
 
       namespace swig {
-	template <>  struct traits<std::map<int, CdiTaxis, std::less<int >, std::allocator<std::pair<int const,CdiTaxis > > > > {
+	template <>  struct traits<std::map<int, CdiTaxis, std::less< int >, std::allocator< std::pair< int const,CdiTaxis > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::map<" "int" "," "CdiTaxis" "," "std::less<int >" "," "std::allocator<std::pair<int const,CdiTaxis > >" " >";
+	    return "std::map<" "int" "," "CdiTaxis" "," "std::less< int >" "," "std::allocator< std::pair< int const,CdiTaxis > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__iterator(std::map<int,CdiTaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__iterator(std::map< int,CdiTaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg____nonzero__(std::map<int,CdiTaxis > const *self){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg____nonzero__(std::map< int,CdiTaxis > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg____bool__(std::map< int,CdiTaxis > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::map<int,CdiTaxis >::size_type std_map_Sl_int_Sc_CdiTaxis_Sg____len__(std::map<int,CdiTaxis > const *self){
+SWIGINTERN std::map< int,CdiTaxis >::size_type std_map_Sl_int_Sc_CdiTaxis_Sg____len__(std::map< int,CdiTaxis > const *self){
       return self->size();
     }
-SWIGINTERN std::map<int,CdiTaxis >::mapped_type std_map_Sl_int_Sc_CdiTaxis_Sg____getitem__(std::map<int,CdiTaxis > const *self,std::map<int,CdiTaxis >::key_type const &key){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::const_iterator i = self->find(key);
+SWIGINTERN std::map< int,CdiTaxis >::mapped_type const &std_map_Sl_int_Sc_CdiTaxis_Sg____getitem__(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::key_type const &key){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::const_iterator i = self->find(key);
       if (i != self->end())
 	return i->second;
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____delitem__(std::map<int,CdiTaxis > *self,std::map<int,CdiTaxis >::key_type const &key){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::iterator i = self->find(key);
+SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____delitem__(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::key_type const &key){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::iterator i = self->find(key);
       if (i != self->end())
 	self->erase(i);
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg__has_key(std::map<int,CdiTaxis > const *self,std::map<int,CdiTaxis >::key_type const &key){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::const_iterator i = self->find(key);
+SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg__has_key(std::map< int,CdiTaxis > const *self,std::map< int,CdiTaxis >::key_type const &key){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::const_iterator i = self->find(key);
       return i != self->end();
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__keys(std::map<int,CdiTaxis > *self){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__keys(std::map< int,CdiTaxis > *self){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* keyList = PyList_New(pysize);
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(keyList, j, swig::from(i->first));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return keyList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__values(std::map<int,CdiTaxis > *self){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__values(std::map< int,CdiTaxis > *self){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* valList = PyList_New(pysize);
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(valList, j, swig::from(i->second));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return valList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__items(std::map<int,CdiTaxis > *self){
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__items(std::map< int,CdiTaxis > *self){
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }    
       PyObject* itemList = PyList_New(pysize);
-      std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(itemList, j, swig::from(*i));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return itemList;
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg____contains__(std::map<int,CdiTaxis > *self,std::map<int,CdiTaxis >::key_type const &key){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiTaxis_Sg____contains__(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::key_type const &key){
       return self->find(key) != self->end();
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__key_iterator(std::map<int,CdiTaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__key_iterator(std::map< int,CdiTaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__value_iterator(std::map<int,CdiTaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiTaxis_Sg__value_iterator(std::map< int,CdiTaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____setitem__(std::map<int,CdiTaxis > *self,std::map<int,CdiTaxis >::key_type const &key,std::map<int,CdiTaxis >::mapped_type const &x){
+SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____setitem____SWIG_0(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::key_type const &key){
+      self->erase(key);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____setitem____SWIG_1(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::key_type const &key,std::map< int,CdiTaxis >::mapped_type const &x){
       (*self)[key] = x;
     }
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiTaxis_Sg__asdict(std::map< int,CdiTaxis > *self){
+      return swig::traits_from< std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > >::asdict(*self);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg__erase__SWIG_1(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::iterator position){ self->erase(position); }
+SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg__erase__SWIG_2(std::map< int,CdiTaxis > *self,std::map< int,CdiTaxis >::iterator first,std::map< int,CdiTaxis >::iterator last){ self->erase(first, last); }
 
   namespace swig {
     template <>  struct traits<CdiZaxis > {
@@ -5036,104 +6038,118 @@ SWIGINTERN void std_map_Sl_int_Sc_CdiTaxis_Sg____setitem__(std::map<int,CdiTaxis
     
 
       namespace swig {
-	template <>  struct traits<std::map<int, CdiZaxis, std::less<int >, std::allocator<std::pair<int const,CdiZaxis > > > > {
+	template <>  struct traits<std::map<int, CdiZaxis, std::less< int >, std::allocator< std::pair< int const,CdiZaxis > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::map<" "int" "," "CdiZaxis" "," "std::less<int >" "," "std::allocator<std::pair<int const,CdiZaxis > >" " >";
+	    return "std::map<" "int" "," "CdiZaxis" "," "std::less< int >" "," "std::allocator< std::pair< int const,CdiZaxis > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__iterator(std::map<int,CdiZaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__iterator(std::map< int,CdiZaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg____nonzero__(std::map<int,CdiZaxis > const *self){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg____nonzero__(std::map< int,CdiZaxis > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::map<int,CdiZaxis >::size_type std_map_Sl_int_Sc_CdiZaxis_Sg____len__(std::map<int,CdiZaxis > const *self){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg____bool__(std::map< int,CdiZaxis > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN std::map< int,CdiZaxis >::size_type std_map_Sl_int_Sc_CdiZaxis_Sg____len__(std::map< int,CdiZaxis > const *self){
       return self->size();
     }
-SWIGINTERN std::map<int,CdiZaxis >::mapped_type std_map_Sl_int_Sc_CdiZaxis_Sg____getitem__(std::map<int,CdiZaxis > const *self,std::map<int,CdiZaxis >::key_type const &key){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::const_iterator i = self->find(key);
+SWIGINTERN std::map< int,CdiZaxis >::mapped_type const &std_map_Sl_int_Sc_CdiZaxis_Sg____getitem__(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::key_type const &key){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::const_iterator i = self->find(key);
       if (i != self->end())
 	return i->second;
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____delitem__(std::map<int,CdiZaxis > *self,std::map<int,CdiZaxis >::key_type const &key){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::iterator i = self->find(key);
+SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____delitem__(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::key_type const &key){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::iterator i = self->find(key);
       if (i != self->end())
 	self->erase(i);
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg__has_key(std::map<int,CdiZaxis > const *self,std::map<int,CdiZaxis >::key_type const &key){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::const_iterator i = self->find(key);
+SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg__has_key(std::map< int,CdiZaxis > const *self,std::map< int,CdiZaxis >::key_type const &key){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::const_iterator i = self->find(key);
       return i != self->end();
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__keys(std::map<int,CdiZaxis > *self){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__keys(std::map< int,CdiZaxis > *self){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* keyList = PyList_New(pysize);
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(keyList, j, swig::from(i->first));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return keyList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__values(std::map<int,CdiZaxis > *self){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__values(std::map< int,CdiZaxis > *self){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* valList = PyList_New(pysize);
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(valList, j, swig::from(i->second));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return valList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__items(std::map<int,CdiZaxis > *self){
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__items(std::map< int,CdiZaxis > *self){
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }    
       PyObject* itemList = PyList_New(pysize);
-      std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >::const_iterator i = self->begin();
+      std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(itemList, j, swig::from(*i));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return itemList;
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg____contains__(std::map<int,CdiZaxis > *self,std::map<int,CdiZaxis >::key_type const &key){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiZaxis_Sg____contains__(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::key_type const &key){
       return self->find(key) != self->end();
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__key_iterator(std::map<int,CdiZaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__key_iterator(std::map< int,CdiZaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__value_iterator(std::map<int,CdiZaxis > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiZaxis_Sg__value_iterator(std::map< int,CdiZaxis > *self,PyObject **PYTHON_SELF){
       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____setitem__(std::map<int,CdiZaxis > *self,std::map<int,CdiZaxis >::key_type const &key,std::map<int,CdiZaxis >::mapped_type const &x){
+SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____setitem____SWIG_0(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::key_type const &key){
+      self->erase(key);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____setitem____SWIG_1(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::key_type const &key,std::map< int,CdiZaxis >::mapped_type const &x){
       (*self)[key] = x;
     }
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiZaxis_Sg__asdict(std::map< int,CdiZaxis > *self){
+      return swig::traits_from< std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > >::asdict(*self);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg__erase__SWIG_1(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::iterator position){ self->erase(position); }
+SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg__erase__SWIG_2(std::map< int,CdiZaxis > *self,std::map< int,CdiZaxis >::iterator first,std::map< int,CdiZaxis >::iterator last){ self->erase(first, last); }
 
   namespace swig {
     template <>  struct traits<CdiGrid > {
@@ -5154,120 +6170,130 @@ SWIGINTERN void std_map_Sl_int_Sc_CdiZaxis_Sg____setitem__(std::map<int,CdiZaxis
     
 
       namespace swig {
-	template <>  struct traits<std::map<int, CdiGrid, std::less<int >, std::allocator<std::pair<int const,CdiGrid > > > > {
+	template <>  struct traits<std::map<int, CdiGrid, std::less< int >, std::allocator< std::pair< int const,CdiGrid > > > > {
 	  typedef pointer_category category;
 	  static const char* type_name() {
-	    return "std::map<" "int" "," "CdiGrid" "," "std::less<int >" "," "std::allocator<std::pair<int const,CdiGrid > >" " >";
+	    return "std::map<" "int" "," "CdiGrid" "," "std::less< int >" "," "std::allocator< std::pair< int const,CdiGrid > >" " >";
 	  }
 	};
       }
     
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiGrid_Sg__iterator(std::map<int,CdiGrid > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiGrid_Sg__iterator(std::map< int,CdiGrid > *self,PyObject **PYTHON_SELF){
       return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg____nonzero__(std::map<int,CdiGrid > const *self){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg____nonzero__(std::map< int,CdiGrid > const *self){
+      return !(self->empty());
+    }
+SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg____bool__(std::map< int,CdiGrid > const *self){
       return !(self->empty());
     }
-SWIGINTERN std::map<int,CdiGrid >::size_type std_map_Sl_int_Sc_CdiGrid_Sg____len__(std::map<int,CdiGrid > const *self){
+SWIGINTERN std::map< int,CdiGrid >::size_type std_map_Sl_int_Sc_CdiGrid_Sg____len__(std::map< int,CdiGrid > const *self){
       return self->size();
     }
-SWIGINTERN std::map<int,CdiGrid >::mapped_type std_map_Sl_int_Sc_CdiGrid_Sg____getitem__(std::map<int,CdiGrid > const *self,std::map<int,CdiGrid >::key_type const &key){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::const_iterator i = self->find(key);
+SWIGINTERN std::map< int,CdiGrid >::mapped_type const &std_map_Sl_int_Sc_CdiGrid_Sg____getitem__(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::key_type const &key){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::const_iterator i = self->find(key);
       if (i != self->end())
 	return i->second;
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg____delitem__(std::map<int,CdiGrid > *self,std::map<int,CdiGrid >::key_type const &key){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::iterator i = self->find(key);
+SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg____delitem__(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::key_type const &key){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::iterator i = self->find(key);
       if (i != self->end())
 	self->erase(i);
       else
 	throw std::out_of_range("key not found");
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg__has_key(std::map<int,CdiGrid > const *self,std::map<int,CdiGrid >::key_type const &key){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::const_iterator i = self->find(key);
+SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg__has_key(std::map< int,CdiGrid > const *self,std::map< int,CdiGrid >::key_type const &key){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::const_iterator i = self->find(key);
       return i != self->end();
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__keys(std::map<int,CdiGrid > *self){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__keys(std::map< int,CdiGrid > *self){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* keyList = PyList_New(pysize);
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::const_iterator i = self->begin();
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(keyList, j, swig::from(i->first));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return keyList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__values(std::map<int,CdiGrid > *self){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__values(std::map< int,CdiGrid > *self){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }
       PyObject* valList = PyList_New(pysize);
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::const_iterator i = self->begin();
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(valList, j, swig::from(i->second));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return valList;
     }
-SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__items(std::map<int,CdiGrid > *self){
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type size = self->size();
-      int pysize = (size <= (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__items(std::map< int,CdiGrid > *self){
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type size = self->size();
+      int pysize = (size <= (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::size_type) INT_MAX) ? (int) size : -1;
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
       if (pysize < 0) {
-	SWIG_PYTHON_THREAD_BEGIN_BLOCK;
 	PyErr_SetString(PyExc_OverflowError,
 			"map size not valid in python");
 	SWIG_PYTHON_THREAD_END_BLOCK;
 	return NULL;
       }    
       PyObject* itemList = PyList_New(pysize);
-      std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >::const_iterator i = self->begin();
+      std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >::const_iterator i = self->begin();
       for (int j = 0; j < pysize; ++i, ++j) {
 	PyList_SET_ITEM(itemList, j, swig::from(*i));
       }
+      SWIG_PYTHON_THREAD_END_BLOCK;
       return itemList;
     }
-SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg____contains__(std::map<int,CdiGrid > *self,std::map<int,CdiGrid >::key_type const &key){
+SWIGINTERN bool std_map_Sl_int_Sc_CdiGrid_Sg____contains__(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::key_type const &key){
       return self->find(key) != self->end();
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiGrid_Sg__key_iterator(std::map<int,CdiGrid > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiGrid_Sg__key_iterator(std::map< int,CdiGrid > *self,PyObject **PYTHON_SELF){
       return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN swig::PySwigIterator *std_map_Sl_int_Sc_CdiGrid_Sg__value_iterator(std::map<int,CdiGrid > *self,PyObject **PYTHON_SELF){
+SWIGINTERN swig::SwigPyIterator *std_map_Sl_int_Sc_CdiGrid_Sg__value_iterator(std::map< int,CdiGrid > *self,PyObject **PYTHON_SELF){
       return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
     }
-SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg____setitem__(std::map<int,CdiGrid > *self,std::map<int,CdiGrid >::key_type const &key,std::map<int,CdiGrid >::mapped_type const &x){
+SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg____setitem____SWIG_0(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::key_type const &key){
+      self->erase(key);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg____setitem____SWIG_1(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::key_type const &key,std::map< int,CdiGrid >::mapped_type const &x){
       (*self)[key] = x;
     }
+SWIGINTERN PyObject *std_map_Sl_int_Sc_CdiGrid_Sg__asdict(std::map< int,CdiGrid > *self){
+      return swig::traits_from< std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > >::asdict(*self);
+    }
+SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg__erase__SWIG_1(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::iterator position){ self->erase(position); }
+SWIGINTERN void std_map_Sl_int_Sc_CdiGrid_Sg__erase__SWIG_2(std::map< int,CdiGrid > *self,std::map< int,CdiGrid >::iterator first,std::map< int,CdiGrid >::iterator last){ self->erase(first, last); }
 
 SWIGINTERN int
 SWIG_AsVal_bool (PyObject *obj, bool *val)
 {
-  if (obj == Py_True) {
-    if (val) *val = true;
-    return SWIG_OK;
-  } else if (obj == Py_False) {
-    if (val) *val = false;
-    return SWIG_OK;
-  } else {
-    long v = 0;
-    int res = SWIG_AddCast(SWIG_AsVal_long (obj, val ? &v : 0));
-    if (SWIG_IsOK(res) && val) *val = v ? true : false;
-    return res;
-  }
+  int r;
+  if (!PyBool_Check(obj))
+    return SWIG_ERROR;
+  r = PyObject_IsTrue(obj);
+  if (r == -1)
+    return SWIG_ERROR;
+  if (val) *val = r ? true : false;
+  return SWIG_OK;
 }
 
 
@@ -5277,7 +6303,8 @@ SWIG_AsCharArray(PyObject * obj, char *val, size_t size)
   char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ;
   int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc);
   if (SWIG_IsOK(res)) {
-    if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize;
+    /* special case of single char conversion when we don't need space for NUL */
+    if (size == 1 && csize == 2 && cptr && !cptr[1]) --csize;
     if (csize <= size) {
       if (val) {
 	if (csize) memcpy(val, cptr, csize*sizeof(char));
@@ -5295,6 +6322,16 @@ SWIG_AsCharArray(PyObject * obj, char *val, size_t size)
 }
 
 
+size_t
+SWIG_strnlen(const char* s, size_t maxlen)
+{
+  const char *p;
+  for (p = s; maxlen-- && *p; p++)
+    ;
+  return p - s;
+}
+
+
 
 
 
@@ -5307,21 +6344,20 @@ SWIG_FromCharPtr(const char *cptr)
 #ifdef __cplusplus
 extern "C" {
 #endif
-SWIGINTERN PyObject *_wrap_delete_PySwigIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_PySwigIterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_SwigPyIterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_PySwigIterator" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -5329,22 +6365,22 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  PyObject *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_value",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_value",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_value" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_value" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   try {
-    result = (PyObject *)((swig::PySwigIterator const *)arg1)->value();
+    result = (PyObject *)((swig::SwigPyIterator const *)arg1)->value();
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5361,31 +6397,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_incr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   size_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator_incr",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_incr",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_incr" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator_incr" "', argument " "2"" of type '" "size_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_incr" "', argument " "2"" of type '" "size_t""'");
   } 
   arg2 = static_cast< size_t >(val2);
   try {
-    result = (swig::PySwigIterator *)(arg1)->incr(arg2);
+    result = (swig::SwigPyIterator *)(arg1)->incr(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5395,29 +6431,29 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_incr__SWIG_0(PyObject *SWIGUNUSEDPARM(
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_incr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_incr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_incr",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_incr",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_incr" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_incr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   try {
-    result = (swig::PySwigIterator *)(arg1)->incr();
+    result = (swig::SwigPyIterator *)(arg1)->incr();
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5427,36 +6463,36 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_incr__SWIG_1(PyObject *SWIGUNUSEDPARM(
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_incr(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_incr(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 1) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_PySwigIterator_incr__SWIG_1(self, args);
+      return _wrap_SwigPyIterator_incr__SWIG_1(self, args);
     }
   }
   if (argc == 2) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -5464,42 +6500,45 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_incr(PyObject *self, PyObject *args) {
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_PySwigIterator_incr__SWIG_0(self, args);
+        return _wrap_SwigPyIterator_incr__SWIG_0(self, args);
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'PySwigIterator_incr'.\n  Possible C/C++ prototypes are:\n    incr(size_t)\n    incr()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'SwigPyIterator_incr'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    swig::SwigPyIterator::incr(size_t)\n"
+    "    swig::SwigPyIterator::incr()\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_decr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   size_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator_decr",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_decr",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_decr" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator_decr" "', argument " "2"" of type '" "size_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_decr" "', argument " "2"" of type '" "size_t""'");
   } 
   arg2 = static_cast< size_t >(val2);
   try {
-    result = (swig::PySwigIterator *)(arg1)->decr(arg2);
+    result = (swig::SwigPyIterator *)(arg1)->decr(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5509,29 +6548,29 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_decr__SWIG_0(PyObject *SWIGUNUSEDPARM(
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_decr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_decr__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_decr",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_decr",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_decr" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_decr" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   try {
-    result = (swig::PySwigIterator *)(arg1)->decr();
+    result = (swig::SwigPyIterator *)(arg1)->decr();
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5541,36 +6580,36 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_decr__SWIG_1(PyObject *SWIGUNUSEDPARM(
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_decr(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_decr(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 1) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_PySwigIterator_decr__SWIG_1(self, args);
+      return _wrap_SwigPyIterator_decr__SWIG_1(self, args);
     }
   }
   if (argc == 2) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -5578,45 +6617,48 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_decr(PyObject *self, PyObject *args) {
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_PySwigIterator_decr__SWIG_0(self, args);
+        return _wrap_SwigPyIterator_decr__SWIG_0(self, args);
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'PySwigIterator_decr'.\n  Possible C/C++ prototypes are:\n    decr(size_t)\n    decr()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'SwigPyIterator_decr'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    swig::SwigPyIterator::decr(size_t)\n"
+    "    swig::SwigPyIterator::decr()\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_distance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_distance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *arg2 = 0 ;
-  ptrdiff_t result;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  swig::SwigPyIterator *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  ptrdiff_t result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator_distance",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_distance",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_distance" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_distance" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__PySwigIterator,  0  | 0);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySwigIterator_distance" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySwigIterator_distance" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_distance" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
-  arg2 = reinterpret_cast< swig::PySwigIterator * >(argp2);
+  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
   try {
-    result = ((swig::PySwigIterator const *)arg1)->distance((swig::PySwigIterator const &)*arg2);
+    result = ((swig::SwigPyIterator const *)arg1)->distance((swig::SwigPyIterator const &)*arg2);
   }
   catch(std::invalid_argument &_e) {
     SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail;
@@ -5629,34 +6671,34 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_equal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_equal(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *arg2 = 0 ;
-  bool result;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  swig::SwigPyIterator *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator_equal",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_equal",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_equal" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_equal" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__PySwigIterator,  0  | 0);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySwigIterator_equal" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySwigIterator_equal" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator_equal" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
-  arg2 = reinterpret_cast< swig::PySwigIterator * >(argp2);
+  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
   try {
-    result = (bool)((swig::PySwigIterator const *)arg1)->equal((swig::PySwigIterator const &)*arg2);
+    result = (bool)((swig::SwigPyIterator const *)arg1)->equal((swig::SwigPyIterator const &)*arg2);
   }
   catch(std::invalid_argument &_e) {
     SWIG_Python_Raise(SWIG_NewPointerObj((new std::invalid_argument(static_cast< const std::invalid_argument& >(_e))),SWIGTYPE_p_std__invalid_argument,SWIG_POINTER_OWN), "std::invalid_argument", SWIGTYPE_p_std__invalid_argument); SWIG_fail;
@@ -5669,42 +6711,42 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_copy(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_copy",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_copy",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_copy" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_copy" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  result = (swig::PySwigIterator *)((swig::PySwigIterator const *)arg1)->copy();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->copy();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_next(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_next(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  PyObject *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_next",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_next",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_next" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_next" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   try {
     result = (PyObject *)(arg1)->next();
   }
@@ -5723,22 +6765,22 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_previous(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___next__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  PyObject *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:PySwigIterator_previous",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator___next__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_previous" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___next__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   try {
-    result = (PyObject *)(arg1)->previous();
+    result = (PyObject *)(arg1)->__next__();
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5755,31 +6797,63 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator_advance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator_previous(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  ptrdiff_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator_advance",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:SwigPyIterator_previous",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator_advance" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_previous" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  try {
+    result = (PyObject *)(arg1)->previous();
+  }
+  catch(swig::stop_iteration &_e) {
+    {
+      (void)_e;
+      SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
+      SWIG_fail;
+    }
+  }
+  
+  resultobj = result;
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_SwigPyIterator_advance(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  ptrdiff_t arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator_advance",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator_advance" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
+  }
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator_advance" "', argument " "2"" of type '" "ptrdiff_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator_advance" "', argument " "2"" of type '" "ptrdiff_t""'");
   } 
   arg2 = static_cast< ptrdiff_t >(val2);
   try {
-    result = (swig::PySwigIterator *)(arg1)->advance(arg2);
+    result = (swig::SwigPyIterator *)(arg1)->advance(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5789,40 +6863,40 @@ SWIGINTERN PyObject *_wrap_PySwigIterator_advance(PyObject *SWIGUNUSEDPARM(self)
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *arg2 = 0 ;
-  bool result;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  swig::SwigPyIterator *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___eq__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___eq__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___eq__" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___eq__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__PySwigIterator,  0  | 0);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySwigIterator___eq__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySwigIterator___eq__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___eq__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
-  arg2 = reinterpret_cast< swig::PySwigIterator * >(argp2);
-  result = (bool)((swig::PySwigIterator const *)arg1)->operator ==((swig::PySwigIterator const &)*arg2);
+  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
+  result = (bool)((swig::SwigPyIterator const *)arg1)->operator ==((swig::SwigPyIterator const &)*arg2);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -5830,33 +6904,33 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___ne__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___ne__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *arg2 = 0 ;
-  bool result;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  swig::SwigPyIterator *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___ne__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___ne__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___ne__" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___ne__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__PySwigIterator,  0  | 0);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySwigIterator___ne__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySwigIterator___ne__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___ne__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
-  arg2 = reinterpret_cast< swig::PySwigIterator * >(argp2);
-  result = (bool)((swig::PySwigIterator const *)arg1)->operator !=((swig::PySwigIterator const &)*arg2);
+  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
+  result = (bool)((swig::SwigPyIterator const *)arg1)->operator !=((swig::SwigPyIterator const &)*arg2);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -5864,34 +6938,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___iadd__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___iadd__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   ptrdiff_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___iadd__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___iadd__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___iadd__" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___iadd__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator___iadd__" "', argument " "2"" of type '" "ptrdiff_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___iadd__" "', argument " "2"" of type '" "ptrdiff_t""'");
   } 
   arg2 = static_cast< ptrdiff_t >(val2);
   try {
-    {
-      swig::PySwigIterator &_result_ref = (arg1)->operator +=(arg2);
-      result = (swig::PySwigIterator *) &_result_ref;
-    }
+    result = (swig::SwigPyIterator *) &(arg1)->operator +=(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5901,41 +6972,38 @@ SWIGINTERN PyObject *_wrap_PySwigIterator___iadd__(PyObject *SWIGUNUSEDPARM(self
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___isub__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___isub__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   ptrdiff_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___isub__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___isub__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___isub__" "', argument " "1"" of type '" "swig::PySwigIterator *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___isub__" "', argument " "1"" of type '" "swig::SwigPyIterator *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator___isub__" "', argument " "2"" of type '" "ptrdiff_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___isub__" "', argument " "2"" of type '" "ptrdiff_t""'");
   } 
   arg2 = static_cast< ptrdiff_t >(val2);
   try {
-    {
-      swig::PySwigIterator &_result_ref = (arg1)->operator -=(arg2);
-      result = (swig::PySwigIterator *) &_result_ref;
-    }
+    result = (swig::SwigPyIterator *) &(arg1)->operator -=(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5945,38 +7013,38 @@ SWIGINTERN PyObject *_wrap_PySwigIterator___isub__(PyObject *SWIGUNUSEDPARM(self
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___add__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___add__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   ptrdiff_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___add__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___add__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___add__" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___add__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator___add__" "', argument " "2"" of type '" "ptrdiff_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___add__" "', argument " "2"" of type '" "ptrdiff_t""'");
   } 
   arg2 = static_cast< ptrdiff_t >(val2);
   try {
-    result = (swig::PySwigIterator *)((swig::PySwigIterator const *)arg1)->operator +(arg2);
+    result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator +(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -5986,38 +7054,38 @@ SWIGINTERN PyObject *_wrap_PySwigIterator___add__(PyObject *SWIGUNUSEDPARM(self)
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___sub____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
   ptrdiff_t arg2 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___sub__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___sub__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___sub__" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "PySwigIterator___sub__" "', argument " "2"" of type '" "ptrdiff_t""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "ptrdiff_t""'");
   } 
   arg2 = static_cast< ptrdiff_t >(val2);
   try {
-    result = (swig::PySwigIterator *)((swig::PySwigIterator const *)arg1)->operator -(arg2);
+    result = (swig::SwigPyIterator *)((swig::SwigPyIterator const *)arg1)->operator -(arg2);
   }
   catch(swig::stop_iteration &_e) {
     {
@@ -6027,40 +7095,40 @@ SWIGINTERN PyObject *_wrap_PySwigIterator___sub____SWIG_0(PyObject *SWIGUNUSEDPA
     }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___sub____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___sub____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  swig::PySwigIterator *arg1 = (swig::PySwigIterator *) 0 ;
-  swig::PySwigIterator *arg2 = 0 ;
-  ptrdiff_t result;
+  swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
+  swig::SwigPyIterator *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
   int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  ptrdiff_t result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:PySwigIterator___sub__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__PySwigIterator, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:SwigPyIterator___sub__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "PySwigIterator___sub__" "', argument " "1"" of type '" "swig::PySwigIterator const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SwigPyIterator___sub__" "', argument " "1"" of type '" "swig::SwigPyIterator const *""'"); 
   }
-  arg1 = reinterpret_cast< swig::PySwigIterator * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__PySwigIterator,  0  | 0);
+  arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_swig__SwigPyIterator,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "PySwigIterator___sub__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "PySwigIterator___sub__" "', argument " "2"" of type '" "swig::PySwigIterator const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SwigPyIterator___sub__" "', argument " "2"" of type '" "swig::SwigPyIterator const &""'"); 
   }
-  arg2 = reinterpret_cast< swig::PySwigIterator * >(argp2);
-  result = ((swig::PySwigIterator const *)arg1)->operator -((swig::PySwigIterator const &)*arg2);
+  arg2 = reinterpret_cast< swig::SwigPyIterator * >(argp2);
+  result = ((swig::SwigPyIterator const *)arg1)->operator -((swig::SwigPyIterator const &)*arg2);
   resultobj = SWIG_From_ptrdiff_t(static_cast< ptrdiff_t >(result));
   return resultobj;
 fail:
@@ -6068,33 +7136,33 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_PySwigIterator___sub__(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_SwigPyIterator___sub__(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_swig__PySwigIterator, 0);
+      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_swig__SwigPyIterator, 0);
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_PySwigIterator___sub____SWIG_1(self, args);
+        return _wrap_SwigPyIterator___sub____SWIG_1(self, args);
       }
     }
   }
   if (argc == 2) {
     int _v;
     void *vptr = 0;
-    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__PySwigIterator, 0);
+    int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_swig__SwigPyIterator, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -6102,7 +7170,7 @@ SWIGINTERN PyObject *_wrap_PySwigIterator___sub__(PyObject *self, PyObject *args
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_PySwigIterator___sub____SWIG_0(self, args);
+        return _wrap_SwigPyIterator___sub____SWIG_0(self, args);
       }
     }
   }
@@ -6113,31 +7181,31 @@ fail:
 }
 
 
-SWIGINTERN PyObject *PySwigIterator_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *SwigPyIterator_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_swig__PySwigIterator, SWIG_NewClientData(obj));
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_swig__SwigPyIterator, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject *_wrap_IntVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
   arg2 = &obj0;
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_iterator" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_iterator" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (swig::PySwigIterator *)std_vector_Sl_int_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (swig::SwigPyIterator *)std_vector_Sl_int_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -6146,19 +7214,41 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  bool result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___nonzero__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (bool)std_vector_Sl_int_Sg____nonzero__((std::vector< int > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___nonzero__" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___bool__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (bool)std_vector_Sl_int_Sg____nonzero__((std::vector<int > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (bool)std_vector_Sl_int_Sg____bool__((std::vector< int > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -6168,19 +7258,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___len__" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___len__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = std_vector_Sl_int_Sg____len__((std::vector<int > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = std_vector_Sl_int_Sg____len__((std::vector< int > const *)arg1);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -6190,20 +7280,20 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::value_type result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::value_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_pop",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   try {
-    result = (std::vector<int >::value_type)std_vector_Sl_int_Sg__pop(arg1);
+    result = (std::vector< int >::value_type)std_vector_Sl_int_Sg__pop(arg1);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -6218,10 +7308,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
-  std::vector<int >::difference_type arg3 ;
-  std::vector<int,std::allocator<int > > *result = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
+  std::vector< int >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -6231,43 +7320,47 @@ SWIGINTERN PyObject *_wrap_IntVector___getslice__(PyObject *SWIGUNUSEDPARM(self)
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< int,std::allocator< int > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getslice__" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getslice__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___getslice__" "', argument " "3"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___getslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<int >::difference_type >(val3);
+  arg3 = static_cast< std::vector< int >::difference_type >(val3);
   try {
-    result = (std::vector<int,std::allocator<int > > *)std_vector_Sl_int_Sg____getslice__(arg1,arg2,arg3);
+    result = (std::vector< int,std::allocator< int > > *)std_vector_Sl_int_Sg____getslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector___setslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
-  std::vector<int >::difference_type arg3 ;
-  std::vector<int,std::allocator<int > > *arg4 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
+  std::vector< int >::difference_type arg3 ;
+  std::vector< int,std::allocator< int > > *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -6281,34 +7374,34 @@ SWIGINTERN PyObject *_wrap_IntVector___setslice__(PyObject *SWIGUNUSEDPARM(self)
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:IntVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setslice__" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setslice__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setslice__" "', argument " "3"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<int >::difference_type >(val3);
+  arg3 = static_cast< std::vector< int >::difference_type >(val3);
   {
-    std::vector<int,std::allocator<int > > *ptr = (std::vector<int,std::allocator<int > > *)0;
+    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
     res4 = swig::asptr(obj3, &ptr);
     if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector<int,std::allocator<int > > const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector<int,std::allocator<int > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector___setslice__" "', argument " "4"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
     }
     arg4 = ptr;
   }
   try {
-    std_vector_Sl_int_Sg____setslice__(arg1,arg2,arg3,(std::vector<int,std::allocator<int > > const &)*arg4);
+    std_vector_Sl_int_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< int,std::allocator< int > > const &)*arg4);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -6326,11 +7419,11 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
-  std::vector<int >::difference_type arg3 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
+  std::vector< int >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -6341,28 +7434,31 @@ SWIGINTERN PyObject *_wrap_IntVector___delslice__(PyObject *SWIGUNUSEDPARM(self)
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delslice__" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delslice__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___delslice__" "', argument " "3"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<int >::difference_type >(val3);
+  arg3 = static_cast< std::vector< int >::difference_type >(val3);
   try {
-    std_vector_Sl_int_Sg____delslice__(arg1,arg2,arg3);
+    std_vector_Sl_int_Sg____setslice____SWIG_0(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -6371,34 +7467,110 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setslice__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[5];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_IntVector___setslice____SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = swig::asptr(argv[3], (std::vector<int,std::allocator< int > >**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_IntVector___setslice____SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___setslice__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::__setslice__(std::vector< int >::difference_type,std::vector< int >::difference_type,std::vector< int,std::allocator< int > > const &)\n"
+    "    std::vector< int >::__setslice__(std::vector< int >::difference_type,std::vector< int >::difference_type)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
+  std::vector< int >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delitem__" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delslice__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delitem__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delslice__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___delslice__" "', argument " "3"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
+  arg3 = static_cast< std::vector< int >::difference_type >(val3);
   try {
-    std_vector_Sl_int_Sg____delitem__(arg1,arg2);
+    std_vector_Sl_int_Sg____delslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -6407,11 +7579,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
-  std::vector<int >::value_type *result = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -6419,607 +7590,751 @@ SWIGINTERN PyObject *_wrap_IntVector___getitem__(PyObject *SWIGUNUSEDPARM(self),
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getitem__" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getitem__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___delitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
   try {
-    {
-      std::vector<int >::value_type const &_result_ref = std_vector_Sl_int_Sg____getitem__((std::vector<int > const *)arg1,arg2);
-      result = (std::vector<int >::value_type *) &_result_ref;
-    }
+    std_vector_Sl_int_Sg____delitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_From_int(static_cast< int >(*result));
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::difference_type arg2 ;
-  std::vector<int >::value_type *arg3 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  std::vector<int >::value_type temp3 ;
-  int val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< int,std::allocator< int > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "std::vector<int >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<int >::difference_type >(val2);
-  ecode3 = SWIG_AsVal_int(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector<int >::value_type""'");
-  } 
-  temp3 = static_cast< std::vector<int >::value_type >(val3);
-  arg3 = &temp3;
   try {
-    std_vector_Sl_int_Sg____setitem__(arg1,arg2,(int const &)*arg3);
+    result = (std::vector< int,std::allocator< int > > *)std_vector_Sl_int_Sg____getitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_Py_Void();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::value_type *arg2 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  std::vector< int,std::allocator< int > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::vector<int >::value_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_append",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_append" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_append" "', argument " "2"" of type '" "std::vector<int >::value_type""'");
-  } 
-  temp2 = static_cast< std::vector<int >::value_type >(val2);
-  arg2 = &temp2;
-  std_vector_Sl_int_Sg__append(arg1,(int const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_IntVector")) SWIG_fail;
-  result = (std::vector<int > *)new std::vector<int >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = 0 ;
-  std::vector<int > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_IntVector",&obj0)) SWIG_fail;
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   {
-    std::vector<int,std::allocator<int > > *ptr = (std::vector<int,std::allocator<int > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector<int > const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  {
+    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector<int > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int,std::allocator< int > > const &""'"); 
     }
-    arg1 = ptr;
+    arg3 = ptr;
   }
-  result = (std::vector<int > *)new std::vector<int >((std::vector<int > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  try {
+    std_vector_Sl_int_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< int,std::allocator< int > > const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  bool result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_empty" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (bool)((std::vector<int > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_int_Sg____setitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_size" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___delitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_int_Sg____delitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_clear" "', argument " "1"" of type '" "std::vector<int > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+SWIGINTERN PyObject *_wrap_IntVector___delitem__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_swap" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector<int > &""'"); 
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_IntVector___delitem____SWIG_1(self, args);
+      }
+    }
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector<int > &""'"); 
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_IntVector___delitem____SWIG_0(self, args);
+      }
+    }
   }
-  arg2 = reinterpret_cast< std::vector<int > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  SwigValueWrapper<std::allocator<int > > result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_get_allocator" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::vector<int >::allocator_type(static_cast< const std::vector<int >::allocator_type& >(result))), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___delitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::__delitem__(std::vector< int >::difference_type)\n"
+    "    std::vector< int >::__delitem__(PySliceObject *)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::vector< int >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_begin" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___getitem__" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntVector_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_begin" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___getitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
+  try {
+    result = (std::vector< int >::value_type *) &std_vector_Sl_int_Sg____getitem____SWIG_1((std::vector< int > const *)arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_From_int(static_cast< int >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_begin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___getitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_IntVector_begin__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_IntVector___getitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_IntVector_begin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_IntVector___getitem____SWIG_1(self, args);
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___getitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::__getitem__(PySliceObject *)\n"
+    "    std::vector< int >::__getitem__(std::vector< int >::difference_type) const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::difference_type arg2 ;
+  std::vector< int >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  std::vector< int >::value_type temp3 ;
+  int val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_end" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector___setitem__" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_IntVector_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_end" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector___setitem__" "', argument " "2"" of type '" "std::vector< int >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< int >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_int(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector___setitem__" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
+  } 
+  temp3 = static_cast< std::vector< int >::value_type >(val3);
+  arg3 = &temp3;
+  try {
+    std_vector_Sl_int_Sg____setitem____SWIG_2(arg1,arg2,(int const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_end(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_IntVector_end__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_IntVector___setitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<int,std::allocator< int > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_IntVector___setitem____SWIG_0(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_IntVector_end__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_int(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_IntVector___setitem____SWIG_2(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::__setitem__(PySliceObject *,std::vector< int,std::allocator< int > > const &)\n"
+    "    std::vector< int >::__setitem__(PySliceObject *)\n"
+    "    std::vector< int >::__setitem__(std::vector< int >::difference_type,std::vector< int >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::reverse_iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::vector< int >::value_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_append",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rbegin" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_append" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_append" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
+  } 
+  temp2 = static_cast< std::vector< int >::value_type >(val2);
+  arg2 = &temp2;
+  std_vector_Sl_int_Sg__append(arg1,(int const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+  std::vector< int > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rbegin" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  if (!PyArg_ParseTuple(args,(char *)":new_IntVector")) SWIG_fail;
+  result = (std::vector< int > *)new std::vector< int >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rbegin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  PyObject * obj0 = 0 ;
+  std::vector< int > *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IntVector_rbegin__SWIG_0(self, args);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_IntVector",&obj0)) SWIG_fail;
+  {
+    std::vector<int,std::allocator< int > > *ptr = (std::vector<int,std::allocator< int > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int > const &""'"); 
     }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IntVector_rbegin__SWIG_1(self, args);
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int > const &""'"); 
     }
+    arg1 = ptr;
   }
-  
+  result = (std::vector< int > *)new std::vector< int >((std::vector< int > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::reverse_iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rend" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_empty" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (bool)((std::vector< int > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IntVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::const_reverse_iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rend" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_size" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = ((std::vector< int > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_IntVector_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_IntVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IntVector_rend__SWIG_0(self, args);
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_clear" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_IntVector_rend__SWIG_1(self, args);
-    }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_swap" "', argument " "1"" of type '" "std::vector< int > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector< int > &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "IntVector_swap" "', argument " "2"" of type '" "std::vector< int > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< int > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< int > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_get_allocator" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = ((std::vector< int > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::vector< int >::allocator_type(static_cast< const std::vector< int >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_int_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< int >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_begin" "', argument " "1"" of type '" "std::vector< int > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< int >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_end" "', argument " "1"" of type '" "std::vector< int > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< int >::reverse_iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rbegin" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_IntVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< int >::reverse_iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:IntVector_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_rend" "', argument " "1"" of type '" "std::vector< int > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int >::size_type arg1 ;
-  std::vector<int > *result = 0 ;
+  std::vector< int >::size_type arg1 ;
   size_t val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_IntVector",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<int >::size_type >(val1);
-  result = (std::vector<int > *)new std::vector<int >(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_NEW |  0 );
+  arg1 = static_cast< std::vector< int >::size_type >(val1);
+  result = (std::vector< int > *)new std::vector< int >(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -7028,17 +8343,17 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_pop_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop_back" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_pop_back" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   (arg1)->pop_back();
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -7049,8 +8364,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type arg2 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -7059,16 +8374,16 @@ SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(sel
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_resize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::size_type >(val2);
+  arg2 = static_cast< std::vector< int >::size_type >(val2);
   (arg1)->resize(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -7079,36 +8394,36 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator arg2 ;
-  std::vector<int >::iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< int >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<int >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_int_Sg__erase__SWIG_0(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -7117,51 +8432,51 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator arg2 ;
-  std::vector<int >::iterator arg3 ;
-  std::vector<int >::iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::iterator arg2 ;
+  std::vector< int >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
+  swig::SwigPyIterator *iter3 = 0 ;
   int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< int >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_erase" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<int >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
     }
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector<int >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector< int >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<int >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter3);
+    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter3);
     if (iter_t) {
       arg3 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector<int >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_erase" "', argument " "3"" of type '" "std::vector< int >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_int_Sg__erase__SWIG_1(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -7174,18 +8489,18 @@ SWIGINTERN PyObject *_wrap_IntVector_erase(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
       if (_v) {
         return _wrap_IntVector_erase__SWIG_0(self, args);
       }
@@ -7193,16 +8508,16 @@ SWIGINTERN PyObject *_wrap_IntVector_erase(PyObject *self, PyObject *args) {
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
       if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter) != 0));
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
         if (_v) {
           return _wrap_IntVector_erase__SWIG_1(self, args);
         }
@@ -7211,38 +8526,41 @@ SWIGINTERN PyObject *_wrap_IntVector_erase(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::vector<int >::iterator)\n    erase(std::vector<int >::iterator,std::vector<int >::iterator)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::erase(std::vector< int >::iterator)\n"
+    "    std::vector< int >::erase(std::vector< int >::iterator,std::vector< int >::iterator)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_IntVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int >::size_type arg1 ;
-  std::vector<int >::value_type *arg2 = 0 ;
-  std::vector<int > *result = 0 ;
+  std::vector< int >::size_type arg1 ;
+  std::vector< int >::value_type *arg2 = 0 ;
   size_t val1 ;
   int ecode1 = 0 ;
-  std::vector<int >::value_type temp2 ;
+  std::vector< int >::value_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< int > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:new_IntVector",&obj0,&obj1)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_IntVector" "', argument " "1"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<int >::size_type >(val1);
+  arg1 = static_cast< std::vector< int >::size_type >(val1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IntVector" "', argument " "2"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_IntVector" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp2 = static_cast< std::vector<int >::value_type >(val2);
+  temp2 = static_cast< std::vector< int >::value_type >(val2);
   arg2 = &temp2;
-  result = (std::vector<int > *)new std::vector<int >(arg1,(std::vector<int >::value_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_NEW |  0 );
+  result = (std::vector< int > *)new std::vector< int >(arg1,(std::vector< int >::value_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -7255,8 +8573,8 @@ SWIGINTERN PyObject *_wrap_new_IntVector(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -7274,7 +8592,7 @@ SWIGINTERN PyObject *_wrap_new_IntVector(PyObject *self, PyObject *args) {
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       return _wrap_new_IntVector__SWIG_1(self, args);
@@ -7298,36 +8616,41 @@ SWIGINTERN PyObject *_wrap_new_IntVector(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_IntVector'.\n  Possible C/C++ prototypes are:\n    std::vector<(int)>()\n    std::vector<(int)>(std::vector<int > const &)\n    std::vector<(int)>(std::vector<int >::size_type)\n    std::vector<(int)>(std::vector<int >::size_type,std::vector<int >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_IntVector'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::vector()\n"
+    "    std::vector< int >::vector(std::vector< int > const &)\n"
+    "    std::vector< int >::vector(std::vector< int >::size_type)\n"
+    "    std::vector< int >::vector(std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_IntVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::value_type *arg2 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::vector<int >::value_type temp2 ;
+  std::vector< int >::value_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_push_back",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_push_back" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_push_back" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_push_back" "', argument " "2"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_push_back" "', argument " "2"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp2 = static_cast< std::vector<int >::value_type >(val2);
+  temp2 = static_cast< std::vector< int >::value_type >(val2);
   arg2 = &temp2;
-  (arg1)->push_back((std::vector<int >::value_type const &)*arg2);
+  (arg1)->push_back((std::vector< int >::value_type const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -7337,22 +8660,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::value_type *result = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_front",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_front" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  {
-    std::vector<int >::value_type const &_result_ref = ((std::vector<int > const *)arg1)->front();
-    result = (std::vector<int >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_front" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (std::vector< int >::value_type *) &((std::vector< int > const *)arg1)->front();
   resultobj = SWIG_From_int(static_cast< int >(*result));
   return resultobj;
 fail:
@@ -7362,22 +8682,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::value_type *result = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_back" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  {
-    std::vector<int >::value_type const &_result_ref = ((std::vector<int > const *)arg1)->back();
-    result = (std::vector<int >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_back" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = (std::vector< int >::value_type *) &((std::vector< int > const *)arg1)->back();
   resultobj = SWIG_From_int(static_cast< int >(*result));
   return resultobj;
 fail:
@@ -7387,14 +8704,14 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type arg2 ;
-  std::vector<int >::value_type *arg3 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::size_type arg2 ;
+  std::vector< int >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
-  std::vector<int >::value_type temp3 ;
+  std::vector< int >::value_type temp3 ;
   int val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -7402,23 +8719,23 @@ SWIGINTERN PyObject *_wrap_IntVector_assign(PyObject *SWIGUNUSEDPARM(self), PyOb
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_assign" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_assign" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_assign" "', argument " "2"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_assign" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::size_type >(val2);
+  arg2 = static_cast< std::vector< int >::size_type >(val2);
   ecode3 = SWIG_AsVal_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_assign" "', argument " "3"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_assign" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<int >::value_type >(val3);
+  temp3 = static_cast< std::vector< int >::value_type >(val3);
   arg3 = &temp3;
-  (arg1)->assign(arg2,(std::vector<int >::value_type const &)*arg3);
+  (arg1)->assign(arg2,(std::vector< int >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -7428,14 +8745,14 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type arg2 ;
-  std::vector<int >::value_type *arg3 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::size_type arg2 ;
+  std::vector< int >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
-  std::vector<int >::value_type temp3 ;
+  std::vector< int >::value_type temp3 ;
   int val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -7443,23 +8760,23 @@ SWIGINTERN PyObject *_wrap_IntVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_resize" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_resize" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::size_type >(val2);
+  arg2 = static_cast< std::vector< int >::size_type >(val2);
   ecode3 = SWIG_AsVal_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_resize" "', argument " "3"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_resize" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<int >::value_type >(val3);
+  temp3 = static_cast< std::vector< int >::value_type >(val3);
   arg3 = &temp3;
-  (arg1)->resize(arg2,(std::vector<int >::value_type const &)*arg3);
+  (arg1)->resize(arg2,(std::vector< int >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -7473,13 +8790,13 @@ SWIGINTERN PyObject *_wrap_IntVector_resize(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -7493,7 +8810,7 @@ SWIGINTERN PyObject *_wrap_IntVector_resize(PyObject *self, PyObject *args) {
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -7513,54 +8830,57 @@ SWIGINTERN PyObject *_wrap_IntVector_resize(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_resize'.\n  Possible C/C++ prototypes are:\n    resize(std::vector<int >::size_type)\n    resize(std::vector<int >::size_type,std::vector<int >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_resize'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::resize(std::vector< int >::size_type)\n"
+    "    std::vector< int >::resize(std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_IntVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator arg2 ;
-  std::vector<int >::value_type *arg3 = 0 ;
-  std::vector<int >::iterator result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::iterator arg2 ;
+  std::vector< int >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  std::vector<int >::value_type temp3 ;
+  std::vector< int >::value_type temp3 ;
   int val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< int >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:IntVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<int >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
     }
   }
   ecode3 = SWIG_AsVal_int(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<int >::value_type >(val3);
+  temp3 = static_cast< std::vector< int >::value_type >(val3);
   arg3 = &temp3;
-  result = (arg1)->insert(arg2,(std::vector<int >::value_type const &)*arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<int >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_int_Sg__insert__SWIG_0(arg1,arg2,(int const &)*arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< int >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -7569,17 +8889,17 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::iterator arg2 ;
-  std::vector<int >::size_type arg3 ;
-  std::vector<int >::value_type *arg4 = 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::iterator arg2 ;
+  std::vector< int >::size_type arg3 ;
+  std::vector< int >::value_type *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   size_t val3 ;
   int ecode3 = 0 ;
-  std::vector<int >::value_type temp4 ;
+  std::vector< int >::value_type temp4 ;
   int val4 ;
   int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
@@ -7588,34 +8908,34 @@ SWIGINTERN PyObject *_wrap_IntVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(sel
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:IntVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_insert" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<int >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< int >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector<int >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "IntVector_insert" "', argument " "2"" of type '" "std::vector< int >::iterator""'");
     }
   }
   ecode3 = SWIG_AsVal_size_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "IntVector_insert" "', argument " "3"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg3 = static_cast< std::vector<int >::size_type >(val3);
+  arg3 = static_cast< std::vector< int >::size_type >(val3);
   ecode4 = SWIG_AsVal_int(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IntVector_insert" "', argument " "4"" of type '" "std::vector<int >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "IntVector_insert" "', argument " "4"" of type '" "std::vector< int >::value_type""'");
   } 
-  temp4 = static_cast< std::vector<int >::value_type >(val4);
+  temp4 = static_cast< std::vector< int >::value_type >(val4);
   arg4 = &temp4;
-  (arg1)->insert(arg2,arg3,(std::vector<int >::value_type const &)*arg4);
+  std_vector_Sl_int_Sg__insert__SWIG_1(arg1,arg2,arg3,(int const &)*arg4);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -7629,18 +8949,18 @@ SWIGINTERN PyObject *_wrap_IntVector_insert(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 4); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
       if (_v) {
         {
           int res = SWIG_AsVal_int(argv[2], NULL);
@@ -7654,12 +8974,12 @@ SWIGINTERN PyObject *_wrap_IntVector_insert(PyObject *self, PyObject *args) {
   }
   if (argc == 4) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<int,std::allocator<int > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<int,std::allocator< int > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<int >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< int >::iterator > *>(iter) != 0));
       if (_v) {
         {
           int res = SWIG_AsVal_size_t(argv[2], NULL);
@@ -7679,15 +8999,18 @@ SWIGINTERN PyObject *_wrap_IntVector_insert(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'IntVector_insert'.\n  Possible C/C++ prototypes are:\n    insert(std::vector<int >::iterator,std::vector<int >::value_type const &)\n    insert(std::vector<int >::iterator,std::vector<int >::size_type,std::vector<int >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'IntVector_insert'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< int >::insert(std::vector< int >::iterator,std::vector< int >::value_type const &)\n"
+    "    std::vector< int >::insert(std::vector< int >::iterator,std::vector< int >::size_type,std::vector< int >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_IntVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type arg2 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
+  std::vector< int >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -7696,16 +9019,16 @@ SWIGINTERN PyObject *_wrap_IntVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyO
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:IntVector_reserve",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_reserve" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_reserve" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_reserve" "', argument " "2"" of type '" "std::vector<int >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "IntVector_reserve" "', argument " "2"" of type '" "std::vector< int >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<int >::size_type >(val2);
+  arg2 = static_cast< std::vector< int >::size_type >(val2);
   (arg1)->reserve(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -7716,19 +9039,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_IntVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
-  std::vector<int >::size_type result;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:IntVector_capacity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_capacity" "', argument " "1"" of type '" "std::vector<int > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IntVector_capacity" "', argument " "1"" of type '" "std::vector< int > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
-  result = ((std::vector<int > const *)arg1)->capacity();
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
+  result = ((std::vector< int > const *)arg1)->capacity();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -7738,19 +9061,18 @@ fail:
 
 SWIGINTERN PyObject *_wrap_delete_IntVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<int > *arg1 = (std::vector<int > *) 0 ;
+  std::vector< int > *arg1 = (std::vector< int > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:delete_IntVector",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_POINTER_DISOWN |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntVector" "', argument " "1"" of type '" "std::vector<int > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IntVector" "', argument " "1"" of type '" "std::vector< int > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<int > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< int > * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -7760,29 +9082,29 @@ fail:
 
 SWIGINTERN PyObject *IntVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, SWIG_NewClientData(obj));
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject *_wrap_DoubleVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
   arg2 = &obj0;
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_iterator" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_iterator" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (swig::PySwigIterator *)std_vector_Sl_double_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (swig::SwigPyIterator *)std_vector_Sl_double_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -7791,19 +9113,41 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  bool result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___nonzero__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (bool)std_vector_Sl_double_Sg____nonzero__((std::vector< double > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___nonzero__" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___bool__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (bool)std_vector_Sl_double_Sg____nonzero__((std::vector<double > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (bool)std_vector_Sl_double_Sg____bool__((std::vector< double > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -7813,19 +9157,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___len__" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___len__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = std_vector_Sl_double_Sg____len__((std::vector<double > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = std_vector_Sl_double_Sg____len__((std::vector< double > const *)arg1);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -7835,20 +9179,20 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::value_type result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::value_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_pop",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   try {
-    result = (std::vector<double >::value_type)std_vector_Sl_double_Sg__pop(arg1);
+    result = (std::vector< double >::value_type)std_vector_Sl_double_Sg__pop(arg1);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -7863,10 +9207,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
-  std::vector<double >::difference_type arg3 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
+  std::vector< double >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -7876,43 +9219,47 @@ SWIGINTERN PyObject *_wrap_DoubleVector___getslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getslice__" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getslice__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___getslice__" "', argument " "3"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___getslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<double >::difference_type >(val3);
+  arg3 = static_cast< std::vector< double >::difference_type >(val3);
   try {
-    result = (std::vector<double,std::allocator<double > > *)std_vector_Sl_double_Sg____getslice__(arg1,arg2,arg3);
+    result = (std::vector< double,std::allocator< double > > *)std_vector_Sl_double_Sg____getslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector___setslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
-  std::vector<double >::difference_type arg3 ;
-  std::vector<double,std::allocator<double > > *arg4 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
+  std::vector< double >::difference_type arg3 ;
+  std::vector< double,std::allocator< double > > *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -7926,34 +9273,34 @@ SWIGINTERN PyObject *_wrap_DoubleVector___setslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setslice__" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setslice__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setslice__" "', argument " "3"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<double >::difference_type >(val3);
+  arg3 = static_cast< std::vector< double >::difference_type >(val3);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res4 = swig::asptr(obj3, &ptr);
     if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector<double,std::allocator<double > > const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector<double,std::allocator<double > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
     }
     arg4 = ptr;
   }
   try {
-    std_vector_Sl_double_Sg____setslice__(arg1,arg2,arg3,(std::vector<double,std::allocator<double > > const &)*arg4);
+    std_vector_Sl_double_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< double,std::allocator< double > > const &)*arg4);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -7971,11 +9318,11 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
-  std::vector<double >::difference_type arg3 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
+  std::vector< double >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -7986,28 +9333,31 @@ SWIGINTERN PyObject *_wrap_DoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delslice__" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delslice__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___delslice__" "', argument " "3"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<double >::difference_type >(val3);
+  arg3 = static_cast< std::vector< double >::difference_type >(val3);
   try {
-    std_vector_Sl_double_Sg____delslice__(arg1,arg2,arg3);
+    std_vector_Sl_double_Sg____setslice____SWIG_0(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -8016,34 +9366,110 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setslice__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[5];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_DoubleVector___setslice____SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = swig::asptr(argv[3], (std::vector<double,std::allocator< double > >**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_DoubleVector___setslice____SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___setslice__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::__setslice__(std::vector< double >::difference_type,std::vector< double >::difference_type,std::vector< double,std::allocator< double > > const &)\n"
+    "    std::vector< double >::__setslice__(std::vector< double >::difference_type,std::vector< double >::difference_type)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
+  std::vector< double >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delitem__" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delslice__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delitem__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delslice__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___delslice__" "', argument " "3"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
+  arg3 = static_cast< std::vector< double >::difference_type >(val3);
   try {
-    std_vector_Sl_double_Sg____delitem__(arg1,arg2);
+    std_vector_Sl_double_Sg____delslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -8052,11 +9478,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
-  std::vector<double >::value_type *result = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -8064,246 +9489,155 @@ SWIGINTERN PyObject *_wrap_DoubleVector___getitem__(PyObject *SWIGUNUSEDPARM(sel
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getitem__" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getitem__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___delitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
   try {
-    {
-      std::vector<double >::value_type const &_result_ref = std_vector_Sl_double_Sg____getitem__((std::vector<double > const *)arg1,arg2);
-      result = (std::vector<double >::value_type *) &_result_ref;
-    }
+    std_vector_Sl_double_Sg____delitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_From_double(static_cast< double >(*result));
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::difference_type arg2 ;
-  std::vector<double >::value_type *arg3 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  std::vector<double >::value_type temp3 ;
-  double val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "std::vector<double >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<double >::difference_type >(val2);
-  ecode3 = SWIG_AsVal_double(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector<double >::value_type""'");
-  } 
-  temp3 = static_cast< std::vector<double >::value_type >(val3);
-  arg3 = &temp3;
   try {
-    std_vector_Sl_double_Sg____setitem__(arg1,arg2,(double const &)*arg3);
+    result = (std::vector< double,std::allocator< double > > *)std_vector_Sl_double_Sg____getitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_Py_Void();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::value_type *arg2 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  std::vector< double,std::allocator< double > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::vector<double >::value_type temp2 ;
-  double val2 ;
-  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_append",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_append" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  ecode2 = SWIG_AsVal_double(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_append" "', argument " "2"" of type '" "std::vector<double >::value_type""'");
-  } 
-  temp2 = static_cast< std::vector<double >::value_type >(val2);
-  arg2 = &temp2;
-  std_vector_Sl_double_Sg__append(arg1,(double const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_DoubleVector")) SWIG_fail;
-  result = (std::vector<double > *)new std::vector<double >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = 0 ;
-  std::vector<double > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleVector",&obj0)) SWIG_fail;
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector<double > const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  {
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector<double > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double,std::allocator< double > > const &""'"); 
     }
-    arg1 = ptr;
+    arg3 = ptr;
   }
-  result = (std::vector<double > *)new std::vector<double >((std::vector<double > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_empty" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+  try {
+    std_vector_Sl_double_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (bool)((std::vector<double > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_size" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_clear" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  (arg1)->clear();
+  
   resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double > *arg2 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_swap" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector<double > &""'"); 
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector<double > &""'"); 
+  try {
+    std_vector_Sl_double_Sg____setitem____SWIG_1(arg1,arg2);
   }
-  arg2 = reinterpret_cast< std::vector<double > * >(argp2);
-  (arg1)->swap(*arg2);
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -8311,360 +9645,595 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  SwigValueWrapper<std::allocator<double > > result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_get_allocator" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::vector<double >::allocator_type(static_cast< const std::vector<double >::allocator_type& >(result))), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_begin" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_begin" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+  try {
+    std_vector_Sl_double_Sg____delitem____SWIG_1(arg1,arg2);
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_begin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___delitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_begin__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleVector___delitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_begin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_DoubleVector___delitem____SWIG_0(self, args);
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___delitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::__delitem__(std::vector< double >::difference_type)\n"
+    "    std::vector< double >::__delitem__(PySliceObject *)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::vector< double >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_end" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_end" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___getitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
+  try {
+    result = (std::vector< double >::value_type *) &std_vector_Sl_double_Sg____getitem____SWIG_1((std::vector< double > const *)arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_From_double(static_cast< double >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_end(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___getitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_end__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleVector___getitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_end__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_DoubleVector___getitem____SWIG_1(self, args);
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___getitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::__getitem__(PySliceObject *)\n"
+    "    std::vector< double >::__getitem__(std::vector< double >::difference_type) const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::reverse_iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::difference_type arg2 ;
+  std::vector< double >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  std::vector< double >::value_type temp3 ;
+  double val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rbegin" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleVector_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rbegin" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector___setitem__" "', argument " "2"" of type '" "std::vector< double >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< double >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_double(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
+  } 
+  temp3 = static_cast< std::vector< double >::value_type >(val3);
+  arg3 = &temp3;
+  try {
+    std_vector_Sl_double_Sg____setitem____SWIG_2(arg1,arg2,(double const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_rbegin__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleVector___setitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleVector_rbegin__SWIG_1(self, args);
-    }
-  }
-  
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_DoubleVector___setitem____SWIG_0(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_double(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_DoubleVector___setitem____SWIG_2(self, args);
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::__setitem__(PySliceObject *,std::vector< double,std::allocator< double > > const &)\n"
+    "    std::vector< double >::__setitem__(PySliceObject *)\n"
+    "    std::vector< double >::__setitem__(std::vector< double >::difference_type,std::vector< double >::value_type const &)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::value_type *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  std::vector< double >::value_type temp2 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_append",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_append" "', argument " "1"" of type '" "std::vector< double > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  ecode2 = SWIG_AsVal_double(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_append" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
+  } 
+  temp2 = static_cast< std::vector< double >::value_type >(val2);
+  arg2 = &temp2;
+  std_vector_Sl_double_Sg__append(arg1,(double const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_DoubleVector")) SWIG_fail;
+  result = (std::vector< double > *)new std::vector< double >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  PyObject * obj0 = 0 ;
+  std::vector< double > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleVector",&obj0)) SWIG_fail;
+  {
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double > const &""'"); 
+    }
+    arg1 = ptr;
+  }
+  result = (std::vector< double > *)new std::vector< double >((std::vector< double > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::reverse_iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rend" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_empty" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (bool)((std::vector< double > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::const_reverse_iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rend" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_size" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = ((std::vector< double > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleVector_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_DoubleVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_clear" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleVector_rend__SWIG_0(self, args);
-    }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_swap" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleVector_rend__SWIG_1(self, args);
-    }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector< double > &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleVector_swap" "', argument " "2"" of type '" "std::vector< double > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< double > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< double > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_get_allocator" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = ((std::vector< double > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::vector< double >::allocator_type(static_cast< const std::vector< double >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_double_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< double >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_begin" "', argument " "1"" of type '" "std::vector< double > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< double >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_end" "', argument " "1"" of type '" "std::vector< double > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< double >::reverse_iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rbegin" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< double >::reverse_iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_rend" "', argument " "1"" of type '" "std::vector< double > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double >::size_type arg1 ;
-  std::vector<double > *result = 0 ;
+  std::vector< double >::size_type arg1 ;
   size_t val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleVector",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<double >::size_type >(val1);
-  result = (std::vector<double > *)new std::vector<double >(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_NEW |  0 );
+  arg1 = static_cast< std::vector< double >::size_type >(val1);
+  result = (std::vector< double > *)new std::vector< double >(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -8673,17 +10242,17 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_pop_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop_back" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_pop_back" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   (arg1)->pop_back();
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -8694,8 +10263,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type arg2 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -8704,16 +10273,16 @@ SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_resize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::size_type >(val2);
+  arg2 = static_cast< std::vector< double >::size_type >(val2);
   (arg1)->resize(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -8724,36 +10293,36 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator arg2 ;
-  std::vector<double >::iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< double >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<double >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_double_Sg__erase__SWIG_0(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -8762,51 +10331,51 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator arg2 ;
-  std::vector<double >::iterator arg3 ;
-  std::vector<double >::iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::iterator arg2 ;
+  std::vector< double >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
+  swig::SwigPyIterator *iter3 = 0 ;
   int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< double >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_erase" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<double >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
     }
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector<double >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector< double >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<double >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter3);
+    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter3);
     if (iter_t) {
       arg3 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector<double >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_erase" "', argument " "3"" of type '" "std::vector< double >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_double_Sg__erase__SWIG_1(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -8819,18 +10388,18 @@ SWIGINTERN PyObject *_wrap_DoubleVector_erase(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
       if (_v) {
         return _wrap_DoubleVector_erase__SWIG_0(self, args);
       }
@@ -8838,16 +10407,16 @@ SWIGINTERN PyObject *_wrap_DoubleVector_erase(PyObject *self, PyObject *args) {
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
       if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter) != 0));
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
         if (_v) {
           return _wrap_DoubleVector_erase__SWIG_1(self, args);
         }
@@ -8856,38 +10425,41 @@ SWIGINTERN PyObject *_wrap_DoubleVector_erase(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::vector<double >::iterator)\n    erase(std::vector<double >::iterator,std::vector<double >::iterator)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::erase(std::vector< double >::iterator)\n"
+    "    std::vector< double >::erase(std::vector< double >::iterator,std::vector< double >::iterator)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_DoubleVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double >::size_type arg1 ;
-  std::vector<double >::value_type *arg2 = 0 ;
-  std::vector<double > *result = 0 ;
+  std::vector< double >::size_type arg1 ;
+  std::vector< double >::value_type *arg2 = 0 ;
   size_t val1 ;
   int ecode1 = 0 ;
-  std::vector<double >::value_type temp2 ;
+  std::vector< double >::value_type temp2 ;
   double val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< double > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:new_DoubleVector",&obj0,&obj1)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleVector" "', argument " "1"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<double >::size_type >(val1);
+  arg1 = static_cast< std::vector< double >::size_type >(val1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_DoubleVector" "', argument " "2"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_DoubleVector" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp2 = static_cast< std::vector<double >::value_type >(val2);
+  temp2 = static_cast< std::vector< double >::value_type >(val2);
   arg2 = &temp2;
-  result = (std::vector<double > *)new std::vector<double >(arg1,(std::vector<double >::value_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_NEW |  0 );
+  result = (std::vector< double > *)new std::vector< double >(arg1,(std::vector< double >::value_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -8900,8 +10472,8 @@ SWIGINTERN PyObject *_wrap_new_DoubleVector(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -8919,7 +10491,7 @@ SWIGINTERN PyObject *_wrap_new_DoubleVector(PyObject *self, PyObject *args) {
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       return _wrap_new_DoubleVector__SWIG_1(self, args);
@@ -8943,36 +10515,41 @@ SWIGINTERN PyObject *_wrap_new_DoubleVector(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_DoubleVector'.\n  Possible C/C++ prototypes are:\n    std::vector<(double)>()\n    std::vector<(double)>(std::vector<double > const &)\n    std::vector<(double)>(std::vector<double >::size_type)\n    std::vector<(double)>(std::vector<double >::size_type,std::vector<double >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_DoubleVector'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::vector()\n"
+    "    std::vector< double >::vector(std::vector< double > const &)\n"
+    "    std::vector< double >::vector(std::vector< double >::size_type)\n"
+    "    std::vector< double >::vector(std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::value_type *arg2 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::vector<double >::value_type temp2 ;
+  std::vector< double >::value_type temp2 ;
   double val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_push_back",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_push_back" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_push_back" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_double(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_push_back" "', argument " "2"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_push_back" "', argument " "2"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp2 = static_cast< std::vector<double >::value_type >(val2);
+  temp2 = static_cast< std::vector< double >::value_type >(val2);
   arg2 = &temp2;
-  (arg1)->push_back((std::vector<double >::value_type const &)*arg2);
+  (arg1)->push_back((std::vector< double >::value_type const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -8982,22 +10559,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::value_type *result = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_front",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_front" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  {
-    std::vector<double >::value_type const &_result_ref = ((std::vector<double > const *)arg1)->front();
-    result = (std::vector<double >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_front" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (std::vector< double >::value_type *) &((std::vector< double > const *)arg1)->front();
   resultobj = SWIG_From_double(static_cast< double >(*result));
   return resultobj;
 fail:
@@ -9007,22 +10581,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::value_type *result = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_back" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  {
-    std::vector<double >::value_type const &_result_ref = ((std::vector<double > const *)arg1)->back();
-    result = (std::vector<double >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_back" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = (std::vector< double >::value_type *) &((std::vector< double > const *)arg1)->back();
   resultobj = SWIG_From_double(static_cast< double >(*result));
   return resultobj;
 fail:
@@ -9032,14 +10603,14 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type arg2 ;
-  std::vector<double >::value_type *arg3 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::size_type arg2 ;
+  std::vector< double >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
-  std::vector<double >::value_type temp3 ;
+  std::vector< double >::value_type temp3 ;
   double val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -9047,23 +10618,23 @@ SWIGINTERN PyObject *_wrap_DoubleVector_assign(PyObject *SWIGUNUSEDPARM(self), P
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_assign" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_assign" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_assign" "', argument " "2"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_assign" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::size_type >(val2);
+  arg2 = static_cast< std::vector< double >::size_type >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_assign" "', argument " "3"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_assign" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<double >::value_type >(val3);
+  temp3 = static_cast< std::vector< double >::value_type >(val3);
   arg3 = &temp3;
-  (arg1)->assign(arg2,(std::vector<double >::value_type const &)*arg3);
+  (arg1)->assign(arg2,(std::vector< double >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -9073,14 +10644,14 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type arg2 ;
-  std::vector<double >::value_type *arg3 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::size_type arg2 ;
+  std::vector< double >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
   int ecode2 = 0 ;
-  std::vector<double >::value_type temp3 ;
+  std::vector< double >::value_type temp3 ;
   double val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
@@ -9088,23 +10659,23 @@ SWIGINTERN PyObject *_wrap_DoubleVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_resize" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_resize" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::size_type >(val2);
+  arg2 = static_cast< std::vector< double >::size_type >(val2);
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_resize" "', argument " "3"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_resize" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<double >::value_type >(val3);
+  temp3 = static_cast< std::vector< double >::value_type >(val3);
   arg3 = &temp3;
-  (arg1)->resize(arg2,(std::vector<double >::value_type const &)*arg3);
+  (arg1)->resize(arg2,(std::vector< double >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -9118,13 +10689,13 @@ SWIGINTERN PyObject *_wrap_DoubleVector_resize(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -9138,7 +10709,7 @@ SWIGINTERN PyObject *_wrap_DoubleVector_resize(PyObject *self, PyObject *args) {
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -9158,54 +10729,57 @@ SWIGINTERN PyObject *_wrap_DoubleVector_resize(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_resize'.\n  Possible C/C++ prototypes are:\n    resize(std::vector<double >::size_type)\n    resize(std::vector<double >::size_type,std::vector<double >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_resize'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::resize(std::vector< double >::size_type)\n"
+    "    std::vector< double >::resize(std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator arg2 ;
-  std::vector<double >::value_type *arg3 = 0 ;
-  std::vector<double >::iterator result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::iterator arg2 ;
+  std::vector< double >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  std::vector<double >::value_type temp3 ;
+  std::vector< double >::value_type temp3 ;
   double val3 ;
   int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< double >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<double >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
     }
   }
   ecode3 = SWIG_AsVal_double(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp3 = static_cast< std::vector<double >::value_type >(val3);
+  temp3 = static_cast< std::vector< double >::value_type >(val3);
   arg3 = &temp3;
-  result = (arg1)->insert(arg2,(std::vector<double >::value_type const &)*arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<double >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_double_Sg__insert__SWIG_0(arg1,arg2,(double const &)*arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< double >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -9214,17 +10788,17 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::iterator arg2 ;
-  std::vector<double >::size_type arg3 ;
-  std::vector<double >::value_type *arg4 = 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::iterator arg2 ;
+  std::vector< double >::size_type arg3 ;
+  std::vector< double >::value_type *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   size_t val3 ;
   int ecode3 = 0 ;
-  std::vector<double >::value_type temp4 ;
+  std::vector< double >::value_type temp4 ;
   double val4 ;
   int ecode4 = 0 ;
   PyObject * obj0 = 0 ;
@@ -9233,34 +10807,34 @@ SWIGINTERN PyObject *_wrap_DoubleVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_insert" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<double >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< double >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector<double >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleVector_insert" "', argument " "2"" of type '" "std::vector< double >::iterator""'");
     }
   }
   ecode3 = SWIG_AsVal_size_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleVector_insert" "', argument " "3"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg3 = static_cast< std::vector<double >::size_type >(val3);
+  arg3 = static_cast< std::vector< double >::size_type >(val3);
   ecode4 = SWIG_AsVal_double(obj3, &val4);
   if (!SWIG_IsOK(ecode4)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "DoubleVector_insert" "', argument " "4"" of type '" "std::vector<double >::value_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "DoubleVector_insert" "', argument " "4"" of type '" "std::vector< double >::value_type""'");
   } 
-  temp4 = static_cast< std::vector<double >::value_type >(val4);
+  temp4 = static_cast< std::vector< double >::value_type >(val4);
   arg4 = &temp4;
-  (arg1)->insert(arg2,arg3,(std::vector<double >::value_type const &)*arg4);
+  std_vector_Sl_double_Sg__insert__SWIG_1(arg1,arg2,arg3,(double const &)*arg4);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -9274,18 +10848,18 @@ SWIGINTERN PyObject *_wrap_DoubleVector_insert(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 4); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
       if (_v) {
         {
           int res = SWIG_AsVal_double(argv[2], NULL);
@@ -9299,12 +10873,12 @@ SWIGINTERN PyObject *_wrap_DoubleVector_insert(PyObject *self, PyObject *args) {
   }
   if (argc == 4) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<double,std::allocator<double > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<double,std::allocator< double > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<double >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< double >::iterator > *>(iter) != 0));
       if (_v) {
         {
           int res = SWIG_AsVal_size_t(argv[2], NULL);
@@ -9324,15 +10898,18 @@ SWIGINTERN PyObject *_wrap_DoubleVector_insert(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleVector_insert'.\n  Possible C/C++ prototypes are:\n    insert(std::vector<double >::iterator,std::vector<double >::value_type const &)\n    insert(std::vector<double >::iterator,std::vector<double >::size_type,std::vector<double >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleVector_insert'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< double >::insert(std::vector< double >::iterator,std::vector< double >::value_type const &)\n"
+    "    std::vector< double >::insert(std::vector< double >::iterator,std::vector< double >::size_type,std::vector< double >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type arg2 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
+  std::vector< double >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -9341,16 +10918,16 @@ SWIGINTERN PyObject *_wrap_DoubleVector_reserve(PyObject *SWIGUNUSEDPARM(self),
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleVector_reserve",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_reserve" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_reserve" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_reserve" "', argument " "2"" of type '" "std::vector<double >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleVector_reserve" "', argument " "2"" of type '" "std::vector< double >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<double >::size_type >(val2);
+  arg2 = static_cast< std::vector< double >::size_type >(val2);
   (arg1)->reserve(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -9361,19 +10938,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
-  std::vector<double >::size_type result;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleVector_capacity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_capacity" "', argument " "1"" of type '" "std::vector<double > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleVector_capacity" "', argument " "1"" of type '" "std::vector< double > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
-  result = ((std::vector<double > const *)arg1)->capacity();
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
+  result = ((std::vector< double > const *)arg1)->capacity();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -9383,19 +10960,18 @@ fail:
 
 SWIGINTERN PyObject *_wrap_delete_DoubleVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<double > *arg1 = (std::vector<double > *) 0 ;
+  std::vector< double > *arg1 = (std::vector< double > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:delete_DoubleVector",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_POINTER_DISOWN |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_DoubleVector" "', argument " "1"" of type '" "std::vector<double > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_DoubleVector" "', argument " "1"" of type '" "std::vector< double > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<double > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< double > * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -9405,29 +10981,29 @@ fail:
 
 SWIGINTERN PyObject *DoubleVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, SWIG_NewClientData(obj));
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
   arg2 = &obj0;
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_iterator" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_iterator" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (swig::PySwigIterator *)std_vector_Sl_std_vector_Sl_double_Sg__Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (swig::SwigPyIterator *)std_vector_Sl_std_vector_Sl_double_Sg__Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -9436,19 +11012,41 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  bool result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___nonzero__" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (bool)std_vector_Sl_std_vector_Sl_double_Sg__Sg____nonzero__((std::vector< std::vector< double > > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___nonzero__" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___bool__" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (bool)std_vector_Sl_std_vector_Sl_double_Sg__Sg____nonzero__((std::vector<std::vector<double > > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (bool)std_vector_Sl_std_vector_Sl_double_Sg__Sg____bool__((std::vector< std::vector< double > > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -9458,19 +11056,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___len__" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___len__" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = std_vector_Sl_std_vector_Sl_double_Sg__Sg____len__((std::vector<std::vector<double > > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = std_vector_Sl_std_vector_Sl_double_Sg__Sg____len__((std::vector< std::vector< double > > const *)arg1);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -9480,18 +11078,18 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::value_type result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::value_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_pop",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_pop" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_pop" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   try {
     result = std_vector_Sl_std_vector_Sl_double_Sg__Sg__pop(arg1);
   }
@@ -9499,7 +11097,7 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_pop(PyObject *SWIGUNUSEDPARM(self)
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = swig::from(static_cast< std::vector<double,std::allocator<double > > >(result));
+  resultobj = swig::from(static_cast< std::vector<double,std::allocator< double > > >(result));
   return resultobj;
 fail:
   return NULL;
@@ -9508,10 +11106,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  std::vector<std::vector<double > >::difference_type arg3 ;
-  std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *result = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
+  std::vector< std::vector< double > >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -9521,43 +11118,47 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getslice__(PyObject *SWIGUNUSEDP
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___getslice__" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___getslice__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___getslice__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___getslice__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___getslice__" "', argument " "3"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___getslice__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::vector<double > >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::vector< double > >::difference_type >(val3);
   try {
-    result = (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *)std_vector_Sl_std_vector_Sl_double_Sg__Sg____getslice__(arg1,arg2,arg3);
+    result = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)std_vector_Sl_std_vector_Sl_double_Sg__Sg____getslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  std::vector<std::vector<double > >::difference_type arg3 ;
-  std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *arg4 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
+  std::vector< std::vector< double > >::difference_type arg3 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -9571,34 +11172,34 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setslice__(PyObject *SWIGUNUSEDP
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleDoubleVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setslice__" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___setslice__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___setslice__" "', argument " "3"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::vector<double > >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::vector< double > >::difference_type >(val3);
   {
-    std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *ptr = (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *)0;
+    std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
     res4 = swig::asptr(obj3, &ptr);
     if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleDoubleVector___setslice__" "', argument " "4"" of type '" "std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleDoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector___setslice__" "', argument " "4"" of type '" "std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector___setslice__" "', argument " "4"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
     arg4 = ptr;
   }
   try {
-    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setslice__(arg1,arg2,arg3,(std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > const &)*arg4);
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg4);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -9616,11 +11217,11 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  std::vector<std::vector<double > >::difference_type arg3 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
+  std::vector< std::vector< double > >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -9631,28 +11232,31 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delslice__(PyObject *SWIGUNUSEDP
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___delslice__" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setslice__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___delslice__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___setslice__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___delslice__" "', argument " "3"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___setslice__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::vector<double > >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::vector< double > >::difference_type >(val3);
   try {
-    std_vector_Sl_std_vector_Sl_double_Sg__Sg____delslice__(arg1,arg2,arg3);
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setslice____SWIG_0(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -9661,34 +11265,110 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  void *argp1 = 0 ;
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setslice__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[5];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_DoubleDoubleVector___setslice____SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = swig::asptr(argv[3], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_DoubleDoubleVector___setslice____SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector___setslice__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::__setslice__(std::vector< std::vector< double > >::difference_type,std::vector< std::vector< double > >::difference_type,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n"
+    "    std::vector< std::vector< double > >::__setslice__(std::vector< std::vector< double > >::difference_type,std::vector< std::vector< double > >::difference_type)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
+  std::vector< std::vector< double > >::difference_type arg3 ;
+  void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___delitem__" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___delslice__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___delitem__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___delslice__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector___delslice__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg3 = static_cast< std::vector< std::vector< double > >::difference_type >(val3);
   try {
-    std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem__(arg1,arg2);
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____delslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -9697,11 +11377,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  std::vector<std::vector<double > >::value_type *result = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -9709,666 +11388,808 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getitem__(PyObject *SWIGUNUSEDPA
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___getitem__" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___getitem__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___delitem__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
   try {
-    {
-      std::vector<std::vector<double > >::value_type const &_result_ref = std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem__((std::vector<std::vector<double > > const *)arg1,arg2);
-      result = (std::vector<std::vector<double > >::value_type *) &_result_ref;
-    }
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = swig::from(static_cast< std::vector<double,std::allocator<double > > >(*result));
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::difference_type arg2 ;
-  std::vector<std::vector<double > >::value_type *arg3 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setitem__" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___setitem__" "', argument " "2"" of type '" "std::vector<std::vector<double > >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<std::vector<double > >::difference_type >(val2);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
-    res3 = swig::asptr(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
-    arg3 = ptr;
+    arg2 = (PySliceObject *) obj1;
   }
   try {
-    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem__(arg1,arg2,(std::vector<double,std::allocator<double > > const &)*arg3);
+    result = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::value_type *arg2 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_append",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_append" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
-    res2 = swig::asptr(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_append" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_append" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
-    arg2 = ptr;
+    arg2 = (PySliceObject *) obj1;
   }
-  std_vector_Sl_std_vector_Sl_double_Sg__Sg__append(arg1,(std::vector<double,std::allocator<double > > const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_DoubleDoubleVector")) SWIG_fail;
-  result = (std::vector<std::vector<double > > *)new std::vector<std::vector<double > >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double,std::allocator<double > > > *arg1 = 0 ;
-  std::vector<std::vector<double > > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleDoubleVector",&obj0)) SWIG_fail;
   {
-    std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *ptr = (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector<std::vector<double,std::allocator<double > > > const &""'"); 
+    std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector<std::vector<double,std::allocator<double > > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &""'"); 
     }
-    arg1 = ptr;
+    arg3 = ptr;
   }
-  result = (std::vector<std::vector<double > > *)new std::vector<std::vector<double > >((std::vector<std::vector<double,std::allocator<double > > > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  try {
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_0(arg1,arg2,(std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  bool result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_empty" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (bool)((std::vector<std::vector<double > > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_size" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___delitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____delitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___delitem__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_clear" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
-  return resultobj;
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleDoubleVector___delitem____SWIG_1(self, args);
+      }
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_DoubleDoubleVector___delitem____SWIG_0(self, args);
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector___delitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::__delitem__(std::vector< std::vector< double > >::difference_type)\n"
+    "    std::vector< std::vector< double > >::__delitem__(PySliceObject *)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double,std::allocator<double > > > *arg2 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< std::vector< double > >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_swap" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___getitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_swap" "', argument " "2"" of type '" "std::vector<std::vector<double,std::allocator<double > > > &""'"); 
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___getitem__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
+  try {
+    result = (std::vector< std::vector< double > >::value_type *) &std_vector_Sl_std_vector_Sl_double_Sg__Sg____getitem____SWIG_1((std::vector< std::vector< double > > const *)arg1,arg2);
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_swap" "', argument " "2"" of type '" "std::vector<std::vector<double,std::allocator<double > > > &""'"); 
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg2 = reinterpret_cast< std::vector<std::vector<double,std::allocator<double > > > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
+  
+  resultobj = swig::from(static_cast< std::vector<double,std::allocator< double > > >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  SwigValueWrapper<std::allocator<std::vector<double,std::allocator<double > > > > result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___getitem__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_get_allocator" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::vector<std::vector<double > >::allocator_type(static_cast< const std::vector<std::vector<double > >::allocator_type& >(result))), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_begin" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleDoubleVector___getitem____SWIG_0(self, args);
+      }
+    }
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_DoubleDoubleVector___getitem____SWIG_1(self, args);
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector___getitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::__getitem__(PySliceObject *)\n"
+    "    std::vector< std::vector< double > >::__getitem__(std::vector< std::vector< double > >::difference_type) const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::const_iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::difference_type arg2 ;
+  std::vector< std::vector< double > >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_begin" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector___setitem__" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector___setitem__" "', argument " "2"" of type '" "std::vector< std::vector< double > >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::vector< double > >::difference_type >(val2);
+  {
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector___setitem__" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  try {
+    std_vector_Sl_std_vector_Sl_double_Sg__Sg____setitem____SWIG_2(arg1,arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_begin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleDoubleVector_begin__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_DoubleDoubleVector___setitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_DoubleDoubleVector___setitem____SWIG_0(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_DoubleDoubleVector_begin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_DoubleDoubleVector___setitem____SWIG_2(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::__setitem__(PySliceObject *,std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &)\n"
+    "    std::vector< std::vector< double > >::__setitem__(PySliceObject *)\n"
+    "    std::vector< std::vector< double > >::__setitem__(std::vector< std::vector< double > >::difference_type,std::vector< std::vector< double > >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_append",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_end" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_append" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  {
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
+    res2 = swig::asptr(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_append" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_append" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  std_vector_Sl_std_vector_Sl_double_Sg__Sg__append(arg1,(std::vector< double,std::allocator< double > > const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_end" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  if (!PyArg_ParseTuple(args,(char *)":new_DoubleDoubleVector")) SWIG_fail;
+  result = (std::vector< std::vector< double > > *)new std::vector< std::vector< double > >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double,std::allocator< double > > > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > > *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_end__SWIG_0(self, args);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleDoubleVector",&obj0)) SWIG_fail;
+  {
+    std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *ptr = (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector< std::vector< double,std::allocator< double > > > const &""'"); 
     }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_end__SWIG_1(self, args);
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector< std::vector< double,std::allocator< double > > > const &""'"); 
     }
+    arg1 = ptr;
   }
-  
+  result = (std::vector< std::vector< double > > *)new std::vector< std::vector< double > >((std::vector< std::vector< double,std::allocator< double > > > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::reverse_iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rbegin" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_empty" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (bool)((std::vector< std::vector< double > > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::const_reverse_iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rbegin" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_size" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = ((std::vector< std::vector< double > > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rbegin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_rbegin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_rbegin__SWIG_1(self, args);
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_clear" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::reverse_iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double,std::allocator< double > > > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rend" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_swap" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_swap" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > > > &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_swap" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > > > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< std::vector< double,std::allocator< double > > > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::const_reverse_iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::vector< double,std::allocator< double > > > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rend" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_get_allocator" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = ((std::vector< std::vector< double > > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::vector< std::vector< double > >::allocator_type(static_cast< const std::vector< std::vector< double > >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_rend__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_DoubleDoubleVector_rend__SWIG_1(self, args);
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_begin" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > >::size_type arg1 ;
-  std::vector<std::vector<double > > *result = 0 ;
-  size_t val1 ;
-  int ecode1 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleDoubleVector",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector<std::vector<double > >::size_type""'");
-  } 
-  arg1 = static_cast< std::vector<std::vector<double > >::size_type >(val1);
-  result = (std::vector<std::vector<double > > *)new std::vector<std::vector<double > >(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_end" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_pop_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_pop_back" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rbegin" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  (arg1)->pop_back();
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type arg2 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::vector< std::vector< double > >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_resize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_resize" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_rend" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > >::size_type arg1 ;
+  size_t val1 ;
+  int ecode1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:new_DoubleDoubleVector",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector< std::vector< double > >::size_type""'");
+  } 
+  arg1 = static_cast< std::vector< std::vector< double > >::size_type >(val1);
+  result = (std::vector< std::vector< double > > *)new std::vector< std::vector< double > >(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_pop_back",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_pop_back" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  (arg1)->pop_back();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::size_type arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_resize",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_resize" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_resize" "', argument " "2"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_resize" "', argument " "2"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::size_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::size_type >(val2);
   (arg1)->resize(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -10379,36 +12200,36 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator arg2 ;
-  std::vector<std::vector<double > >::iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< std::vector< double > >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_erase" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_erase" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_std_vector_Sl_double_Sg__Sg__erase__SWIG_0(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -10417,51 +12238,51 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator arg2 ;
-  std::vector<std::vector<double > >::iterator arg3 ;
-  std::vector<std::vector<double > >::iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::iterator arg2 ;
+  std::vector< std::vector< double > >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
+  swig::SwigPyIterator *iter3 = 0 ;
   int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::vector< double > >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_erase" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_erase" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
     }
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "3"" of type '" "std::vector<std::vector<double > >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "3"" of type '" "std::vector< std::vector< double > >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter3);
+    swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter3);
     if (iter_t) {
       arg3 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "3"" of type '" "std::vector<std::vector<double > >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_erase" "', argument " "3"" of type '" "std::vector< std::vector< double > >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_std_vector_Sl_double_Sg__Sg__erase__SWIG_1(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -10474,18 +12295,18 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_erase(PyObject *self, PyObject *ar
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter) != 0));
       if (_v) {
         return _wrap_DoubleDoubleVector_erase__SWIG_0(self, args);
       }
@@ -10493,16 +12314,16 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_erase(PyObject *self, PyObject *ar
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter) != 0));
       if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter) != 0));
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter) != 0));
         if (_v) {
           return _wrap_DoubleDoubleVector_erase__SWIG_1(self, args);
         }
@@ -10511,41 +12332,44 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_erase(PyObject *self, PyObject *ar
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::vector<std::vector<double > >::iterator)\n    erase(std::vector<std::vector<double > >::iterator,std::vector<std::vector<double > >::iterator)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::erase(std::vector< std::vector< double > >::iterator)\n"
+    "    std::vector< std::vector< double > >::erase(std::vector< std::vector< double > >::iterator,std::vector< std::vector< double > >::iterator)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > >::size_type arg1 ;
-  std::vector<std::vector<double > >::value_type *arg2 = 0 ;
-  std::vector<std::vector<double > > *result = 0 ;
+  std::vector< std::vector< double > >::size_type arg1 ;
+  std::vector< std::vector< double > >::value_type *arg2 = 0 ;
   size_t val1 ;
   int ecode1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< std::vector< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:new_DoubleDoubleVector",&obj0,&obj1)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<std::vector<double > >::size_type >(val1);
+  arg1 = static_cast< std::vector< std::vector< double > >::size_type >(val1);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res2 = swig::asptr(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_DoubleDoubleVector" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_DoubleDoubleVector" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleDoubleVector" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_DoubleDoubleVector" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg2 = ptr;
   }
-  result = (std::vector<std::vector<double > > *)new std::vector<std::vector<double > >(arg1,(std::vector<std::vector<double > >::value_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_NEW |  0 );
+  result = (std::vector< std::vector< double > > *)new std::vector< std::vector< double > >(arg1,(std::vector< std::vector< double > >::value_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_NEW |  0 );
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
@@ -10560,8 +12384,8 @@ SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector(PyObject *self, PyObject *args
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -10579,7 +12403,7 @@ SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector(PyObject *self, PyObject *args
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       return _wrap_new_DoubleDoubleVector__SWIG_1(self, args);
@@ -10592,7 +12416,7 @@ SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector(PyObject *self, PyObject *args
       _v = SWIG_CheckState(res);
     }
     if (_v) {
-      int res = swig::asptr(argv[1], (std::vector<double,std::allocator<double > >**)(0));
+      int res = swig::asptr(argv[1], (std::vector<double,std::allocator< double > >**)(0));
       _v = SWIG_CheckState(res);
       if (_v) {
         return _wrap_new_DoubleDoubleVector__SWIG_3(self, args);
@@ -10601,15 +12425,20 @@ SWIGINTERN PyObject *_wrap_new_DoubleDoubleVector(PyObject *self, PyObject *args
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_DoubleDoubleVector'.\n  Possible C/C++ prototypes are:\n    std::vector<(std::vector<(double)>)>()\n    std::vector<(std::vector<(double)>)>(std::vector<std::vector<double,std::allocator<double > > > const &)\n    std::vector<(std::vector<(double)>)>(std::vector<std::vector<double > >::size_type)\n    std::vector<(std::vector<(double)>)>(std::vector<std::vector<double > >::size_type,std:: [...]
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_DoubleDoubleVector'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::vector()\n"
+    "    std::vector< std::vector< double > >::vector(std::vector< std::vector< double,std::allocator< double > > > const &)\n"
+    "    std::vector< std::vector< double > >::vector(std::vector< std::vector< double > >::size_type)\n"
+    "    std::vector< std::vector< double > >::vector(std::vector< std::vector< double > >::size_type,std::vector< std::vector< double > >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::value_type *arg2 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
@@ -10617,23 +12446,23 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_push_back(PyObject *SWIGUNUSEDPARM
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_push_back",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_push_back" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_push_back" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res2 = swig::asptr(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_push_back" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "DoubleDoubleVector_push_back" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_push_back" "', argument " "2"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_push_back" "', argument " "2"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg2 = ptr;
   }
-  (arg1)->push_back((std::vector<std::vector<double > >::value_type const &)*arg2);
+  (arg1)->push_back((std::vector< std::vector< double > >::value_type const &)*arg2);
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -10645,23 +12474,20 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::value_type *result = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_front",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_front" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  {
-    std::vector<std::vector<double > >::value_type const &_result_ref = ((std::vector<std::vector<double > > const *)arg1)->front();
-    result = (std::vector<std::vector<double > >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_front" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  resultobj = swig::from(static_cast< std::vector<double,std::allocator<double > > >(*result));
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (std::vector< std::vector< double > >::value_type *) &((std::vector< std::vector< double > > const *)arg1)->front();
+  resultobj = swig::from(static_cast< std::vector<double,std::allocator< double > > >(*result));
   return resultobj;
 fail:
   return NULL;
@@ -10670,23 +12496,20 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::value_type *result = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::value_type *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_back" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  {
-    std::vector<std::vector<double > >::value_type const &_result_ref = ((std::vector<std::vector<double > > const *)arg1)->back();
-    result = (std::vector<std::vector<double > >::value_type *) &_result_ref;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_back" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  resultobj = swig::from(static_cast< std::vector<double,std::allocator<double > > >(*result));
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = (std::vector< std::vector< double > >::value_type *) &((std::vector< std::vector< double > > const *)arg1)->back();
+  resultobj = swig::from(static_cast< std::vector<double,std::allocator< double > > >(*result));
   return resultobj;
 fail:
   return NULL;
@@ -10695,9 +12518,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type arg2 ;
-  std::vector<std::vector<double > >::value_type *arg3 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::size_type arg2 ;
+  std::vector< std::vector< double > >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -10708,28 +12531,28 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_assign(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_assign" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_assign" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_assign" "', argument " "2"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_assign" "', argument " "2"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::size_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::size_type >(val2);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res3 = swig::asptr(obj2, &ptr);
     if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_assign" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_assign" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_assign" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_assign" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg3 = ptr;
   }
-  (arg1)->assign(arg2,(std::vector<std::vector<double > >::value_type const &)*arg3);
+  (arg1)->assign(arg2,(std::vector< std::vector< double > >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
@@ -10741,9 +12564,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type arg2 ;
-  std::vector<std::vector<double > >::value_type *arg3 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::size_type arg2 ;
+  std::vector< std::vector< double > >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -10754,28 +12577,28 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize__SWIG_1(PyObject *SWIGUNUSE
   PyObject * obj2 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_resize" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_resize" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_resize" "', argument " "2"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_resize" "', argument " "2"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::size_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::size_type >(val2);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res3 = swig::asptr(obj2, &ptr);
     if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_resize" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_resize" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_resize" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_resize" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg3 = ptr;
   }
-  (arg1)->resize(arg2,(std::vector<std::vector<double > >::value_type const &)*arg3);
+  (arg1)->resize(arg2,(std::vector< std::vector< double > >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
@@ -10791,13 +12614,13 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize(PyObject *self, PyObject *a
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -10811,7 +12634,7 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize(PyObject *self, PyObject *a
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -10819,7 +12642,7 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize(PyObject *self, PyObject *a
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        int res = swig::asptr(argv[2], (std::vector<double,std::allocator<double > >**)(0));
+        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
         _v = SWIG_CheckState(res);
         if (_v) {
           return _wrap_DoubleDoubleVector_resize__SWIG_1(self, args);
@@ -10829,57 +12652,60 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_resize(PyObject *self, PyObject *a
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_resize'.\n  Possible C/C++ prototypes are:\n    resize(std::vector<std::vector<double > >::size_type)\n    resize(std::vector<std::vector<double > >::size_type,std::vector<std::vector<double > >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector_resize'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::resize(std::vector< std::vector< double > >::size_type)\n"
+    "    std::vector< std::vector< double > >::resize(std::vector< std::vector< double > >::size_type,std::vector< std::vector< double > >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator arg2 ;
-  std::vector<std::vector<double > >::value_type *arg3 = 0 ;
-  std::vector<std::vector<double > >::iterator result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::iterator arg2 ;
+  std::vector< std::vector< double > >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::vector< double > >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:DoubleDoubleVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_insert" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_insert" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
     }
   }
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res3 = swig::asptr(obj2, &ptr);
     if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg3 = ptr;
   }
-  result = (arg1)->insert(arg2,(std::vector<std::vector<double > >::value_type const &)*arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::vector<double > >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_std_vector_Sl_double_Sg__Sg__insert__SWIG_0(arg1,arg2,(std::vector< double,std::allocator< double > > const &)*arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::vector< double > >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
@@ -10890,13 +12716,13 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::iterator arg2 ;
-  std::vector<std::vector<double > >::size_type arg3 ;
-  std::vector<std::vector<double > >::value_type *arg4 = 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::iterator arg2 ;
+  std::vector< std::vector< double > >::size_type arg3 ;
+  std::vector< std::vector< double > >::value_type *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   size_t val3 ;
   int ecode3 = 0 ;
@@ -10907,39 +12733,39 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert__SWIG_1(PyObject *SWIGUNUSE
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:DoubleDoubleVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_insert" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_insert" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector<std::vector<double > >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DoubleDoubleVector_insert" "', argument " "2"" of type '" "std::vector< std::vector< double > >::iterator""'");
     }
   }
   ecode3 = SWIG_AsVal_size_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "DoubleDoubleVector_insert" "', argument " "3"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg3 = static_cast< std::vector<std::vector<double > >::size_type >(val3);
+  arg3 = static_cast< std::vector< std::vector< double > >::size_type >(val3);
   {
-    std::vector<double,std::allocator<double > > *ptr = (std::vector<double,std::allocator<double > > *)0;
+    std::vector<double,std::allocator< double > > *ptr = (std::vector<double,std::allocator< double > > *)0;
     res4 = swig::asptr(obj3, &ptr);
     if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleDoubleVector_insert" "', argument " "4"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "DoubleDoubleVector_insert" "', argument " "4"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_insert" "', argument " "4"" of type '" "std::vector<std::vector<double > >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "DoubleDoubleVector_insert" "', argument " "4"" of type '" "std::vector< std::vector< double > >::value_type const &""'"); 
     }
     arg4 = ptr;
   }
-  (arg1)->insert(arg2,arg3,(std::vector<std::vector<double > >::value_type const &)*arg4);
+  std_vector_Sl_std_vector_Sl_double_Sg__Sg__insert__SWIG_1(arg1,arg2,arg3,(std::vector< double,std::allocator< double > > const &)*arg4);
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res4)) delete arg4;
   return resultobj;
@@ -10955,20 +12781,20 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert(PyObject *self, PyObject *a
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 4); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter) != 0));
       if (_v) {
-        int res = swig::asptr(argv[2], (std::vector<double,std::allocator<double > >**)(0));
+        int res = swig::asptr(argv[2], (std::vector<double,std::allocator< double > >**)(0));
         _v = SWIG_CheckState(res);
         if (_v) {
           return _wrap_DoubleDoubleVector_insert__SWIG_0(self, args);
@@ -10978,19 +12804,19 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert(PyObject *self, PyObject *a
   }
   if (argc == 4) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::vector<double > >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::vector< double > >::iterator > *>(iter) != 0));
       if (_v) {
         {
           int res = SWIG_AsVal_size_t(argv[2], NULL);
           _v = SWIG_CheckState(res);
         }
         if (_v) {
-          int res = swig::asptr(argv[3], (std::vector<double,std::allocator<double > >**)(0));
+          int res = swig::asptr(argv[3], (std::vector<double,std::allocator< double > >**)(0));
           _v = SWIG_CheckState(res);
           if (_v) {
             return _wrap_DoubleDoubleVector_insert__SWIG_1(self, args);
@@ -11001,15 +12827,18 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_insert(PyObject *self, PyObject *a
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'DoubleDoubleVector_insert'.\n  Possible C/C++ prototypes are:\n    insert(std::vector<std::vector<double > >::iterator,std::vector<std::vector<double > >::value_type const &)\n    insert(std::vector<std::vector<double > >::iterator,std::vector<std::vector<double > >::size_type,std::vector<std::vector<double > >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'DoubleDoubleVector_insert'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::vector< double > >::insert(std::vector< std::vector< double > >::iterator,std::vector< std::vector< double > >::value_type const &)\n"
+    "    std::vector< std::vector< double > >::insert(std::vector< std::vector< double > >::iterator,std::vector< std::vector< double > >::size_type,std::vector< std::vector< double > >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type arg2 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
+  std::vector< std::vector< double > >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -11018,16 +12847,16 @@ SWIGINTERN PyObject *_wrap_DoubleDoubleVector_reserve(PyObject *SWIGUNUSEDPARM(s
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:DoubleDoubleVector_reserve",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_reserve" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_reserve" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_reserve" "', argument " "2"" of type '" "std::vector<std::vector<double > >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "DoubleDoubleVector_reserve" "', argument " "2"" of type '" "std::vector< std::vector< double > >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<std::vector<double > >::size_type >(val2);
+  arg2 = static_cast< std::vector< std::vector< double > >::size_type >(val2);
   (arg1)->reserve(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -11038,19 +12867,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_DoubleDoubleVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
-  std::vector<std::vector<double > >::size_type result;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double > >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:DoubleDoubleVector_capacity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_capacity" "', argument " "1"" of type '" "std::vector<std::vector<double > > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DoubleDoubleVector_capacity" "', argument " "1"" of type '" "std::vector< std::vector< double > > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
-  result = ((std::vector<std::vector<double > > const *)arg1)->capacity();
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
+  result = ((std::vector< std::vector< double > > const *)arg1)->capacity();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -11060,19 +12889,18 @@ fail:
 
 SWIGINTERN PyObject *_wrap_delete_DoubleDoubleVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::vector<double > > *arg1 = (std::vector<std::vector<double > > *) 0 ;
+  std::vector< std::vector< double > > *arg1 = (std::vector< std::vector< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:delete_DoubleDoubleVector",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_POINTER_DISOWN |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector<std::vector<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_DoubleDoubleVector" "', argument " "1"" of type '" "std::vector< std::vector< double > > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::vector<double > > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::vector< double > > * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -11082,29 +12910,29 @@ fail:
 
 SWIGINTERN PyObject *DoubleDoubleVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, SWIG_NewClientData(obj));
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
 SWIGINTERN PyObject *_wrap_StringVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
   arg2 = &obj0;
   if (!PyArg_ParseTuple(args,(char *)"O:StringVector_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_iterator" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_iterator" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (swig::PySwigIterator *)std_vector_Sl_std_string_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (swig::SwigPyIterator *)std_vector_Sl_std_string_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -11113,19 +12941,41 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  bool result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:StringVector___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___nonzero__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (bool)std_vector_Sl_std_string_Sg____nonzero__((std::vector< std::string > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___nonzero__" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___bool__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (bool)std_vector_Sl_std_string_Sg____nonzero__((std::vector<std::string > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (bool)std_vector_Sl_std_string_Sg____bool__((std::vector< std::string > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -11135,19 +12985,19 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string >::size_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:StringVector___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___len__" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___len__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = std_vector_Sl_std_string_Sg____len__((std::vector<std::string > const *)arg1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = std_vector_Sl_std_string_Sg____len__((std::vector< std::string > const *)arg1);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -11157,18 +13007,18 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::value_type result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string >::value_type result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:StringVector_pop",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_pop" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_pop" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   try {
     result = std_vector_Sl_std_string_Sg__pop(arg1);
   }
@@ -11185,10 +13035,9 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
-  std::vector<std::string >::difference_type arg3 ;
-  std::vector<std::string,std::allocator<std::string > > *result = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
+  std::vector< std::string >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -11198,43 +13047,47 @@ SWIGINTERN PyObject *_wrap_StringVector___getslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::string,std::allocator< std::string > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___getslice__" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___getslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___getslice__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___getslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___getslice__" "', argument " "3"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___getslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::string >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::string >::difference_type >(val3);
   try {
-    result = (std::vector<std::string,std::allocator<std::string > > *)std_vector_Sl_std_string_Sg____getslice__(arg1,arg2,arg3);
+    result = (std::vector< std::string,std::allocator< std::string > > *)std_vector_Sl_std_string_Sg____getslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector___setslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
-  std::vector<std::string >::difference_type arg3 ;
-  std::vector<std::string,std::allocator<std::string > > *arg4 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
+  std::vector< std::string >::difference_type arg3 ;
+  std::vector< std::string,std::allocator< std::string > > *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -11248,34 +13101,34 @@ SWIGINTERN PyObject *_wrap_StringVector___setslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj3 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:StringVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setslice__" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___setslice__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___setslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___setslice__" "', argument " "3"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___setslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::string >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::string >::difference_type >(val3);
   {
-    std::vector<std::string,std::allocator<std::string > > *ptr = (std::vector<std::string,std::allocator<std::string > > *)0;
+    std::vector<std::string,std::allocator< std::string > > *ptr = (std::vector<std::string,std::allocator< std::string > > *)0;
     res4 = swig::asptr(obj3, &ptr);
     if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVector___setslice__" "', argument " "4"" of type '" "std::vector<std::string,std::allocator<std::string > > const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVector___setslice__" "', argument " "4"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector___setslice__" "', argument " "4"" of type '" "std::vector<std::string,std::allocator<std::string > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector___setslice__" "', argument " "4"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
     }
     arg4 = ptr;
   }
   try {
-    std_vector_Sl_std_string_Sg____setslice__(arg1,arg2,arg3,(std::vector<std::string,std::allocator<std::string > > const &)*arg4);
+    std_vector_Sl_std_string_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< std::string,std::allocator< std::string > > const &)*arg4);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
@@ -11293,11 +13146,11 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
-  std::vector<std::string >::difference_type arg3 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
+  std::vector< std::string >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -11308,28 +13161,31 @@ SWIGINTERN PyObject *_wrap_StringVector___delslice__(PyObject *SWIGUNUSEDPARM(se
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___delslice__" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___delslice__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___setslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
   ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
   if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___delslice__" "', argument " "3"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___setslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg3 = static_cast< std::vector<std::string >::difference_type >(val3);
+  arg3 = static_cast< std::vector< std::string >::difference_type >(val3);
   try {
-    std_vector_Sl_std_string_Sg____delslice__(arg1,arg2,arg3);
+    std_vector_Sl_std_string_Sg____setslice____SWIG_0(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -11338,34 +13194,110 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setslice__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[5];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_StringVector___setslice____SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 4) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = swig::asptr(argv[3], (std::vector<std::string,std::allocator< std::string > >**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_StringVector___setslice____SWIG_0(self, args);
+          }
+        }
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector___setslice__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::__setslice__(std::vector< std::string >::difference_type,std::vector< std::string >::difference_type,std::vector< std::string,std::allocator< std::string > > const &)\n"
+    "    std::vector< std::string >::__setslice__(std::vector< std::string >::difference_type,std::vector< std::string >::difference_type)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
+  std::vector< std::string >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
   int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___delitem__" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___delslice__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___delitem__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___delslice__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector___delslice__" "', argument " "3"" of type '" "std::vector< std::string >::difference_type""'");
+  } 
+  arg3 = static_cast< std::vector< std::string >::difference_type >(val3);
   try {
-    std_vector_Sl_std_string_Sg____delitem__(arg1,arg2);
+    std_vector_Sl_std_string_Sg____delslice__(arg1,arg2,arg3);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -11374,11 +13306,10 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
-  std::vector<std::string >::value_type *result = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   ptrdiff_t val2 ;
@@ -11386,223 +13317,193 @@ SWIGINTERN PyObject *_wrap_StringVector___getitem__(PyObject *SWIGUNUSEDPARM(sel
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___getitem__" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___delitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___getitem__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___delitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
   try {
-    {
-      std::vector<std::string >::value_type const &_result_ref = std_vector_Sl_std_string_Sg____getitem__((std::vector<std::string > const *)arg1,arg2);
-      result = (std::vector<std::string >::value_type *) &_result_ref;
-    }
+    std_vector_Sl_std_string_Sg____delitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::difference_type arg2 ;
-  std::vector<std::string >::value_type *arg3 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< std::string,std::allocator< std::string > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setitem__" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___getitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___setitem__" "', argument " "2"" of type '" "std::vector<std::string >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<std::string >::difference_type >(val2);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
-    arg3 = ptr;
+    arg2 = (PySliceObject *) obj1;
   }
   try {
-    std_vector_Sl_std_string_Sg____setitem__(arg1,arg2,(std::string const &)*arg3);
+    result = (std::vector< std::string,std::allocator< std::string > > *)std_vector_Sl_std_string_Sg____getitem____SWIG_0(arg1,arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
   
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::value_type *arg2 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  std::vector< std::string,std::allocator< std::string > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_append",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_append" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_append" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  {
+    std::vector<std::string,std::allocator< std::string > > *ptr = (std::vector<std::string,std::allocator< std::string > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_append" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector< std::string,std::allocator< std::string > > const &""'"); 
     }
-    arg2 = ptr;
+    arg3 = ptr;
+  }
+  try {
+    std_vector_Sl_std_string_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< std::string,std::allocator< std::string > > const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
   }
-  std_vector_Sl_std_string_Sg__append(arg1,(std::string const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)":new_StringVector")) SWIG_fail;
-  result = (std::vector<std::string > *)new std::vector<std::string >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_NEW |  0 );
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = 0 ;
-  std::vector<std::string > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_StringVector",&obj0)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   {
-    std::vector<std::string,std::allocator<std::string > > *ptr = (std::vector<std::string,std::allocator<std::string > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector<std::string > const &""'"); 
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector<std::string > const &""'"); 
-    }
-    arg1 = ptr;
+    arg2 = (PySliceObject *) obj1;
   }
-  result = (std::vector<std::string > *)new std::vector<std::string >((std::vector<std::string > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  try {
+    std_vector_Sl_std_string_Sg____setitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  bool result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_empty" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___delitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (bool)((std::vector<std::string > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_size" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_clear" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+  try {
+    std_vector_Sl_std_string_Sg____delitem____SWIG_1(arg1,arg2);
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  (arg1)->clear();
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -11610,393 +13511,565 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string > *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+SWIGINTERN PyObject *_wrap_StringVector___delitem__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_swap" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_swap" "', argument " "2"" of type '" "std::vector<std::string > &""'"); 
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_StringVector___delitem____SWIG_1(self, args);
+      }
+    }
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_swap" "', argument " "2"" of type '" "std::vector<std::string > &""'"); 
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_StringVector___delitem____SWIG_0(self, args);
+      }
+    }
   }
-  arg2 = reinterpret_cast< std::vector<std::string > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  SwigValueWrapper<std::allocator<std::string > > result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_get_allocator" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::vector<std::string >::allocator_type(static_cast< const std::vector<std::string >::allocator_type& >(result))), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector___delitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::__delitem__(std::vector< std::string >::difference_type)\n"
+    "    std::vector< std::string >::__delitem__(PySliceObject *)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::vector< std::string >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_begin" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___getitem__" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_begin" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___getitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
+  try {
+    result = (std::vector< std::string >::value_type *) &std_vector_Sl_std_string_Sg____getitem____SWIG_1((std::vector< std::string > const *)arg1,arg2);
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_begin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___getitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_StringVector_begin__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_StringVector___getitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_StringVector_begin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_StringVector___getitem____SWIG_1(self, args);
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector___getitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::__getitem__(PySliceObject *)\n"
+    "    std::vector< std::string >::__getitem__(std::vector< std::string >::difference_type) const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::difference_type arg2 ;
+  std::vector< std::string >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_end" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector___setitem__" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_end" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector___setitem__" "', argument " "2"" of type '" "std::vector< std::string >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::string >::difference_type >(val2);
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector___setitem__" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  try {
+    std_vector_Sl_std_string_Sg____setitem____SWIG_2(arg1,arg2,(std::string const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_end(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_StringVector_end__SWIG_0(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_StringVector___setitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<std::string,std::allocator< std::string > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_StringVector___setitem____SWIG_0(self, args);
+        }
+      }
+    }
+  }
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_StringVector_end__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_StringVector___setitem____SWIG_2(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::__setitem__(PySliceObject *,std::vector< std::string,std::allocator< std::string > > const &)\n"
+    "    std::vector< std::string >::__setitem__(PySliceObject *)\n"
+    "    std::vector< std::string >::__setitem__(std::vector< std::string >::difference_type,std::vector< std::string >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::reverse_iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_append",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rbegin" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_append" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_append" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_append" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  std_vector_Sl_std_string_Sg__append(arg1,(std::string const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+  std::vector< std::string > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rbegin" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  if (!PyArg_ParseTuple(args,(char *)":new_StringVector")) SWIG_fail;
+  result = (std::vector< std::string > *)new std::vector< std::string >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rbegin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::string > *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_StringVector_rbegin__SWIG_0(self, args);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_StringVector",&obj0)) SWIG_fail;
+  {
+    std::vector<std::string,std::allocator< std::string > > *ptr = (std::vector<std::string,std::allocator< std::string > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector< std::string > const &""'"); 
     }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_StringVector_rbegin__SWIG_1(self, args);
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector< std::string > const &""'"); 
     }
+    arg1 = ptr;
   }
+  result = (std::vector< std::string > *)new std::vector< std::string >((std::vector< std::string > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return resultobj;
+fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_empty" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (bool)((std::vector< std::string > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::reverse_iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rend" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_size" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = ((std::vector< std::string > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::const_reverse_iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rend" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_clear" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_StringVector_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_StringVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string > *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_swap" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_StringVector_rend__SWIG_0(self, args);
-    }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_swap" "', argument " "2"" of type '" "std::vector< std::string > &""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_StringVector_rend__SWIG_1(self, args);
-    }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_swap" "', argument " "2"" of type '" "std::vector< std::string > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< std::string > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::string > > result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_get_allocator" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = ((std::vector< std::string > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::vector< std::string >::allocator_type(static_cast< const std::vector< std::string >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__string_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::string >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_begin" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::string >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_end" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::string >::reverse_iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rbegin" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_StringVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< std::string >::reverse_iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_rend" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string >::size_type arg1 ;
-  std::vector<std::string > *result = 0 ;
+  std::vector< std::string >::size_type arg1 ;
   size_t val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_StringVector",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector<std::string >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector< std::string >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<std::string >::size_type >(val1);
-  result = (std::vector<std::string > *)new std::vector<std::string >(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_NEW |  0 );
+  arg1 = static_cast< std::vector< std::string >::size_type >(val1);
+  result = (std::vector< std::string > *)new std::vector< std::string >(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -12005,17 +14078,17 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:StringVector_pop_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_pop_back" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_pop_back" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   (arg1)->pop_back();
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -12026,8 +14099,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type arg2 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   size_t val2 ;
@@ -12036,16 +14109,16 @@ SWIGINTERN PyObject *_wrap_StringVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_resize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_resize" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_resize" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_resize" "', argument " "2"" of type '" "std::vector<std::string >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_resize" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<std::string >::size_type >(val2);
+  arg2 = static_cast< std::vector< std::string >::size_type >(val2);
   (arg1)->resize(arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
@@ -12056,36 +14129,36 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator arg2 ;
-  std::vector<std::string >::iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< std::string >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_erase" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_erase" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::string >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::string >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_std_string_Sg__erase__SWIG_0(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -12094,51 +14167,51 @@ fail:
 
 SWIGINTERN PyObject *_wrap_StringVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator arg2 ;
-  std::vector<std::string >::iterator arg3 ;
-  std::vector<std::string >::iterator result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::iterator arg2 ;
+  std::vector< std::string >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
   int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
+  swig::SwigPyIterator *iter3 = 0 ;
   int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::string >::iterator result;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_erase" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_erase" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::string >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter2);
+    swig::SwigPyIterator_T<std::vector< std::string >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter2);
     if (iter_t) {
       arg2 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
     }
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
   if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "3"" of type '" "std::vector<std::string >::iterator""'");
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "3"" of type '" "std::vector< std::string >::iterator""'");
   } else {
-    swig::PySwigIterator_T<std::vector<std::string >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter3);
+    swig::SwigPyIterator_T<std::vector< std::string >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter3);
     if (iter_t) {
       arg3 = iter_t->get_current();
     } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "3"" of type '" "std::vector<std::string >::iterator""'");
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_erase" "', argument " "3"" of type '" "std::vector< std::string >::iterator""'");
     }
   }
-  result = (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = std_vector_Sl_std_string_Sg__erase__SWIG_1(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
@@ -12151,18 +14224,18 @@ SWIGINTERN PyObject *_wrap_StringVector_erase(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter) != 0));
       if (_v) {
         return _wrap_StringVector_erase__SWIG_0(self, args);
       }
@@ -12170,16 +14243,16 @@ SWIGINTERN PyObject *_wrap_StringVector_erase(PyObject *self, PyObject *args) {
   }
   if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter) != 0));
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter) != 0));
       if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter) != 0));
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter) != 0));
         if (_v) {
           return _wrap_StringVector_erase__SWIG_1(self, args);
         }
@@ -12188,41 +14261,44 @@ SWIGINTERN PyObject *_wrap_StringVector_erase(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::vector<std::string >::iterator)\n    erase(std::vector<std::string >::iterator,std::vector<std::string >::iterator)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::erase(std::vector< std::string >::iterator)\n"
+    "    std::vector< std::string >::erase(std::vector< std::string >::iterator,std::vector< std::string >::iterator)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_new_StringVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string >::size_type arg1 ;
-  std::vector<std::string >::value_type *arg2 = 0 ;
-  std::vector<std::string > *result = 0 ;
+  std::vector< std::string >::size_type arg1 ;
+  std::vector< std::string >::value_type *arg2 = 0 ;
   size_t val1 ;
   int ecode1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< std::string > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:new_StringVector",&obj0,&obj1)) SWIG_fail;
   ecode1 = SWIG_AsVal_size_t(obj0, &val1);
   if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector<std::string >::size_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_StringVector" "', argument " "1"" of type '" "std::vector< std::string >::size_type""'");
   } 
-  arg1 = static_cast< std::vector<std::string >::size_type >(val1);
+  arg1 = static_cast< std::vector< std::string >::size_type >(val1);
   {
     std::string *ptr = (std::string *)0;
     res2 = SWIG_AsPtr_std_string(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_StringVector" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_StringVector" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVector" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_StringVector" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
     }
     arg2 = ptr;
   }
-  result = (std::vector<std::string > *)new std::vector<std::string >(arg1,(std::vector<std::string >::value_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_NEW |  0 );
+  result = (std::vector< std::string > *)new std::vector< std::string >(arg1,(std::vector< std::string >::value_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_NEW |  0 );
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
@@ -12237,8 +14313,8 @@ SWIGINTERN PyObject *_wrap_new_StringVector(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -12256,7 +14332,7 @@ SWIGINTERN PyObject *_wrap_new_StringVector(PyObject *self, PyObject *args) {
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       return _wrap_new_StringVector__SWIG_1(self, args);
@@ -12278,15 +14354,20 @@ SWIGINTERN PyObject *_wrap_new_StringVector(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_StringVector'.\n  Possible C/C++ prototypes are:\n    std::vector<(std::string)>()\n    std::vector<(std::string)>(std::vector<std::string > const &)\n    std::vector<(std::string)>(std::vector<std::string >::size_type)\n    std::vector<(std::string)>(std::vector<std::string >::size_type,std::vector<std::string >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_StringVector'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::vector()\n"
+    "    std::vector< std::string >::vector(std::vector< std::string > const &)\n"
+    "    std::vector< std::string >::vector(std::vector< std::string >::size_type)\n"
+    "    std::vector< std::string >::vector(std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_StringVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::value_type *arg2 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
@@ -12294,963 +14375,440 @@ SWIGINTERN PyObject *_wrap_StringVector_push_back(PyObject *SWIGUNUSEDPARM(self)
   PyObject * obj1 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_push_back",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_push_back" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_push_back" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
   {
     std::string *ptr = (std::string *)0;
     res2 = SWIG_AsPtr_std_string(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_push_back" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_push_back" "', argument " "2"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    arg2 = ptr;
-  }
-  (arg1)->push_back((std::vector<std::string >::value_type const &)*arg2);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::value_type *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_front",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_front" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  {
-    std::vector<std::string >::value_type const &_result_ref = ((std::vector<std::string > const *)arg1)->front();
-    result = (std::vector<std::string >::value_type *) &_result_ref;
-  }
-  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::value_type *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_back" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  {
-    std::vector<std::string >::value_type const &_result_ref = ((std::vector<std::string > const *)arg1)->back();
-    result = (std::vector<std::string >::value_type *) &_result_ref;
-  }
-  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type arg2 ;
-  std::vector<std::string >::value_type *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_assign" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_assign" "', argument " "2"" of type '" "std::vector<std::string >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<std::string >::size_type >(val2);
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_assign" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_assign" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->assign(arg2,(std::vector<std::string >::value_type const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type arg2 ;
-  std::vector<std::string >::value_type *arg3 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_resize" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_resize" "', argument " "2"" of type '" "std::vector<std::string >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<std::string >::size_type >(val2);
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_resize" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_resize" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  (arg1)->resize(arg2,(std::vector<std::string >::value_type const &)*arg3);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_resize(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_StringVector_resize__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_StringVector_resize__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_resize'.\n  Possible C/C++ prototypes are:\n    resize(std::vector<std::string >::size_type)\n    resize(std::vector<std::string >::size_type,std::vector<std::string >::value_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator arg2 ;
-  std::vector<std::string >::value_type *arg3 = 0 ;
-  std::vector<std::string >::iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  int res3 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_insert" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<std::string >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
-    }
-  }
-  {
-    std::string *ptr = (std::string *)0;
-    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
-    if (!SWIG_IsOK(res3)) {
-      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    arg3 = ptr;
-  }
-  result = (arg1)->insert(arg2,(std::vector<std::string >::value_type const &)*arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<std::string >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res3)) delete arg3;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::iterator arg2 ;
-  std::vector<std::string >::size_type arg3 ;
-  std::vector<std::string >::value_type *arg4 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  size_t val3 ;
-  int ecode3 = 0 ;
-  int res4 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:StringVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_insert" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<std::string >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector<std::string >::iterator""'");
-    }
-  }
-  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector<std::string >::size_type""'");
-  } 
-  arg3 = static_cast< std::vector<std::string >::size_type >(val3);
-  {
-    std::string *ptr = (std::string *)0;
-    res4 = SWIG_AsPtr_std_string(obj3, &ptr);
-    if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVector_insert" "', argument " "4"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_insert" "', argument " "4"" of type '" "std::vector<std::string >::value_type const &""'"); 
-    }
-    arg4 = ptr;
-  }
-  (arg1)->insert(arg2,arg3,(std::vector<std::string >::value_type const &)*arg4);
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res4)) delete arg4;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_insert(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[5];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 4); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter) != 0));
-      if (_v) {
-        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_StringVector_insert__SWIG_0(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator<std::string > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<std::string >::iterator > *>(iter) != 0));
-      if (_v) {
-        {
-          int res = SWIG_AsVal_size_t(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          int res = SWIG_AsPtr_std_string(argv[3], (std::string**)(0));
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_StringVector_insert__SWIG_1(self, args);
-          }
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'StringVector_insert'.\n  Possible C/C++ prototypes are:\n    insert(std::vector<std::string >::iterator,std::vector<std::string >::value_type const &)\n    insert(std::vector<std::string >::iterator,std::vector<std::string >::size_type,std::vector<std::string >::value_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_reserve",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_reserve" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_reserve" "', argument " "2"" of type '" "std::vector<std::string >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<std::string >::size_type >(val2);
-  (arg1)->reserve(arg2);
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_StringVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  std::vector<std::string >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_capacity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_capacity" "', argument " "1"" of type '" "std::vector<std::string > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  result = ((std::vector<std::string > const *)arg1)->capacity();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_StringVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<std::string > *arg1 = (std::vector<std::string > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_StringVector",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_StringVector" "', argument " "1"" of type '" "std::vector<std::string > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<std::string > * >(argp1);
-  delete arg1;
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *StringVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_VarsVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_iterator" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_vector_Sl_CdiVariable_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___nonzero__" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (bool)std_vector_Sl_CdiVariable_Sg____nonzero__((std::vector<CdiVariable > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___len__" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "StringVector_push_back" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_push_back" "', argument " "2"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg2 = ptr;
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = std_vector_Sl_CdiVariable_Sg____len__((std::vector<CdiVariable > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  (arg1)->push_back((std::vector< std::string >::value_type const &)*arg2);
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::value_type result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_pop",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_front",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_pop" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  try {
-    result = std_vector_Sl_CdiVariable_Sg__pop(arg1);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_front" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  
-  resultobj = SWIG_NewPointerObj((new std::vector<CdiVariable >::value_type(static_cast< const std::vector<CdiVariable >::value_type& >(result))), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (std::vector< std::string >::value_type *) &((std::vector< std::string > const *)arg1)->front();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  std::vector<CdiVariable >::difference_type arg3 ;
-  std::vector<CdiVariable,std::allocator<CdiVariable > > *result = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  ptrdiff_t val3 ;
-  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< std::string >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_back",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___getslice__" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___getslice__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___getslice__" "', argument " "3"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg3 = static_cast< std::vector<CdiVariable >::difference_type >(val3);
-  try {
-    result = (std::vector<CdiVariable,std::allocator<CdiVariable > > *)std_vector_Sl_CdiVariable_Sg____getslice__(arg1,arg2,arg3);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_back" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = (std::vector< std::string >::value_type *) &((std::vector< std::string > const *)arg1)->back();
+  resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector___setslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  std::vector<CdiVariable >::difference_type arg3 ;
-  std::vector<CdiVariable,std::allocator<CdiVariable > > *arg4 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::size_type arg2 ;
+  std::vector< std::string >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
+  size_t val2 ;
   int ecode2 = 0 ;
-  ptrdiff_t val3 ;
-  int ecode3 = 0 ;
-  int res4 = SWIG_OLDOBJ ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:VarsVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setslice__" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_assign" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___setslice__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___setslice__" "', argument " "3"" of type '" "std::vector<CdiVariable >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_assign" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'");
   } 
-  arg3 = static_cast< std::vector<CdiVariable >::difference_type >(val3);
+  arg2 = static_cast< std::vector< std::string >::size_type >(val2);
   {
-    std::vector<CdiVariable,std::allocator<CdiVariable > > *ptr = (std::vector<CdiVariable,std::allocator<CdiVariable > > *)0;
-    res4 = swig::asptr(obj3, &ptr);
-    if (!SWIG_IsOK(res4)) {
-      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VarsVector___setslice__" "', argument " "4"" of type '" "std::vector<CdiVariable,std::allocator<CdiVariable > > const &""'"); 
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_assign" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector___setslice__" "', argument " "4"" of type '" "std::vector<CdiVariable,std::allocator<CdiVariable > > const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_assign" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
     }
-    arg4 = ptr;
-  }
-  try {
-    std_vector_Sl_CdiVariable_Sg____setslice__(arg1,arg2,arg3,(std::vector<CdiVariable,std::allocator<CdiVariable > > const &)*arg4);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  catch(std::invalid_argument &_e) {
-    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+    arg3 = ptr;
   }
-  
+  (arg1)->assign(arg2,(std::vector< std::string >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res4)) delete arg4;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res4)) delete arg4;
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  std::vector<CdiVariable >::difference_type arg3 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::size_type arg2 ;
+  std::vector< std::string >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
+  size_t val2 ;
   int ecode2 = 0 ;
-  ptrdiff_t val3 ;
-  int ecode3 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___delslice__" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___delslice__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___delslice__" "', argument " "3"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg3 = static_cast< std::vector<CdiVariable >::difference_type >(val3);
-  try {
-    std_vector_Sl_CdiVariable_Sg____delslice__(arg1,arg2,arg3);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___delitem__" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_resize" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___delitem__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_resize" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'");
   } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  try {
-    std_vector_Sl_CdiVariable_Sg____delitem__(arg1,arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  arg2 = static_cast< std::vector< std::string >::size_type >(val2);
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_resize" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_resize" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg3 = ptr;
   }
-  
+  (arg1)->resize(arg2,(std::vector< std::string >::value_type const &)*arg3);
   resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  std::vector<CdiVariable >::value_type *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+SWIGINTERN PyObject *_wrap_StringVector_resize(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[4];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___getitem__" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___getitem__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  try {
-    {
-      std::vector<CdiVariable >::value_type const &_result_ref = std_vector_Sl_CdiVariable_Sg____getitem__((std::vector<CdiVariable > const *)arg1,arg2);
-      result = (std::vector<CdiVariable >::value_type *) &_result_ref;
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_StringVector_resize__SWIG_0(self, args);
+      }
     }
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_StringVector_resize__SWIG_1(self, args);
+        }
+      }
+    }
   }
   
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0 |  0 );
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector_resize'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::resize(std::vector< std::string >::size_type)\n"
+    "    std::vector< std::string >::resize(std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::difference_type arg2 ;
-  std::vector<CdiVariable >::value_type *arg3 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::iterator arg2 ;
+  std::vector< std::string >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  ptrdiff_t val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< std::string >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:StringVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setitem__" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___setitem__" "', argument " "2"" of type '" "std::vector<CdiVariable >::difference_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::difference_type >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_insert" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg3 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp3);
-  try {
-    std_vector_Sl_CdiVariable_Sg____setitem__(arg1,arg2,(CdiVariable const &)*arg3);
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< std::string >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
+    }
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  {
+    std::string *ptr = (std::string *)0;
+    res3 = SWIG_AsPtr_std_string(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg3 = ptr;
   }
-  
-  resultobj = SWIG_Py_Void();
+  result = std_vector_Sl_std_string_Sg__insert__SWIG_0(arg1,arg2,(std::string const &)*arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::value_type *arg2 = 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::iterator arg2 ;
+  std::vector< std::string >::size_type arg3 ;
+  std::vector< std::string >::value_type *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  size_t val3 ;
+  int ecode3 = 0 ;
+  int res4 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_append",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:StringVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_append" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_insert" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_append" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< std::string >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "StringVector_insert" "', argument " "2"" of type '" "std::vector< std::string >::iterator""'");
+    }
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_append" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "StringVector_insert" "', argument " "3"" of type '" "std::vector< std::string >::size_type""'");
+  } 
+  arg3 = static_cast< std::vector< std::string >::size_type >(val3);
+  {
+    std::string *ptr = (std::string *)0;
+    res4 = SWIG_AsPtr_std_string(obj3, &ptr);
+    if (!SWIG_IsOK(res4)) {
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "StringVector_insert" "', argument " "4"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "StringVector_insert" "', argument " "4"" of type '" "std::vector< std::string >::value_type const &""'"); 
+    }
+    arg4 = ptr;
   }
-  arg2 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp2);
-  std_vector_Sl_CdiVariable_Sg__append(arg1,(CdiVariable const &)*arg2);
+  std_vector_Sl_std_string_Sg__insert__SWIG_1(arg1,arg2,arg3,(std::string const &)*arg4);
   resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res4)) delete arg4;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res4)) delete arg4;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_VarsVector")) SWIG_fail;
-  result = (std::vector<CdiVariable > *)new std::vector<CdiVariable >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = 0 ;
-  std::vector<CdiVariable > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
+SWIGINTERN PyObject *_wrap_StringVector_insert(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[5];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsVector",&obj0)) SWIG_fail;
-  {
-    std::vector<CdiVariable,std::allocator<CdiVariable > > *ptr = (std::vector<CdiVariable,std::allocator<CdiVariable > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector<CdiVariable > const &""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter) != 0));
+      if (_v) {
+        int res = SWIG_AsPtr_std_string(argv[2], (std::string**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_StringVector_insert__SWIG_0(self, args);
+        }
+      }
     }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector<CdiVariable > const &""'"); 
+  }
+  if (argc == 4) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<std::string,std::allocator< std::string > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< std::string >::iterator > *>(iter) != 0));
+      if (_v) {
+        {
+          int res = SWIG_AsVal_size_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = SWIG_AsPtr_std_string(argv[3], (std::string**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_StringVector_insert__SWIG_1(self, args);
+          }
+        }
+      }
     }
-    arg1 = ptr;
   }
-  result = (std::vector<CdiVariable > *)new std::vector<CdiVariable >((std::vector<CdiVariable > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
+  
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'StringVector_insert'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< std::string >::insert(std::vector< std::string >::iterator,std::vector< std::string >::value_type const &)\n"
+    "    std::vector< std::string >::insert(std::vector< std::string >::iterator,std::vector< std::string >::size_type,std::vector< std::string >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  bool result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
+  std::vector< std::string >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:StringVector_reserve",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_empty" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_reserve" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (bool)((std::vector<CdiVariable > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "StringVector_reserve" "', argument " "2"" of type '" "std::vector< std::string >::size_type""'");
+  } 
+  arg2 = static_cast< std::vector< std::string >::size_type >(val2);
+  (arg1)->reserve(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_StringVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type result;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:StringVector_capacity",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_size" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_capacity" "', argument " "1"" of type '" "std::vector< std::string > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->size();
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  result = ((std::vector< std::string > const *)arg1)->capacity();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -13258,20 +14816,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_StringVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
+  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_StringVector",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_clear" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_StringVector" "', argument " "1"" of type '" "std::vector< std::string > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  (arg1)->clear();
+  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
+  delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -13279,443 +14837,564 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *StringVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_VarsVector_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable > *arg2 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_swap" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_swap" "', argument " "2"" of type '" "std::vector<CdiVariable > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_iterator" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_swap" "', argument " "2"" of type '" "std::vector<CdiVariable > &""'"); 
-  }
-  arg2 = reinterpret_cast< std::vector<CdiVariable > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_vector_Sl_CdiVariable_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  SwigValueWrapper<std::allocator<CdiVariable > > result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_get_allocator" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___nonzero__" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::vector<CdiVariable >::allocator_type(static_cast< const std::vector<CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (bool)std_vector_Sl_CdiVariable_Sg____nonzero__((std::vector< CdiVariable > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_begin" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___bool__" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (bool)std_vector_Sl_CdiVariable_Sg____bool__((std::vector< CdiVariable > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::const_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_begin" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___len__" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = std_vector_Sl_CdiVariable_Sg____len__((std::vector< CdiVariable > const *)arg1);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_begin__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_pop(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::value_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_pop",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_end" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_pop" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  try {
+    result = std_vector_Sl_CdiVariable_Sg__pop(arg1);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_NewPointerObj((new std::vector< CdiVariable >::value_type(static_cast< const std::vector< CdiVariable >::value_type& >(result))), SWIGTYPE_p_CdiVariable, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___getslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::const_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
+  std::vector< CdiVariable >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___getslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_end" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___getslice__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___getslice__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___getslice__" "', argument " "3"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg3 = static_cast< std::vector< CdiVariable >::difference_type >(val3);
+  try {
+    result = (std::vector< CdiVariable,std::allocator< CdiVariable > > *)std_vector_Sl_CdiVariable_Sg____getslice__(arg1,arg2,arg3);
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_end__SWIG_0(self, args);
-    }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_end__SWIG_1(self, args);
-    }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
   }
   
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setslice____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::reverse_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
+  std::vector< CdiVariable >::difference_type arg3 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *arg4 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
+  int res4 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:VarsVector___setslice__",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rbegin" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setslice__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___setslice__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___setslice__" "', argument " "3"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg3 = static_cast< std::vector< CdiVariable >::difference_type >(val3);
+  {
+    std::vector<CdiVariable,std::allocator< CdiVariable > > *ptr = (std::vector<CdiVariable,std::allocator< CdiVariable > > *)0;
+    res4 = swig::asptr(obj3, &ptr);
+    if (!SWIG_IsOK(res4)) {
+      SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VarsVector___setslice__" "', argument " "4"" of type '" "std::vector< CdiVariable,std::allocator< CdiVariable > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector___setslice__" "', argument " "4"" of type '" "std::vector< CdiVariable,std::allocator< CdiVariable > > const &""'"); 
+    }
+    arg4 = ptr;
+  }
+  try {
+    std_vector_Sl_CdiVariable_Sg____setslice____SWIG_0(arg1,arg2,arg3,(std::vector< CdiVariable,std::allocator< CdiVariable > > const &)*arg4);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res4)) delete arg4;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res4)) delete arg4;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setslice____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::const_reverse_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
+  std::vector< CdiVariable >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___setslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rbegin" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setslice__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___setslice__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___setslice__" "', argument " "3"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg3 = static_cast< std::vector< CdiVariable >::difference_type >(val3);
+  try {
+    std_vector_Sl_CdiVariable_Sg____setslice____SWIG_0(arg1,arg2,arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setslice__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[5];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsVector_rbegin__SWIG_0(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          return _wrap_VarsVector___setslice____SWIG_1(self, args);
+        }
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 4) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsVector_rbegin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        {
+          int res = SWIG_AsVal_ptrdiff_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = swig::asptr(argv[3], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_VarsVector___setslice____SWIG_0(self, args);
+          }
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector___setslice__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::__setslice__(std::vector< CdiVariable >::difference_type,std::vector< CdiVariable >::difference_type,std::vector< CdiVariable,std::allocator< CdiVariable > > const &)\n"
+    "    std::vector< CdiVariable >::__setslice__(std::vector< CdiVariable >::difference_type,std::vector< CdiVariable >::difference_type)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___delslice__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::reverse_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
+  std::vector< CdiVariable >::difference_type arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  ptrdiff_t val3 ;
+  int ecode3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___delslice__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rend" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___delslice__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___delslice__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  ecode3 = SWIG_AsVal_ptrdiff_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector___delslice__" "', argument " "3"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg3 = static_cast< std::vector< CdiVariable >::difference_type >(val3);
+  try {
+    std_vector_Sl_CdiVariable_Sg____delslice__(arg1,arg2,arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___delitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::const_reverse_iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rend" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___delitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___delitem__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  try {
+    std_vector_Sl_CdiVariable_Sg____delitem____SWIG_0(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsVector___getitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___getitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_rend__SWIG_0(self, args);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector___getitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
+    arg2 = (PySliceObject *) obj1;
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsVector_rend__SWIG_1(self, args);
-    }
+  try {
+    result = (std::vector< CdiVariable,std::allocator< CdiVariable > > *)std_vector_Sl_CdiVariable_Sg____getitem____SWIG_0(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
   }
   
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::vector<CdiVariable >::size_type arg1 ;
-  std::vector<CdiVariable > *result = 0 ;
-  size_t val1 ;
-  int ecode1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsVector",&obj0)) SWIG_fail;
-  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg1 = static_cast< std::vector<CdiVariable >::size_type >(val1);
-  result = (std::vector<CdiVariable > *)new std::vector<CdiVariable >(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_NEW |  0 );
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res3 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_pop_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_pop_back" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  (arg1)->pop_back();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  {
+    std::vector<CdiVariable,std::allocator< CdiVariable > > *ptr = (std::vector<CdiVariable,std::allocator< CdiVariable > > *)0;
+    res3 = swig::asptr(obj2, &ptr);
+    if (!SWIG_IsOK(res3)) {
+      SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector< CdiVariable,std::allocator< CdiVariable > > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector< CdiVariable,std::allocator< CdiVariable > > const &""'"); 
+    }
+    arg3 = ptr;
+  }
+  try {
+    std_vector_Sl_CdiVariable_Sg____setitem____SWIG_0(arg1,arg2,(std::vector< CdiVariable,std::allocator< CdiVariable > > const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
   resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res3)) delete arg3;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type arg2 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_resize",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_resize" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_resize" "', argument " "2"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::size_type >(val2);
-  (arg1)->resize(arg2);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector___setitem__" "', argument " "2"" of type '" "PySliceObject *""'");
+    }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_CdiVariable_Sg____setitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -13723,235 +15402,296 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___delitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator arg2 ;
-  std::vector<CdiVariable >::iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  PySliceObject *arg2 = (PySliceObject *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_erase" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___delitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  {
+    if (!PySlice_Check(obj1)) {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector___delitem__" "', argument " "2"" of type '" "PySliceObject *""'");
     }
+    arg2 = (PySliceObject *) obj1;
+  }
+  try {
+    std_vector_Sl_CdiVariable_Sg____delitem____SWIG_1(arg1,arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  result = (arg1)->erase(arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::invalid_argument &_e) {
+    SWIG_exception_fail(SWIG_ValueError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___delitem__(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_VarsVector___delitem____SWIG_1(self, args);
+      }
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_VarsVector___delitem____SWIG_0(self, args);
+      }
+    }
+  }
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector___delitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::__delitem__(std::vector< CdiVariable >::difference_type)\n"
+    "    std::vector< CdiVariable >::__delitem__(PySliceObject *)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsVector___getitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator arg2 ;
-  std::vector<CdiVariable >::iterator arg3 ;
-  std::vector<CdiVariable >::iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< CdiVariable >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_erase" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___getitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-    }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___getitem__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  try {
+    result = (std::vector< CdiVariable >::value_type *) &std_vector_Sl_CdiVariable_Sg____getitem____SWIG_1((std::vector< CdiVariable > const *)arg1,arg2);
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "3"" of type '" "std::vector<CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "3"" of type '" "std::vector<CdiVariable >::iterator""'");
-    }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  result = (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiVariable, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_erase(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___getitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[4];
+  PyObject *argv[3];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter) != 0));
+      {
+        _v = PySlice_Check(argv[1]);
+      }
       if (_v) {
-        return _wrap_VarsVector_erase__SWIG_0(self, args);
+        return _wrap_VarsVector___getitem____SWIG_0(self, args);
       }
     }
   }
-  if (argc == 3) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter) != 0));
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
       if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_VarsVector_erase__SWIG_1(self, args);
-        }
+        return _wrap_VarsVector___getitem____SWIG_1(self, args);
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::vector<CdiVariable >::iterator)\n    erase(std::vector<CdiVariable >::iterator,std::vector<CdiVariable >::iterator)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector___getitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::__getitem__(PySliceObject *)\n"
+    "    std::vector< CdiVariable >::__getitem__(std::vector< CdiVariable >::difference_type) const\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setitem____SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable >::size_type arg1 ;
-  std::vector<CdiVariable >::value_type *arg2 = 0 ;
-  std::vector<CdiVariable > *result = 0 ;
-  size_t val1 ;
-  int ecode1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::difference_type arg2 ;
+  std::vector< CdiVariable >::value_type *arg3 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  ptrdiff_t val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:new_VarsVector",&obj0,&obj1)) SWIG_fail;
-  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
-  if (!SWIG_IsOK(ecode1)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector<CdiVariable >::size_type""'");
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector___setitem__" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_ptrdiff_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector___setitem__" "', argument " "2"" of type '" "std::vector< CdiVariable >::difference_type""'");
   } 
-  arg1 = static_cast< std::vector<CdiVariable >::size_type >(val1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_VarsVector" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  arg2 = static_cast< std::vector< CdiVariable >::difference_type >(val2);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsVector" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector___setitem__" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp2);
-  result = (std::vector<CdiVariable > *)new std::vector<CdiVariable >(arg1,(std::vector<CdiVariable >::value_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_NEW |  0 );
+  arg3 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp3);
+  try {
+    std_vector_Sl_CdiVariable_Sg____setitem____SWIG_2(arg1,arg2,(CdiVariable const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsVector(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 0) {
-    return _wrap_new_VarsVector__SWIG_0(self, args);
-  }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    {
-      int res = SWIG_AsVal_size_t(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_VarsVector__SWIG_2(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        return _wrap_VarsVector___setitem____SWIG_1(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_VarsVector__SWIG_1(self, args);
+      {
+        _v = PySlice_Check(argv[1]);
+      }
+      if (_v) {
+        int res = swig::asptr(argv[2], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsVector___setitem____SWIG_0(self, args);
+        }
+      }
     }
   }
-  if (argc == 2) {
+  if (argc == 3) {
     int _v;
-    {
-      int res = SWIG_AsVal_size_t(argv[0], NULL);
-      _v = SWIG_CheckState(res);
-    }
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0);
-      _v = SWIG_CheckState(res);
+      {
+        int res = SWIG_AsVal_ptrdiff_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
       if (_v) {
-        return _wrap_new_VarsVector__SWIG_3(self, args);
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiVariable, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsVector___setitem____SWIG_2(self, args);
+        }
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_VarsVector'.\n  Possible C/C++ prototypes are:\n    std::vector<(CdiVariable)>()\n    std::vector<(CdiVariable)>(std::vector<CdiVariable > const &)\n    std::vector<(CdiVariable)>(std::vector<CdiVariable >::size_type)\n    std::vector<(CdiVariable)>(std::vector<CdiVariable >::size_type,std::vector<CdiVariable >::value_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::__setitem__(PySliceObject *,std::vector< CdiVariable,std::allocator< CdiVariable > > const &)\n"
+    "    std::vector< CdiVariable >::__setitem__(PySliceObject *)\n"
+    "    std::vector< CdiVariable >::__setitem__(std::vector< CdiVariable >::difference_type,std::vector< CdiVariable >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::value_type *arg2 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -13959,21 +15699,21 @@ SWIGINTERN PyObject *_wrap_VarsVector_push_back(PyObject *SWIGUNUSEDPARM(self),
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_push_back",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_append",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_push_back" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_append" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_CdiVariable,  0  | 0);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_push_back" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_append" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
   if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_push_back" "', argument " "2"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_append" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp2);
-  (arg1)->push_back((std::vector<CdiVariable >::value_type const &)*arg2);
+  arg2 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp2);
+  std_vector_Sl_CdiVariable_Sg__append(arg1,(CdiVariable const &)*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -13981,289 +15721,139 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::value_type *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+  std::vector< CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_front",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_front" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  {
-    std::vector<CdiVariable >::value_type const &_result_ref = ((std::vector<CdiVariable > const *)arg1)->front();
-    result = (std::vector<CdiVariable >::value_type *) &_result_ref;
-  }
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)":new_VarsVector")) SWIG_fail;
+  result = (std::vector< CdiVariable > *)new std::vector< CdiVariable >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::value_type *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  std::vector< CdiVariable > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_back",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_back" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsVector",&obj0)) SWIG_fail;
   {
-    std::vector<CdiVariable >::value_type const &_result_ref = ((std::vector<CdiVariable > const *)arg1)->back();
-    result = (std::vector<CdiVariable >::value_type *) &_result_ref;
+    std::vector<CdiVariable,std::allocator< CdiVariable > > *ptr = (std::vector<CdiVariable,std::allocator< CdiVariable > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector< CdiVariable > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector< CdiVariable > const &""'"); 
+    }
+    arg1 = ptr;
   }
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0 |  0 );
+  result = (std::vector< CdiVariable > *)new std::vector< CdiVariable >((std::vector< CdiVariable > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type arg2 ;
-  std::vector<CdiVariable >::value_type *arg3 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_assign" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_assign" "', argument " "2"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::size_type >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_assign" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_assign" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_empty" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg3 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp3);
-  (arg1)->assign(arg2,(std::vector<CdiVariable >::value_type const &)*arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (bool)((std::vector< CdiVariable > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type arg2 ;
-  std::vector<CdiVariable >::value_type *arg3 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::vector< CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_resize" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_resize" "', argument " "2"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::size_type >(val2);
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_resize" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_resize" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_size" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg3 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp3);
-  (arg1)->resize(arg2,(std::vector<CdiVariable >::value_type const &)*arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = ((std::vector< CdiVariable > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_resize(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsVector_resize__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_size_t(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_VarsVector_resize__SWIG_1(self, args);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_resize'.\n  Possible C/C++ prototypes are:\n    resize(std::vector<CdiVariable >::size_type)\n    resize(std::vector<CdiVariable >::size_type,std::vector<CdiVariable >::value_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator arg2 ;
-  std::vector<CdiVariable >::value_type *arg3 = 0 ;
-  std::vector<CdiVariable >::iterator result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_insert" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_clear" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
-  }
-  arg3 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp3);
-  result = (arg1)->insert(arg2,(std::vector<CdiVariable >::value_type const &)*arg3);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector<CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::iterator arg2 ;
-  std::vector<CdiVariable >::size_type arg3 ;
-  std::vector<CdiVariable >::value_type *arg4 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  size_t val3 ;
-  int ecode3 = 0 ;
-  void *argp4 = 0 ;
-  int res4 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
-  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOO:VarsVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_insert" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector<CdiVariable >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_swap" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
-  if (!SWIG_IsOK(ecode3)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg3 = static_cast< std::vector<CdiVariable >::size_type >(val3);
-  res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,  0  | 0);
-  if (!SWIG_IsOK(res4)) {
-    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VarsVector_insert" "', argument " "4"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_swap" "', argument " "2"" of type '" "std::vector< CdiVariable > &""'"); 
   }
-  if (!argp4) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_insert" "', argument " "4"" of type '" "std::vector<CdiVariable >::value_type const &""'"); 
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_swap" "', argument " "2"" of type '" "std::vector< CdiVariable > &""'"); 
   }
-  arg4 = reinterpret_cast< std::vector<CdiVariable >::value_type * >(argp4);
-  (arg1)->insert(arg2,arg3,(std::vector<CdiVariable >::value_type const &)*arg4);
+  arg2 = reinterpret_cast< std::vector< CdiVariable > * >(argp2);
+  (arg1)->swap(*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -14271,651 +15861,851 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_insert(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[5];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsVector_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< CdiVariable > > result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 4); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0);
-        _v = SWIG_CheckState(res);
-        if (_v) {
-          return _wrap_VarsVector_insert__SWIG_0(self, args);
-        }
-      }
-    }
-  }
-  if (argc == 4) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator<CdiVariable > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::vector<CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        {
-          int res = SWIG_AsVal_size_t(argv[2], NULL);
-          _v = SWIG_CheckState(res);
-        }
-        if (_v) {
-          int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0);
-          _v = SWIG_CheckState(res);
-          if (_v) {
-            return _wrap_VarsVector_insert__SWIG_1(self, args);
-          }
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_get_allocator" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = ((std::vector< CdiVariable > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::vector< CdiVariable >::allocator_type(static_cast< const std::vector< CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_CdiVariable_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsVector_insert'.\n  Possible C/C++ prototypes are:\n    insert(std::vector<CdiVariable >::iterator,std::vector<CdiVariable >::value_type const &)\n    insert(std::vector<CdiVariable >::iterator,std::vector<CdiVariable >::size_type,std::vector<CdiVariable >::value_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type arg2 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  size_t val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::vector< CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_reserve",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_reserve" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_begin" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_reserve" "', argument " "2"" of type '" "std::vector<CdiVariable >::size_type""'");
-  } 
-  arg2 = static_cast< std::vector<CdiVariable >::size_type >(val2);
-  (arg1)->reserve(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
-  std::vector<CdiVariable >::size_type result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_capacity",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_capacity" "', argument " "1"" of type '" "std::vector<CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_end" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  result = ((std::vector<CdiVariable > const *)arg1)->capacity();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_VarsVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::vector<CdiVariable > *arg1 = (std::vector<CdiVariable > *) 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsVector",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsVector" "', argument " "1"" of type '" "std::vector<CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rbegin" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::vector<CdiVariable > * >(argp1);
-  delete arg1;
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsVector_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::reverse_iterator result;
   
-  resultobj = SWIG_Py_Void();
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_rend" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *VarsVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
+SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::vector< CdiVariable >::size_type arg1 ;
+  size_t val1 ;
+  int ecode1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::vector< CdiVariable > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsVector",&obj0)) SWIG_fail;
+  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg1 = static_cast< std::vector< CdiVariable >::size_type >(val1);
+  result = (std::vector< CdiVariable > *)new std::vector< CdiVariable >(arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
 }
 
-SWIGINTERN PyObject *_wrap_VarsMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+
+SWIGINTERN PyObject *_wrap_VarsVector_pop_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_pop_back",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_iterator" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_pop_back" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  (arg1)->pop_back();
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_resize__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  bool result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_resize",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___nonzero__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_resize" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg____nonzero__((std::map<std::string,CdiVariable > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_resize" "', argument " "2"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::size_type >(val2);
+  (arg1)->resize(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::size_type result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::vector< CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___len__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_erase" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = std_map_Sl_std_string_Sc_CdiVariable_Sg____len__((std::map<std::string,CdiVariable > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
+    }
+  }
+  result = std_vector_Sl_CdiVariable_Sg__erase__SWIG_0(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::mapped_type result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::iterator arg2 ;
+  std::vector< CdiVariable >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  std::vector< CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___getitem__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_erase" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___getitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
     }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___getitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "3"" of type '" "std::vector< CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_erase" "', argument " "3"" of type '" "std::vector< CdiVariable >::iterator""'");
     }
-    arg2 = ptr;
   }
-  try {
-    result = std_map_Sl_std_string_Sc_CdiVariable_Sg____getitem__((std::map<std::string,CdiVariable > const *)arg1,(std::string const &)*arg2);
+  result = std_vector_Sl_CdiVariable_Sg__erase__SWIG_1(arg1,arg2,arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsVector_erase(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[4];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        return _wrap_VarsVector_erase__SWIG_0(self, args);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_VarsVector_erase__SWIG_1(self, args);
+        }
+      }
+    }
   }
   
-  resultobj = SWIG_NewPointerObj((new std::map<std::string,CdiVariable >::mapped_type(static_cast< const std::map<std::string,CdiVariable >::mapped_type& >(result))), SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type, SWIG_POINTER_OWN |  0 );
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::erase(std::vector< CdiVariable >::iterator)\n"
+    "    std::vector< CdiVariable >::erase(std::vector< CdiVariable >::iterator,std::vector< CdiVariable >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsVector__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  std::vector< CdiVariable >::size_type arg1 ;
+  std::vector< CdiVariable >::value_type *arg2 = 0 ;
+  size_t val1 ;
+  int ecode1 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::vector< CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___delitem__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"OO:new_VarsVector",&obj0,&obj1)) SWIG_fail;
+  ecode1 = SWIG_AsVal_size_t(obj0, &val1);
+  if (!SWIG_IsOK(ecode1)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_VarsVector" "', argument " "1"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg1 = static_cast< std::vector< CdiVariable >::size_type >(val1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "new_VarsVector" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___delitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsVector" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
+  }
+  arg2 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp2);
+  result = (std::vector< CdiVariable > *)new std::vector< CdiVariable >(arg1,(std::vector< CdiVariable >::value_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_VarsVector(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[3];
+  int ii;
+  
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
+  }
+  if (argc == 0) {
+    return _wrap_new_VarsVector__SWIG_0(self, args);
+  }
+  if (argc == 1) {
+    int _v;
+    {
+      int res = SWIG_AsVal_size_t(argv[0], NULL);
+      _v = SWIG_CheckState(res);
     }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___delitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+    if (_v) {
+      return _wrap_new_VarsVector__SWIG_2(self, args);
+    }
+  }
+  if (argc == 1) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      return _wrap_new_VarsVector__SWIG_1(self, args);
     }
-    arg2 = ptr;
-  }
-  try {
-    std_map_Sl_std_string_Sc_CdiVariable_Sg____delitem__(arg1,(std::string const &)*arg2);
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  if (argc == 2) {
+    int _v;
+    {
+      int res = SWIG_AsVal_size_t(argv[0], NULL);
+      _v = SWIG_CheckState(res);
+    }
+    if (_v) {
+      int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_CdiVariable, 0);
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_new_VarsVector__SWIG_3(self, args);
+      }
+    }
   }
   
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VarsVector'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::vector()\n"
+    "    std::vector< CdiVariable >::vector(std::vector< CdiVariable > const &)\n"
+    "    std::vector< CdiVariable >::vector(std::vector< CdiVariable >::size_type)\n"
+    "    std::vector< CdiVariable >::vector(std::vector< CdiVariable >::size_type,std::vector< CdiVariable >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_push_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  bool result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::value_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_has_key",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_push_back",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_has_key" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_push_back" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_has_key" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_has_key" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsVector_push_back" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg__has_key((std::map<std::string,CdiVariable > const *)arg1,(std::string const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_keys",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_keys" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_push_back" "', argument " "2"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__keys(arg1);
-  resultobj = result;
+  arg2 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp2);
+  (arg1)->push_back((std::vector< CdiVariable >::value_type const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_front(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_front",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_values" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_front" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__values(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (std::vector< CdiVariable >::value_type *) &((std::vector< CdiVariable > const *)arg1)->front();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiVariable, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_back(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::value_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_items",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_back",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_items" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_back" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__items(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = (std::vector< CdiVariable >::value_type *) &((std::vector< CdiVariable > const *)arg1)->back();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiVariable, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_assign(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  bool result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::size_type arg2 ;
+  std::vector< CdiVariable >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___contains__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_assign",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___contains__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_assign" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___contains__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___contains__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_assign" "', argument " "2"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::size_type >(val2);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_assign" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg____contains__(arg1,(std::string const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_assign" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp3);
+  (arg1)->assign(arg2,(std::vector< CdiVariable >::value_type const &)*arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_resize__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::size_type arg2 ;
+  std::vector< CdiVariable >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_key_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_resize",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_key_iterator" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_resize" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_resize" "', argument " "2"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::size_type >(val2);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_resize" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__key_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_resize" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp3);
+  (arg1)->resize(arg2,(std::vector< CdiVariable >::value_type const &)*arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+SWIGINTERN PyObject *_wrap_VarsVector_resize(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[4];
+  int ii;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_value_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_value_iterator" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__value_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_VarsVector_resize__SWIG_0(self, args);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      {
+        int res = SWIG_AsVal_size_t(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiVariable, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsVector_resize__SWIG_1(self, args);
+        }
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector_resize'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::resize(std::vector< CdiVariable >::size_type)\n"
+    "    std::vector< CdiVariable >::resize(std::vector< CdiVariable >::size_type,std::vector< CdiVariable >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_insert__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::mapped_type *arg3 = 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::iterator arg2 ;
+  std::vector< CdiVariable >::value_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   void *argp3 = 0 ;
   int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  std::vector< CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsVector_insert",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___setitem__" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_insert" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
     }
-    arg2 = ptr;
   }
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type,  0  | 0);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
   if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsMap___setitem__" "', argument " "3"" of type '" "std::map<std::string,CdiVariable >::mapped_type const &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
   if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___setitem__" "', argument " "3"" of type '" "std::map<std::string,CdiVariable >::mapped_type const &""'"); 
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
   }
-  arg3 = reinterpret_cast< std::map<std::string,CdiVariable >::mapped_type * >(argp3);
-  try {
-    std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem__(arg1,(std::string const &)*arg2,(CdiVariable const &)*arg3);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_Py_Void();
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_VarsMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_VarsMap")) SWIG_fail;
-  result = (std::map<std::string,CdiVariable > *)new std::map<std::string,CdiVariable >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  arg3 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp3);
+  result = std_vector_Sl_CdiVariable_Sg__insert__SWIG_0(arg1,arg2,(CdiVariable const &)*arg3);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_insert__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = 0 ;
-  std::map<std::string,CdiVariable > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::iterator arg2 ;
+  std::vector< CdiVariable >::size_type arg3 ;
+  std::vector< CdiVariable >::value_type *arg4 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  size_t val3 ;
+  int ecode3 = 0 ;
+  void *argp4 = 0 ;
+  int res4 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
+  PyObject * obj3 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsMap",&obj0)) SWIG_fail;
-  {
-    std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *ptr = (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const &""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"OOOO:VarsVector_insert",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_insert" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsVector_insert" "', argument " "2"" of type '" "std::vector< CdiVariable >::iterator""'");
     }
-    arg1 = ptr;
   }
-  result = (std::map<std::string,CdiVariable > *)new std::map<std::string,CdiVariable >((std::map<std::string,CdiVariable > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  ecode3 = SWIG_AsVal_size_t(obj2, &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "VarsVector_insert" "', argument " "3"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg3 = static_cast< std::vector< CdiVariable >::size_type >(val3);
+  res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res4)) {
+    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "VarsVector_insert" "', argument " "4"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
+  }
+  if (!argp4) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsVector_insert" "', argument " "4"" of type '" "std::vector< CdiVariable >::value_type const &""'"); 
+  }
+  arg4 = reinterpret_cast< std::vector< CdiVariable >::value_type * >(argp4);
+  std_vector_Sl_CdiVariable_Sg__insert__SWIG_1(arg1,arg2,arg3,(CdiVariable const &)*arg4);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsMap(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_insert(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[5];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 4) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 0) {
-    return _wrap_new_VarsMap__SWIG_0(self, args);
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiVariable, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsVector_insert__SWIG_0(self, args);
+        }
+      }
+    }
   }
-  if (argc == 1) {
+  if (argc == 4) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::vector<CdiVariable,std::allocator< CdiVariable > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_new_VarsMap__SWIG_1(self, args);
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::vector< CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        {
+          int res = SWIG_AsVal_size_t(argv[2], NULL);
+          _v = SWIG_CheckState(res);
+        }
+        if (_v) {
+          int res = SWIG_ConvertPtr(argv[3], 0, SWIGTYPE_p_CdiVariable, 0);
+          _v = SWIG_CheckState(res);
+          if (_v) {
+            return _wrap_VarsVector_insert__SWIG_1(self, args);
+          }
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_VarsMap'.\n  Possible C/C++ prototypes are:\n    std::map<(std::string,CdiVariable)>()\n    std::map<(std::string,CdiVariable)>(std::map<std::string,CdiVariable > const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsVector_insert'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::vector< CdiVariable >::insert(std::vector< CdiVariable >::iterator,std::vector< CdiVariable >::value_type const &)\n"
+    "    std::vector< CdiVariable >::insert(std::vector< CdiVariable >::iterator,std::vector< CdiVariable >::size_type,std::vector< CdiVariable >::value_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_reserve(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  bool result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
+  std::vector< CdiVariable >::size_type arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsVector_reserve",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_empty" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_reserve" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (bool)((std::map<std::string,CdiVariable > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsVector_reserve" "', argument " "2"" of type '" "std::vector< CdiVariable >::size_type""'");
+  } 
+  arg2 = static_cast< std::vector< CdiVariable >::size_type >(val2);
+  (arg1)->reserve(arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsVector_capacity(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::size_type result;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsVector_capacity",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_size" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsVector_capacity" "', argument " "1"" of type '" "std::vector< CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->size();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  result = ((std::vector< CdiVariable > const *)arg1)->capacity();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -14923,20 +16713,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_VarsVector(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
+  std::vector< CdiVariable > *arg1 = (std::vector< CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsVector",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_clear" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsVector" "', argument " "1"" of type '" "std::vector< CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  (arg1)->clear();
+  arg1 = reinterpret_cast< std::vector< CdiVariable > * >(argp1);
+  delete arg1;
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -14944,445 +16734,349 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *VarsVector_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_VarsMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable > *arg2 = 0 ;
+  std::less< std::string > *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__lessT_std__string_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_swap" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_swap" "', argument " "2"" of type '" "std::map<std::string,CdiVariable > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::less< std::string > const &""'"); 
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_swap" "', argument " "2"" of type '" "std::map<std::string,CdiVariable > &""'"); 
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::less< std::string > const &""'"); 
   }
-  arg2 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::less< std::string > * >(argp1);
+  result = (std::map< std::string,CdiVariable > *)new std::map< std::string,CdiVariable >((std::less< std::string > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  SwigValueWrapper<std::allocator<std::pair<std::string const,CdiVariable > > > result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_get_allocator" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_iterator" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::map<std::string,CdiVariable >::allocator_type(static_cast< const std::map<std::string,CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_begin" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___nonzero__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg____nonzero__((std::map< std::string,CdiVariable > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::const_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_begin" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___bool__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg____bool__((std::map< std::string,CdiVariable > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_begin__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_end" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___len__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = std_map_Sl_std_string_Sc_CdiVariable_Sg____len__((std::map< std::string,CdiVariable > const *)arg1);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::const_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::mapped_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_end" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___getitem__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_end__SWIG_0(self, args);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___getitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_end__SWIG_1(self, args);
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___getitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
+    arg2 = ptr;
   }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rbegin" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+  try {
+    result = (std::map< std::string,CdiVariable >::mapped_type *) &std_map_Sl_std_string_Sc_CdiVariable_Sg____getitem__(arg1,(std::string const &)*arg2);
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiVariable, 0 |  0 );
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::const_reverse_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rbegin" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_rbegin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___delitem__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_rbegin__SWIG_0(self, args);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___delitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_rbegin__SWIG_1(self, args);
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___delitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
+    arg2 = ptr;
+  }
+  try {
+    std_map_Sl_std_string_Sc_CdiVariable_Sg____delitem__(arg1,(std::string const &)*arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
+  resultobj = SWIG_Py_Void();
+  if (SWIG_IsNewObj(res2)) delete arg2;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::reverse_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_has_key",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rend" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_has_key" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_has_key" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_has_key" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg__has_key((std::map< std::string,CdiVariable > const *)arg1,(std::string const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::const_reverse_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_keys",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rend" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_rend__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsMap_rend__SWIG_1(self, args);
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_keys" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__keys(arg1);
+  resultobj = result;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::size_type result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_values",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_values" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__values(arg1);
+  resultobj = result;
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_items",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_items" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  result = (arg1)->erase((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__items(arg1);
+  resultobj = result;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::size_type result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_count",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___contains__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_count" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___contains__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
   {
     std::string *ptr = (std::string *)0;
     res2 = SWIG_AsPtr_std_string(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_count" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___contains__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_count" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___contains__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     arg2 = ptr;
   }
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->count((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  result = (bool)std_map_Sl_std_string_Sc_CdiVariable_Sg____contains__(arg1,(std::string const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
@@ -15391,184 +17085,83 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::iterator arg2 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_key_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_key_iterator" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  (arg1)->erase(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__key_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::iterator arg2 ;
-  std::map<std::string,CdiVariable >::iterator arg3 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_value_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-    }
-  }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "3"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "3"" of type '" "std::map<std::string,CdiVariable >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_value_iterator" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_std_string_Sc_CdiVariable_Sg__value_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_erase(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        return _wrap_VarsMap_erase__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_VarsMap_erase__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<std::string,CdiVariable >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_VarsMap_erase__SWIG_2(self, args);
-        }
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::map<std::string,CdiVariable >::key_type const &)\n    erase(std::map<std::string,CdiVariable >::iterator)\n    erase(std::map<std::string,CdiVariable >::iterator,std::map<std::string,CdiVariable >::iterator)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsMap_find__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_find" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___setitem__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
   {
     std::string *ptr = (std::string *)0;
     res2 = SWIG_AsPtr_std_string(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     arg2 = ptr;
   }
-  result = (arg1)->find((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem____SWIG_0(arg1,(std::string const &)*arg2);
+  resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
@@ -15577,37 +17170,53 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_find__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::const_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
+  std::map< std::string,CdiVariable >::mapped_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int res2 = SWIG_OLDOBJ ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_find" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap___setitem__" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
   {
     std::string *ptr = (std::string *)0;
     res2 = SWIG_AsPtr_std_string(obj1, &ptr);
     if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___setitem__" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
     }
     arg2 = ptr;
   }
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->find((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsMap___setitem__" "', argument " "3"" of type '" "std::map< std::string,CdiVariable >::mapped_type const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap___setitem__" "', argument " "3"" of type '" "std::map< std::string,CdiVariable >::mapped_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::map< std::string,CdiVariable >::mapped_type * >(argp3);
+  try {
+    std_map_Sl_std_string_Sc_CdiVariable_Sg____setitem____SWIG_1(arg1,(std::string const &)*arg2,(CdiVariable const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
@@ -15616,774 +17225,828 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_find(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_VarsMap_find__SWIG_0(self, args);
+        return _wrap_VarsMap___setitem____SWIG_0(self, args);
       }
     }
   }
-  if (argc == 2) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
       _v = SWIG_CheckState(res);
       if (_v) {
-        return _wrap_VarsMap_find__SWIG_1(self, args);
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiVariable, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsMap___setitem____SWIG_1(self, args);
+        }
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_find'.\n  Possible C/C++ prototypes are:\n    find(std::map<std::string,CdiVariable >::key_type const &)\n    find(std::map<std::string,CdiVariable >::key_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsMap___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< std::string,CdiVariable >::__setitem__(std::map< std::string,CdiVariable >::key_type const &)\n"
+    "    std::map< std::string,CdiVariable >::__setitem__(std::map< std::string,CdiVariable >::key_type const &,std::map< std::string,CdiVariable >::mapped_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_lower_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_asdict(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_asdict",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_lower_bound" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_asdict" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  result = (arg1)->lower_bound((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_std_string_Sc_CdiVariable_Sg__asdict(arg1);
+  resultobj = result;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_lower_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::const_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  std::map< std::string,CdiVariable > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_VarsMap")) SWIG_fail;
+  result = (std::map< std::string,CdiVariable > *)new std::map< std::string,CdiVariable >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_VarsMap__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< std::string,CdiVariable > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_lower_bound" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsMap",&obj0)) SWIG_fail;
   {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+    std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *ptr = (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const &""'"); 
     }
     if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsMap" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const &""'"); 
     }
-    arg2 = ptr;
+    arg1 = ptr;
   }
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->lower_bound((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  result = (std::map< std::string,CdiVariable > *)new std::map< std::string,CdiVariable >((std::map< std::string,CdiVariable > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_lower_bound(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsMap(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[2];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 2) {
+  if (argc == 0) {
+    return _wrap_new_VarsMap__SWIG_1(self, args);
+  }
+  if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__lessT_std__string_t, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_VarsMap_lower_bound__SWIG_0(self, args);
-      }
+      return _wrap_new_VarsMap__SWIG_0(self, args);
     }
   }
-  if (argc == 2) {
+  if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_VarsMap_lower_bound__SWIG_1(self, args);
-      }
+      return _wrap_new_VarsMap__SWIG_2(self, args);
     }
   }
-  
+  
+fail:
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VarsMap'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< std::string,CdiVariable >::map(std::less< std::string > const &)\n"
+    "    std::map< std::string,CdiVariable >::map()\n"
+    "    std::map< std::string,CdiVariable >::map(std::map< std::string,CdiVariable > const &)\n");
+  return 0;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  bool result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_empty" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (bool)((std::map< std::string,CdiVariable > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::size_type result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_size" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = ((std::map< std::string,CdiVariable > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_lower_bound'.\n  Possible C/C++ prototypes are:\n    lower_bound(std::map<std::string,CdiVariable >::key_type const &)\n    lower_bound(std::map<std::string,CdiVariable >::key_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_upper_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_upper_bound" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_clear" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  result = (arg1)->upper_bound((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_upper_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
-  std::map<std::string,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<std::string,CdiVariable >::const_iterator result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  int res2 = SWIG_OLDOBJ ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_upper_bound" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_swap" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  {
-    std::string *ptr = (std::string *)0;
-    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
-    if (!SWIG_IsOK(res2)) {
-      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map<std::string,CdiVariable >::key_type const &""'"); 
-    }
-    arg2 = ptr;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_swap" "', argument " "2"" of type '" "std::map< std::string,CdiVariable > &""'"); 
   }
-  result = ((std::map<std::string,CdiVariable > const *)arg1)->upper_bound((std::map<std::string,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<std::string,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  if (SWIG_IsNewObj(res2)) delete arg2;
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_swap" "', argument " "2"" of type '" "std::map< std::string,CdiVariable > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsMap_upper_bound(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::pair< std::string const,CdiVariable > > > result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_VarsMap_upper_bound__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
-      _v = SWIG_CheckState(res);
-      if (_v) {
-        return _wrap_VarsMap_upper_bound__SWIG_1(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_get_allocator" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = ((std::map< std::string,CdiVariable > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::map< std::string,CdiVariable >::allocator_type(static_cast< const std::map< std::string,CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsMap_upper_bound'.\n  Possible C/C++ prototypes are:\n    upper_bound(std::map<std::string,CdiVariable >::key_type const &)\n    upper_bound(std::map<std::string,CdiVariable >::key_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_VarsMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<std::string,CdiVariable > *arg1 = (std::map<std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsMap",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, SWIG_POINTER_DISOWN |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsMap" "', argument " "1"" of type '" "std::map<std::string,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_begin" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<std::string,CdiVariable > * >(argp1);
-  delete arg1;
-  
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *VarsMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_VarsByCode_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::iterator result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_iterator" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_end" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  bool result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___nonzero__" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rbegin" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg____nonzero__((std::map<int,CdiVariable > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::size_type result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsMap_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___len__" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_rend" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = std_map_Sl_int_Sc_CdiVariable_Sg____len__((std::map<int,CdiVariable > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::mapped_type result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___getitem__" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___getitem__" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  try {
-    result = std_map_Sl_int_Sc_CdiVariable_Sg____getitem__((std::map<int,CdiVariable > const *)arg1,(int const &)*arg2);
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
   }
-  
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiVariable >::mapped_type(static_cast< const std::map<int,CdiVariable >::mapped_type& >(result))), SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type, SWIG_POINTER_OWN |  0 );
+  result = (arg1)->erase((std::map< std::string,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_count",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___delitem__" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___delitem__" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  try {
-    std_map_Sl_int_Sc_CdiVariable_Sg____delitem__(arg1,(int const &)*arg2);
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_count" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > const *""'"); 
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_count" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_count" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
   }
-  
-  resultobj = SWIG_Py_Void();
+  result = ((std::map< std::string,CdiVariable > const *)arg1)->count((std::map< std::string,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_has_key",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_has_key" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_has_key" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg__has_key((std::map<int,CdiVariable > const *)arg1,(int const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+    }
+  }
+  std_map_Sl_std_string_Sc_CdiVariable_Sg__erase__SWIG_1(arg1,arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::iterator arg2 ;
+  std::map< std::string,CdiVariable >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_keys",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_keys" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_erase" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__keys(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+    }
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "3"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsMap_erase" "', argument " "3"" of type '" "std::map< std::string,CdiVariable >::iterator""'");
+    }
+  }
+  std_map_Sl_std_string_Sc_CdiVariable_Sg__erase__SWIG_2(arg1,arg2,arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
+SWIGINTERN PyObject *_wrap_VarsMap_erase(PyObject *self, PyObject *args) {
+  int argc;
+  PyObject *argv[4];
+  int ii;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_values" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+  if (!PyTuple_Check(args)) SWIG_fail;
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
+    argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__values(arg1);
-  resultobj = result;
-  return resultobj;
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        return _wrap_VarsMap_erase__SWIG_1(self, args);
+      }
+    }
+  }
+  if (argc == 2) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      int res = SWIG_AsPtr_std_string(argv[1], (std::string**)(0));
+      _v = SWIG_CheckState(res);
+      if (_v) {
+        return _wrap_VarsMap_erase__SWIG_0(self, args);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< std::string,CdiVariable >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_VarsMap_erase__SWIG_2(self, args);
+        }
+      }
+    }
+  }
+  
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsMap_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< std::string,CdiVariable >::erase(std::map< std::string,CdiVariable >::key_type const &)\n"
+    "    std::map< std::string,CdiVariable >::erase(std::map< std::string,CdiVariable >::iterator)\n"
+    "    std::map< std::string,CdiVariable >::erase(std::map< std::string,CdiVariable >::iterator,std::map< std::string,CdiVariable >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_find(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_items",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_find",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_items" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_find" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__items(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_find" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  result = (arg1)->find((std::map< std::string,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_lower_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___contains__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___contains__" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_lower_bound" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___contains__" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg____contains__(arg1,(int const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_lower_bound" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
+  }
+  result = (arg1)->lower_bound((std::map< std::string,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsMap_upper_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
+  std::map< std::string,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  int res2 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::map< std::string,CdiVariable >::iterator result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_key_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_key_iterator" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsMap_upper_bound" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  {
+    std::string *ptr = (std::string *)0;
+    res2 = SWIG_AsPtr_std_string(obj1, &ptr);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsMap_upper_bound" "', argument " "2"" of type '" "std::map< std::string,CdiVariable >::key_type const &""'"); 
+    }
+    arg2 = ptr;
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__key_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  result = (arg1)->upper_bound((std::map< std::string,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< std::string,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res2)) delete arg2;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_VarsMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< std::string,CdiVariable > *arg1 = (std::map< std::string,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_value_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_value_iterator" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsMap" "', argument " "1"" of type '" "std::map< std::string,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__value_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< std::string,CdiVariable > * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *VarsMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_VarsByCode__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::mapped_type *arg3 = 0 ;
+  std::less< int > *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::map< int,CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsByCode___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsByCode",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__lessT_int_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___setitem__" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___setitem__" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsByCode___setitem__" "', argument " "3"" of type '" "std::map<int,CdiVariable >::mapped_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsByCode___setitem__" "', argument " "3"" of type '" "std::map<int,CdiVariable >::mapped_type const &""'"); 
-  }
-  arg3 = reinterpret_cast< std::map<int,CdiVariable >::mapped_type * >(argp3);
-  try {
-    std_map_Sl_int_Sc_CdiVariable_Sg____setitem__(arg1,(int const &)*arg2,(CdiVariable const &)*arg3);
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::less< int > const &""'"); 
   }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::less< int > const &""'"); 
   }
-  
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::less< int > * >(argp1);
+  result = (std::map< int,CdiVariable > *)new std::map< int,CdiVariable >((std::less< int > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsByCode__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *result = 0 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)":new_VarsByCode")) SWIG_fail;
-  result = (std::map<int,CdiVariable > *)new std::map<int,CdiVariable >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_iterator" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_new_VarsByCode__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = 0 ;
-  std::map<int,CdiVariable > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsByCode",&obj0)) SWIG_fail;
-  {
-    std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *ptr = (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::map<int,CdiVariable > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::map<int,CdiVariable > const &""'"); 
-    }
-    arg1 = ptr;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___nonzero__" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  result = (std::map<int,CdiVariable > *)new std::map<int,CdiVariable >((std::map<int,CdiVariable > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg____nonzero__((std::map< int,CdiVariable > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_VarsByCode(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_VarsByCode__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_VarsByCode__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_VarsByCode'.\n  Possible C/C++ prototypes are:\n    std::map<(int,CdiVariable)>()\n    std::map<(int,CdiVariable)>(std::map<int,CdiVariable > const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  bool result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_empty" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___bool__" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (bool)((std::map<int,CdiVariable > const *)arg1)->empty();
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg____bool__((std::map< int,CdiVariable > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -16391,21 +18054,21 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::size_type result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_size" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___len__" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->size();
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = std_map_Sl_int_Sc_CdiVariable_Sg____len__((std::map< int,CdiVariable > const *)arg1);
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -16413,53 +18076,76 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::mapped_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_clear" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___getitem__" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___getitem__" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  try {
+    result = (std::map< int,CdiVariable >::mapped_type *) &std_map_Sl_int_Sc_CdiVariable_Sg____getitem__(arg1,(int const &)*arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiVariable, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable > *arg2 = 0 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_swap" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___delitem__" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsByCode_swap" "', argument " "2"" of type '" "std::map<int,CdiVariable > &""'"); 
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___delitem__" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  try {
+    std_map_Sl_int_Sc_CdiVariable_Sg____delitem__(arg1,(int const &)*arg2);
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsByCode_swap" "', argument " "2"" of type '" "std::map<int,CdiVariable > &""'"); 
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg2 = reinterpret_cast< std::map<int,CdiVariable > * >(argp2);
-  (arg1)->swap(*arg2);
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -16467,403 +18153,461 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  SwigValueWrapper<std::allocator<std::pair<int const,CdiVariable > > > result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_has_key",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_get_allocator" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_has_key" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiVariable >::allocator_type(static_cast< const std::map<int,CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_has_key" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg__has_key((std::map< int,CdiVariable > const *)arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_keys",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_begin" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_keys" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__keys(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::const_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_values",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_begin" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_values" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__values(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsByCode_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsByCode_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsByCode_begin__SWIG_1(self, args);
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_items",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_items" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__items(arg1);
+  resultobj = result;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___contains__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_end" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___contains__" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___contains__" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiVariable_Sg____contains__(arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::const_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_key_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_end" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_key_iterator" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__key_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsByCode_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsByCode_end__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_VarsByCode_end__SWIG_1(self, args);
-    }
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_value_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_value_iterator" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiVariable_Sg__value_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::reverse_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rbegin" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___setitem__" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___setitem__" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  std_map_Sl_int_Sc_CdiVariable_Sg____setitem____SWIG_0(arg1,(int const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::const_reverse_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
+  std::map< int,CdiVariable >::mapped_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsByCode___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rbegin" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode___setitem__" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode___setitem__" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiVariable,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "VarsByCode___setitem__" "', argument " "3"" of type '" "std::map< int,CdiVariable >::mapped_type const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsByCode___setitem__" "', argument " "3"" of type '" "std::map< int,CdiVariable >::mapped_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::map< int,CdiVariable >::mapped_type * >(argp3);
+  try {
+    std_map_Sl_int_Sc_CdiVariable_Sg____setitem____SWIG_1(arg1,(int const &)*arg2,(CdiVariable const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsByCode_rbegin__SWIG_0(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_VarsByCode___setitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsByCode_rbegin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiVariable, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_VarsByCode___setitem____SWIG_1(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsByCode___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiVariable >::__setitem__(std::map< int,CdiVariable >::key_type const &)\n"
+    "    std::map< int,CdiVariable >::__setitem__(std::map< int,CdiVariable >::key_type const &,std::map< int,CdiVariable >::mapped_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_asdict(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::reverse_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_asdict",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rend" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_asdict" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiVariable_Sg__asdict(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsByCode__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  std::map< int,CdiVariable > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_VarsByCode")) SWIG_fail;
+  result = (std::map< int,CdiVariable > *)new std::map< int,CdiVariable >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_VarsByCode__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiVariable > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rend" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_VarsByCode",&obj0)) SWIG_fail;
+  {
+    std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *ptr = (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::map< int,CdiVariable > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_VarsByCode" "', argument " "1"" of type '" "std::map< int,CdiVariable > const &""'"); 
+    }
+    arg1 = ptr;
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  result = ((std::map<int,CdiVariable > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (std::map< int,CdiVariable > *)new std::map< int,CdiVariable >((std::map< int,CdiVariable > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_rend(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_VarsByCode(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[2];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
+  if (argc == 0) {
+    return _wrap_new_VarsByCode__SWIG_1(self, args);
+  }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__lessT_int_t, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsByCode_rend__SWIG_0(self, args);
+      return _wrap_new_VarsByCode__SWIG_0(self, args);
     }
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_VarsByCode_rend__SWIG_1(self, args);
+      return _wrap_new_VarsByCode__SWIG_2(self, args);
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_VarsByCode'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiVariable >::map(std::less< int > const &)\n"
+    "    std::map< int,CdiVariable >::map()\n"
+    "    std::map< int,CdiVariable >::map(std::map< int,CdiVariable > const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::size_type result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_empty" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->erase((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (bool)((std::map< int,CdiVariable > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::size_type result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_count",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_count" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_size" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_count" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiVariable > const *)arg1)->count((std::map<int,CdiVariable >::key_type const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = ((std::map< int,CdiVariable > const *)arg1)->size();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -16871,35 +18615,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::iterator arg2 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map<int,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map<int,CdiVariable >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_clear" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  (arg1)->erase(arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  (arg1)->clear();
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -16907,50 +18636,32 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::iterator arg2 ;
-  std::map<int,CdiVariable >::iterator arg3 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsByCode_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_swap" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map<int,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map<int,CdiVariable >::iterator""'");
-    }
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "VarsByCode_swap" "', argument " "2"" of type '" "std::map< int,CdiVariable > &""'"); 
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "3"" of type '" "std::map<int,CdiVariable >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "3"" of type '" "std::map<int,CdiVariable >::iterator""'");
-    }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "VarsByCode_swap" "', argument " "2"" of type '" "std::map< int,CdiVariable > &""'"); 
   }
-  (arg1)->erase(arg2,arg3);
+  arg2 = reinterpret_cast< std::map< int,CdiVariable > * >(argp2);
+  (arg1)->swap(*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -16958,389 +18669,299 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_erase(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsByCode_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::pair< int const,CdiVariable > > > result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        return _wrap_VarsByCode_erase__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsByCode_erase__SWIG_0(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_get_allocator" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter) != 0));
-      if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiVariable >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_VarsByCode_erase__SWIG_2(self, args);
-        }
-      }
-    }
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = ((std::map< int,CdiVariable > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::map< int,CdiVariable >::allocator_type(static_cast< const std::map< int,CdiVariable >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_VarsByCode_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiVariable >::iterator result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_begin" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::map<int,CdiVariable >::key_type const &)\n    erase(std::map<int,CdiVariable >::iterator)\n    erase(std::map<int,CdiVariable >::iterator,std::map<int,CdiVariable >::iterator)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_find__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_find" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_end" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_find" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->find((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_find__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::const_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_find" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rbegin" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_find" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiVariable > const *)arg1)->find((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_find(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
+SWIGINTERN PyObject *_wrap_VarsByCode_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiVariable >::reverse_iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsByCode_find__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsByCode_find__SWIG_1(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:VarsByCode_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_rend" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_find'.\n  Possible C/C++ prototypes are:\n    find(std::map<int,CdiVariable >::key_type const &)\n    find(std::map<int,CdiVariable >::key_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_lower_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
   arg2 = &temp2;
-  result = (arg1)->lower_bound((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->erase((std::map< int,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_lower_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::const_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_count",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_count" "', argument " "1"" of type '" "std::map< int,CdiVariable > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_count" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
   arg2 = &temp2;
-  result = ((std::map<int,CdiVariable > const *)arg1)->lower_bound((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = ((std::map< int,CdiVariable > const *)arg1)->count((std::map< int,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_lower_bound(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsByCode_lower_bound__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_VarsByCode_lower_bound__SWIG_1(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_lower_bound'.\n  Possible C/C++ prototypes are:\n    lower_bound(std::map<int,CdiVariable >::key_type const &)\n    lower_bound(std::map<int,CdiVariable >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_VarsByCode_upper_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->upper_bound((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map< int,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map< int,CdiVariable >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiVariable_Sg__erase__SWIG_1(arg1,arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_upper_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  std::map<int,CdiVariable >::key_type *arg2 = 0 ;
-  std::map<int,CdiVariable >::const_iterator result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::iterator arg2 ;
+  std::map< int,CdiVariable >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiVariable >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:VarsByCode_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiVariable > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_erase" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiVariable >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiVariable >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiVariable > const *)arg1)->upper_bound((std::map<int,CdiVariable >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiVariable >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map< int,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "2"" of type '" "std::map< int,CdiVariable >::iterator""'");
+    }
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "3"" of type '" "std::map< int,CdiVariable >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "VarsByCode_erase" "', argument " "3"" of type '" "std::map< int,CdiVariable >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiVariable_Sg__erase__SWIG_2(arg1,arg2,arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_VarsByCode_upper_bound(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_erase(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter) != 0));
       if (_v) {
-        return _wrap_VarsByCode_upper_bound__SWIG_0(self, args);
+        return _wrap_VarsByCode_erase__SWIG_1(self, args);
       }
     }
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -17348,316 +18969,233 @@ SWIGINTERN PyObject *_wrap_VarsByCode_upper_bound(PyObject *self, PyObject *args
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_VarsByCode_upper_bound__SWIG_1(self, args);
+        return _wrap_VarsByCode_erase__SWIG_0(self, args);
       }
     }
   }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'VarsByCode_upper_bound'.\n  Possible C/C++ prototypes are:\n    upper_bound(std::map<int,CdiVariable >::key_type const &)\n    upper_bound(std::map<int,CdiVariable >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_VarsByCode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiVariable > *arg1 = (std::map<int,CdiVariable > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsByCode",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsByCode" "', argument " "1"" of type '" "std::map<int,CdiVariable > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiVariable > * >(argp1);
-  delete arg1;
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *VarsByCode_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_TaxesMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_iterator" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___nonzero__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiVariable >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_VarsByCode_erase__SWIG_2(self, args);
+        }
+      }
+    }
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg____nonzero__((std::map<int,CdiTaxis > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___len__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = std_map_Sl_int_Sc_CdiTaxis_Sg____len__((std::map<int,CdiTaxis > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'VarsByCode_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiVariable >::erase(std::map< int,CdiVariable >::key_type const &)\n"
+    "    std::map< int,CdiVariable >::erase(std::map< int,CdiVariable >::iterator)\n"
+    "    std::map< int,CdiVariable >::erase(std::map< int,CdiVariable >::iterator,std::map< int,CdiVariable >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_find(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::mapped_type result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_find",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___getitem__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_find" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___getitem__" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  try {
-    result = std_map_Sl_int_Sc_CdiTaxis_Sg____getitem__((std::map<int,CdiTaxis > const *)arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiTaxis >::mapped_type(static_cast< const std::map<int,CdiTaxis >::mapped_type& >(result))), SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type, SWIG_POINTER_OWN |  0 );
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_find" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
+  arg2 = &temp2;
+  result = (arg1)->find((std::map< int,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_lower_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_lower_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___delitem__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_lower_bound" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___delitem__" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_lower_bound" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
   arg2 = &temp2;
-  try {
-    std_map_Sl_int_Sc_CdiTaxis_Sg____delitem__(arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_Py_Void();
+  result = (arg1)->lower_bound((std::map< int,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_VarsByCode_upper_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
+  std::map< int,CdiVariable >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiVariable >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiVariable >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_has_key",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:VarsByCode_upper_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_has_key" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "VarsByCode_upper_bound" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_has_key" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "VarsByCode_upper_bound" "', argument " "2"" of type '" "std::map< int,CdiVariable >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiVariable >::key_type >(val2);
   arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg__has_key((std::map<int,CdiTaxis > const *)arg1,(int const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  result = (arg1)->upper_bound((std::map< int,CdiVariable >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiVariable >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_VarsByCode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiVariable > *arg1 = (std::map< int,CdiVariable > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_keys",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_VarsByCode",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_keys" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_VarsByCode" "', argument " "1"" of type '" "std::map< int,CdiVariable > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__keys(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiVariable > * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *VarsByCode_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_TaxesMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::less< int > *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_TaxesMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__lessT_int_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_values" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__values(arg1);
-  resultobj = result;
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
+  }
+  arg1 = reinterpret_cast< std::less< int > * >(argp1);
+  result = (std::map< int,CdiTaxis > *)new std::map< int,CdiTaxis >((std::less< int > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_items",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_items" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_iterator" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__items(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___contains__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___contains__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___nonzero__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___contains__" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg____contains__(arg1,(int const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg____nonzero__((std::map< int,CdiTaxis > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -17665,232 +19203,120 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_key_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_key_iterator" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___bool__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__key_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg____bool__((std::map< int,CdiTaxis > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis >::size_type result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_value_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_value_iterator" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___len__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__value_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = std_map_Sl_int_Sc_CdiTaxis_Sg____len__((std::map< int,CdiTaxis > const *)arg1);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::mapped_type *arg3 = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::map< int,CdiTaxis >::mapped_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:TaxesMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___setitem__" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___getitem__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___setitem__" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___getitem__" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "TaxesMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiTaxis >::mapped_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "TaxesMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiTaxis >::mapped_type const &""'"); 
-  }
-  arg3 = reinterpret_cast< std::map<int,CdiTaxis >::mapped_type * >(argp3);
   try {
-    std_map_Sl_int_Sc_CdiTaxis_Sg____setitem__(arg1,(int const &)*arg2,(CdiTaxis const &)*arg3);
+    result = (std::map< int,CdiTaxis >::mapped_type *) &std_map_Sl_int_Sc_CdiTaxis_Sg____getitem__(arg1,(int const &)*arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_TaxesMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_TaxesMap")) SWIG_fail;
-  result = (std::map<int,CdiTaxis > *)new std::map<int,CdiTaxis >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_TaxesMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = 0 ;
-  std::map<int,CdiTaxis > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_TaxesMap",&obj0)) SWIG_fail;
-  {
-    std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *ptr = (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (std::map<int,CdiTaxis > *)new std::map<int,CdiTaxis >((std::map<int,CdiTaxis > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiTaxis, 0 |  0 );
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_TaxesMap(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_TaxesMap__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_TaxesMap__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_TaxesMap'.\n  Possible C/C++ prototypes are:\n    std::map<(int,CdiTaxis)>()\n    std::map<(int,CdiTaxis)>(std::map<int,CdiTaxis > const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  bool result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_empty" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___delitem__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (bool)((std::map<int,CdiTaxis > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_size" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___delitem__" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
+  arg2 = &temp2;
+  try {
+    std_map_Sl_int_Sc_CdiTaxis_Sg____delitem__(arg1,(int const &)*arg2);
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_clear" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  (arg1)->clear();
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -17898,436 +19324,461 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis > *arg2 = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_has_key",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_swap" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "TaxesMap_swap" "', argument " "2"" of type '" "std::map<int,CdiTaxis > &""'"); 
-  }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "TaxesMap_swap" "', argument " "2"" of type '" "std::map<int,CdiTaxis > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_has_key" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_has_key" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg__has_key((std::map< int,CdiTaxis > const *)arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  SwigValueWrapper<std::allocator<std::pair<int const,CdiTaxis > > > result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_keys",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_get_allocator" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_keys" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiTaxis >::allocator_type(static_cast< const std::map<int,CdiTaxis >::allocator_type& >(result))), SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__keys(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_values",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_begin" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_values" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__values(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::const_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_items",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_begin" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_TaxesMap_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_TaxesMap_begin__SWIG_1(self, args);
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_items" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__items(arg1);
+  resultobj = result;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___contains__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_end" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___contains__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___contains__" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiTaxis_Sg____contains__(arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::const_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_key_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_end" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_key_iterator" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__key_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_TaxesMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_TaxesMap_end__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_TaxesMap_end__SWIG_1(self, args);
-    }
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_value_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_value_iterator" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiTaxis_Sg__value_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::reverse_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
+  arg2 = &temp2;
+  std_map_Sl_int_Sc_CdiTaxis_Sg____setitem____SWIG_0(arg1,(int const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::const_reverse_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
+  std::map< int,CdiTaxis >::mapped_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:TaxesMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
+  arg2 = &temp2;
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiTaxis,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "TaxesMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiTaxis >::mapped_type const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "TaxesMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiTaxis >::mapped_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::map< int,CdiTaxis >::mapped_type * >(argp3);
+  try {
+    std_map_Sl_int_Sc_CdiTaxis_Sg____setitem____SWIG_1(arg1,(int const &)*arg2,(CdiTaxis const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_TaxesMap_rbegin__SWIG_0(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_TaxesMap___setitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_TaxesMap_rbegin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiTaxis, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_TaxesMap___setitem____SWIG_1(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'TaxesMap___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiTaxis >::__setitem__(std::map< int,CdiTaxis >::key_type const &)\n"
+    "    std::map< int,CdiTaxis >::__setitem__(std::map< int,CdiTaxis >::key_type const &,std::map< int,CdiTaxis >::mapped_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_asdict(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::reverse_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_asdict",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rend" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_asdict" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiTaxis_Sg__asdict(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_TaxesMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  std::map< int,CdiTaxis > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_TaxesMap")) SWIG_fail;
+  result = (std::map< int,CdiTaxis > *)new std::map< int,CdiTaxis >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_TaxesMap__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiTaxis > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rend" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_TaxesMap",&obj0)) SWIG_fail;
+  {
+    std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *ptr = (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_TaxesMap" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const &""'"); 
+    }
+    arg1 = ptr;
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  result = ((std::map<int,CdiTaxis > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (std::map< int,CdiTaxis > *)new std::map< int,CdiTaxis >((std::map< int,CdiTaxis > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_rend(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_TaxesMap(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[2];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
+  if (argc == 0) {
+    return _wrap_new_TaxesMap__SWIG_1(self, args);
+  }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__lessT_int_t, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_TaxesMap_rend__SWIG_0(self, args);
+      return _wrap_new_TaxesMap__SWIG_0(self, args);
     }
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_TaxesMap_rend__SWIG_1(self, args);
+      return _wrap_new_TaxesMap__SWIG_2(self, args);
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_TaxesMap'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiTaxis >::map(std::less< int > const &)\n"
+    "    std::map< int,CdiTaxis >::map()\n"
+    "    std::map< int,CdiTaxis >::map(std::map< int,CdiTaxis > const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::size_type result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_empty" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->erase((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (bool)((std::map< int,CdiTaxis > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::size_type result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_count",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_count" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_size" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_count" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiTaxis > const *)arg1)->count((std::map<int,CdiTaxis >::key_type const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = ((std::map< int,CdiTaxis > const *)arg1)->size();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -18335,35 +19786,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::iterator arg2 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_clear" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  (arg1)->erase(arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  (arg1)->clear();
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -18371,50 +19807,32 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::iterator arg2 ;
-  std::map<int,CdiTaxis >::iterator arg3 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:TaxesMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_swap" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-    }
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "TaxesMap_swap" "', argument " "2"" of type '" "std::map< int,CdiTaxis > &""'"); 
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "3"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "3"" of type '" "std::map<int,CdiTaxis >::iterator""'");
-    }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "TaxesMap_swap" "', argument " "2"" of type '" "std::map< int,CdiTaxis > &""'"); 
   }
-  (arg1)->erase(arg2,arg3);
+  arg2 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp2);
+  (arg1)->swap(*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -18422,389 +19840,299 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_erase(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
+SWIGINTERN PyObject *_wrap_TaxesMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::pair< int const,CdiTaxis > > > result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter) != 0));
-      if (_v) {
-        return _wrap_TaxesMap_erase__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_TaxesMap_erase__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter) != 0));
-      if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiTaxis >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_TaxesMap_erase__SWIG_2(self, args);
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_get_allocator" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = ((std::map< int,CdiTaxis > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::map< int,CdiTaxis >::allocator_type(static_cast< const std::map< int,CdiTaxis >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_TaxesMap_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis >::iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_begin" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::map<int,CdiTaxis >::key_type const &)\n    erase(std::map<int,CdiTaxis >::iterator)\n    erase(std::map<int,CdiTaxis >::iterator,std::map<int,CdiTaxis >::iterator)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_find__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_find" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_end" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_find" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->find((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_find__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::const_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::reverse_iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_find" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rbegin" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_find" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiTaxis > const *)arg1)->find((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_find(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
+SWIGINTERN PyObject *_wrap_TaxesMap_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis >::reverse_iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_TaxesMap_find__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_TaxesMap_find__SWIG_1(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:TaxesMap_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_rend" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_find'.\n  Possible C/C++ prototypes are:\n    find(std::map<int,CdiTaxis >::key_type const &)\n    find(std::map<int,CdiTaxis >::key_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_lower_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = (arg1)->lower_bound((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->erase((std::map< int,CdiTaxis >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_lower_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::const_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_count",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_count" "', argument " "1"" of type '" "std::map< int,CdiTaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_count" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = ((std::map<int,CdiTaxis > const *)arg1)->lower_bound((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = ((std::map< int,CdiTaxis > const *)arg1)->count((std::map< int,CdiTaxis >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_lower_bound(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_TaxesMap_lower_bound__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_TaxesMap_lower_bound__SWIG_1(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_lower_bound'.\n  Possible C/C++ prototypes are:\n    lower_bound(std::map<int,CdiTaxis >::key_type const &)\n    lower_bound(std::map<int,CdiTaxis >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_TaxesMap_upper_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->upper_bound((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiTaxis_Sg__erase__SWIG_1(arg1,arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_upper_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  std::map<int,CdiTaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiTaxis >::const_iterator result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::iterator arg2 ;
+  std::map< int,CdiTaxis >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiTaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:TaxesMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiTaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiTaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiTaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiTaxis > const *)arg1)->upper_bound((std::map<int,CdiTaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiTaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+    }
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "3"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "TaxesMap_erase" "', argument " "3"" of type '" "std::map< int,CdiTaxis >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiTaxis_Sg__erase__SWIG_2(arg1,arg2,arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_TaxesMap_upper_bound(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_erase(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter) != 0));
       if (_v) {
-        return _wrap_TaxesMap_upper_bound__SWIG_0(self, args);
+        return _wrap_TaxesMap_erase__SWIG_1(self, args);
       }
     }
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -18812,316 +20140,233 @@ SWIGINTERN PyObject *_wrap_TaxesMap_upper_bound(PyObject *self, PyObject *args)
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_TaxesMap_upper_bound__SWIG_1(self, args);
+        return _wrap_TaxesMap_erase__SWIG_0(self, args);
       }
     }
   }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'TaxesMap_upper_bound'.\n  Possible C/C++ prototypes are:\n    upper_bound(std::map<int,CdiTaxis >::key_type const &)\n    upper_bound(std::map<int,CdiTaxis >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_TaxesMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiTaxis > *arg1 = (std::map<int,CdiTaxis > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_TaxesMap",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_TaxesMap" "', argument " "1"" of type '" "std::map<int,CdiTaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiTaxis > * >(argp1);
-  delete arg1;
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *TaxesMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_ZaxesMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_iterator" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___nonzero__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiTaxis >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_TaxesMap_erase__SWIG_2(self, args);
+        }
+      }
+    }
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg____nonzero__((std::map<int,CdiZaxis > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___len__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = std_map_Sl_int_Sc_CdiZaxis_Sg____len__((std::map<int,CdiZaxis > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'TaxesMap_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiTaxis >::erase(std::map< int,CdiTaxis >::key_type const &)\n"
+    "    std::map< int,CdiTaxis >::erase(std::map< int,CdiTaxis >::iterator)\n"
+    "    std::map< int,CdiTaxis >::erase(std::map< int,CdiTaxis >::iterator,std::map< int,CdiTaxis >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_find(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::mapped_type result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_find",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___getitem__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_find" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___getitem__" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_find" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  try {
-    result = std_map_Sl_int_Sc_CdiZaxis_Sg____getitem__((std::map<int,CdiZaxis > const *)arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiZaxis >::mapped_type(static_cast< const std::map<int,CdiZaxis >::mapped_type& >(result))), SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type, SWIG_POINTER_OWN |  0 );
+  result = (arg1)->find((std::map< int,CdiTaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_lower_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___delitem__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_lower_bound" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___delitem__" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_lower_bound" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  try {
-    std_map_Sl_int_Sc_CdiZaxis_Sg____delitem__(arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_Py_Void();
+  result = (arg1)->lower_bound((std::map< int,CdiTaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_TaxesMap_upper_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
+  std::map< int,CdiTaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiTaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiTaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_has_key",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:TaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_has_key" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "TaxesMap_upper_bound" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_has_key" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "TaxesMap_upper_bound" "', argument " "2"" of type '" "std::map< int,CdiTaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiTaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg__has_key((std::map<int,CdiZaxis > const *)arg1,(int const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  result = (arg1)->upper_bound((std::map< int,CdiTaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiTaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_TaxesMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiTaxis > *arg1 = (std::map< int,CdiTaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_keys",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_TaxesMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_keys" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_TaxesMap" "', argument " "1"" of type '" "std::map< int,CdiTaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__keys(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiTaxis > * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *TaxesMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_ZaxesMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::less< int > *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_ZaxesMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__lessT_int_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_values" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__values(arg1);
-  resultobj = result;
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
+  }
+  arg1 = reinterpret_cast< std::less< int > * >(argp1);
+  result = (std::map< int,CdiZaxis > *)new std::map< int,CdiZaxis >((std::less< int > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_items",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_items" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_iterator" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__items(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___contains__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___contains__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___nonzero__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___contains__" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg____contains__(arg1,(int const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg____nonzero__((std::map< int,CdiZaxis > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -19129,265 +20374,120 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_key_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_key_iterator" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___bool__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__key_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg____bool__((std::map< int,CdiZaxis > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis >::size_type result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_value_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_value_iterator" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___len__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__value_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = std_map_Sl_int_Sc_CdiZaxis_Sg____len__((std::map< int,CdiZaxis > const *)arg1);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::mapped_type *arg3 = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::map< int,CdiZaxis >::mapped_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:ZaxesMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___setitem__" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___getitem__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___setitem__" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___getitem__" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ZaxesMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiZaxis >::mapped_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ZaxesMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiZaxis >::mapped_type const &""'"); 
-  }
-  arg3 = reinterpret_cast< std::map<int,CdiZaxis >::mapped_type * >(argp3);
   try {
-    std_map_Sl_int_Sc_CdiZaxis_Sg____setitem__(arg1,(int const &)*arg2,(CdiZaxis const &)*arg3);
+    result = (std::map< int,CdiZaxis >::mapped_type *) &std_map_Sl_int_Sc_CdiZaxis_Sg____getitem__(arg1,(int const &)*arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_ZaxesMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_ZaxesMap")) SWIG_fail;
-  result = (std::map<int,CdiZaxis > *)new std::map<int,CdiZaxis >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_ZaxesMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = 0 ;
-  std::map<int,CdiZaxis > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_ZaxesMap",&obj0)) SWIG_fail;
-  {
-    std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *ptr = (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (std::map<int,CdiZaxis > *)new std::map<int,CdiZaxis >((std::map<int,CdiZaxis > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return resultobj;
-fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_ZaxesMap(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_ZaxesMap__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_ZaxesMap__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_ZaxesMap'.\n  Possible C/C++ prototypes are:\n    std::map<(int,CdiZaxis)>()\n    std::map<(int,CdiZaxis)>(std::map<int,CdiZaxis > const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_empty" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (bool)((std::map<int,CdiZaxis > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_size" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_clear" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiZaxis, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis > *arg2 = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_swap" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___delitem__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ZaxesMap_swap" "', argument " "2"" of type '" "std::map<int,CdiZaxis > &""'"); 
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___delitem__" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
+  arg2 = &temp2;
+  try {
+    std_map_Sl_int_Sc_CdiZaxis_Sg____delitem__(arg1,(int const &)*arg2);
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ZaxesMap_swap" "', argument " "2"" of type '" "std::map<int,CdiZaxis > &""'"); 
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg2 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp2);
-  (arg1)->swap(*arg2);
+  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -19395,403 +20495,461 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  SwigValueWrapper<std::allocator<std::pair<int const,CdiZaxis > > > result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_has_key",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_get_allocator" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_has_key" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiZaxis >::allocator_type(static_cast< const std::map<int,CdiZaxis >::allocator_type& >(result))), SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_has_key" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg__has_key((std::map< int,CdiZaxis > const *)arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_keys",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_begin" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_keys" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__keys(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::const_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_values",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_begin" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_values" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__values(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_ZaxesMap_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_ZaxesMap_begin__SWIG_1(self, args);
-    }
-  }
+SWIGINTERN PyObject *_wrap_ZaxesMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_items",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_items" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__items(arg1);
+  resultobj = result;
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___contains__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_end" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___contains__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___contains__" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiZaxis_Sg____contains__(arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::const_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_key_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_end" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_key_iterator" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__key_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_end(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_ZaxesMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_ZaxesMap_end__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_ZaxesMap_end__SWIG_1(self, args);
-    }
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_value_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_value_iterator" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiZaxis_Sg__value_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::reverse_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
+  arg2 = &temp2;
+  std_map_Sl_int_Sc_CdiZaxis_Sg____setitem____SWIG_0(arg1,(int const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::const_reverse_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
+  std::map< int,CdiZaxis >::mapped_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:ZaxesMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
+  arg2 = &temp2;
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiZaxis,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ZaxesMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiZaxis >::mapped_type const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ZaxesMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiZaxis >::mapped_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::map< int,CdiZaxis >::mapped_type * >(argp3);
+  try {
+    std_map_Sl_int_Sc_CdiZaxis_Sg____setitem____SWIG_1(arg1,(int const &)*arg2,(CdiZaxis const &)*arg3);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_ZaxesMap_rbegin__SWIG_0(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_ZaxesMap___setitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_ZaxesMap_rbegin__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiZaxis, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_ZaxesMap___setitem____SWIG_1(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ZaxesMap___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiZaxis >::__setitem__(std::map< int,CdiZaxis >::key_type const &)\n"
+    "    std::map< int,CdiZaxis >::__setitem__(std::map< int,CdiZaxis >::key_type const &,std::map< int,CdiZaxis >::mapped_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_asdict(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::reverse_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_asdict",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rend" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_asdict" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiZaxis_Sg__asdict(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_ZaxesMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  std::map< int,CdiZaxis > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_ZaxesMap")) SWIG_fail;
+  result = (std::map< int,CdiZaxis > *)new std::map< int,CdiZaxis >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_ZaxesMap__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rend" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_ZaxesMap",&obj0)) SWIG_fail;
+  {
+    std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *ptr = (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_ZaxesMap" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const &""'"); 
+    }
+    arg1 = ptr;
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  result = ((std::map<int,CdiZaxis > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (std::map< int,CdiZaxis > *)new std::map< int,CdiZaxis >((std::map< int,CdiZaxis > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_rend(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_ZaxesMap(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[2];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
+  if (argc == 0) {
+    return _wrap_new_ZaxesMap__SWIG_1(self, args);
+  }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__lessT_int_t, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_ZaxesMap_rend__SWIG_0(self, args);
+      return _wrap_new_ZaxesMap__SWIG_0(self, args);
     }
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_ZaxesMap_rend__SWIG_1(self, args);
+      return _wrap_new_ZaxesMap__SWIG_2(self, args);
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_ZaxesMap'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiZaxis >::map(std::less< int > const &)\n"
+    "    std::map< int,CdiZaxis >::map()\n"
+    "    std::map< int,CdiZaxis >::map(std::map< int,CdiZaxis > const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::size_type result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_empty" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->erase((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (bool)((std::map< int,CdiZaxis > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::size_type result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_count",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_count" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_size" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_count" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiZaxis > const *)arg1)->count((std::map<int,CdiZaxis >::key_type const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = ((std::map< int,CdiZaxis > const *)arg1)->size();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -19799,35 +20957,20 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::iterator arg2 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-    }
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_clear" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  (arg1)->erase(arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  (arg1)->clear();
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -19835,50 +20978,32 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::iterator arg2 ;
-  std::map<int,CdiZaxis >::iterator arg3 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:ZaxesMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_swap" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-    }
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ZaxesMap_swap" "', argument " "2"" of type '" "std::map< int,CdiZaxis > &""'"); 
   }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "3"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "3"" of type '" "std::map<int,CdiZaxis >::iterator""'");
-    }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "ZaxesMap_swap" "', argument " "2"" of type '" "std::map< int,CdiZaxis > &""'"); 
   }
-  (arg1)->erase(arg2,arg3);
+  arg2 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp2);
+  (arg1)->swap(*arg2);
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -19886,389 +21011,299 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_erase(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
+SWIGINTERN PyObject *_wrap_ZaxesMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::allocator< std::pair< int const,CdiZaxis > > > result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter) != 0));
-      if (_v) {
-        return _wrap_ZaxesMap_erase__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ZaxesMap_erase__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter) != 0));
-      if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiZaxis >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_ZaxesMap_erase__SWIG_2(self, args);
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_get_allocator" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = ((std::map< int,CdiZaxis > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::map< int,CdiZaxis >::allocator_type(static_cast< const std::map< int,CdiZaxis >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::map<int,CdiZaxis >::key_type const &)\n    erase(std::map<int,CdiZaxis >::iterator)\n    erase(std::map<int,CdiZaxis >::iterator,std::map<int,CdiZaxis >::iterator)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_find__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_find" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_begin" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_find" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->find((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_find__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::const_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_find" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_end" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_find" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiZaxis > const *)arg1)->find((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_find(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
+SWIGINTERN PyObject *_wrap_ZaxesMap_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis >::reverse_iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ZaxesMap_find__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ZaxesMap_find__SWIG_1(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rbegin" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ZaxesMap_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis >::reverse_iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:ZaxesMap_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_rend" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_find'.\n  Possible C/C++ prototypes are:\n    find(std::map<int,CdiZaxis >::key_type const &)\n    find(std::map<int,CdiZaxis >::key_type const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_lower_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = (arg1)->lower_bound((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->erase((std::map< int,CdiZaxis >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_lower_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::const_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_count",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_count" "', argument " "1"" of type '" "std::map< int,CdiZaxis > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_count" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = ((std::map<int,CdiZaxis > const *)arg1)->lower_bound((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = ((std::map< int,CdiZaxis > const *)arg1)->count((std::map< int,CdiZaxis >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_lower_bound(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ZaxesMap_lower_bound__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_ZaxesMap_lower_bound__SWIG_1(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_lower_bound'.\n  Possible C/C++ prototypes are:\n    lower_bound(std::map<int,CdiZaxis >::key_type const &)\n    lower_bound(std::map<int,CdiZaxis >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_ZaxesMap_upper_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->upper_bound((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiZaxis_Sg__erase__SWIG_1(arg1,arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_upper_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  std::map<int,CdiZaxis >::key_type *arg2 = 0 ;
-  std::map<int,CdiZaxis >::const_iterator result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::iterator arg2 ;
+  std::map< int,CdiZaxis >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiZaxis >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:ZaxesMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiZaxis > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_erase" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiZaxis >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiZaxis >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiZaxis > const *)arg1)->upper_bound((std::map<int,CdiZaxis >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiZaxis >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+    }
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "3"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ZaxesMap_erase" "', argument " "3"" of type '" "std::map< int,CdiZaxis >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiZaxis_Sg__erase__SWIG_2(arg1,arg2,arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_ZaxesMap_upper_bound(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_erase(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter) != 0));
       if (_v) {
-        return _wrap_ZaxesMap_upper_bound__SWIG_0(self, args);
+        return _wrap_ZaxesMap_erase__SWIG_1(self, args);
       }
     }
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -20276,316 +21311,233 @@ SWIGINTERN PyObject *_wrap_ZaxesMap_upper_bound(PyObject *self, PyObject *args)
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_ZaxesMap_upper_bound__SWIG_1(self, args);
+        return _wrap_ZaxesMap_erase__SWIG_0(self, args);
       }
     }
   }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'ZaxesMap_upper_bound'.\n  Possible C/C++ prototypes are:\n    upper_bound(std::map<int,CdiZaxis >::key_type const &)\n    upper_bound(std::map<int,CdiZaxis >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_ZaxesMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiZaxis > *arg1 = (std::map<int,CdiZaxis > *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:delete_ZaxesMap",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ZaxesMap" "', argument " "1"" of type '" "std::map<int,CdiZaxis > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiZaxis > * >(argp1);
-  delete arg1;
-  
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *ZaxesMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, SWIG_NewClientData(obj));
-  return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *_wrap_GridsMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_iterator" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_GridsMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  bool result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap___nonzero__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___nonzero__" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiZaxis >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_ZaxesMap_erase__SWIG_2(self, args);
+        }
+      }
+    }
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg____nonzero__((std::map<int,CdiGrid > const *)arg1);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_GridsMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::size_type result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap___len__",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___len__" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = std_map_Sl_int_Sc_CdiGrid_Sg____len__((std::map<int,CdiGrid > const *)arg1);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
-  return resultobj;
 fail:
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'ZaxesMap_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiZaxis >::erase(std::map< int,CdiZaxis >::key_type const &)\n"
+    "    std::map< int,CdiZaxis >::erase(std::map< int,CdiZaxis >::iterator)\n"
+    "    std::map< int,CdiZaxis >::erase(std::map< int,CdiZaxis >::iterator,std::map< int,CdiZaxis >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_find(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::mapped_type result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___getitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_find",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___getitem__" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_find" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___getitem__" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_find" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  try {
-    result = std_map_Sl_int_Sc_CdiGrid_Sg____getitem__((std::map<int,CdiGrid > const *)arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiGrid >::mapped_type(static_cast< const std::map<int,CdiGrid >::mapped_type& >(result))), SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type, SWIG_POINTER_OWN |  0 );
+  result = (arg1)->find((std::map< int,CdiZaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_lower_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___delitem__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_lower_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___delitem__" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_lower_bound" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___delitem__" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_lower_bound" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  try {
-    std_map_Sl_int_Sc_CdiGrid_Sg____delitem__(arg1,(int const &)*arg2);
-  }
-  catch(std::out_of_range &_e) {
-    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
-  }
-  
-  resultobj = SWIG_Py_Void();
+  result = (arg1)->lower_bound((std::map< int,CdiZaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_ZaxesMap_upper_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
+  std::map< int,CdiZaxis >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiZaxis >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiZaxis >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_has_key",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:ZaxesMap_upper_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_has_key" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ZaxesMap_upper_bound" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_has_key" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "ZaxesMap_upper_bound" "', argument " "2"" of type '" "std::map< int,CdiZaxis >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiZaxis >::key_type >(val2);
   arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg__has_key((std::map<int,CdiGrid > const *)arg1,(int const &)*arg2);
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  result = (arg1)->upper_bound((std::map< int,CdiZaxis >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiZaxis >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_delete_ZaxesMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiZaxis > *arg1 = (std::map< int,CdiZaxis > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_keys",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:delete_ZaxesMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_keys" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_ZaxesMap" "', argument " "1"" of type '" "std::map< int,CdiZaxis > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__keys(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiZaxis > * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *ZaxesMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, SWIG_NewClientData(obj));
+  return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_GridsMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject *result = 0 ;
+  std::less< int > *arg1 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_values",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:new_GridsMap",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1, SWIGTYPE_p_std__lessT_int_t,  0  | 0);
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_values" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__values(arg1);
-  resultobj = result;
+  if (!argp1) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::less< int > const &""'"); 
+  }
+  arg1 = reinterpret_cast< std::less< int > * >(argp1);
+  result = (std::map< int,CdiGrid > *)new std::map< int,CdiGrid >((std::less< int > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, SWIG_POINTER_NEW |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject *result = 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_items",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_items" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_iterator" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__items(arg1);
-  resultobj = result;
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___nonzero__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  bool result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___contains__",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap___nonzero__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___contains__" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___nonzero__" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___contains__" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
-  arg2 = &temp2;
-  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg____contains__(arg1,(int const &)*arg2);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg____nonzero__((std::map< int,CdiGrid > const *)arg1);
   resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
@@ -20593,1033 +21545,936 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___bool__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_key_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap___bool__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_key_iterator" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___bool__" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__key_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg____bool__((std::map< int,CdiGrid > const *)arg1);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___len__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  PyObject **arg2 = (PyObject **) 0 ;
-  swig::PySwigIterator *result = 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid >::size_type result;
   
-  arg2 = &obj0;
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_value_iterator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap___len__",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_value_iterator" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___len__" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (swig::PySwigIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__value_iterator(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__PySwigIterator, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = std_map_Sl_int_Sc_CdiGrid_Sg____len__((std::map< int,CdiGrid > const *)arg1);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap___setitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::mapped_type *arg3 = 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
-  void *argp3 = 0 ;
-  int res3 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::map< int,CdiGrid >::mapped_type *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:GridsMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___getitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___setitem__" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___getitem__" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___setitem__" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___getitem__" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
   arg2 = &temp2;
-  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type,  0  | 0);
-  if (!SWIG_IsOK(res3)) {
-    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "GridsMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiGrid >::mapped_type const &""'"); 
-  }
-  if (!argp3) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GridsMap___setitem__" "', argument " "3"" of type '" "std::map<int,CdiGrid >::mapped_type const &""'"); 
-  }
-  arg3 = reinterpret_cast< std::map<int,CdiGrid >::mapped_type * >(argp3);
   try {
-    std_map_Sl_int_Sc_CdiGrid_Sg____setitem__(arg1,(int const &)*arg2,(CdiGrid const &)*arg3);
+    result = (std::map< int,CdiGrid >::mapped_type *) &std_map_Sl_int_Sc_CdiGrid_Sg____getitem__(arg1,(int const &)*arg2);
   }
   catch(std::out_of_range &_e) {
     SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
   }
   
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_GridsMap__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *result = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)":new_GridsMap")) SWIG_fail;
-  result = (std::map<int,CdiGrid > *)new std::map<int,CdiGrid >();
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, SWIG_POINTER_NEW |  0 );
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_GridsMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = 0 ;
-  std::map<int,CdiGrid > *result = 0 ;
-  int res1 = SWIG_OLDOBJ ;
-  PyObject * obj0 = 0 ;
-  
-  if (!PyArg_ParseTuple(args,(char *)"O:new_GridsMap",&obj0)) SWIG_fail;
-  {
-    std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *ptr = (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *)0;
-    res1 = swig::asptr(obj0, &ptr);
-    if (!SWIG_IsOK(res1)) {
-      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::map<int,CdiGrid > const &""'"); 
-    }
-    if (!ptr) {
-      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::map<int,CdiGrid > const &""'"); 
-    }
-    arg1 = ptr;
-  }
-  result = (std::map<int,CdiGrid > *)new std::map<int,CdiGrid >((std::map<int,CdiGrid > const &)*arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, SWIG_POINTER_NEW |  0 );
-  if (SWIG_IsNewObj(res1)) delete arg1;
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_CdiGrid, 0 |  0 );
   return resultobj;
 fail:
-  if (SWIG_IsNewObj(res1)) delete arg1;
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_new_GridsMap(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 0) {
-    return _wrap_new_GridsMap__SWIG_0(self, args);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_new_GridsMap__SWIG_1(self, args);
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_GridsMap'.\n  Possible C/C++ prototypes are:\n    std::map<(int,CdiGrid)>()\n    std::map<(int,CdiGrid)>(std::map<int,CdiGrid > const &)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___delitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  bool result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_empty",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___delitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_empty" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___delitem__" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (bool)((std::map<int,CdiGrid > const *)arg1)->empty();
-  resultobj = SWIG_From_bool(static_cast< bool >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___delitem__" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  try {
+    std_map_Sl_int_Sc_CdiGrid_Sg____delitem__(arg1,(int const &)*arg2);
+  }
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_has_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::size_type result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_size",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_has_key",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_size" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_has_key" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->size();
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_has_key" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg__has_key((std::map< int,CdiGrid > const *)arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_clear",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_keys",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_clear" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_keys" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  (arg1)->clear();
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__keys(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_values(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid > *arg2 = 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  void *argp2 = 0 ;
-  int res2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_swap",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_values",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_swap" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
-  }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t,  0 );
-  if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GridsMap_swap" "', argument " "2"" of type '" "std::map<int,CdiGrid > &""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_values" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  if (!argp2) {
-    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GridsMap_swap" "', argument " "2"" of type '" "std::map<int,CdiGrid > &""'"); 
-  }
-  arg2 = reinterpret_cast< std::map<int,CdiGrid > * >(argp2);
-  (arg1)->swap(*arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__values(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_items(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  SwigValueWrapper<std::allocator<std::pair<int const,CdiGrid > > > result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_get_allocator",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_items",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_get_allocator" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_items" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->get_allocator();
-  resultobj = SWIG_NewPointerObj((new std::map<int,CdiGrid >::allocator_type(static_cast< const std::map<int,CdiGrid >::allocator_type& >(result))), SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type, SWIG_POINTER_OWN |  0 );
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__items(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_begin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___contains__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_begin" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___contains__" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___contains__" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  result = (bool)std_map_Sl_int_Sc_CdiGrid_Sg____contains__(arg1,(int const &)*arg2);
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_begin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_key_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::const_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_begin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_key_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_begin" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_key_iterator" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->begin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__key_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
-
-SWIGINTERN PyObject *_wrap_GridsMap_begin(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_GridsMap_begin__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_GridsMap_begin__SWIG_1(self, args);
-    }
-  }
+
+SWIGINTERN PyObject *_wrap_GridsMap_value_iterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  PyObject **arg2 = (PyObject **) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  swig::SwigPyIterator *result = 0 ;
   
+  arg2 = &obj0;
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_value_iterator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_value_iterator" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (swig::SwigPyIterator *)std_map_Sl_int_Sc_CdiGrid_Sg__value_iterator(arg1,arg2);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_OWN |  0 );
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_begin'.\n  Possible C/C++ prototypes are:\n    begin()\n    begin()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_end__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___setitem____SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap___setitem__",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_end" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  std_map_Sl_int_Sc_CdiGrid_Sg____setitem____SWIG_0(arg1,(int const &)*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_end__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___setitem____SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::const_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
+  std::map< int,CdiGrid >::mapped_type *arg3 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  void *argp3 = 0 ;
+  int res3 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_end",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:GridsMap___setitem__",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_end" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap___setitem__" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap___setitem__" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  res3 = SWIG_ConvertPtr(obj2, &argp3, SWIGTYPE_p_CdiGrid,  0  | 0);
+  if (!SWIG_IsOK(res3)) {
+    SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "GridsMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiGrid >::mapped_type const &""'"); 
+  }
+  if (!argp3) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GridsMap___setitem__" "', argument " "3"" of type '" "std::map< int,CdiGrid >::mapped_type const &""'"); 
+  }
+  arg3 = reinterpret_cast< std::map< int,CdiGrid >::mapped_type * >(argp3);
+  try {
+    std_map_Sl_int_Sc_CdiGrid_Sg____setitem____SWIG_1(arg1,(int const &)*arg2,(CdiGrid const &)*arg3);
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->end();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  catch(std::out_of_range &_e) {
+    SWIG_exception_fail(SWIG_IndexError, (&_e)->what());
+  }
+  
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_end(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap___setitem__(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[2];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
-  if (argc == 1) {
+  if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_GridsMap_end__SWIG_0(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        return _wrap_GridsMap___setitem____SWIG_0(self, args);
+      }
     }
   }
-  if (argc == 1) {
+  if (argc == 3) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_GridsMap_end__SWIG_1(self, args);
+      {
+        int res = SWIG_AsVal_int(argv[1], NULL);
+        _v = SWIG_CheckState(res);
+      }
+      if (_v) {
+        int res = SWIG_ConvertPtr(argv[2], 0, SWIGTYPE_p_CdiGrid, 0);
+        _v = SWIG_CheckState(res);
+        if (_v) {
+          return _wrap_GridsMap___setitem____SWIG_1(self, args);
+        }
+      }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_end'.\n  Possible C/C++ prototypes are:\n    end()\n    end()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'GridsMap___setitem__'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiGrid >::__setitem__(std::map< int,CdiGrid >::key_type const &)\n"
+    "    std::map< int,CdiGrid >::__setitem__(std::map< int,CdiGrid >::key_type const &,std::map< int,CdiGrid >::mapped_type const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rbegin__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_asdict(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::reverse_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  PyObject *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_asdict",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_asdict" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (PyObject *)std_map_Sl_int_Sc_CdiGrid_Sg__asdict(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rbegin__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_GridsMap__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::const_reverse_iterator result;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
+  std::map< int,CdiGrid > *result = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)":new_GridsMap")) SWIG_fail;
+  result = (std::map< int,CdiGrid > *)new std::map< int,CdiGrid >();
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, SWIG_POINTER_NEW |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_new_GridsMap__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = 0 ;
+  int res1 = SWIG_OLDOBJ ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid > *result = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rbegin",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rbegin" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+  if (!PyArg_ParseTuple(args,(char *)"O:new_GridsMap",&obj0)) SWIG_fail;
+  {
+    std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *ptr = (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *)0;
+    res1 = swig::asptr(obj0, &ptr);
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::map< int,CdiGrid > const &""'"); 
+    }
+    if (!ptr) {
+      SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "new_GridsMap" "', argument " "1"" of type '" "std::map< int,CdiGrid > const &""'"); 
+    }
+    arg1 = ptr;
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->rbegin();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (std::map< int,CdiGrid > *)new std::map< int,CdiGrid >((std::map< int,CdiGrid > const &)*arg1);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, SWIG_POINTER_NEW |  0 );
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return resultobj;
 fail:
+  if (SWIG_IsNewObj(res1)) delete arg1;
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rbegin(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_GridsMap(PyObject *self, PyObject *args) {
   int argc;
   PyObject *argv[2];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
+  if (argc == 0) {
+    return _wrap_new_GridsMap__SWIG_1(self, args);
+  }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = SWIG_ConvertPtr(argv[0], 0, SWIGTYPE_p_std__lessT_int_t, 0);
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_GridsMap_rbegin__SWIG_0(self, args);
+      return _wrap_new_GridsMap__SWIG_0(self, args);
     }
   }
   if (argc == 1) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      return _wrap_GridsMap_rbegin__SWIG_1(self, args);
+      return _wrap_new_GridsMap__SWIG_2(self, args);
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_rbegin'.\n  Possible C/C++ prototypes are:\n    rbegin()\n    rbegin()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_GridsMap'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiGrid >::map(std::less< int > const &)\n"
+    "    std::map< int,CdiGrid >::map()\n"
+    "    std::map< int,CdiGrid >::map(std::map< int,CdiGrid > const &)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rend__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::reverse_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_empty",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rend" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_empty" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = (arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (bool)((std::map< int,CdiGrid > const *)arg1)->empty();
+  resultobj = SWIG_From_bool(static_cast< bool >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rend__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::const_reverse_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rend",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_size",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rend" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_size" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  result = ((std::map<int,CdiGrid > const *)arg1)->rend();
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_reverse_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = ((std::map< int,CdiGrid > const *)arg1)->size();
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_rend(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[2];
-  int ii;
+SWIGINTERN PyObject *_wrap_GridsMap_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_GridsMap_rend__SWIG_0(self, args);
-    }
-  }
-  if (argc == 1) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      return _wrap_GridsMap_rend__SWIG_1(self, args);
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_clear",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_clear" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  (arg1)->clear();
+  resultobj = SWIG_Py_Void();
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_rend'.\n  Possible C/C++ prototypes are:\n    rend()\n    rend()\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_swap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::size_type result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid > *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  void *argp2 = 0 ;
+  int res2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_swap",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_swap" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->erase((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t,  0 );
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "GridsMap_swap" "', argument " "2"" of type '" "std::map< int,CdiGrid > &""'"); 
+  }
+  if (!argp2) {
+    SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "GridsMap_swap" "', argument " "2"" of type '" "std::map< int,CdiGrid > &""'"); 
+  }
+  arg2 = reinterpret_cast< std::map< int,CdiGrid > * >(argp2);
+  (arg1)->swap(*arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_get_allocator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::size_type result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  SwigValueWrapper< std::allocator< std::pair< int const,CdiGrid > > > result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_count",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_get_allocator",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_count" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_get_allocator" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_count" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiGrid > const *)arg1)->count((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = ((std::map< int,CdiGrid > const *)arg1)->get_allocator();
+  resultobj = SWIG_NewPointerObj((new std::map< int,CdiGrid >::allocator_type(static_cast< const std::map< int,CdiGrid >::allocator_type& >(result))), SWIGTYPE_p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_begin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::iterator arg2 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_erase",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_begin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_begin" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map<int,CdiGrid >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map<int,CdiGrid >::iterator""'");
-    }
-  }
-  (arg1)->erase(arg2);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (arg1)->begin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_end(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::iterator arg2 ;
-  std::map<int,CdiGrid >::iterator arg3 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  swig::PySwigIterator *iter2 = 0 ;
-  int res2 ;
-  swig::PySwigIterator *iter3 = 0 ;
-  int res3 ;
   PyObject * obj0 = 0 ;
-  PyObject * obj1 = 0 ;
-  PyObject * obj2 = 0 ;
+  std::map< int,CdiGrid >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOO:GridsMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_end",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_end" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res2) || !iter2) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map<int,CdiGrid >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter2);
-    if (iter_t) {
-      arg2 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map<int,CdiGrid >::iterator""'");
-    }
-  }
-  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::PySwigIterator::descriptor(), 0);
-  if (!SWIG_IsOK(res3) || !iter3) {
-    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "3"" of type '" "std::map<int,CdiGrid >::iterator""'");
-  } else {
-    swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter3);
-    if (iter_t) {
-      arg3 = iter_t->get_current();
-    } else {
-      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "3"" of type '" "std::map<int,CdiGrid >::iterator""'");
-    }
-  }
-  (arg1)->erase(arg2,arg3);
-  resultobj = SWIG_Py_Void();
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (arg1)->end();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_erase(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[4];
-  int ii;
+SWIGINTERN PyObject *_wrap_GridsMap_rbegin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid >::reverse_iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter) != 0));
-      if (_v) {
-        return _wrap_GridsMap_erase__SWIG_1(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_GridsMap_erase__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 3) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      swig::PySwigIterator *iter = 0;
-      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter) != 0));
-      if (_v) {
-        swig::PySwigIterator *iter = 0;
-        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::PySwigIterator::descriptor(), 0);
-        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::PySwigIterator_T<std::map<int,CdiGrid >::iterator > *>(iter) != 0));
-        if (_v) {
-          return _wrap_GridsMap_erase__SWIG_2(self, args);
-        }
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rbegin",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rbegin" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (arg1)->rbegin();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_GridsMap_rend(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid >::reverse_iterator result;
   
+  if (!PyArg_ParseTuple(args,(char *)"O:GridsMap_rend",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_rend" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
+  }
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  result = (arg1)->rend();
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::reverse_iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_erase'.\n  Possible C/C++ prototypes are:\n    erase(std::map<int,CdiGrid >::key_type const &)\n    erase(std::map<int,CdiGrid >::iterator)\n    erase(std::map<int,CdiGrid >::iterator,std::map<int,CdiGrid >::iterator)\n");
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_find__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_find" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_find" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
   arg2 = &temp2;
-  result = (arg1)->find((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->erase((std::map< int,CdiGrid >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_find__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_count(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::const_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::size_type result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_find",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_count",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_find" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_count" "', argument " "1"" of type '" "std::map< int,CdiGrid > const *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_find" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_count" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
   arg2 = &temp2;
-  result = ((std::map<int,CdiGrid > const *)arg1)->find((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = ((std::map< int,CdiGrid > const *)arg1)->count((std::map< int,CdiGrid >::key_type const &)*arg2);
+  resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_find(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
-  
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_GridsMap_find__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_GridsMap_find__SWIG_1(self, args);
-      }
-    }
-  }
-  
-fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_find'.\n  Possible C/C++ prototypes are:\n    find(std::map<int,CdiGrid >::key_type const &)\n    find(std::map<int,CdiGrid >::key_type const &)\n");
-  return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_GridsMap_lower_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::iterator arg2 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_erase",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
-  arg2 = &temp2;
-  result = (arg1)->lower_bound((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map< int,CdiGrid >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map< int,CdiGrid >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiGrid_Sg__erase__SWIG_1(arg1,arg2);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_lower_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_erase__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::const_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::iterator arg2 ;
+  std::map< int,CdiGrid >::iterator arg3 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
-  int val2 ;
-  int ecode2 = 0 ;
+  swig::SwigPyIterator *iter2 = 0 ;
+  int res2 ;
+  swig::SwigPyIterator *iter3 = 0 ;
+  int res3 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  PyObject * obj2 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OOO:GridsMap_erase",&obj0,&obj1,&obj2)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_lower_bound" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_erase" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
-  ecode2 = SWIG_AsVal_int(obj1, &val2);
-  if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_lower_bound" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
-  } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
-  arg2 = &temp2;
-  result = ((std::map<int,CdiGrid > const *)arg1)->lower_bound((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  res2 = SWIG_ConvertPtr(obj1, SWIG_as_voidptrptr(&iter2), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res2) || !iter2) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map< int,CdiGrid >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter2);
+    if (iter_t) {
+      arg2 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "2"" of type '" "std::map< int,CdiGrid >::iterator""'");
+    }
+  }
+  res3 = SWIG_ConvertPtr(obj2, SWIG_as_voidptrptr(&iter3), swig::SwigPyIterator::descriptor(), 0);
+  if (!SWIG_IsOK(res3) || !iter3) {
+    SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "3"" of type '" "std::map< int,CdiGrid >::iterator""'");
+  } else {
+    swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *iter_t = dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter3);
+    if (iter_t) {
+      arg3 = iter_t->get_current();
+    } else {
+      SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "GridsMap_erase" "', argument " "3"" of type '" "std::map< int,CdiGrid >::iterator""'");
+    }
+  }
+  std_map_Sl_int_Sc_CdiGrid_Sg__erase__SWIG_2(arg1,arg2,arg3);
+  resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_lower_bound(PyObject *self, PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_erase(PyObject *self, PyObject *args) {
   int argc;
-  PyObject *argv[3];
+  PyObject *argv[4];
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter) != 0));
       if (_v) {
-        return _wrap_GridsMap_lower_bound__SWIG_0(self, args);
+        return _wrap_GridsMap_erase__SWIG_1(self, args);
       }
     }
   }
   if (argc == 2) {
     int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
     _v = SWIG_CheckState(res);
     if (_v) {
       {
@@ -21627,145 +22482,155 @@ SWIGINTERN PyObject *_wrap_GridsMap_lower_bound(PyObject *self, PyObject *args)
         _v = SWIG_CheckState(res);
       }
       if (_v) {
-        return _wrap_GridsMap_lower_bound__SWIG_1(self, args);
+        return _wrap_GridsMap_erase__SWIG_0(self, args);
+      }
+    }
+  }
+  if (argc == 3) {
+    int _v;
+    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > >**)(0));
+    _v = SWIG_CheckState(res);
+    if (_v) {
+      swig::SwigPyIterator *iter = 0;
+      int res = SWIG_ConvertPtr(argv[1], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+      _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter) != 0));
+      if (_v) {
+        swig::SwigPyIterator *iter = 0;
+        int res = SWIG_ConvertPtr(argv[2], SWIG_as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
+        _v = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<std::map< int,CdiGrid >::iterator > *>(iter) != 0));
+        if (_v) {
+          return _wrap_GridsMap_erase__SWIG_2(self, args);
+        }
       }
     }
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_lower_bound'.\n  Possible C/C++ prototypes are:\n    lower_bound(std::map<int,CdiGrid >::key_type const &)\n    lower_bound(std::map<int,CdiGrid >::key_type const &)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'GridsMap_erase'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    std::map< int,CdiGrid >::erase(std::map< int,CdiGrid >::key_type const &)\n"
+    "    std::map< int,CdiGrid >::erase(std::map< int,CdiGrid >::iterator)\n"
+    "    std::map< int,CdiGrid >::erase(std::map< int,CdiGrid >::iterator,std::map< int,CdiGrid >::iterator)\n");
+  return 0;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_upper_bound__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_find(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_find",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_find" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_find" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
   arg2 = &temp2;
-  result = (arg1)->upper_bound((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->find((std::map< int,CdiGrid >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_upper_bound__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_GridsMap_lower_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
-  std::map<int,CdiGrid >::key_type *arg2 = 0 ;
-  std::map<int,CdiGrid >::const_iterator result;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
-  std::map<int,CdiGrid >::key_type temp2 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::iterator result;
   
-  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_lower_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_upper_bound" "', argument " "1"" of type '" "std::map<int,CdiGrid > const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_lower_bound" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
-    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_upper_bound" "', argument " "2"" of type '" "std::map<int,CdiGrid >::key_type""'");
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_lower_bound" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
   } 
-  temp2 = static_cast< std::map<int,CdiGrid >::key_type >(val2);
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
   arg2 = &temp2;
-  result = ((std::map<int,CdiGrid > const *)arg1)->upper_bound((std::map<int,CdiGrid >::key_type const &)*arg2);
-  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map<int,CdiGrid >::const_iterator & >(result)),
-    swig::PySwigIterator::descriptor(),SWIG_POINTER_OWN);
+  result = (arg1)->lower_bound((std::map< int,CdiGrid >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   return resultobj;
 fail:
   return NULL;
 }
 
 
-SWIGINTERN PyObject *_wrap_GridsMap_upper_bound(PyObject *self, PyObject *args) {
-  int argc;
-  PyObject *argv[3];
-  int ii;
+SWIGINTERN PyObject *_wrap_GridsMap_upper_bound(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid >::key_type *arg2 = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  std::map< int,CdiGrid >::key_type temp2 ;
+  int val2 ;
+  int ecode2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  std::map< int,CdiGrid >::iterator result;
   
-  if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
-    argv[ii] = PyTuple_GET_ITEM(args,ii);
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_GridsMap_upper_bound__SWIG_0(self, args);
-      }
-    }
-  }
-  if (argc == 2) {
-    int _v;
-    int res = swig::asptr(argv[0], (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > >**)(0));
-    _v = SWIG_CheckState(res);
-    if (_v) {
-      {
-        int res = SWIG_AsVal_int(argv[1], NULL);
-        _v = SWIG_CheckState(res);
-      }
-      if (_v) {
-        return _wrap_GridsMap_upper_bound__SWIG_1(self, args);
-      }
-    }
+  if (!PyArg_ParseTuple(args,(char *)"OO:GridsMap_upper_bound",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GridsMap_upper_bound" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
+  ecode2 = SWIG_AsVal_int(obj1, &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "GridsMap_upper_bound" "', argument " "2"" of type '" "std::map< int,CdiGrid >::key_type""'");
+  } 
+  temp2 = static_cast< std::map< int,CdiGrid >::key_type >(val2);
+  arg2 = &temp2;
+  result = (arg1)->upper_bound((std::map< int,CdiGrid >::key_type const &)*arg2);
+  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::map< int,CdiGrid >::iterator & >(result)),
+    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
+  return resultobj;
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'GridsMap_upper_bound'.\n  Possible C/C++ prototypes are:\n    upper_bound(std::map<int,CdiGrid >::key_type const &)\n    upper_bound(std::map<int,CdiGrid >::key_type const &)\n");
   return NULL;
 }
 
 
 SWIGINTERN PyObject *_wrap_delete_GridsMap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  std::map<int,CdiGrid > *arg1 = (std::map<int,CdiGrid > *) 0 ;
+  std::map< int,CdiGrid > *arg1 = (std::map< int,CdiGrid > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:delete_GridsMap",&obj0)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, SWIG_POINTER_DISOWN |  0 );
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, SWIG_POINTER_DISOWN |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_GridsMap" "', argument " "1"" of type '" "std::map<int,CdiGrid > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_GridsMap" "', argument " "1"" of type '" "std::map< int,CdiGrid > *""'"); 
   }
-  arg1 = reinterpret_cast< std::map<int,CdiGrid > * >(argp1);
+  arg1 = reinterpret_cast< std::map< int,CdiGrid > * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -21775,8 +22640,8 @@ fail:
 
 SWIGINTERN PyObject *GridsMap_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
-  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, SWIG_NewClientData(obj));
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+  SWIG_TypeNewClientData(SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
@@ -21796,10 +22661,10 @@ fail:
 SWIGINTERN PyObject *_wrap_new_CdiGrid__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   int arg1 ;
-  CdiGrid *result = 0 ;
   int val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiGrid *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_CdiGrid",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_int(obj0, &val1);
@@ -21821,8 +22686,8 @@ SWIGINTERN PyObject *_wrap_new_CdiGrid(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -21840,8 +22705,11 @@ SWIGINTERN PyObject *_wrap_new_CdiGrid(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_CdiGrid'.\n  Possible C/C++ prototypes are:\n    CdiGrid()\n    CdiGrid(int)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_CdiGrid'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiGrid::CdiGrid()\n"
+    "    CdiGrid::CdiGrid(int)\n");
+  return 0;
 }
 
 
@@ -21859,7 +22727,6 @@ SWIGINTERN PyObject *_wrap_delete_CdiGrid(PyObject *SWIGUNUSEDPARM(self), PyObje
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -21890,7 +22757,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_gridID_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->gridID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -21901,10 +22767,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_gridID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_gridID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -21943,7 +22809,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_type_set(PyObject *SWIGUNUSEDPARM(self), PyOb
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->type = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -21954,10 +22819,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_type_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_type_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -21996,7 +22861,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_size_set(PyObject *SWIGUNUSEDPARM(self), PyOb
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->size = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22007,10 +22871,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_size_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_size_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22049,7 +22913,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xsize_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->xsize = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22060,10 +22923,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xsize_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xsize_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22102,7 +22965,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ysize_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ysize = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22113,10 +22975,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ysize_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_ysize_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22155,7 +23017,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_prec_set(PyObject *SWIGUNUSEDPARM(self), PyOb
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->prec = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22166,10 +23027,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_prec_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_prec_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22208,7 +23069,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ncorner_set(PyObject *SWIGUNUSEDPARM(self), P
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ncorner = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22219,10 +23079,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ncorner_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_ncorner_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22261,7 +23121,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_hasXValues_set(PyObject *SWIGUNUSEDPARM(self)
   } 
   arg2 = static_cast< bool >(val2);
   if (arg1) (arg1)->hasXValues = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22272,10 +23131,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_hasXValues_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  bool result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_hasXValues_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22314,7 +23173,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_hasYValues_set(PyObject *SWIGUNUSEDPARM(self)
   } 
   arg2 = static_cast< bool >(val2);
   if (arg1) (arg1)->hasYValues = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22325,10 +23183,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_hasYValues_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  bool result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_hasYValues_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22367,7 +23225,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_hasBounds_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< bool >(val2);
   if (arg1) (arg1)->hasBounds = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22378,10 +23235,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_hasBounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  bool result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  bool result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_hasBounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22400,7 +23257,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xvalues_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -22414,13 +23271,12 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xvalues_set(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xvalues_set" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_xvalues_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_xvalues_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->xvalues = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22431,10 +23287,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xvalues_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xvalues_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22442,8 +23298,8 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xvalues_get(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xvalues_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->xvalues);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->xvalues);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -22453,7 +23309,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_yvalues_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -22467,13 +23323,12 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yvalues_set(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_yvalues_set" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_yvalues_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_yvalues_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->yvalues = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22484,10 +23339,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_yvalues_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_yvalues_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22495,8 +23350,8 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yvalues_get(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_yvalues_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->yvalues);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->yvalues);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -22506,7 +23361,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xbounds_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -22520,13 +23375,12 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xbounds_set(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xbounds_set" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_xbounds_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_xbounds_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->xbounds = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22537,10 +23391,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xbounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xbounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22548,8 +23402,8 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xbounds_get(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xbounds_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->xbounds);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->xbounds);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -22559,7 +23413,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ybounds_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -22573,13 +23427,12 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ybounds_set(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_ybounds_set" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_ybounds_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiGrid_ybounds_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->ybounds = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -22590,10 +23443,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ybounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_ybounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22601,8 +23454,8 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ybounds_get(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_ybounds_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->ybounds);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->ybounds);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -22637,7 +23490,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xname_set(PyObject *SWIGUNUSEDPARM(self), PyO
     arg2 = ptr;
   }
   if (arg1) (arg1)->xname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22650,10 +23502,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22661,10 +23513,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xname_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->xname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->xname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -22700,7 +23549,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xlongname_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->xlongname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22713,10 +23561,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xlongname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xlongname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22724,10 +23572,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xlongname_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xlongname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->xlongname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->xlongname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -22763,7 +23608,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xstdname_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->xstdname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22776,10 +23620,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xstdname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xstdname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22787,10 +23631,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xstdname_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xstdname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->xstdname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->xstdname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -22826,7 +23667,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xunits_set(PyObject *SWIGUNUSEDPARM(self), Py
     arg2 = ptr;
   }
   if (arg1) (arg1)->xunits = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22839,10 +23679,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_xunits_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_xunits_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22850,10 +23690,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_xunits_get(PyObject *SWIGUNUSEDPARM(self), Py
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_xunits_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->xunits);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->xunits);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -22889,7 +23726,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yname_set(PyObject *SWIGUNUSEDPARM(self), PyO
     arg2 = ptr;
   }
   if (arg1) (arg1)->yname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22902,10 +23738,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_yname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_yname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22913,10 +23749,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yname_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_yname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->yname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->yname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -22952,7 +23785,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ylongname_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->ylongname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -22965,10 +23797,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ylongname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_ylongname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -22976,10 +23808,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ylongname_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_ylongname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->ylongname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->ylongname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -23015,7 +23844,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ystdname_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->ystdname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -23028,10 +23856,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_ystdname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_ystdname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -23039,10 +23867,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_ystdname_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_ystdname_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->ystdname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->ystdname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -23078,7 +23903,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yunits_set(PyObject *SWIGUNUSEDPARM(self), Py
     arg2 = ptr;
   }
   if (arg1) (arg1)->yunits = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -23091,10 +23915,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_yunits_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_yunits_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -23102,10 +23926,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_yunits_get(PyObject *SWIGUNUSEDPARM(self), Py
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_yunits_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->yunits);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->yunits);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -23141,7 +23962,6 @@ SWIGINTERN PyObject *_wrap_CdiGrid_name_set(PyObject *SWIGUNUSEDPARM(self), PyOb
     arg2 = ptr;
   }
   if (arg1) (arg1)->name = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -23154,10 +23974,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiGrid_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiGrid *arg1 = (CdiGrid *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiGrid_name_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiGrid, 0 |  0 );
@@ -23165,10 +23985,7 @@ SWIGINTERN PyObject *_wrap_CdiGrid_name_get(PyObject *SWIGUNUSEDPARM(self), PyOb
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiGrid_name_get" "', argument " "1"" of type '" "CdiGrid *""'"); 
   }
   arg1 = reinterpret_cast< CdiGrid * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->name);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->name);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -23376,7 +24193,7 @@ fail:
 
 SWIGINTERN PyObject *CdiGrid_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
   SWIG_TypeNewClientData(SWIGTYPE_p_CdiGrid, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
@@ -23397,10 +24214,10 @@ fail:
 SWIGINTERN PyObject *_wrap_new_CdiTaxis__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   int arg1 ;
-  CdiTaxis *result = 0 ;
   int val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiTaxis *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_CdiTaxis",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_int(obj0, &val1);
@@ -23422,8 +24239,8 @@ SWIGINTERN PyObject *_wrap_new_CdiTaxis(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -23441,8 +24258,11 @@ SWIGINTERN PyObject *_wrap_new_CdiTaxis(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_CdiTaxis'.\n  Possible C/C++ prototypes are:\n    CdiTaxis()\n    CdiTaxis(int)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_CdiTaxis'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiTaxis::CdiTaxis()\n"
+    "    CdiTaxis::CdiTaxis(int)\n");
+  return 0;
 }
 
 
@@ -23460,7 +24280,6 @@ SWIGINTERN PyObject *_wrap_delete_CdiTaxis(PyObject *SWIGUNUSEDPARM(self), PyObj
   }
   arg1 = reinterpret_cast< CdiTaxis * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23491,7 +24310,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_taxisID_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->taxisID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23502,10 +24320,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_taxisID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_taxisID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23544,7 +24362,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_ntsteps_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ntsteps = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23555,10 +24372,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_ntsteps_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_ntsteps_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23597,7 +24414,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_unit_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->unit = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23608,10 +24424,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_unit_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_unit_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23650,7 +24466,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_rdate_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->rdate = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23661,10 +24476,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_rdate_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_rdate_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23703,7 +24518,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_rtime_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->rtime = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23714,10 +24528,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_rtime_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_rtime_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23756,7 +24570,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_vdate_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->vdate = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23767,10 +24580,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_vdate_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_vdate_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23809,7 +24622,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_vtime_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->vtime = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23820,10 +24632,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_vtime_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_vtime_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23862,7 +24674,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_type_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->type = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23873,10 +24684,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_type_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_type_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23915,7 +24726,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_calendar_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->calendar = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23926,10 +24736,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_calendar_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_calendar_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -23968,7 +24778,6 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_hasBounds_set(PyObject *SWIGUNUSEDPARM(self)
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->hasBounds = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -23979,10 +24788,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_hasBounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_hasBounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -24032,10 +24841,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  char *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  char *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_name_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -24045,9 +24854,9 @@ SWIGINTERN PyObject *_wrap_CdiTaxis_name_get(PyObject *SWIGUNUSEDPARM(self), PyO
   arg1 = reinterpret_cast< CdiTaxis * >(argp1);
   result = (char *)(char *) ((arg1)->name);
   {
-    size_t size = 128;
+    size_t size = SWIG_strnlen(result, 128);
+    
     
-    while (size && (result[size - 1] == '\0')) --size;
     
     resultobj = SWIG_FromCharPtrAndSize(result, size);
   }
@@ -24099,10 +24908,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiTaxis_unitname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiTaxis *arg1 = (CdiTaxis *) 0 ;
-  char *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  char *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiTaxis_unitname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiTaxis, 0 |  0 );
@@ -24120,7 +24929,7 @@ fail:
 
 SWIGINTERN PyObject *CdiTaxis_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
   SWIG_TypeNewClientData(SWIGTYPE_p_CdiTaxis, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
@@ -24141,10 +24950,10 @@ fail:
 SWIGINTERN PyObject *_wrap_new_CdiZaxis__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   int arg1 ;
-  CdiZaxis *result = 0 ;
   int val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiZaxis *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_CdiZaxis",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_int(obj0, &val1);
@@ -24166,8 +24975,8 @@ SWIGINTERN PyObject *_wrap_new_CdiZaxis(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 1); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 1) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -24185,8 +24994,11 @@ SWIGINTERN PyObject *_wrap_new_CdiZaxis(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_CdiZaxis'.\n  Possible C/C++ prototypes are:\n    CdiZaxis()\n    CdiZaxis(int)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_CdiZaxis'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiZaxis::CdiZaxis()\n"
+    "    CdiZaxis::CdiZaxis(int)\n");
+  return 0;
 }
 
 
@@ -24204,7 +25016,6 @@ SWIGINTERN PyObject *_wrap_delete_CdiZaxis(PyObject *SWIGUNUSEDPARM(self), PyObj
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24235,7 +25046,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_zaxisID_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->zaxisID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24246,10 +25056,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_zaxisID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_zaxisID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24288,7 +25098,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_type_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->type = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24299,10 +25108,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_type_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_type_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24341,7 +25150,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_ltype_set(PyObject *SWIGUNUSEDPARM(self), Py
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ltype = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24352,10 +25160,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_ltype_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_ltype_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24394,7 +25202,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_size_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->size = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24405,10 +25212,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_size_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_size_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24447,7 +25254,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_prec_set(PyObject *SWIGUNUSEDPARM(self), PyO
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->prec = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24458,10 +25264,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_prec_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_prec_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24500,7 +25306,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_plevels_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< double * >(argp2);
   if (arg1) (arg1)->plevels = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24511,10 +25316,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_plevels_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  double *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_plevels_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24553,7 +25358,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_plbounds_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< double * >(argp2);
   if (arg1) (arg1)->plbounds = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24564,10 +25368,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_plbounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  double *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_plbounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24606,7 +25410,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_pubounds_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< double * >(argp2);
   if (arg1) (arg1)->pubounds = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24617,10 +25420,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_pubounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  double *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_pubounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24659,7 +25462,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_pweights_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< double * >(argp2);
   if (arg1) (arg1)->pweights = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24670,10 +25472,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_pweights_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  double *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_pweights_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24692,7 +25494,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_levels_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -24706,13 +25508,12 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_levels_set(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_levels_set" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_levels_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_levels_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->levels = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24723,10 +25524,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_levels_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_levels_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24734,8 +25535,8 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_levels_get(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_levels_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->levels);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->levels);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -24745,7 +25546,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_lbounds_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -24759,13 +25560,12 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_lbounds_set(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_lbounds_set" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_lbounds_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_lbounds_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->lbounds = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24776,10 +25576,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_lbounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_lbounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24787,8 +25587,8 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_lbounds_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_lbounds_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->lbounds);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->lbounds);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -24798,7 +25598,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_ubounds_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -24812,13 +25612,12 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_ubounds_set(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_ubounds_set" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_ubounds_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_ubounds_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->ubounds = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24829,10 +25628,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_ubounds_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_ubounds_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24840,8 +25639,8 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_ubounds_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_ubounds_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->ubounds);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->ubounds);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -24851,7 +25650,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_weights_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -24865,13 +25664,12 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_weights_set(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_weights_set" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_weights_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiZaxis_weights_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->weights = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -24882,10 +25680,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_weights_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_weights_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24893,8 +25691,8 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_weights_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_weights_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->weights);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->weights);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -24929,7 +25727,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_name_set(PyObject *SWIGUNUSEDPARM(self), PyO
     arg2 = ptr;
   }
   if (arg1) (arg1)->name = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -24942,10 +25739,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_name_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -24953,10 +25750,7 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_name_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_name_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->name);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->name);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -24992,7 +25786,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_longname_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->longname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25005,10 +25798,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_longname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_longname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -25016,10 +25809,7 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_longname_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_longname_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->longname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->longname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -25055,7 +25845,6 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_units_set(PyObject *SWIGUNUSEDPARM(self), Py
     arg2 = ptr;
   }
   if (arg1) (arg1)->units = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25068,10 +25857,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiZaxis_units_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiZaxis *arg1 = (CdiZaxis *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiZaxis_units_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiZaxis, 0 |  0 );
@@ -25079,10 +25868,7 @@ SWIGINTERN PyObject *_wrap_CdiZaxis_units_get(PyObject *SWIGUNUSEDPARM(self), Py
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiZaxis_units_get" "', argument " "1"" of type '" "CdiZaxis *""'"); 
   }
   arg1 = reinterpret_cast< CdiZaxis * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->units);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->units);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -25092,7 +25878,7 @@ fail:
 
 SWIGINTERN PyObject *CdiZaxis_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
   SWIG_TypeNewClientData(SWIGTYPE_p_CdiZaxis, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
@@ -25115,7 +25901,6 @@ SWIGINTERN PyObject *_wrap_new_CdiVariable__SWIG_1(PyObject *SWIGUNUSEDPARM(self
   int arg1 ;
   int arg2 ;
   int arg3 ;
-  CdiVariable *result = 0 ;
   int val1 ;
   int ecode1 = 0 ;
   int val2 ;
@@ -25125,6 +25910,7 @@ SWIGINTERN PyObject *_wrap_new_CdiVariable__SWIG_1(PyObject *SWIGUNUSEDPARM(self
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
+  CdiVariable *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOO:new_CdiVariable",&obj0,&obj1,&obj2)) SWIG_fail;
   ecode1 = SWIG_AsVal_int(obj0, &val1);
@@ -25156,8 +25942,8 @@ SWIGINTERN PyObject *_wrap_new_CdiVariable(PyObject *self, PyObject *args) {
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 3) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 0) {
@@ -25187,8 +25973,11 @@ SWIGINTERN PyObject *_wrap_new_CdiVariable(PyObject *self, PyObject *args) {
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'new_CdiVariable'.\n  Possible C/C++ prototypes are:\n    CdiVariable()\n    CdiVariable(int,int,int)\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'new_CdiVariable'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiVariable::CdiVariable()\n"
+    "    CdiVariable::CdiVariable(int,int,int)\n");
+  return 0;
 }
 
 
@@ -25206,7 +25995,6 @@ SWIGINTERN PyObject *_wrap_delete_CdiVariable(PyObject *SWIGUNUSEDPARM(self), Py
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25237,7 +26025,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_varID_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->varID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25248,10 +26035,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_varID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_varID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25290,7 +26077,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_zaxisID_set(PyObject *SWIGUNUSEDPARM(self
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->zaxisID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25301,10 +26087,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_zaxisID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_zaxisID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25343,7 +26129,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_gridID_set(PyObject *SWIGUNUSEDPARM(self)
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->gridID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25354,10 +26139,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_gridID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_gridID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25396,7 +26181,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_taxisID_set(PyObject *SWIGUNUSEDPARM(self
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->taxisID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25407,10 +26191,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_taxisID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_taxisID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25449,7 +26233,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_timeID_set(PyObject *SWIGUNUSEDPARM(self)
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->timeID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25460,10 +26243,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_timeID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_timeID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25502,7 +26285,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_vlistID_set(PyObject *SWIGUNUSEDPARM(self
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->vlistID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25513,10 +26295,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_vlistID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_vlistID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25555,7 +26337,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_size_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->size = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25566,10 +26347,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_size_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_size_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25608,7 +26389,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_code_set(PyObject *SWIGUNUSEDPARM(self),
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->code = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25619,10 +26399,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_code_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_code_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25661,7 +26441,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_datatype_set(PyObject *SWIGUNUSEDPARM(sel
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->datatype = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25672,10 +26451,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_datatype_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_datatype_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25714,7 +26493,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_streamID_set(PyObject *SWIGUNUSEDPARM(sel
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->streamID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -25725,10 +26503,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_streamID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_streamID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25772,7 +26550,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_name_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->name = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25785,10 +26562,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_name_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_name_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25796,10 +26573,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_name_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_name_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->name);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->name);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -25835,7 +26609,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_longname_set(PyObject *SWIGUNUSEDPARM(sel
     arg2 = ptr;
   }
   if (arg1) (arg1)->longname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25848,10 +26621,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_longname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_longname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25859,10 +26632,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_longname_get(PyObject *SWIGUNUSEDPARM(sel
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_longname_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->longname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->longname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -25898,7 +26668,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_units_set(PyObject *SWIGUNUSEDPARM(self),
     arg2 = ptr;
   }
   if (arg1) (arg1)->units = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25911,10 +26680,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_units_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_units_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25922,10 +26691,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_units_get(PyObject *SWIGUNUSEDPARM(self),
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_units_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->units);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->units);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -25961,7 +26727,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_stdname_set(PyObject *SWIGUNUSEDPARM(self
     arg2 = ptr;
   }
   if (arg1) (arg1)->stdname = *arg2;
-  
   resultobj = SWIG_Py_Void();
   if (SWIG_IsNewObj(res2)) delete arg2;
   return resultobj;
@@ -25974,10 +26739,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_stdname_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::string *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::string *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_stdname_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -25985,10 +26750,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_stdname_get(PyObject *SWIGUNUSEDPARM(self
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_stdname_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  {
-    std::string const &_result_ref =  ((arg1)->stdname);
-    result = (std::string *) &_result_ref;
-  }
+  result = (std::string *) & ((arg1)->stdname);
   resultobj = SWIG_From_std_string(static_cast< std::string >(*result));
   return resultobj;
 fail:
@@ -26019,7 +26781,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_missval_set(PyObject *SWIGUNUSEDPARM(self
   } 
   arg2 = static_cast< double >(val2);
   if (arg1) (arg1)->missval = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26030,10 +26791,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_missval_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  double result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_missval_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26052,7 +26813,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_values_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::vector<double,std::allocator<double > > *arg2 = (std::vector<double,std::allocator<double > > *) 0 ;
+  std::vector< double,std::allocator< double > > *arg2 = (std::vector< double,std::allocator< double > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -26066,13 +26827,12 @@ SWIGINTERN PyObject *_wrap_CdiVariable_values_set(PyObject *SWIGUNUSEDPARM(self)
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_values_set" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiVariable_values_set" "', argument " "2"" of type '" "std::vector<double,std::allocator<double > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiVariable_values_set" "', argument " "2"" of type '" "std::vector< double,std::allocator< double > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<double,std::allocator<double > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< double,std::allocator< double > > * >(argp2);
   if (arg1) (arg1)->values = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26083,10 +26843,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_values_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::vector<double,std::allocator<double > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< double,std::allocator< double > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_values_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26094,8 +26854,8 @@ SWIGINTERN PyObject *_wrap_CdiVariable_values_get(PyObject *SWIGUNUSEDPARM(self)
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_values_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  result = (std::vector<double,std::allocator<double > > *)& ((arg1)->values);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTdouble_std__allocatorTdouble_t_t, 0 |  0 );
+  result = (std::vector< double,std::allocator< double > > *)& ((arg1)->values);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_double_std__allocatorT_double_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26105,7 +26865,7 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_valuesWithLevel_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *arg2 = (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *) 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *arg2 = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -26119,13 +26879,12 @@ SWIGINTERN PyObject *_wrap_CdiVariable_valuesWithLevel_set(PyObject *SWIGUNUSEDP
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_valuesWithLevel_set" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiVariable_valuesWithLevel_set" "', argument " "2"" of type '" "std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CdiVariable_valuesWithLevel_set" "', argument " "2"" of type '" "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > * >(argp2);
   if (arg1) (arg1)->valuesWithLevel = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26136,10 +26895,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_valuesWithLevel_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_valuesWithLevel_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26147,8 +26906,8 @@ SWIGINTERN PyObject *_wrap_CdiVariable_valuesWithLevel_get(PyObject *SWIGUNUSEDP
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CdiVariable_valuesWithLevel_get" "', argument " "1"" of type '" "CdiVariable *""'"); 
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
-  result = (std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *)& ((arg1)->valuesWithLevel);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0 |  0 );
+  result = (std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *)& ((arg1)->valuesWithLevel);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26178,7 +26937,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_grid_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< CdiGrid * >(argp2);
   if (arg1) (arg1)->grid = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26189,10 +26947,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_grid_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  CdiGrid *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiGrid *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_grid_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26231,7 +26989,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_zaxis_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< CdiZaxis * >(argp2);
   if (arg1) (arg1)->zaxis = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26242,10 +26999,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_zaxis_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  CdiZaxis *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiZaxis *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_zaxis_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26284,7 +27041,6 @@ SWIGINTERN PyObject *_wrap_CdiVariable_taxis_set(PyObject *SWIGUNUSEDPARM(self),
   }
   arg2 = reinterpret_cast< CdiTaxis * >(argp2);
   if (arg1) (arg1)->taxis = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26295,10 +27051,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_taxis_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  CdiTaxis *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  CdiTaxis *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_taxis_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26413,8 +27169,8 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevel(PyObject *self, PyObje
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 1) {
@@ -26443,18 +27199,21 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevel(PyObject *self, PyObje
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'CdiVariable_getValuesWithLevel'.\n  Possible C/C++ prototypes are:\n    getValuesWithLevel(int)\n    getValuesWithLevel()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'CdiVariable_getValuesWithLevel'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiVariable::getValuesWithLevel(int)\n"
+    "    CdiVariable::getValuesWithLevel()\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_CdiVariable_getFValues(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  SwigValueWrapper<std::vector<float,std::allocator<float > > > result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::vector< float,std::allocator< float > > > result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_getFValues",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26463,7 +27222,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValues(PyObject *SWIGUNUSEDPARM(self)
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
   result = (arg1)->getFValues();
-  resultobj = SWIG_NewPointerObj((new std::vector<float,std::allocator<float > >(static_cast< const std::vector<float,std::allocator<float > >& >(result))), SWIGTYPE_p_std__vectorTfloat_std__allocatorTfloat_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new std::vector< float,std::allocator< float > >(static_cast< const std::vector< float,std::allocator< float > >& >(result))), SWIGTYPE_p_std__vectorT_float_std__allocatorT_float_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26474,13 +27233,13 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel__SWIG_0(PyObject *SWI
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
   int arg2 ;
-  SwigValueWrapper<std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > > > result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  SwigValueWrapper< std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > > > result;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:CdiVariable_getFValuesWithLevel",&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26494,7 +27253,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel__SWIG_0(PyObject *SWI
   } 
   arg2 = static_cast< int >(val2);
   result = (arg1)->getFValuesWithLevel(arg2);
-  resultobj = SWIG_NewPointerObj((new std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > >(static_cast< const std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > >& >(result))), SWIGTYPE_p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > >(static_cast< const std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > >& >(result))), SWIGTYPE_p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26504,10 +27263,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  SwigValueWrapper<std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > > > result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  SwigValueWrapper< std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > > > result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_getFValuesWithLevel",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26516,7 +27275,7 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel__SWIG_1(PyObject *SWI
   }
   arg1 = reinterpret_cast< CdiVariable * >(argp1);
   result = (arg1)->getFValuesWithLevel();
-  resultobj = SWIG_NewPointerObj((new std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > >(static_cast< const std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > >& >(result))), SWIGTYPE_p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t, SWIG_POINTER_OWN |  0 );
+  resultobj = SWIG_NewPointerObj((new std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > >(static_cast< const std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > >& >(result))), SWIGTYPE_p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t, SWIG_POINTER_OWN |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -26529,8 +27288,8 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel(PyObject *self, PyObj
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 1) {
@@ -26559,18 +27318,21 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getFValuesWithLevel(PyObject *self, PyObj
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'CdiVariable_getFValuesWithLevel'.\n  Possible C/C++ prototypes are:\n    getFValuesWithLevel(int)\n    getFValuesWithLevel()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'CdiVariable_getFValuesWithLevel'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiVariable::getFValuesWithLevel(int)\n"
+    "    CdiVariable::getFValuesWithLevel()\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *_wrap_CdiVariable_getValuesAsPointer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  double *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_getValuesAsPointer",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26590,13 +27352,13 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevelAsPointer__SWIG_0(PyObj
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
   int arg2 ;
-  double **result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
+  double **result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:CdiVariable_getValuesWithLevelAsPointer",&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26620,10 +27382,10 @@ fail:
 SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevelAsPointer__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CdiVariable *arg1 = (CdiVariable *) 0 ;
-  double **result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  double **result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:CdiVariable_getValuesWithLevelAsPointer",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CdiVariable, 0 |  0 );
@@ -26645,8 +27407,8 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevelAsPointer(PyObject *sel
   int ii;
   
   if (!PyTuple_Check(args)) SWIG_fail;
-  argc = PyObject_Length(args);
-  for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+  argc = args ? (int)PyObject_Length(args) : 0;
+  for (ii = 0; (ii < 2) && (ii < argc); ii++) {
     argv[ii] = PyTuple_GET_ITEM(args,ii);
   }
   if (argc == 1) {
@@ -26675,14 +27437,17 @@ SWIGINTERN PyObject *_wrap_CdiVariable_getValuesWithLevelAsPointer(PyObject *sel
   }
   
 fail:
-  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'CdiVariable_getValuesWithLevelAsPointer'.\n  Possible C/C++ prototypes are:\n    getValuesWithLevelAsPointer(int)\n    getValuesWithLevelAsPointer()\n");
-  return NULL;
+  SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number or type of arguments for overloaded function 'CdiVariable_getValuesWithLevelAsPointer'.\n"
+    "  Possible C/C++ prototypes are:\n"
+    "    CdiVariable::getValuesWithLevelAsPointer(int)\n"
+    "    CdiVariable::getValuesWithLevelAsPointer()\n");
+  return 0;
 }
 
 
 SWIGINTERN PyObject *CdiVariable_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
   SWIG_TypeNewClientData(SWIGTYPE_p_CdiVariable, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
@@ -26690,11 +27455,11 @@ SWIGINTERN PyObject *CdiVariable_swigregister(PyObject *SWIGUNUSEDPARM(self), Py
 SWIGINTERN PyObject *_wrap_new_Cdi(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   char *arg1 = (char *) 0 ;
-  Cdi *result = 0 ;
   int res1 ;
   char *buf1 = 0 ;
   int alloc1 = 0 ;
   PyObject * obj0 = 0 ;
+  Cdi *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:new_Cdi",&obj0)) SWIG_fail;
   res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
@@ -26726,7 +27491,6 @@ SWIGINTERN PyObject *_wrap_delete_Cdi(PyObject *SWIGUNUSEDPARM(self), PyObject *
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
   delete arg1;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26757,7 +27521,6 @@ SWIGINTERN PyObject *_wrap_Cdi_streamID_set(PyObject *SWIGUNUSEDPARM(self), PyOb
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->streamID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26768,10 +27531,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_streamID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_streamID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -26810,7 +27573,6 @@ SWIGINTERN PyObject *_wrap_Cdi_vlistID_set(PyObject *SWIGUNUSEDPARM(self), PyObj
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->vlistID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26821,10 +27583,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_vlistID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_vlistID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -26863,7 +27625,6 @@ SWIGINTERN PyObject *_wrap_Cdi_nvars_set(PyObject *SWIGUNUSEDPARM(self), PyObjec
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->nvars = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26874,10 +27635,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_nvars_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_nvars_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -26916,7 +27677,6 @@ SWIGINTERN PyObject *_wrap_Cdi_nzaxes_set(PyObject *SWIGUNUSEDPARM(self), PyObje
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->nzaxes = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26927,10 +27687,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_nzaxes_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_nzaxes_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -26969,7 +27729,6 @@ SWIGINTERN PyObject *_wrap_Cdi_ngrids_set(PyObject *SWIGUNUSEDPARM(self), PyObje
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ngrids = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -26980,10 +27739,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_ngrids_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_ngrids_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27022,7 +27781,6 @@ SWIGINTERN PyObject *_wrap_Cdi_ntaxes_set(PyObject *SWIGUNUSEDPARM(self), PyObje
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->ntaxes = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27033,10 +27791,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_ntaxes_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_ntaxes_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27075,7 +27833,6 @@ SWIGINTERN PyObject *_wrap_Cdi_taxisID_set(PyObject *SWIGUNUSEDPARM(self), PyObj
   } 
   arg2 = static_cast< int >(val2);
   if (arg1) (arg1)->taxisID = arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27086,10 +27843,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_taxisID_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  int result;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_taxisID_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27108,7 +27865,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_varnames_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<std::string,std::allocator<std::string > > *arg2 = (std::vector<std::string,std::allocator<std::string > > *) 0 ;
+  std::vector< std::string,std::allocator< std::string > > *arg2 = (std::vector< std::string,std::allocator< std::string > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27122,13 +27879,12 @@ SWIGINTERN PyObject *_wrap_Cdi_varnames_set(PyObject *SWIGUNUSEDPARM(self), PyOb
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_varnames_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_varnames_set" "', argument " "2"" of type '" "std::vector<std::string,std::allocator<std::string > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_varnames_set" "', argument " "2"" of type '" "std::vector< std::string,std::allocator< std::string > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<std::string,std::allocator<std::string > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< std::string,std::allocator< std::string > > * >(argp2);
   if (arg1) (arg1)->varnames = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27139,10 +27895,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_varnames_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<std::string,std::allocator<std::string > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< std::string,std::allocator< std::string > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_varnames_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27150,8 +27906,8 @@ SWIGINTERN PyObject *_wrap_Cdi_varnames_get(PyObject *SWIGUNUSEDPARM(self), PyOb
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_varnames_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::vector<std::string,std::allocator<std::string > > *)& ((arg1)->varnames);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0 |  0 );
+  result = (std::vector< std::string,std::allocator< std::string > > *)& ((arg1)->varnames);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27161,7 +27917,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_codes_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<int,std::allocator<int > > *arg2 = (std::vector<int,std::allocator<int > > *) 0 ;
+  std::vector< int,std::allocator< int > > *arg2 = (std::vector< int,std::allocator< int > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27175,13 +27931,12 @@ SWIGINTERN PyObject *_wrap_Cdi_codes_set(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_codes_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_codes_set" "', argument " "2"" of type '" "std::vector<int,std::allocator<int > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_codes_set" "', argument " "2"" of type '" "std::vector< int,std::allocator< int > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<int,std::allocator<int > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< int,std::allocator< int > > * >(argp2);
   if (arg1) (arg1)->codes = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27192,10 +27947,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_codes_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<int,std::allocator<int > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< int,std::allocator< int > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_codes_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27203,8 +27958,8 @@ SWIGINTERN PyObject *_wrap_Cdi_codes_get(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_codes_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::vector<int,std::allocator<int > > *)& ((arg1)->codes);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTint_std__allocatorTint_t_t, 0 |  0 );
+  result = (std::vector< int,std::allocator< int > > *)& ((arg1)->codes);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_int_std__allocatorT_int_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27214,7 +27969,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_variables_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<CdiVariable,std::allocator<CdiVariable > > *arg2 = (std::vector<CdiVariable,std::allocator<CdiVariable > > *) 0 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *arg2 = (std::vector< CdiVariable,std::allocator< CdiVariable > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27228,13 +27983,12 @@ SWIGINTERN PyObject *_wrap_Cdi_variables_set(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_variables_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_variables_set" "', argument " "2"" of type '" "std::vector<CdiVariable,std::allocator<CdiVariable > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_variables_set" "', argument " "2"" of type '" "std::vector< CdiVariable,std::allocator< CdiVariable > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::vector<CdiVariable,std::allocator<CdiVariable > > * >(argp2);
+  arg2 = reinterpret_cast< std::vector< CdiVariable,std::allocator< CdiVariable > > * >(argp2);
   if (arg1) (arg1)->variables = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27245,10 +27999,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_variables_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::vector<CdiVariable,std::allocator<CdiVariable > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::vector< CdiVariable,std::allocator< CdiVariable > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_variables_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27256,8 +28010,8 @@ SWIGINTERN PyObject *_wrap_Cdi_variables_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_variables_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::vector<CdiVariable,std::allocator<CdiVariable > > *)& ((arg1)->variables);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0 |  0 );
+  result = (std::vector< CdiVariable,std::allocator< CdiVariable > > *)& ((arg1)->variables);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27267,7 +28021,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_var_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *arg2 = (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *) 0 ;
+  std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *arg2 = (std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27281,13 +28035,12 @@ SWIGINTERN PyObject *_wrap_Cdi_var_set(PyObject *SWIGUNUSEDPARM(self), PyObject
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_var_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_var_set" "', argument " "2"" of type '" "std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_var_set" "', argument " "2"" of type '" "std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > * >(argp2);
+  arg2 = reinterpret_cast< std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > * >(argp2);
   if (arg1) (arg1)->var = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27298,10 +28051,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_var_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_var_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27309,8 +28062,8 @@ SWIGINTERN PyObject *_wrap_Cdi_var_get(PyObject *SWIGUNUSEDPARM(self), PyObject
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_var_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *)& ((arg1)->var);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0 |  0 );
+  result = (std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *)& ((arg1)->var);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27320,7 +28073,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_varByCode_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *arg2 = (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *) 0 ;
+  std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *arg2 = (std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27334,13 +28087,12 @@ SWIGINTERN PyObject *_wrap_Cdi_varByCode_set(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_varByCode_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_varByCode_set" "', argument " "2"" of type '" "std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_varByCode_set" "', argument " "2"" of type '" "std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > * >(argp2);
+  arg2 = reinterpret_cast< std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > * >(argp2);
   if (arg1) (arg1)->varByCode = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27351,10 +28103,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_varByCode_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_varByCode_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27362,8 +28114,8 @@ SWIGINTERN PyObject *_wrap_Cdi_varByCode_get(PyObject *SWIGUNUSEDPARM(self), PyO
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_varByCode_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *)& ((arg1)->varByCode);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0 |  0 );
+  result = (std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *)& ((arg1)->varByCode);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27373,7 +28125,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_taxes_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *arg2 = (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *) 0 ;
+  std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *arg2 = (std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27387,13 +28139,12 @@ SWIGINTERN PyObject *_wrap_Cdi_taxes_set(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_taxes_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_taxes_set" "', argument " "2"" of type '" "std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_taxes_set" "', argument " "2"" of type '" "std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > * >(argp2);
+  arg2 = reinterpret_cast< std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > * >(argp2);
   if (arg1) (arg1)->taxes = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27404,10 +28155,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_taxes_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_taxes_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27415,8 +28166,8 @@ SWIGINTERN PyObject *_wrap_Cdi_taxes_get(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_taxes_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *)& ((arg1)->taxes);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0 |  0 );
+  result = (std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *)& ((arg1)->taxes);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27426,7 +28177,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_zaxes_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *arg2 = (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *) 0 ;
+  std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *arg2 = (std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27440,13 +28191,12 @@ SWIGINTERN PyObject *_wrap_Cdi_zaxes_set(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_zaxes_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_zaxes_set" "', argument " "2"" of type '" "std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_zaxes_set" "', argument " "2"" of type '" "std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > * >(argp2);
+  arg2 = reinterpret_cast< std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > * >(argp2);
   if (arg1) (arg1)->zaxes = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27457,10 +28207,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_zaxes_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_zaxes_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27468,8 +28218,8 @@ SWIGINTERN PyObject *_wrap_Cdi_zaxes_get(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_zaxes_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *)& ((arg1)->zaxes);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0 |  0 );
+  result = (std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *)& ((arg1)->zaxes);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27479,7 +28229,7 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_grids_set(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *arg2 = (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *) 0 ;
+  std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *arg2 = (std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *) 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   void *argp2 = 0 ;
@@ -27493,13 +28243,12 @@ SWIGINTERN PyObject *_wrap_Cdi_grids_set(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_grids_set" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_grids_set" "', argument " "2"" of type '" "std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Cdi_grids_set" "', argument " "2"" of type '" "std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *""'"); 
   }
-  arg2 = reinterpret_cast< std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > * >(argp2);
+  arg2 = reinterpret_cast< std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > * >(argp2);
   if (arg1) (arg1)->grids = *arg2;
-  
   resultobj = SWIG_Py_Void();
   return resultobj;
 fail:
@@ -27510,10 +28259,10 @@ fail:
 SWIGINTERN PyObject *_wrap_Cdi_grids_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   Cdi *arg1 = (Cdi *) 0 ;
-  std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *result = 0 ;
   void *argp1 = 0 ;
   int res1 = 0 ;
   PyObject * obj0 = 0 ;
+  std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:Cdi_grids_get",&obj0)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Cdi, 0 |  0 );
@@ -27521,8 +28270,8 @@ SWIGINTERN PyObject *_wrap_Cdi_grids_get(PyObject *SWIGUNUSEDPARM(self), PyObjec
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cdi_grids_get" "', argument " "1"" of type '" "Cdi *""'"); 
   }
   arg1 = reinterpret_cast< Cdi * >(argp1);
-  result = (std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *)& ((arg1)->grids);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0 |  0 );
+  result = (std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *)& ((arg1)->grids);
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0 |  0 );
   return resultobj;
 fail:
   return NULL;
@@ -27552,31 +28301,34 @@ fail:
 
 SWIGINTERN PyObject *Cdi_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
-  if (!PyArg_ParseTuple(args,(char*)"O|swigregister", &obj)) return NULL;
+  if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
   SWIG_TypeNewClientData(SWIGTYPE_p_Cdi, SWIG_NewClientData(obj));
   return SWIG_Py_Void();
 }
 
 static PyMethodDef SwigMethods[] = {
-	 { (char *)"delete_PySwigIterator", _wrap_delete_PySwigIterator, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_value", _wrap_PySwigIterator_value, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_incr", _wrap_PySwigIterator_incr, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_decr", _wrap_PySwigIterator_decr, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_distance", _wrap_PySwigIterator_distance, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_equal", _wrap_PySwigIterator_equal, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_copy", _wrap_PySwigIterator_copy, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_next", _wrap_PySwigIterator_next, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_previous", _wrap_PySwigIterator_previous, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_advance", _wrap_PySwigIterator_advance, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___eq__", _wrap_PySwigIterator___eq__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___ne__", _wrap_PySwigIterator___ne__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___iadd__", _wrap_PySwigIterator___iadd__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___isub__", _wrap_PySwigIterator___isub__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___add__", _wrap_PySwigIterator___add__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator___sub__", _wrap_PySwigIterator___sub__, METH_VARARGS, NULL},
-	 { (char *)"PySwigIterator_swigregister", PySwigIterator_swigregister, METH_VARARGS, NULL},
+	 { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
+	 { (char *)"delete_SwigPyIterator", _wrap_delete_SwigPyIterator, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_value", _wrap_SwigPyIterator_value, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_incr", _wrap_SwigPyIterator_incr, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_decr", _wrap_SwigPyIterator_decr, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_distance", _wrap_SwigPyIterator_distance, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_equal", _wrap_SwigPyIterator_equal, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_copy", _wrap_SwigPyIterator_copy, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_next", _wrap_SwigPyIterator_next, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___next__", _wrap_SwigPyIterator___next__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_previous", _wrap_SwigPyIterator_previous, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_advance", _wrap_SwigPyIterator_advance, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___eq__", _wrap_SwigPyIterator___eq__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___ne__", _wrap_SwigPyIterator___ne__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___iadd__", _wrap_SwigPyIterator___iadd__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___isub__", _wrap_SwigPyIterator___isub__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___add__", _wrap_SwigPyIterator___add__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator___sub__", _wrap_SwigPyIterator___sub__, METH_VARARGS, NULL},
+	 { (char *)"SwigPyIterator_swigregister", SwigPyIterator_swigregister, METH_VARARGS, NULL},
 	 { (char *)"IntVector_iterator", _wrap_IntVector_iterator, METH_VARARGS, NULL},
 	 { (char *)"IntVector___nonzero__", _wrap_IntVector___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"IntVector___bool__", _wrap_IntVector___bool__, METH_VARARGS, NULL},
 	 { (char *)"IntVector___len__", _wrap_IntVector___len__, METH_VARARGS, NULL},
 	 { (char *)"IntVector_pop", _wrap_IntVector_pop, METH_VARARGS, NULL},
 	 { (char *)"IntVector___getslice__", _wrap_IntVector___getslice__, METH_VARARGS, NULL},
@@ -27610,6 +28362,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"IntVector_swigregister", IntVector_swigregister, METH_VARARGS, NULL},
 	 { (char *)"DoubleVector_iterator", _wrap_DoubleVector_iterator, METH_VARARGS, NULL},
 	 { (char *)"DoubleVector___nonzero__", _wrap_DoubleVector___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"DoubleVector___bool__", _wrap_DoubleVector___bool__, METH_VARARGS, NULL},
 	 { (char *)"DoubleVector___len__", _wrap_DoubleVector___len__, METH_VARARGS, NULL},
 	 { (char *)"DoubleVector_pop", _wrap_DoubleVector_pop, METH_VARARGS, NULL},
 	 { (char *)"DoubleVector___getslice__", _wrap_DoubleVector___getslice__, METH_VARARGS, NULL},
@@ -27643,6 +28396,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DoubleVector_swigregister", DoubleVector_swigregister, METH_VARARGS, NULL},
 	 { (char *)"DoubleDoubleVector_iterator", _wrap_DoubleDoubleVector_iterator, METH_VARARGS, NULL},
 	 { (char *)"DoubleDoubleVector___nonzero__", _wrap_DoubleDoubleVector___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"DoubleDoubleVector___bool__", _wrap_DoubleDoubleVector___bool__, METH_VARARGS, NULL},
 	 { (char *)"DoubleDoubleVector___len__", _wrap_DoubleDoubleVector___len__, METH_VARARGS, NULL},
 	 { (char *)"DoubleDoubleVector_pop", _wrap_DoubleDoubleVector_pop, METH_VARARGS, NULL},
 	 { (char *)"DoubleDoubleVector___getslice__", _wrap_DoubleDoubleVector___getslice__, METH_VARARGS, NULL},
@@ -27676,6 +28430,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"DoubleDoubleVector_swigregister", DoubleDoubleVector_swigregister, METH_VARARGS, NULL},
 	 { (char *)"StringVector_iterator", _wrap_StringVector_iterator, METH_VARARGS, NULL},
 	 { (char *)"StringVector___nonzero__", _wrap_StringVector___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"StringVector___bool__", _wrap_StringVector___bool__, METH_VARARGS, NULL},
 	 { (char *)"StringVector___len__", _wrap_StringVector___len__, METH_VARARGS, NULL},
 	 { (char *)"StringVector_pop", _wrap_StringVector_pop, METH_VARARGS, NULL},
 	 { (char *)"StringVector___getslice__", _wrap_StringVector___getslice__, METH_VARARGS, NULL},
@@ -27709,6 +28464,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"StringVector_swigregister", StringVector_swigregister, METH_VARARGS, NULL},
 	 { (char *)"VarsVector_iterator", _wrap_VarsVector_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsVector___nonzero__", _wrap_VarsVector___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"VarsVector___bool__", _wrap_VarsVector___bool__, METH_VARARGS, NULL},
 	 { (char *)"VarsVector___len__", _wrap_VarsVector___len__, METH_VARARGS, NULL},
 	 { (char *)"VarsVector_pop", _wrap_VarsVector_pop, METH_VARARGS, NULL},
 	 { (char *)"VarsVector___getslice__", _wrap_VarsVector___getslice__, METH_VARARGS, NULL},
@@ -27742,6 +28498,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"VarsVector_swigregister", VarsVector_swigregister, METH_VARARGS, NULL},
 	 { (char *)"VarsMap_iterator", _wrap_VarsMap_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsMap___nonzero__", _wrap_VarsMap___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"VarsMap___bool__", _wrap_VarsMap___bool__, METH_VARARGS, NULL},
 	 { (char *)"VarsMap___len__", _wrap_VarsMap___len__, METH_VARARGS, NULL},
 	 { (char *)"VarsMap___getitem__", _wrap_VarsMap___getitem__, METH_VARARGS, NULL},
 	 { (char *)"VarsMap___delitem__", _wrap_VarsMap___delitem__, METH_VARARGS, NULL},
@@ -27753,6 +28510,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"VarsMap_key_iterator", _wrap_VarsMap_key_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsMap_value_iterator", _wrap_VarsMap_value_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsMap___setitem__", _wrap_VarsMap___setitem__, METH_VARARGS, NULL},
+	 { (char *)"VarsMap_asdict", _wrap_VarsMap_asdict, METH_VARARGS, NULL},
 	 { (char *)"new_VarsMap", _wrap_new_VarsMap, METH_VARARGS, NULL},
 	 { (char *)"VarsMap_empty", _wrap_VarsMap_empty, METH_VARARGS, NULL},
 	 { (char *)"VarsMap_size", _wrap_VarsMap_size, METH_VARARGS, NULL},
@@ -27772,6 +28530,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"VarsMap_swigregister", VarsMap_swigregister, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode_iterator", _wrap_VarsByCode_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode___nonzero__", _wrap_VarsByCode___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"VarsByCode___bool__", _wrap_VarsByCode___bool__, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode___len__", _wrap_VarsByCode___len__, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode___getitem__", _wrap_VarsByCode___getitem__, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode___delitem__", _wrap_VarsByCode___delitem__, METH_VARARGS, NULL},
@@ -27783,6 +28542,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"VarsByCode_key_iterator", _wrap_VarsByCode_key_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode_value_iterator", _wrap_VarsByCode_value_iterator, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode___setitem__", _wrap_VarsByCode___setitem__, METH_VARARGS, NULL},
+	 { (char *)"VarsByCode_asdict", _wrap_VarsByCode_asdict, METH_VARARGS, NULL},
 	 { (char *)"new_VarsByCode", _wrap_new_VarsByCode, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode_empty", _wrap_VarsByCode_empty, METH_VARARGS, NULL},
 	 { (char *)"VarsByCode_size", _wrap_VarsByCode_size, METH_VARARGS, NULL},
@@ -27802,6 +28562,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"VarsByCode_swigregister", VarsByCode_swigregister, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap_iterator", _wrap_TaxesMap_iterator, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap___nonzero__", _wrap_TaxesMap___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"TaxesMap___bool__", _wrap_TaxesMap___bool__, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap___len__", _wrap_TaxesMap___len__, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap___getitem__", _wrap_TaxesMap___getitem__, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap___delitem__", _wrap_TaxesMap___delitem__, METH_VARARGS, NULL},
@@ -27813,6 +28574,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"TaxesMap_key_iterator", _wrap_TaxesMap_key_iterator, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap_value_iterator", _wrap_TaxesMap_value_iterator, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap___setitem__", _wrap_TaxesMap___setitem__, METH_VARARGS, NULL},
+	 { (char *)"TaxesMap_asdict", _wrap_TaxesMap_asdict, METH_VARARGS, NULL},
 	 { (char *)"new_TaxesMap", _wrap_new_TaxesMap, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap_empty", _wrap_TaxesMap_empty, METH_VARARGS, NULL},
 	 { (char *)"TaxesMap_size", _wrap_TaxesMap_size, METH_VARARGS, NULL},
@@ -27832,6 +28594,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"TaxesMap_swigregister", TaxesMap_swigregister, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap_iterator", _wrap_ZaxesMap_iterator, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap___nonzero__", _wrap_ZaxesMap___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"ZaxesMap___bool__", _wrap_ZaxesMap___bool__, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap___len__", _wrap_ZaxesMap___len__, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap___getitem__", _wrap_ZaxesMap___getitem__, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap___delitem__", _wrap_ZaxesMap___delitem__, METH_VARARGS, NULL},
@@ -27843,6 +28606,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"ZaxesMap_key_iterator", _wrap_ZaxesMap_key_iterator, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap_value_iterator", _wrap_ZaxesMap_value_iterator, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap___setitem__", _wrap_ZaxesMap___setitem__, METH_VARARGS, NULL},
+	 { (char *)"ZaxesMap_asdict", _wrap_ZaxesMap_asdict, METH_VARARGS, NULL},
 	 { (char *)"new_ZaxesMap", _wrap_new_ZaxesMap, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap_empty", _wrap_ZaxesMap_empty, METH_VARARGS, NULL},
 	 { (char *)"ZaxesMap_size", _wrap_ZaxesMap_size, METH_VARARGS, NULL},
@@ -27862,6 +28626,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"ZaxesMap_swigregister", ZaxesMap_swigregister, METH_VARARGS, NULL},
 	 { (char *)"GridsMap_iterator", _wrap_GridsMap_iterator, METH_VARARGS, NULL},
 	 { (char *)"GridsMap___nonzero__", _wrap_GridsMap___nonzero__, METH_VARARGS, NULL},
+	 { (char *)"GridsMap___bool__", _wrap_GridsMap___bool__, METH_VARARGS, NULL},
 	 { (char *)"GridsMap___len__", _wrap_GridsMap___len__, METH_VARARGS, NULL},
 	 { (char *)"GridsMap___getitem__", _wrap_GridsMap___getitem__, METH_VARARGS, NULL},
 	 { (char *)"GridsMap___delitem__", _wrap_GridsMap___delitem__, METH_VARARGS, NULL},
@@ -27873,6 +28638,7 @@ static PyMethodDef SwigMethods[] = {
 	 { (char *)"GridsMap_key_iterator", _wrap_GridsMap_key_iterator, METH_VARARGS, NULL},
 	 { (char *)"GridsMap_value_iterator", _wrap_GridsMap_value_iterator, METH_VARARGS, NULL},
 	 { (char *)"GridsMap___setitem__", _wrap_GridsMap___setitem__, METH_VARARGS, NULL},
+	 { (char *)"GridsMap_asdict", _wrap_GridsMap_asdict, METH_VARARGS, NULL},
 	 { (char *)"new_GridsMap", _wrap_new_GridsMap, METH_VARARGS, NULL},
 	 { (char *)"GridsMap_empty", _wrap_GridsMap_empty, METH_VARARGS, NULL},
 	 { (char *)"GridsMap_size", _wrap_GridsMap_size, METH_VARARGS, NULL},
@@ -28098,10 +28864,10 @@ static PyMethodDef SwigMethods[] = {
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
 static swig_type_info _swigt__p_Cdi = {"_p_Cdi", "Cdi *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_CdiGrid = {"_p_CdiGrid", "CdiGrid *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_CdiTaxis = {"_p_CdiTaxis", "CdiTaxis *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_CdiVariable = {"_p_CdiVariable", "CdiVariable *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_CdiZaxis = {"_p_CdiZaxis", "CdiZaxis *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_CdiGrid = {"_p_CdiGrid", "std::map< int,CdiGrid >::mapped_type *|CdiGrid *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_CdiTaxis = {"_p_CdiTaxis", "std::map< int,CdiTaxis >::mapped_type *|CdiTaxis *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_CdiVariable = {"_p_CdiVariable", "std::map< std::string,CdiVariable >::mapped_type *|std::vector< CdiVariable >::value_type *|std::map< int,CdiVariable >::mapped_type *|CdiVariable *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_CdiZaxis = {"_p_CdiZaxis", "std::map< int,CdiZaxis >::mapped_type *|CdiZaxis *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_allocator_type = {"_p_allocator_type", "allocator_type *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_difference_type = {"_p_difference_type", "difference_type *", 0, 0, (void*)0, 0};
@@ -28112,36 +28878,33 @@ static swig_type_info _swigt__p_mapped_type = {"_p_mapped_type", "mapped_type *"
 static swig_type_info _swigt__p_p_PyObject = {"_p_p_PyObject", "PyObject **", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_p_double = {"_p_p_double", "double **", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_size_type = {"_p_size_type", "size_type *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_CdiVariable_t = {"_p_std__allocatorT_CdiVariable_t", "std::vector< CdiVariable >::allocator_type *|std::allocator< CdiVariable > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_double_t = {"_p_std__allocatorT_double_t", "std::vector< double >::allocator_type *|std::allocator< double > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_int_t = {"_p_std__allocatorT_int_t", "std::vector< int >::allocator_type *|std::allocator< int > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t = {"_p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t", "std::map< int,CdiGrid >::allocator_type *|std::allocator< std::pair< int const,CdiGrid > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t = {"_p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t", "std::map< int,CdiTaxis >::allocator_type *|std::allocator< std::pair< int const,CdiTaxis > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t = {"_p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t", "std::map< int,CdiVariable >::allocator_type *|std::allocator< std::pair< int const,CdiVariable > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t = {"_p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t", "std::map< int,CdiZaxis >::allocator_type *|std::allocator< std::pair< int const,CdiZaxis > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t = {"_p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t", "std::allocator< std::pair< std::string const,CdiVariable > > *|std::map< std::string,CdiVariable >::allocator_type *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__string_t = {"_p_std__allocatorT_std__string_t", "std::vector< std::string >::allocator_type *|std::allocator< std::string > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t = {"_p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t", "std::vector< std::vector< double > >::allocator_type *|std::allocator< std::vector< double,std::allocator< double > > > *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_std__invalid_argument = {"_p_std__invalid_argument", "std::invalid_argument *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t = {"_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t", "std::map<int,CdiGrid,std::less<int >,std::allocator<std::pair<int const,CdiGrid > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type = {"_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type", "std::allocator<std::pair<int const,CdiGrid > > *|std::map<int,CdiGrid >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type = {"_p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type", "CdiGrid *|std::map<int,CdiGrid >::mapped_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t = {"_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t", "std::map<int,CdiTaxis,std::less<int >,std::allocator<std::pair<int const,CdiTaxis > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type = {"_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type", "std::allocator<std::pair<int const,CdiTaxis > > *|std::map<int,CdiTaxis >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type = {"_p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type", "CdiTaxis *|std::map<int,CdiTaxis >::mapped_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t = {"_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t", "std::map<int,CdiVariable,std::less<int >,std::allocator<std::pair<int const,CdiVariable > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type = {"_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type", "std::allocator<std::pair<int const,CdiVariable > > *|std::map<int,CdiVariable >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type = {"_p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type", "CdiVariable *|std::map<int,CdiVariable >::mapped_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t = {"_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t", "std::map<int,CdiZaxis,std::less<int >,std::allocator<std::pair<int const,CdiZaxis > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type = {"_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type", "std::allocator<std::pair<int const,CdiZaxis > > *|std::map<int,CdiZaxis >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type = {"_p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type", "CdiZaxis *|std::map<int,CdiZaxis >::mapped_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t = {"_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t", "std::map<std::string,CdiVariable,std::less<std::string >,std::allocator<std::pair<std::string const,CdiVariable > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type = {"_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type", "std::allocator<std::pair<std::string const,CdiVariable > > *|std::map<std::string,CdiVariable >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type = {"_p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type", "CdiVariable *|std::map<std::string,CdiVariable >::mapped_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t = {"_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t", "std::vector<CdiVariable,std::allocator<CdiVariable > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type = {"_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type", "std::allocator<CdiVariable > *|std::vector<CdiVariable >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type = {"_p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type", "CdiVariable *|std::vector<CdiVariable >::value_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t = {"_p_std__vectorTdouble_std__allocatorTdouble_t_t", "std::vector<double,std::allocator<double > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type = {"_p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type", "std::allocator<double > *|std::vector<double >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTfloat_std__allocatorTfloat_t_t = {"_p_std__vectorTfloat_std__allocatorTfloat_t_t", "std::vector<float,std::allocator<float > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTint_std__allocatorTint_t_t = {"_p_std__vectorTint_std__allocatorTint_t_t", "std::vector<int,std::allocator<int > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTint_std__allocatorTint_t_t__allocator_type = {"_p_std__vectorTint_std__allocatorTint_t_t__allocator_type", "std::allocator<int > *|std::vector<int >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t = {"_p_std__vectorTstd__string_std__allocatorTstd__string_t_t", "std::vector<std::string,std::allocator<std::string > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type = {"_p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type", "std::allocator<std::string > *|std::vector<std::string >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t = {"_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t", "std::vector<std::vector<double,std::allocator<double > >,std::allocator<std::vector<double,std::allocator<double > > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type = {"_p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type", "std::allocator<std::vector<double,std::allocator<double > > > *|std::vector<std::vector<double > >::allocator_type *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t = {"_p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t", "std::vector<std::vector<float,std::allocator<float > >,std::allocator<std::vector<float,std::allocator<float > > > > *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_swig__PySwigIterator = {"_p_swig__PySwigIterator", "swig::PySwigIterator *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__lessT_int_t = {"_p_std__lessT_int_t", "std::less< int > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__lessT_std__string_t = {"_p_std__lessT_std__string_t", "std::less< std::string > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t = {"_p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t", "std::map< int,CdiGrid > *|std::map< int,CdiGrid,std::less< int >,std::allocator< std::pair< int const,CdiGrid > > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t = {"_p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t", "std::map< int,CdiTaxis > *|std::map< int,CdiTaxis,std::less< int >,std::allocator< std::pair< int const,CdiTaxis > > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t = {"_p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t", "std::map< int,CdiVariable,std::less< int >,std::allocator< std::pair< int const,CdiVariable > > > *|std::map< int,CdiVariable > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t = {"_p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t", "std::map< int,CdiZaxis > *|std::map< int,CdiZaxis,std::less< int >,std::allocator< std::pair< int const,CdiZaxis > > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t = {"_p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t", "std::map< std::string,CdiVariable,std::less< std::string >,std::allocator< std::pair< std::string const,CdiVariable > > > *|std::map< std::string,CdiVariable > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t = {"_p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t", "std::vector< CdiVariable,std::allocator< CdiVariable > > *|std::vector< CdiVariable > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT__Tp__Alloc_t = {"_p_std__vectorT__Tp__Alloc_t", "std::vector< _Tp,_Alloc > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_double_std__allocatorT_double_t_t = {"_p_std__vectorT_double_std__allocatorT_double_t_t", "std::vector< double,std::allocator< double > > *|std::vector< double > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_float_std__allocatorT_float_t_t = {"_p_std__vectorT_float_std__allocatorT_float_t_t", "std::vector< float,std::allocator< float > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_int_std__allocatorT_int_t_t = {"_p_std__vectorT_int_std__allocatorT_int_t_t", "std::vector< int,std::allocator< int > > *|std::vector< int > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_std__string_std__allocatorT_std__string_t_t = {"_p_std__vectorT_std__string_std__allocatorT_std__string_t_t", "std::vector< std::string,std::allocator< std::string > > *|std::vector< std::string > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t = {"_p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t", "std::vector< std::vector< double > > *|std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > *|std::vector< std::vector< do [...]
+static swig_type_info _swigt__p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t = {"_p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t", "std::vector< std::vector< float,std::allocator< float > >,std::allocator< std::vector< float,std::allocator< float > > > > *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_swig__SwigPyIterator = {"_p_swig__SwigPyIterator", "swig::SwigPyIterator *", 0, 0, (void*)0, 0};
 static swig_type_info _swigt__p_value_type = {"_p_value_type", "value_type *", 0, 0, (void*)0, 0};
 
 static swig_type_info *swig_type_initial[] = {
@@ -28160,44 +28923,41 @@ static swig_type_info *swig_type_initial[] = {
   &_swigt__p_p_PyObject,
   &_swigt__p_p_double,
   &_swigt__p_size_type,
+  &_swigt__p_std__allocatorT_CdiVariable_t,
+  &_swigt__p_std__allocatorT_double_t,
+  &_swigt__p_std__allocatorT_int_t,
+  &_swigt__p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t,
+  &_swigt__p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t,
+  &_swigt__p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t,
+  &_swigt__p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t,
+  &_swigt__p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t,
+  &_swigt__p_std__allocatorT_std__string_t,
+  &_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   &_swigt__p_std__invalid_argument,
-  &_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t,
-  &_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type,
-  &_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type,
-  &_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t,
-  &_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type,
-  &_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type,
-  &_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t,
-  &_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type,
-  &_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type,
-  &_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t,
-  &_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type,
-  &_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type,
-  &_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t,
-  &_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type,
-  &_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type,
-  &_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t,
-  &_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type,
-  &_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,
-  &_swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t,
-  &_swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type,
-  &_swigt__p_std__vectorTfloat_std__allocatorTfloat_t_t,
-  &_swigt__p_std__vectorTint_std__allocatorTint_t_t,
-  &_swigt__p_std__vectorTint_std__allocatorTint_t_t__allocator_type,
-  &_swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t,
-  &_swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type,
-  &_swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t,
-  &_swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type,
-  &_swigt__p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t,
-  &_swigt__p_swig__PySwigIterator,
+  &_swigt__p_std__lessT_int_t,
+  &_swigt__p_std__lessT_std__string_t,
+  &_swigt__p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t,
+  &_swigt__p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t,
+  &_swigt__p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t,
+  &_swigt__p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t,
+  &_swigt__p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t,
+  &_swigt__p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t,
+  &_swigt__p_std__vectorT__Tp__Alloc_t,
+  &_swigt__p_std__vectorT_double_std__allocatorT_double_t_t,
+  &_swigt__p_std__vectorT_float_std__allocatorT_float_t_t,
+  &_swigt__p_std__vectorT_int_std__allocatorT_int_t_t,
+  &_swigt__p_std__vectorT_std__string_std__allocatorT_std__string_t_t,
+  &_swigt__p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t,
+  &_swigt__p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t,
+  &_swigt__p_swig__SwigPyIterator,
   &_swigt__p_value_type,
 };
 
 static swig_cast_info _swigc__p_Cdi[] = {  {&_swigt__p_Cdi, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_CdiGrid[] = {  {&_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_CdiGrid, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_CdiTaxis[] = {  {&_swigt__p_CdiTaxis, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_CdiVariable[] = {  {&_swigt__p_CdiVariable, 0, 0, 0},  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_CdiZaxis[] = {  {&_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_CdiZaxis, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_CdiGrid[] = {  {&_swigt__p_CdiGrid, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_CdiTaxis[] = {  {&_swigt__p_CdiTaxis, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_CdiVariable[] = {  {&_swigt__p_CdiVariable, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_CdiZaxis[] = {  {&_swigt__p_CdiZaxis, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_allocator_type[] = {  {&_swigt__p_allocator_type, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_difference_type[] = {  {&_swigt__p_difference_type, 0, 0, 0},{0, 0, 0, 0}};
@@ -28208,36 +28968,33 @@ static swig_cast_info _swigc__p_mapped_type[] = {  {&_swigt__p_mapped_type, 0, 0
 static swig_cast_info _swigc__p_p_PyObject[] = {  {&_swigt__p_p_PyObject, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_p_double[] = {  {&_swigt__p_p_double, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_size_type[] = {  {&_swigt__p_size_type, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_CdiVariable_t[] = {  {&_swigt__p_std__allocatorT_CdiVariable_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_double_t[] = {  {&_swigt__p_std__allocatorT_double_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_int_t[] = {  {&_swigt__p_std__allocatorT_int_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t[] = {  {&_swigt__p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t[] = {  {&_swigt__p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t[] = {  {&_swigt__p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t[] = {  {&_swigt__p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t[] = {  {&_swigt__p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__string_t[] = {  {&_swigt__p_std__allocatorT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t[] = {  {&_swigt__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_std__invalid_argument[] = {  {&_swigt__p_std__invalid_argument, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t[] = {  {&_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type[] = {  {&_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type[] = {  {&_swigt__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_CdiGrid, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t[] = {  {&_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type[] = {  {&_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type[] = {  {&_swigt__p_CdiTaxis, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t[] = {  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type[] = {  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type[] = {  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0, 0, 0},  {&_swigt__p_CdiVariable, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd_ [...]
-static swig_cast_info _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t[] = {  {&_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type[] = {  {&_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type[] = {  {&_swigt__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_CdiZaxis, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t[] = {  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type[] = {  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type[] = {  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0, 0, 0},  {&_swigt__p_CdiVariable, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__stri [...]
-static swig_cast_info _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t[] = {  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type[] = {  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type[] = {  {&_swigt__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type, 0, 0, 0},  {&_swigt__p_CdiVariable, 0, 0, 0},  {&_swigt__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type, 0, 0, 0},  {&_swigt__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_ [...]
-static swig_cast_info _swigc__p_std__vectorTdouble_std__allocatorTdouble_t_t[] = {  {&_swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type[] = {  {&_swigt__p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTfloat_std__allocatorTfloat_t_t[] = {  {&_swigt__p_std__vectorTfloat_std__allocatorTfloat_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTint_std__allocatorTint_t_t[] = {  {&_swigt__p_std__vectorTint_std__allocatorTint_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTint_std__allocatorTint_t_t__allocator_type[] = {  {&_swigt__p_std__vectorTint_std__allocatorTint_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTstd__string_std__allocatorTstd__string_t_t[] = {  {&_swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type[] = {  {&_swigt__p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t[] = {  {&_swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type[] = {  {&_swigt__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t[] = {  {&_swigt__p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_swig__PySwigIterator[] = {  {&_swigt__p_swig__PySwigIterator, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__lessT_int_t[] = {  {&_swigt__p_std__lessT_int_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__lessT_std__string_t[] = {  {&_swigt__p_std__lessT_std__string_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t[] = {  {&_swigt__p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t[] = {  {&_swigt__p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t[] = {  {&_swigt__p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t[] = {  {&_swigt__p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t[] = {  {&_swigt__p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t[] = {  {&_swigt__p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT__Tp__Alloc_t[] = {  {&_swigt__p_std__vectorT__Tp__Alloc_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_double_std__allocatorT_double_t_t[] = {  {&_swigt__p_std__vectorT_double_std__allocatorT_double_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_float_std__allocatorT_float_t_t[] = {  {&_swigt__p_std__vectorT_float_std__allocatorT_float_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_int_std__allocatorT_int_t_t[] = {  {&_swigt__p_std__vectorT_int_std__allocatorT_int_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_std__string_std__allocatorT_std__string_t_t[] = {  {&_swigt__p_std__vectorT_std__string_std__allocatorT_std__string_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t[] = {  {&_swigt__p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t[] = {  {&_swigt__p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_swig__SwigPyIterator[] = {  {&_swigt__p_swig__SwigPyIterator, 0, 0, 0},{0, 0, 0, 0}};
 static swig_cast_info _swigc__p_value_type[] = {  {&_swigt__p_value_type, 0, 0, 0},{0, 0, 0, 0}};
 
 static swig_cast_info *swig_cast_initial[] = {
@@ -28256,36 +29013,33 @@ static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_p_PyObject,
   _swigc__p_p_double,
   _swigc__p_size_type,
+  _swigc__p_std__allocatorT_CdiVariable_t,
+  _swigc__p_std__allocatorT_double_t,
+  _swigc__p_std__allocatorT_int_t,
+  _swigc__p_std__allocatorT_std__pairT_int_const_CdiGrid_t_t,
+  _swigc__p_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t,
+  _swigc__p_std__allocatorT_std__pairT_int_const_CdiVariable_t_t,
+  _swigc__p_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t,
+  _swigc__p_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t,
+  _swigc__p_std__allocatorT_std__string_t,
+  _swigc__p_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t,
   _swigc__p_std__invalid_argument,
-  _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t,
-  _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__allocator_type,
-  _swigc__p_std__mapTint_CdiGrid_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiGrid_t_t_t__mapped_type,
-  _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t,
-  _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__allocator_type,
-  _swigc__p_std__mapTint_CdiTaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiTaxis_t_t_t__mapped_type,
-  _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t,
-  _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__allocator_type,
-  _swigc__p_std__mapTint_CdiVariable_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiVariable_t_t_t__mapped_type,
-  _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t,
-  _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__allocator_type,
-  _swigc__p_std__mapTint_CdiZaxis_std__lessTint_t_std__allocatorTstd__pairTint_const_CdiZaxis_t_t_t__mapped_type,
-  _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t,
-  _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__allocator_type,
-  _swigc__p_std__mapTstd__string_CdiVariable_std__lessTstd__string_t_std__allocatorTstd__pairTstd__string_const_CdiVariable_t_t_t__mapped_type,
-  _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t,
-  _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__allocator_type,
-  _swigc__p_std__vectorTCdiVariable_std__allocatorTCdiVariable_t_t__value_type,
-  _swigc__p_std__vectorTdouble_std__allocatorTdouble_t_t,
-  _swigc__p_std__vectorTdouble_std__allocatorTdouble_t_t__allocator_type,
-  _swigc__p_std__vectorTfloat_std__allocatorTfloat_t_t,
-  _swigc__p_std__vectorTint_std__allocatorTint_t_t,
-  _swigc__p_std__vectorTint_std__allocatorTint_t_t__allocator_type,
-  _swigc__p_std__vectorTstd__string_std__allocatorTstd__string_t_t,
-  _swigc__p_std__vectorTstd__string_std__allocatorTstd__string_t_t__allocator_type,
-  _swigc__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t,
-  _swigc__p_std__vectorTstd__vectorTdouble_std__allocatorTdouble_t_t_std__allocatorTstd__vectorTdouble_std__allocatorTdouble_t_t_t_t__allocator_type,
-  _swigc__p_std__vectorTstd__vectorTfloat_std__allocatorTfloat_t_t_std__allocatorTstd__vectorTfloat_std__allocatorTfloat_t_t_t_t,
-  _swigc__p_swig__PySwigIterator,
+  _swigc__p_std__lessT_int_t,
+  _swigc__p_std__lessT_std__string_t,
+  _swigc__p_std__mapT_int_CdiGrid_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiGrid_t_t_t,
+  _swigc__p_std__mapT_int_CdiTaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiTaxis_t_t_t,
+  _swigc__p_std__mapT_int_CdiVariable_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiVariable_t_t_t,
+  _swigc__p_std__mapT_int_CdiZaxis_std__lessT_int_t_std__allocatorT_std__pairT_int_const_CdiZaxis_t_t_t,
+  _swigc__p_std__mapT_std__string_CdiVariable_std__lessT_std__string_t_std__allocatorT_std__pairT_std__string_const_CdiVariable_t_t_t,
+  _swigc__p_std__vectorT_CdiVariable_std__allocatorT_CdiVariable_t_t,
+  _swigc__p_std__vectorT__Tp__Alloc_t,
+  _swigc__p_std__vectorT_double_std__allocatorT_double_t_t,
+  _swigc__p_std__vectorT_float_std__allocatorT_float_t_t,
+  _swigc__p_std__vectorT_int_std__allocatorT_int_t_t,
+  _swigc__p_std__vectorT_std__string_std__allocatorT_std__string_t_t,
+  _swigc__p_std__vectorT_std__vectorT_double_std__allocatorT_double_t_t_std__allocatorT_std__vectorT_double_std__allocatorT_double_t_t_t_t,
+  _swigc__p_std__vectorT_std__vectorT_float_std__allocatorT_float_t_t_std__allocatorT_std__vectorT_float_std__allocatorT_float_t_t_t_t,
+  _swigc__p_swig__SwigPyIterator,
   _swigc__p_value_type,
 };
 
@@ -28300,18 +29054,18 @@ static swig_const_info swig_const_table[] = {
 #endif
 /* -----------------------------------------------------------------------------
  * Type initialization:
- * This problem is tough by the requirement that no dynamic 
- * memory is used. Also, since swig_type_info structures store pointers to 
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
  * swig_cast_info structures and swig_cast_info structures store pointers back
- * to swig_type_info structures, we need some lookup code at initialization. 
- * The idea is that swig generates all the structures that are needed. 
- * The runtime then collects these partially filled structures. 
- * The SWIG_InitializeModule function takes these initial arrays out of 
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
  * swig_module, and does all the lookup, filling in the swig_module.types
  * array with the correct data and linking the correct swig_cast_info
  * structures together.
  *
- * The generated swig_type_info structures are assigned staticly to an initial 
+ * The generated swig_type_info structures are assigned statically to an initial
  * array. We just loop through that array, and handle each type individually.
  * First we lookup if this type has been already loaded, and if so, use the
  * loaded structure instead of the generated one. Then we have to fill in the
@@ -28321,17 +29075,17 @@ static swig_const_info swig_const_table[] = {
  * a column is one of the swig_cast_info structures for that type.
  * The cast_initial array is actually an array of arrays, because each row has
  * a variable number of columns. So to actually build the cast linked list,
- * we find the array of casts associated with the type, and loop through it 
+ * we find the array of casts associated with the type, and loop through it
  * adding the casts to the list. The one last trick we need to do is making
  * sure the type pointer in the swig_cast_info struct is correct.
  *
- * First off, we lookup the cast->type name to see if it is already loaded. 
+ * First off, we lookup the cast->type name to see if it is already loaded.
  * There are three cases to handle:
  *  1) If the cast->type has already been loaded AND the type we are adding
  *     casting info to has not been loaded (it is in this module), THEN we
  *     replace the cast->type pointer with the type pointer that has already
  *     been loaded.
- *  2) If BOTH types (the one we are adding casting info to, and the 
+ *  2) If BOTH types (the one we are adding casting info to, and the
  *     cast->type) are loaded, THEN the cast info has already been loaded by
  *     the previous module so we just ignore it.
  *  3) Finally, if cast->type has not already been loaded, then we add that
@@ -28355,9 +29109,7 @@ SWIGRUNTIME void
 SWIG_InitializeModule(void *clientdata) {
   size_t i;
   swig_module_info *module_head, *iter;
-  int found;
-  
-  clientdata = clientdata;
+  int found, init;
   
   /* check to see if the circular list has been setup, if not, set it up */
   if (swig_module.next==0) {
@@ -28365,6 +29117,9 @@ SWIG_InitializeModule(void *clientdata) {
     swig_module.type_initial = swig_type_initial;
     swig_module.cast_initial = swig_cast_initial;
     swig_module.next = &swig_module;
+    init = 1;
+  } else {
+    init = 0;
   }
   
   /* Try and load any already created modules */
@@ -28393,6 +29148,12 @@ SWIG_InitializeModule(void *clientdata) {
     module_head->next = &swig_module;
   }
   
+  /* When multiple interpreters are used, a module could have already been initialized in
+       a different interpreter, but not yet have a pointer in this interpreter.
+       In this case, we do not want to continue adding types... everything should be
+       set up already */
+  if (init == 0) return;
+  
   /* Now work on filling in swig_module.types */
 #ifdef SWIGRUNTIME_DEBUG
   printf("SWIG_InitializeModule: size %d\n", swig_module.size);
@@ -28555,26 +29316,58 @@ extern "C" {
   
   SWIGINTERN PyObject *
   swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+#if PY_VERSION_HEX >= 0x03000000
+    return PyUnicode_InternFromString("<Swig global variables>");
+#else
     return PyString_FromString("<Swig global variables>");
+#endif
   }
   
   SWIGINTERN PyObject *
   swig_varlink_str(swig_varlinkobject *v) {
+#if PY_VERSION_HEX >= 0x03000000
+    PyObject *str = PyUnicode_InternFromString("(");
+    PyObject *tail;
+    PyObject *joined;
+    swig_globalvar *var;
+    for (var = v->vars; var; var=var->next) {
+      tail = PyUnicode_FromString(var->name);
+      joined = PyUnicode_Concat(str, tail);
+      Py_DecRef(str);
+      Py_DecRef(tail);
+      str = joined;
+      if (var->next) {
+        tail = PyUnicode_InternFromString(", ");
+        joined = PyUnicode_Concat(str, tail);
+        Py_DecRef(str);
+        Py_DecRef(tail);
+        str = joined;
+      }
+    }
+    tail = PyUnicode_InternFromString(")");
+    joined = PyUnicode_Concat(str, tail);
+    Py_DecRef(str);
+    Py_DecRef(tail);
+    str = joined;
+#else
     PyObject *str = PyString_FromString("(");
-    swig_globalvar  *var;
+    swig_globalvar *var;
     for (var = v->vars; var; var=var->next) {
       PyString_ConcatAndDel(&str,PyString_FromString(var->name));
       if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
     }
     PyString_ConcatAndDel(&str,PyString_FromString(")"));
+#endif
     return str;
   }
   
   SWIGINTERN int
   swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+    char *tmp;
     PyObject *str = swig_varlink_str(v);
     fprintf(fp,"Swig global variables ");
-    fprintf(fp,"%s\n", PyString_AsString(str));
+    fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
+    SWIG_Python_str_DelForPy3(tmp);
     Py_DECREF(str);
     return 0;
   }
@@ -28602,7 +29395,7 @@ extern "C" {
       var = var->next;
     }
     if (res == NULL && !PyErr_Occurred()) {
-      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+      PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
     }
     return res;
   }
@@ -28619,7 +29412,7 @@ extern "C" {
       var = var->next;
     }
     if (res == 1 && !PyErr_Occurred()) {
-      PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+      PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
     }
     return res;
   }
@@ -28628,19 +29421,23 @@ extern "C" {
   swig_varlink_type(void) {
     static char varlink__doc__[] = "Swig var link object";
     static PyTypeObject varlink_type;
-    static int type_init = 0;  
+    static int type_init = 0;
     if (!type_init) {
-      const PyTypeObject tmp
-      = {
+      const PyTypeObject tmp = {
+        /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+        PyVarObject_HEAD_INIT(NULL, 0)
+#else
         PyObject_HEAD_INIT(NULL)
-        0,                                  /* Number of items in variable part (ob_size) */
-        (char *)"swigvarlink",              /* Type name (tp_name) */
-        sizeof(swig_varlinkobject),         /* Basic size (tp_basicsize) */
-        0,                                  /* Itemsize (tp_itemsize) */
-        (destructor) swig_varlink_dealloc,   /* Deallocator (tp_dealloc) */ 
-        (printfunc) swig_varlink_print,     /* Print (tp_print) */
-        (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
-        (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
+        0,                                  /* ob_size */
+#endif
+        (char *)"swigvarlink",              /* tp_name */
+        sizeof(swig_varlinkobject),         /* tp_basicsize */
+        0,                                  /* tp_itemsize */
+        (destructor) swig_varlink_dealloc,  /* tp_dealloc */
+        (printfunc) swig_varlink_print,     /* tp_print */
+        (getattrfunc) swig_varlink_getattr, /* tp_getattr */
+        (setattrfunc) swig_varlink_setattr, /* tp_setattr */
         0,                                  /* tp_compare */
         (reprfunc) swig_varlink_repr,       /* tp_repr */
         0,                                  /* tp_as_number */
@@ -28648,7 +29445,7 @@ extern "C" {
         0,                                  /* tp_as_mapping */
         0,                                  /* tp_hash */
         0,                                  /* tp_call */
-        (reprfunc)swig_varlink_str,        /* tp_str */
+        (reprfunc) swig_varlink_str,        /* tp_str */
         0,                                  /* tp_getattro */
         0,                                  /* tp_setattro */
         0,                                  /* tp_as_buffer */
@@ -28664,13 +29461,21 @@ extern "C" {
 #if PY_VERSION_HEX >= 0x02030000
         0,                                  /* tp_del */
 #endif
+#if PY_VERSION_HEX >= 0x02060000
+        0,                                  /* tp_version */
+#endif
 #ifdef COUNT_ALLOCS
         0,0,0,0                             /* tp_alloc -> tp_next */
 #endif
       };
       varlink_type = tmp;
-      varlink_type.ob_type = &PyType_Type;
       type_init = 1;
+#if PY_VERSION_HEX < 0x02020000
+      varlink_type.ob_type = &PyType_Type;
+#else
+      if (PyType_Ready(&varlink_type) < 0)
+      return NULL;
+#endif
     }
     return &varlink_type;
   }
@@ -28721,7 +29526,7 @@ extern "C" {
     for (i = 0; constants[i].type; ++i) {
       switch(constants[i].type) {
       case SWIG_PY_POINTER:
-        obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
+        obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
         break;
       case SWIG_PY_BINARY:
         obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
@@ -28761,15 +29566,15 @@ extern "C" {
           }
         }
         if (ci) {
-          size_t shift = (ci->ptype) - types;
-          swig_type_info *ty = types_initial[shift];
-          size_t ldoc = (c - methods[i].ml_doc);
-          size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
-          char *ndoc = (char*)malloc(ldoc + lptr + 10);
-          if (ndoc) {
-            char *buff = ndoc;
-            void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
-            if (ptr) {
+          void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+          if (ptr) {
+            size_t shift = (ci->ptype) - types;
+            swig_type_info *ty = types_initial[shift];
+            size_t ldoc = (c - methods[i].ml_doc);
+            size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+            char *ndoc = (char*)malloc(ldoc + lptr + 10);
+            if (ndoc) {
+              char *buff = ndoc;
               strncpy(buff, methods[i].ml_doc, ldoc);
               buff += ldoc;
               strncpy(buff, "swig_ptr: ", 10);
@@ -28794,19 +29599,137 @@ extern "C" {
 #ifdef __cplusplus
 extern "C"
 #endif
-SWIGEXPORT void SWIG_init(void) {
-  PyObject *m, *d;
+
+SWIGEXPORT 
+#if PY_VERSION_HEX >= 0x03000000
+PyObject*
+#else
+void
+#endif
+SWIG_init(void) {
+  PyObject *m, *d, *md;
+#if PY_VERSION_HEX >= 0x03000000
+  static struct PyModuleDef SWIG_module = {
+# if PY_VERSION_HEX >= 0x03020000
+    PyModuleDef_HEAD_INIT,
+# else
+    {
+      PyObject_HEAD_INIT(NULL)
+      NULL, /* m_init */
+      0,    /* m_index */
+      NULL, /* m_copy */
+    },
+# endif
+    (char *) SWIG_name,
+    NULL,
+    -1,
+    SwigMethods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+  };
+#endif
+  
+#if defined(SWIGPYTHON_BUILTIN)
+  static SwigPyClientData SwigPyObject_clientdata = {
+    0, 0, 0, 0, 0, 0, 0
+  };
+  static PyGetSetDef this_getset_def = {
+    (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL
+  };
+  static SwigPyGetSet thisown_getset_closure = {
+    (PyCFunction) SwigPyObject_own,
+    (PyCFunction) SwigPyObject_own
+  };
+  static PyGetSetDef thisown_getset_def = {
+    (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
+  };
+  PyObject *metatype_args;
+  PyTypeObject *builtin_pytype;
+  int builtin_base_count;
+  swig_type_info *builtin_basetype;
+  PyObject *tuple;
+  PyGetSetDescrObject *static_getset;
+  PyTypeObject *metatype;
+  SwigPyClientData *cd;
+  PyObject *public_interface, *public_symbol;
+  PyObject *this_descr;
+  PyObject *thisown_descr;
+  int i;
+  
+  (void)builtin_pytype;
+  (void)builtin_base_count;
+  (void)builtin_basetype;
+  (void)tuple;
+  (void)static_getset;
+  
+  /* metatype is used to implement static member variables. */
+  metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
+  assert(metatype_args);
+  metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
+  assert(metatype);
+  Py_DECREF(metatype_args);
+  metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
+  assert(PyType_Ready(metatype) >= 0);
+#endif
   
   /* Fix SwigMethods to carry the callback ptrs when needed */
   SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
   
+#if PY_VERSION_HEX >= 0x03000000
+  m = PyModule_Create(&SWIG_module);
+#else
   m = Py_InitModule((char *) SWIG_name, SwigMethods);
-  d = PyModule_GetDict(m);
+#endif
+  md = d = PyModule_GetDict(m);
+  (void)md;
   
   SWIG_InitializeModule(0);
-  SWIG_InstallConstants(d,swig_const_table);
   
+#ifdef SWIGPYTHON_BUILTIN
+  SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
+  assert(SwigPyObject_stype);
+  cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
+  if (!cd) {
+    SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
+    SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
+  } else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
+    PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
+# if PY_VERSION_HEX >= 0x03000000
+    return NULL;
+# else
+    return;
+# endif
+  }
+  
+  /* All objects have a 'this' attribute */
+  this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def);
+  (void)this_descr;
+  
+  /* All objects have a 'thisown' attribute */
+  thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def);
+  (void)thisown_descr;
+  
+  public_interface = PyList_New(0);
+  public_symbol = 0;
+  (void)public_symbol;
+  
+  PyDict_SetItemString(md, "__all__", public_interface);
+  Py_DECREF(public_interface);
+  for (i = 0; SwigMethods[i].ml_name != NULL; ++i)
+  SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name);
+  for (i = 0; swig_const_table[i].name != 0; ++i)
+  SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name);
+#endif
+  
+  SWIG_InstallConstants(d,swig_const_table);
   
   SWIG_Python_SetConstant(d, "CHARSIZE",SWIG_From_int(static_cast< int >(128)));
+#if PY_VERSION_HEX >= 0x03000000
+  return m;
+#else
+  return;
+#endif
 }
 
diff --git a/libcdi/interfaces/python/testObj.py b/libcdi/interfaces/python/testObj.py
index 50d0832..8155b93 100644
--- a/libcdi/interfaces/python/testObj.py
+++ b/libcdi/interfaces/python/testObj.py
@@ -4,44 +4,44 @@ ifile = "../testdata/mulval.grb"
 
 cdi = CdiObj.Cdi(ifile)
 
-print 'Stream: ',cdi.streamID,' vlistID:',cdi.vlistID,' nvars:{d}', cdi.nvars
+print('Stream: ',cdi.streamID,' vlistID:',cdi.vlistID,' nvars:{d}', cdi.nvars)
 
-print '#========== TAXES ====================================#'
+print('#========== TAXES ====================================#')
 for k in range(cdi.taxes.size()):
-  print  k,": ", cdi.taxes[k].ntsteps
+  print(k,": ", cdi.taxes[k].unitname)
 
-print '#========== GRIDS ====================================#'
+print('#========== GRIDS ====================================#')
 for k in range(cdi.grids.size()):
-  print k,": ", cdi.grids[k].size,' ', cdi.grids[k].xname,' ', cdi.grids[k].yname,' ', cdi.grids[k].ylongname 
+  print(k,": ", cdi.grids[k].size,' ', cdi.grids[k].xname,' ', cdi.grids[k].yname,' ', cdi.grids[k].ylongname) 
 
-print "#========== ZAXES ====================================#"
+print("#========== ZAXES ====================================#")
 for k in range(cdi.zaxes.size()):
-  print k,": ", cdi.zaxes[k].size,' ', cdi.zaxes[k].name,' ', cdi.zaxes[k].units
+  print(k,": ", cdi.zaxes[k].size,' ', cdi.zaxes[k].name,' ', cdi.zaxes[k].units)
 
-print "#========== VARIABLES ================================#"
+print("#========== VARIABLES ================================#")
 for k in range(cdi.variables.size()):
   v = cdi.variables[k]
-  print v.name," ",v.size, " ", v.missval
+  print(v.name," ",v.size, " ", v.missval)
 
-print "#========== VARIABLEcdi.NAMES =================================#"
+print("#========== VARIABLEcdi.NAMES =================================#")
 for k in range(cdi.variables.size()):
-  print cdi.variables[k].longname,' ',cdi.variables[k].units
+  print(cdi.variables[k].longname,' ',cdi.variables[k].units)
 
-print "#========== VAR by index ======================================#"
+print("#========== VAR by index ======================================#")
 var = cdi.variables[1]
 var.getValues()
 val = var.values
-i=0; print 'val[',i,'] = ',val[i]
-i=1; print 'val[',i,'] = ',val[i]
-i=2; print 'val[',i,'] = ',val[i]
-i=3; print 'val[',i,'] = ',val[i]
-i=4; print 'val[',i,'] = ',val[i]
-i=5; print 'val[',i,'] = ',val[i]
-print "#========= Var by name ===============================#"
+i=0; print('val[',i,'] = ',val[i])
+i=1; print('val[',i,'] = ',val[i])
+i=2; print('val[',i,'] = ',val[i])
+i=3; print('val[',i,'] = ',val[i])
+i=4; print('val[',i,'] = ',val[i])
+i=5; print('val[',i,'] = ',val[i])
+print("#========= Var by name ===============================#")
 name ="tsurf"
 newvar = cdi.var[name]
-print "name ",name," var.name: ", newvar.name, " var.grids.xsize: " , newvar.grid.xsize
-print "#========= Var by code ===============================#"
+print("name ",name," var.name: ", newvar.name, " var.grids.xsize: " , newvar.grid.xsize)
+print("#========= Var by code ===============================#")
 code = 169
 newvar = cdi.varByCode[code]
 newvar.sinfo()
diff --git a/libcdi/m4/ac_lang_program_fortran.m4 b/libcdi/m4/ac_lang_program_fortran.m4
new file mode 100644
index 0000000..566dbe2
--- /dev/null
+++ b/libcdi/m4/ac_lang_program_fortran.m4
@@ -0,0 +1,57 @@
+dnl we override the AC_LANG_PROGRAM macro here so we can portably
+dnl include a Fortran header
+dnl
+dnl it's meant to stay only as long as 2.64 is still reasonably current
+dnl the original Copyright notice is as follows:
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception, the Free Software Foundation gives unlimited
+# permission to copy, distribute and modify the configure scripts that
+# are the output of Autoconf.  You need not follow the terms of the GNU
+# General Public License when using or distributing such scripts, even
+# though portions of the text of Autoconf appear in them.  The GNU
+# General Public License (GPL) does govern all other use of the material
+# that constitutes the Autoconf program.
+#
+# Certain portions of the Autoconf source text are designed to be copied
+# (in certain cases, depending on the input) into the output of
+# Autoconf.  We call these the "data" portions.  The rest of the Autoconf
+# source text consists of comments plus executable code that decides which
+# of the data portions to output in any given case.  We call these
+# comments and executable code the "non-data" portions.  Autoconf never
+# copies any of the non-data portions into its output.
+#
+# This special exception to the GPL applies to versions of Autoconf
+# released by the Free Software Foundation.  When you make and
+# distribute a modified version of Autoconf, you may extend this special
+# exception to the GPL to apply to your modified version as well, *unless*
+# your modified version has the potential to copy into its output some
+# of the text that was the non-data portion of the version that you started
+# with.  (In other words, unless your change moves or copies text from
+# the non-data portions to the data portions.)  If your modification has
+# such potential, you must delete any notice of this special exception
+# to the GPL from your modified version.
+#
+# AC_LANG_PROGRAM(Fortran)([PROLOGUE], [BODY])
+# -----------------------------------------------
+# FIXME: can the PROLOGUE be used?
+# Yes, override AC_LANG_PROGRAM(Fortran)([PROLOGUE], [BODY]) with a version
+# that uses prologue
+m4_define([AC_LANG_PROGRAM(Fortran)],dnl
+[      program conftest
+m4_ifval([$1],[$1
+])$2
+      end])
diff --git a/libcdi/m4/acx_c_package.m4 b/libcdi/m4/acx_c_package.m4
new file mode 100644
index 0000000..4ffa169
--- /dev/null
+++ b/libcdi/m4/acx_c_package.m4
@@ -0,0 +1,66 @@
+dnl
+dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords: configure configure.ac autotools
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are  permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl Commentary:
+dnl
+dnl
+dnl
+dnl Code:
+dnl
+dnl
+dnl ACX_C_PACKAGE(PACKAGE,
+dnl    [INCLUDE], [EXTRA-INCLUDES], [EXTRA-INCLUDEFLAGS],
+dnl       [ACTION-IF_HEADER-NOT-FOUND],
+dnl    [FUNCTION], [LIB-CANDIDATES], [EXTRA-LIBS], [EXTRA-LIBFLAGS],
+dnl      [ACTION-IF-LIB-NOT-FOUND],
+dnl    [DEFAULT-ROOT])
+dnl -------------------------------------------------------------------
+dnl Check wether INCLUDE can be compiled and FUNCTION is found in
+dnl LIB-CANDIDATES. Sets PACKAGE_C_LIB and PACKAGE_C_INCLUDE variables to
+dnl necessary C compiler switches and arguments such that
+dnl inclusion/compilation succeed for program using INCLUDE or
+dnl FUNCTION respectively.
+dnl Also defines configure --with arguments for PACKAGEROOT,
+dnl PACKAGE-LIB and PACKAGE-INCLUDE.
+AC_DEFUN([ACX_C_PACKAGE],
+  [AC_LANG_PUSH([C])
+   ACX_GENERIC_PACKAGE([$1],[$2],[-I],[$3],[$4],[$5],[$6],[-L],[$7],[$8],[$9],[$10],[$11],[$12])
+   AC_LANG_POP([C])dnl
+  ])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl End:
diff --git a/libcdi/m4/acx_fortran_package.m4 b/libcdi/m4/acx_fortran_package.m4
new file mode 100644
index 0000000..aa5b316
--- /dev/null
+++ b/libcdi/m4/acx_fortran_package.m4
@@ -0,0 +1,144 @@
+dnl acx_fortran_package.m4 --- aggregate check for availability of
+dnl                            include file(s) and library routines
+dnl                            associated with a given package
+dnl
+dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords: fortran package availability check
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are  permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl Commentary:
+dnl
+dnl
+dnl
+dnl Code:
+dnl
+dnl
+dnl ACX_FORTRAN_PACKAGE(PACKAGE,
+dnl    [INCLUDE], [EXTRA-INCLUDES], [EXTRA-INCLUDEFLAGS],
+dnl       [ACTION-IF_HEADER-NOT-FOUND],
+dnl    [FUNCTION], [LIB-CANDIDATES], [EXTRA-LIBS], [EXTRA-LIBFLAGS],
+dnl      [ACTION-IF-LIB-NOT-FOUND],
+dnl    [DEFAULT-ROOT])
+dnl -------------------------------------------------------------------
+dnl Check wether INCLUDE can be compiled and FUNCTION is found in
+dnl LIB-CANDIDATES. Sets PACKAGE_LIB and PACKAGE_INCLUDE variables to
+dnl necessary Fortran compiler switches and arguments such that
+dnl inclusion/compilation succeed for program using INCLUDE or
+dnl FUNCTION respectively.
+dnl Also defines configure --with arguments for PACKAGEROOT,
+dnl PACKAGE-LIB and PACKAGE-INCLUDE.
+AC_DEFUN([ACX_FORTRAN_PACKAGE],
+  [AC_LANG_PUSH([Fortran])
+   AC_REQUIRE([AC_PROG_FPP])
+   ACX_GENERIC_PACKAGE([$1],[$2],[$FPP_INCOPT],[$3],[$4],[$5],[$6],[-L],[$7],[$8],[$9],[$10],[$11],[$12])
+   AC_LANG_POP([Fortran])dnl
+  ])
+dnl
+dnl
+dnl ACX_F90_PACKAGE: same as ACX_FORTRAN_PACKAGE but uses module
+dnl instead of header
+dnl
+dnl ACX_F90_PACKAGE(PACKAGE,
+dnl    MODULE, [EXTRA-INCLUDES], [EXTRA-INCLUDEFLAGS],
+dnl       [ACTION-IF-MODULE-NOT-FOUND],
+dnl    SUBROUTINE, [LIB-CANDIDATES], [EXTRA-LIBS], [EXTRA-LIBFLAGS],
+dnl      [ACTION-IF-LIB-NOT-FOUND],
+dnl    [DEFAULT-ROOT],[EXTRA-DECLARATION],[SUBROUTINE-ARGUMENTS])
+dnl -------------------------------------------------------------------
+
+dnl Check wether USE MODULE can be compiled and FUNCTION is found in
+dnl LIB-CANDIDATES. Sets PACKAGE_LIB and PACKAGE_MOD variables to
+dnl necessary Fortran compiler switches and arguments such that
+dnl compilation and linking succeed for programs using MODULE and
+dnl calling SUBROUTINE respectively.  Extra declaration will be
+dnl inserted between use MODULE and the subroutine call.
+dnl
+dnl Also defines configure --with arguments for PACKAGEROOT,
+dnl PACKAGE_FC_LIB and PACKAGE_FC_MOD.
+AC_DEFUN([ACX_F90_PACKAGE],
+  [AC_LANG_PUSH([Fortran])
+   AC_REQUIRE([AC_PROG_FC])
+   AC_REQUIRE([ACX_SL_FC_CHECK_MOD_PATH_FLAG])
+   AC_REQUIRE([_ASX_TR_ARG_PREPARE])
+   AC_SUBST(AS_TR_CPP([$1][root]))
+   AC_ARG_WITH(ASX_TR_ARG([$1-root]),
+     [AS_HELP_STRING([--with-]ASX_TR_ARG([$1])[-root],
+        [set directory to search for $1 headers and library, @<:@default=$11@:>@])],
+        [AS_TR_CPP([$1][root])="$AS_TR_SH([with_]ASX_TR_ARG([$1])[_root])"],
+        m4_ifval([$11], [AS_TR_CPP([$1][root])=$11]))
+   AS_VAR_SET_IF(AS_TR_CPP([$1][root]),
+     [AS_VAR_SET_IF([AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB])],,
+        [AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB])="-L$[]AS_TR_CPP([$1][root])/lib"])
+      AS_VAR_SET_IF([AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD])],,
+        [AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD])="$FC_MOD_FLAG$[]AS_TR_CPP([$1][root])/include"])])
+   m4_ifval([$2],dnl
+     [AC_ARG_WITH(ASX_TR_ARG([$1-]_AC_LANG_ABBREV[-mod]),
+        [AS_HELP_STRING([--with-]ASX_TR_ARG([$1-]_AC_LANG_ABBREV)[-mod],
+           [specifically set directory to search for $1 module, ]dnl
+[@<:@default=$]AS_TR_SH(ASX_TR_ARG([with_$1_root]))[/include@:>@])],
+        AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD])[="$FC_MOD_FLAG$AS_TR_SH(ASX_TR_ARG([with_$1_]_AC_LANG_ABBREV[_mod]))"],
+        [])
+      AC_ARG_VAR(AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD]),
+        [flags to enable 'USE $1' in Fortran program.])
+      ACX_FORTRAN_CHECK_MOD_PATHS_IFELSE([$2],["$[]AS_TR_CPP([$1][root])/include" "$[]AS_TR_CPP([$1][root])/lib"],
+        AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD])[=]AS_VAR_GET([acx_Mod]),
+        [$5],
+        [$3],m4_ifval([$4],[$4 ])[$[]AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD])])])
+   m4_ifval([$6],
+     [AC_ARG_WITH(ASX_TR_ARG([$1]_AC_LANG_ABBREV[-lib]),
+        [AS_HELP_STRING([--with-]ASX_TR_ARG([$1-]_AC_LANG_ABBREV)[-lib],
+        [specifically set directory to search for $1 library, ]dnl
+[@<:@default=$]AS_TR_SH(ASX_TR_ARG([with_$1_root]))[/lib@:>@])],
+        AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB])[="-L$AS_TR_SH(ASX_TR_ARG([with_$1_]_AC_LANG_ABBREV[_lib]))"],
+        [])
+      AS_IF([test x$]AS_TR_SH([have_][$1_]_AC_LANG_ABBREV[_bindings])[ = xyes],
+        [AS_VAR_PUSHDEF([ac_Search], [acx_cv_option_search_$6_]_AC_LANG_ABBREV)dnl
+         AC_SUBST(AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB]))
+         acx_save_FCFLAGS="$FCFLAGS"
+         FCFLAGS="$[]AS_TR_CPP([$1_]_AC_LANG_ABBREV[_MOD]) $FCFLAGS"
+         ACX_OPTION_SEARCH_LIBS_MULTI([$6],[$7],,dnl
+           [$10],[$8],m4_ifval([$9],[$9 ])$[]AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB]),
+           [      use $2]m4_ifval([$12],[[
+      $12]]),[      call $6$13])
+         FCFLAGS="$acx_save_FCFLAGS"
+         AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB])="AS_VAR_GET([ac_Search])"
+         AS_VAR_POPDEF([ac_Search])])])
+   AC_LANG_POP([Fortran])dnl
+  ])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/libcdi/m4/acx_sl_fc_mod_path_flag.m4 b/libcdi/m4/acx_lang_c_check_include.m4
similarity index 51%
copy from libcdi/m4/acx_sl_fc_mod_path_flag.m4
copy to libcdi/m4/acx_lang_c_check_include.m4
index 022255b..8c04bfc 100644
--- a/libcdi/m4/acx_sl_fc_mod_path_flag.m4
+++ b/libcdi/m4/acx_lang_c_check_include.m4
@@ -1,9 +1,11 @@
-dnl acx_sl_fc_mod_path_flag.m4 --- find flag to use module from other directory
+dnl acx_lang_c_check_include.m4 --- Check wether an include succeeds
+dnl                                 given one from a collection of
+dnl                                 include paths.
 dnl
 dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
 dnl
 dnl Version: 1.0
-dnl Keywords:
+dnl Keywords: c header check -I path
 dnl Author: Thomas Jahns <jahns at dkrz.de>
 dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
 dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
@@ -41,53 +43,17 @@ dnl
 dnl
 dnl Code:
 dnl
-# ACX_SL_FC_MOD_PATH_FLAG([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-# -------------------------
-# Check which flag is necessary to alter the compiler's search path
-# for module files.
-# This obviously requires that the compiler has some notion of
-# module files as separate from object files and some sensible
-# method of altering its search path. This will therefore not work
-# on early Cray F90 compilers, or on v5 (and 6?) of ifc.
+# ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE(C)(HEADER-FILE, PATH...
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES], [INCLUDE-FLAGS], [EXTRA-INCLUDE-FLAG-SETS])
+# ------------------------------------------------------------------
+# Check the compiler accepts HEADER-FILE. The INCLUDES might be defaulted.
+AC_DEFUN([ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE(C)],dnl
+  [ACX_GENERIC_CHECK_INCLUDE_PATHS_IFELSE(CPPFLAGS,-I,$@)])
 #
-# Nearly every compiler I have found uses -Ipath for this purpose;
-# Sun F95 v7.1 (at least), uses -Mpath
-#
-AC_DEFUN([ACX_SL_FC_CHECK_MOD_PATH_FLAG],dnl
-  [ACX_ASSERT_LANG_IS_FORTRAN_VARIANT
-   AC_REQUIRE([AC_PROG_FC])
-   AS_VAR_PUSHDEF([mod_flag],[acx_sl_cv_fc_mod_path_flag_]_AC_LANG_ABBREV)dnl
-   ASX_VAR_UNSET([mod_flag])
-   AC_CACHE_CHECK([for flag to alter module search path],[mod_flag],
-     [mkdir conftestdir
-      cd conftestdir
-      AC_COMPILE_IFELSE([AC_LANG_SOURCE([      module cnftst
-       implicit none
-       integer :: i
-      end module cnftst])],,
-        [AC_MSG_ERROR([Cannot compile fortran modules])])
-      cd ..
-      for i in -I -M -module -p; do
-        FCFLAGS_save=$FCFLAGS
-        FCFLAGS="$FCFLAGS ${i}conftestdir"
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[dnl
-       use cnftst
-       implicit none
-       i = 0
-])
-             ],[AS_VAR_SET([mod_flag],[$i]) ; FCFLAGS=$FCFLAGS_save ; break],
-             [:])
-        FCFLAGS=$FCFLAGS_save
-      done
-      FCFLAGS=$FCFLAGS_save
-      rm -rf conftestdir
-      AS_VAR_SET_IF([mod_flag],dnl
-        [m4_default([$1],[:])],dnl
-        [m4_default([$2],[AC_MSG_ERROR([Cannot find flag to alter module search path])])])])
-   FC_MOD_FLAG=AS_VAR_GET([mod_flag])
-   AC_SUBST([FC_MOD_FLAG])
-   AS_VAR_POPDEF([mod_flag])dnl
-])# ACX_SL_FC_MOD_PATH_FLAG
+m4_define([ACX_LANG_INCLUDE_PROGRAM(C)],
+  [AC_LANG_SOURCE([AC_INCLUDES_DEFAULT([$2])
+@%:@include <$1>])])
 dnl
 dnl Local Variables:
 dnl mode: autoconf
diff --git a/libcdi/m4/acx_lang_check_include.m4 b/libcdi/m4/acx_lang_check_include.m4
new file mode 100644
index 0000000..9d4832f
--- /dev/null
+++ b/libcdi/m4/acx_lang_check_include.m4
@@ -0,0 +1,123 @@
+dnl acx_lang_check_include.m4 --- generic check for package includes
+dnl
+dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords: package include check
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are  permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl Commentary:
+dnl
+dnl
+dnl
+dnl Code:
+dnl
+# ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE(HEADER-FILE, PATH...
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES], [INCLUDE-FLAGS])
+# ------------------------------------------------------------------
+# Check wether the compiler accepts HEADER-FILE.
+# The INCLUDES might be defaulted.
+AC_DEFUN([ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE],dnl
+  [_AC_LANG_DISPATCH([$0],_AC_LANG,$@)])
+
+# ACX_LANG_INCLUDE_PROGRAM(HEADER-FILE,[PRELUDE])
+AC_DEFUN([ACX_LANG_INCLUDE_PROGRAM],
+  [_AC_LANG_DISPATCH([$0],_AC_LANG,$@)])
+
+# AC_LANG_CHECK_INCLUDE_IFELSE(HEADER-FILE,
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES])
+# ------------------------------------------------------------------
+# Check the compiler accepts HEADER-FILE. The INCLUDES might be defaulted.
+AC_DEFUN([_ACX_LANG_CHECK_INCLUDE_IFELSE],
+  [AC_COMPILE_IFELSE([ACX_LANG_INCLUDE_PROGRAM([$1],[$4])],
+     [AS_VAR_SET([acx_Include], [yes])])
+   AS_VAR_SET_IF([acx_Include],[$2],[$3])dnl
+])# AC_LANG_CHECK_INCLUDE_IFELSE
+
+# ACX_LANG_CHECK_INCLUDE_IFELSE(HEADER-FILE,
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES])
+# ------------------------------------------------------------------
+# Check the compiler accepts HEADER-FILE. The INCLUDES might be defaulted.
+AC_DEFUN([ACX_LANG_CHECK_INCLUDE_IFELSE],
+  [AS_VAR_PUSHDEF([acx_Include], [acx_cv_]_AC_LANG_ABBREV[_include_$1])dnl
+   AC_CACHE_CHECK([for $1],[acx_Include],dnl
+     [_ACX_LANG_CHECK_INCLUDE_IFELSE([$1],[$2],[$3],[$4])])
+   AS_VAR_POPDEF([acx_Include])])
+
+# ACX_GENERIC_CHECK_INCLUDE_PATHS_IFELSE(FLAGSVAR, INCOPT, HEADER-FILE, PATH...
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES], [INCLUDE-FLAGS], [EXTRA-INCLUDE-FLAG-SETS])
+# ------------------------------------------------------------------
+# Check wether the the current language compiler accepts HEADER-FILE.
+# The INCLUDES might be defaulted.
+AC_DEFUN([ACX_GENERIC_CHECK_INCLUDE_PATHS_IFELSE],
+  [AS_VAR_PUSHDEF([acx_Include], [acx_cv_]_AC_LANG_ABBREV[_include_$3])dnl
+   AS_VAR_PUSHDEF([save_flags],[ac_include_search_$3_SAVE])
+   AC_MSG_CHECKING([for $3 extra include path])
+   AC_CACHE_VAL([acx_Include],dnl
+     [AS_VAR_SET([save_flags],["@S|@$1"])
+      while :; do
+        m4_foreach([ACX_IncSet],[$9],
+          [for ac_incdir in ''m4_ifval([$4],[ $4]); do
+             AS_IF([test -z "$ac_incdir"],
+               [ac_res="none required"
+                $1="m4_ifval(ACX_IncSet,ACX_IncSet )$8 AS_VAR_GET([save_flags])"],
+               [ac_res="$2$ac_incdir"
+                $1="m4_ifval(ACX_IncSet,ACX_IncSet )$8 $ac_res AS_VAR_GET([save_flags])"])
+             _ACX_LANG_CHECK_INCLUDE_IFELSE([$3],dnl
+               [AS_IF([test -z "$ac_incdir"],dnl
+                  [AS_VAR_SET([acx_Include],["]m4_ifval(ACX_IncSet,ACX_IncSet )$8["])],dnl
+                  [AS_VAR_SET([acx_Include],["]m4_ifval(ACX_IncSet,ACX_IncSet )[$8 $2$ac_incdir"])])],,[$7])
+             AS_VAR_SET_IF([acx_Include], [break])
+           done
+           AS_VAR_SET_IF([acx_Include], [break])
+          ])
+        break
+      done
+      AS_VAR_COPY([$1],[save_flags])])
+   AS_VAR_SET_IF([acx_Include],
+     [acx_temp=]AS_VAR_GET([acx_Include])[
+      AS_IF([test x"$acx_temp" = x],
+        [AC_MSG_RESULT([(none required)])],
+        [AC_MSG_RESULT([$acx_temp])])],
+     [AC_MSG_RESULT([not found])])
+   AS_VAR_SET_IF([acx_Include], [$5], [$6])
+   AS_VAR_POPDEF([acx_Include])])dnl
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/libcdi/m4/acx_sl_fc_mod_path_flag.m4 b/libcdi/m4/acx_lang_fortran_check_include.m4
similarity index 51%
copy from libcdi/m4/acx_sl_fc_mod_path_flag.m4
copy to libcdi/m4/acx_lang_fortran_check_include.m4
index 022255b..f522555 100644
--- a/libcdi/m4/acx_sl_fc_mod_path_flag.m4
+++ b/libcdi/m4/acx_lang_fortran_check_include.m4
@@ -1,4 +1,5 @@
-dnl acx_sl_fc_mod_path_flag.m4 --- find flag to use module from other directory
+dnl acx_lang_fortran_check_include.m4 --- check for fortran include files
+dnl                                       given a collection of paths
 dnl
 dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
 dnl
@@ -41,53 +42,22 @@ dnl
 dnl
 dnl Code:
 dnl
-# ACX_SL_FC_MOD_PATH_FLAG([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-# -------------------------
-# Check which flag is necessary to alter the compiler's search path
-# for module files.
-# This obviously requires that the compiler has some notion of
-# module files as separate from object files and some sensible
-# method of altering its search path. This will therefore not work
-# on early Cray F90 compilers, or on v5 (and 6?) of ifc.
-#
-# Nearly every compiler I have found uses -Ipath for this purpose;
-# Sun F95 v7.1 (at least), uses -Mpath
-#
-AC_DEFUN([ACX_SL_FC_CHECK_MOD_PATH_FLAG],dnl
-  [ACX_ASSERT_LANG_IS_FORTRAN_VARIANT
-   AC_REQUIRE([AC_PROG_FC])
-   AS_VAR_PUSHDEF([mod_flag],[acx_sl_cv_fc_mod_path_flag_]_AC_LANG_ABBREV)dnl
-   ASX_VAR_UNSET([mod_flag])
-   AC_CACHE_CHECK([for flag to alter module search path],[mod_flag],
-     [mkdir conftestdir
-      cd conftestdir
-      AC_COMPILE_IFELSE([AC_LANG_SOURCE([      module cnftst
-       implicit none
-       integer :: i
-      end module cnftst])],,
-        [AC_MSG_ERROR([Cannot compile fortran modules])])
-      cd ..
-      for i in -I -M -module -p; do
-        FCFLAGS_save=$FCFLAGS
-        FCFLAGS="$FCFLAGS ${i}conftestdir"
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[dnl
-       use cnftst
-       implicit none
-       i = 0
-])
-             ],[AS_VAR_SET([mod_flag],[$i]) ; FCFLAGS=$FCFLAGS_save ; break],
-             [:])
-        FCFLAGS=$FCFLAGS_save
-      done
-      FCFLAGS=$FCFLAGS_save
-      rm -rf conftestdir
-      AS_VAR_SET_IF([mod_flag],dnl
-        [m4_default([$1],[:])],dnl
-        [m4_default([$2],[AC_MSG_ERROR([Cannot find flag to alter module search path])])])])
-   FC_MOD_FLAG=AS_VAR_GET([mod_flag])
-   AC_SUBST([FC_MOD_FLAG])
-   AS_VAR_POPDEF([mod_flag])dnl
-])# ACX_SL_FC_MOD_PATH_FLAG
+# ACX_FORTRAN_CHECK_INCLUDE_PATHS_IFELSE(HEADER-FILE, PATH...
+#   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+#   [INCLUDES], [INCLUDE-FLAGS])
+# ------------------------------------------------------------------
+# Check the compiler accepts HEADER-FILE. The INCLUDES might be defaulted.
+AC_DEFUN([ACX_FORTRAN_CHECK_INCLUDE_PATHS_IFELSE],
+  [AC_LANG_PUSH([Fortran])
+   ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE($@)
+   AC_LANG_POP([Fortran])])
+dnl /ACX_FORTRAN_CHECK_INCLUDE_PATHS_IFELSE
+dnl
+AC_DEFUN([ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE(Fortran)],dnl
+  [ACX_GENERIC_CHECK_INCLUDE_PATHS_IFELSE(FCFLAGS,$FPP_INCOPT,$@)])
+dnl
+AC_DEFUN([ACX_LANG_INCLUDE_PROGRAM(Fortran)],
+  [AC_LANG_PROGRAM([$2],[      include '$1'])])
 dnl
 dnl Local Variables:
 dnl mode: autoconf
diff --git a/libcdi/m4/acx_lang_package.m4 b/libcdi/m4/acx_lang_package.m4
new file mode 100644
index 0000000..f4c4b6b
--- /dev/null
+++ b/libcdi/m4/acx_lang_package.m4
@@ -0,0 +1,134 @@
+dnl acx_lang_package.m4 --- generic check for packaged software component
+dnl                         consisting of header and library in directories
+dnl                         that can be used by adding the flags in
+dnl                         PACKAGE_LANG_INCLUDE and PACKAGE_LANG_LIB
+dnl                         respectively to the language compiler command
+dnl
+dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords:
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are  permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl Commentary:
+dnl
+dnl
+dnl
+dnl Code:
+dnl
+dnl
+dnl ACX_GENERIC_PACKAGE(PACKAGE, [INCLUDE], INC_FLAG, [EXTRA-INCLUDES],
+dnl [EXTRA-INCLUDEFLAGS], [ACTION-IF_HEADER-NOT-FOUND], [FUNCTION],
+dnl LIBFLAG, [LIB-CANDIDATES], [EXTRA-LIBS], [EXTRA-LIBFLAGS],
+dnl [ACTION-IF-LIB-NOT-FOUND], [DEFAULT-ROOT])
+dnl -------------------------------------------------------------------
+dnl Check wether INCLUDE can be compiled and FUNCTION is found in
+dnl LIB-CANDIDATES with current language compiler. Sets PACKAGE_LANG_LIB
+dnl and PACKAGE_LANG_INCLUDE variables to necessary compiler
+dnl switches and arguments such that inclusion/compilation succeed for
+dnl program using INCLUDE or FUNCTION respectively.  Also defines
+dnl configure --with arguments for PACKAGEROOT, PACKAGE-LIB and
+dnl PACKAGE-INCLUDE.
+dnl The code sets the shell variable have_PACKAGE__AC_LANG_ABBREV_bindings
+dnl to yes if all requested tests succeeded, to no if any test failed.
+dnl The library check will not run if the header check failed.
+AC_DEFUN([ACX_GENERIC_PACKAGE],
+  [AC_REQUIRE([_ASX_TR_ARG_PREPARE])
+   AS_VAR_PUSHDEF([acx_pkg_root],[AS_TR_CPP([$1][root])])
+   AS_VAR_PUSHDEF([acx_pkg_lib],[AS_TR_CPP([$1_]_AC_LANG_ABBREV[_LIB])])
+   AS_VAR_PUSHDEF([acx_pkg_inc],[AS_TR_CPP([$1_]_AC_LANG_ABBREV[_INCLUDE])])
+   AS_VAR_PUSHDEF([acx_cv_pkg_inc],
+     [AS_TR_SH([acx_cv_]_AC_LANG_ABBREV[_include_]$2)])
+   AS_VAR_PUSHDEF([acx_pkg_bindings],
+     [AS_TR_SH([have_][$1_]_AC_LANG_ABBREV[_bindings])])
+   AS_VAR_SET([acx_pkg_bindings],[yes])
+   AC_SUBST(acx_pkg_root)
+   AC_ARG_WITH(ASX_TR_ARG([$1-root]),
+     [AS_HELP_STRING([--with-]ASX_TR_ARG([$1])[-root],
+        [set directory to search for $1 headers and library]m4_ifval([$13],[, @<:@default=$13@:>@]))],
+     [AS_VAR_SET([acx_pkg_root],"$AS_TR_SH([with_]ASX_TR_ARG([$1])[_root])")],
+     m4_ifval([$13], AS_VAR_SET([acx_pkg_root],[$13])))
+   AS_VAR_SET_IF([acx_pkg_root],
+     [AS_VAR_SET_IF([acx_pkg_lib],,
+        [AS_VAR_COPY([acx_temp],acx_pkg_root)
+         AS_VAR_SET([acx_pkg_lib],["$8$acx_temp/lib"])])
+      AS_VAR_SET_IF([acx_pkg_inc],,
+        [AS_VAR_COPY([acx_temp],acx_pkg_root)
+         AS_VAR_SET([acx_pkg_inc],["$3$acx_temp/include"])])])
+   m4_ifval([$2],
+     [AC_ARG_WITH(ASX_TR_ARG([$1-include]),
+        [AS_HELP_STRING([--with-[]ASX_TR_ARG([$1])[]-include],
+           [specifically set directory to search for $1 headers, ]dnl
+[@<:@default=$]AS_TR_SH(ASX_TR_ARG([with_$1_root]))[/include@:>@])],
+        [AS_VAR_SET([acx_pkg_inc],["]$3[$]AS_TR_SH(ASX_TR_ARG([with_$1_include]))["])])
+      AC_ARG_VAR(acx_pkg_inc,dnl
+[specifically set flags to use when compiling sources
+using $1 includes.])
+      ACX_LANG_CHECK_INCLUDE_PATHS_IFELSE([$2],[],
+        [AS_VAR_COPY([acx_temp],[acx_cv_pkg_inc])
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         AS_VAR_COPY([acx_pkg_inc],[acx_temp])],
+        [AS_VAR_SET([acx_pkg_bindings],[no])
+         $6],
+        [$4],[$]acx_pkg_inc,m4_ifval([$5],[[$5]],[[[]]]))])
+   m4_ifval([$7],
+     [AC_ARG_WITH(ASX_TR_ARG([$1-lib]),
+        [AS_HELP_STRING([--with-]ASX_TR_ARG([$1])[-lib],
+        [specifically set directory to search for $1 library, ]dnl
+[@<:@default=$]AS_TR_SH(ASX_TR_ARG([with_$1_root]))[/lib@:>@])],
+        [AS_VAR_SET([acx_pkg_lib],["$8$AS_TR_SH(ASX_TR_ARG([with_$1_lib]))"])])
+      AC_ARG_VAR(acx_pkg_lib,
+        [specifically set flags to use when linking $1.])
+      AC_SUBST(acx_pkg_lib)
+      AS_VAR_IF([acx_pkg_bindings],[yes],
+        [AS_VAR_PUSHDEF([ac_Search],[acx_cv_option_search_$7_]_AC_LANG_ABBREV)dnl
+         ACX_OPTION_SEARCH_LIBS_MULTI([$7],[$9],,dnl
+           [AS_VAR_SET([acx_pkg_bindings],[no])
+            $12],[$10],m4_ifval([$11],[$11 ])$[acx_pkg_lib])
+         AS_VAR_COPY([acx_temp],[ac_Search])
+         acx_temp=`echo "$acx_temp" | sed -e 's/^ *//;s/ *$//'`
+         AS_VAR_COPY([acx_pkg_lib],[acx_temp])
+         AS_VAR_POPDEF([ac_Search])dnl
+        ])
+     ])dnl
+   AS_VAR_POPDEF([acx_pkg_bindings])
+   AS_VAR_POPDEF([acx_cv_pkg_inc])
+   AS_VAR_POPDEF([acx_pkg_inc])
+   AS_VAR_POPDEF([acx_pkg_lib])
+   AS_VAR_POPDEF([acx_pkg_root])
+ ])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/libcdi/m4/acx_option_search_libs.m4 b/libcdi/m4/acx_option_search_libs.m4
new file mode 100644
index 0000000..a00edfb
--- /dev/null
+++ b/libcdi/m4/acx_option_search_libs.m4
@@ -0,0 +1,128 @@
+dnl acx_option_search_libs.m4 --- Search for library needed only by some
+dnl                               sub-components and do not add corresponding
+dnl                               flags to LIBS but give the user control with
+dnl                               respect to how the test result is used
+dnl
+dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
+dnl
+dnl Version: 1.0
+dnl Keywords:
+dnl Author: Thomas Jahns <jahns at dkrz.de>
+dnl Maintainer: Thomas Jahns <jahns at dkrz.de>
+dnl URL: https://www.dkrz.de/redmine/projects/show/scales-ppm
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are  permitted provided that the following conditions are
+dnl met:
+dnl
+dnl Redistributions of source code must retain the above copyright notice,
+dnl this list of conditions and the following disclaimer.
+dnl
+dnl Redistributions in binary form must reproduce the above copyright
+dnl notice, this list of conditions and the following disclaimer in the
+dnl documentation and/or other materials provided with the distribution.
+dnl
+dnl Neither the name of the DKRZ GmbH nor the names of its contributors
+dnl may be used to endorse or promote products derived from this software
+dnl without specific prior written permission.
+dnl
+dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+dnl IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+dnl TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+dnl PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+dnl OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+dnl EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+dnl PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+dnl PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+dnl LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+dnl NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+dnl SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+dnl
+dnl Commentary:
+dnl
+dnl
+dnl
+dnl Code:
+dnl
+dnl _ACX_OPTION_SEARCH_LIBS(FUNCTION, SEARCH-LIBS,
+dnl   [OTHER-LIBRARIES], [EXTRA-FLAGS], [PREAMBLE], [CALL-CODE])
+dnl same as ACX_OPTION_SEARCH_LIBS but does not cache result
+dnl
+dnl Uses either AC_LANG_PROGRAM([PREAMBLE],CALL-CODE) or
+dnl AC_LANG_CALL([PREAMBLE],FUNCTION), depending on wether CALL-CODE
+dnl is given or not.
+AC_DEFUN([_ACX_OPTION_SEARCH_LIBS],
+  [acx_option_func_search_save_LIBS="$LIBS"
+   AC_LANG_CONFTEST([m4_ifval([$6],[AC_LANG_PROGRAM([$5],[$6])],[AC_LANG_CALL([$5], [$1])])])
+   for ac_lib in '' $2; do
+     AS_IF([test -z "$ac_lib"],
+       [ac_res="none required"
+        LIBS="m4_ifval([$4],[$4 ])m4_ifnblank($3,[$3 ])$acx_option_func_search_save_LIBS"],
+       [ac_res="-l$ac_lib"
+        LIBS="m4_ifval([$4],[$4 ])$ac_res m4_ifnblank($3,[$3 ])$acx_option_func_search_save_LIBS"])
+     AC_LINK_IFELSE([], [AS_IF([test x"$ac_res" = x"none required"],dnl
+        [AS_VAR_SET([ac_Search],["]m4_ifval([$4],[$4 ])[$3"])],dnl
+        [AS_VAR_SET([ac_Search],["]m4_ifval([$4],[$4 ])[-l$ac_lib $3"])])])
+     AS_VAR_SET_IF([ac_Search], [break])
+   done
+   rm conftest.$ac_ext
+   LIBS="$acx_option_func_search_save_LIBS"])
+dnl ACX_OPTION_SEARCH_LIBS(FUNCTION, SEARCH-LIBS,
+dnl   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES],
+dnl   [EXTRA-FLAGS], [PREAMBLE])
+dnl --------------------------------------------------------
+dnl Search for a library defining FUNC, if it's not already available.
+dnl Do not add said library to default LIBS output variable.
+dnl Use $ac_lib or $ac_res in ACTION if needed. Uses OTHER-LIBRARIES
+dnl unconditionally, which might provoke linker errors.
+AC_DEFUN([ACX_OPTION_SEARCH_LIBS],
+  [AS_VAR_PUSHDEF([ac_Search], [acx_cv_option_search_$1_]_AC_LANG_ABBREV)dnl
+   AC_CACHE_CHECK([for library containing $1], [ac_Search],
+     [_ACX_OPTION_SEARCH_LIBS([$1],[$2],[$5],[$6],[$7])])
+   ac_res=AS_VAR_GET([ac_Search])
+   AS_VAR_SET_IF([ac_Search],
+     [$3],
+     [$4])
+   AS_VAR_POPDEF([ac_Search])dnl
+])
+dnl ACX_OPTION_SEARCH_LIBS_MULTI(FUNCTION, SEARCH-LIBS,
+dnl   [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES],
+dnl   [EXTRA-FLAGS], [PREAMBLE], [CALL-CODE])
+dnl --------------------------------------------------------
+dnl Search for a library defining FUNC, if it's not already available.
+dnl Do not add said library to default LIBS output variable.
+dnl Use $ac_lib or $ac_res in ACTION if needed.
+dnl
+dnl If CALL-CODE is present it will be compiled to make the function
+dnl call, otherwise AC_LANG_CALL will be used with FUNCTION as
+dnl argument.
+dnl
+dnl Tries first to link without any OTHER-LIBRARY, then successively
+dnl tries each library in the list.
+AC_DEFUN([ACX_OPTION_SEARCH_LIBS_MULTI],
+  [AS_VAR_PUSHDEF([ac_Search], [acx_cv_option_search_$1_]_AC_LANG_ABBREV)dnl
+   AC_MSG_CHECKING([for library containing $1])
+   AC_CACHE_VAL([ac_Search],dnl
+     [while :; do
+        m4_if(m4_car($5),[[]],,[_ACX_OPTION_SEARCH_LIBS([$1],[$2],,[$6],[$7],[$8])
+        AS_VAR_SET_IF([ac_Search], [break])])
+        m4_foreach([ACX_LibSet], [$5],dnl
+          [_ACX_OPTION_SEARCH_LIBS([$1],[$2],[ACX_LibSet],[$6],[$7],[$8])
+           AS_VAR_SET_IF([ac_Search],[break])
+          ])
+        break
+      done])
+   AS_VAR_SET_IF([ac_Search],dnl
+     [AS_IF([test x"AS_VAR_GET([ac_Search])" = x],dnl
+        [AC_MSG_RESULT([(none required)])],dnl
+        [AC_MSG_RESULT([AS_VAR_GET([ac_Search])])])],dnl
+     [AC_MSG_RESULT([not found])])
+   AS_VAR_SET_IF([ac_Search],[$3],[$4])
+   AS_VAR_POPDEF([ac_Search])dnl
+])
+dnl
+dnl Local Variables:
+dnl mode: autoconf
+dnl license-project-url: "https://www.dkrz.de/redmine/projects/show/scales-ppm"
+dnl license-default: "bsd"
+dnl End:
diff --git a/libcdi/m4/acx_options.m4 b/libcdi/m4/acx_options.m4
index 91b3eab..fa5cbf8 100644
--- a/libcdi/m4/acx_options.m4
+++ b/libcdi/m4/acx_options.m4
@@ -314,6 +314,7 @@ AC_ARG_WITH([grib_api],
              AC_MSG_RESULT([suppressed])])
 AC_SUBST([GRIB_API_INCLUDE])
 AC_SUBST([GRIB_API_LIBS])
+AM_CONDITIONAL([HAVE_LIBGRIB_API],[test "x$with_grib_api" != 'x' -a "x$with_grib_api" != 'xno' ])
 #  ----------------------------------------------------------------------
 #  Enable GRIB support
 AC_MSG_CHECKING([for GRIB support])
diff --git a/libcdi/m4/acx_sl_fc_mod_path_flag.m4 b/libcdi/m4/acx_sl_fc_mod_path_flag.m4
index 022255b..3ac0440 100644
--- a/libcdi/m4/acx_sl_fc_mod_path_flag.m4
+++ b/libcdi/m4/acx_sl_fc_mod_path_flag.m4
@@ -61,22 +61,22 @@ AC_DEFUN([ACX_SL_FC_CHECK_MOD_PATH_FLAG],dnl
    AC_CACHE_CHECK([for flag to alter module search path],[mod_flag],
      [mkdir conftestdir
       cd conftestdir
-      AC_COMPILE_IFELSE([AC_LANG_SOURCE([      module cnftst
-       implicit none
-       integer :: i
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+[      module cnftst
+      implicit none
+      integer :: i
       end module cnftst])],,
         [AC_MSG_ERROR([Cannot compile fortran modules])])
       cd ..
       for i in -I -M -module -p; do
         FCFLAGS_save=$FCFLAGS
         FCFLAGS="$FCFLAGS ${i}conftestdir"
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[dnl
-       use cnftst
-       implicit none
-       i = 0
-])
-             ],[AS_VAR_SET([mod_flag],[$i]) ; FCFLAGS=$FCFLAGS_save ; break],
-             [:])
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
+[      use cnftst
+      implicit none
+      i = 0])],
+          [AS_VAR_SET([mod_flag],[$i]) ; FCFLAGS=$FCFLAGS_save ; break],
+          [:])
         FCFLAGS=$FCFLAGS_save
       done
       FCFLAGS=$FCFLAGS_save
diff --git a/libcdi/m4/acx_sl_mod_suffix.m4 b/libcdi/m4/acx_sl_mod_suffix.m4
index bf26daa..b92d8f5 100644
--- a/libcdi/m4/acx_sl_mod_suffix.m4
+++ b/libcdi/m4/acx_sl_mod_suffix.m4
@@ -61,12 +61,11 @@ AC_DEFUN([ACX_SL_FC_MOD_SUFFIX],
    AC_ARG_VAR([FCMODEXT], [file extension of compiled Fortran module files])
    ac_fc_mod_uppercase=no
    AC_LANG_PUSH([Fortran])
-   AC_COMPILE_IFELSE([
-      module conftest
-       implicit none
-       integer :: i
-      end module conftest
-     ])
+   AC_COMPILE_IFELSE(
+[      module conftest
+      implicit none
+      integer :: i
+      end module conftest])
    while :; do
      acx_fc_mod_name=
    m4_foreach([acx_fc_mod_name],dnl
diff --git a/libcdi/m4/acx_sl_fc_mod_path_flag.m4 b/libcdi/m4/asx_tr_arg.m4
similarity index 51%
copy from libcdi/m4/acx_sl_fc_mod_path_flag.m4
copy to libcdi/m4/asx_tr_arg.m4
index 022255b..58c27da 100644
--- a/libcdi/m4/acx_sl_fc_mod_path_flag.m4
+++ b/libcdi/m4/asx_tr_arg.m4
@@ -1,4 +1,4 @@
-dnl acx_sl_fc_mod_path_flag.m4 --- find flag to use module from other directory
+dnl asx_tr_arg.m4 --- create configure argument string for AC_ARG_* macros
 dnl
 dnl Copyright  (C)  2010  Thomas Jahns <jahns at dkrz.de>
 dnl
@@ -41,53 +41,26 @@ dnl
 dnl
 dnl Code:
 dnl
-# ACX_SL_FC_MOD_PATH_FLAG([ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-# -------------------------
-# Check which flag is necessary to alter the compiler's search path
-# for module files.
-# This obviously requires that the compiler has some notion of
-# module files as separate from object files and some sensible
-# method of altering its search path. This will therefore not work
-# on early Cray F90 compilers, or on v5 (and 6?) of ifc.
-#
-# Nearly every compiler I have found uses -Ipath for this purpose;
-# Sun F95 v7.1 (at least), uses -Mpath
-#
-AC_DEFUN([ACX_SL_FC_CHECK_MOD_PATH_FLAG],dnl
-  [ACX_ASSERT_LANG_IS_FORTRAN_VARIANT
-   AC_REQUIRE([AC_PROG_FC])
-   AS_VAR_PUSHDEF([mod_flag],[acx_sl_cv_fc_mod_path_flag_]_AC_LANG_ABBREV)dnl
-   ASX_VAR_UNSET([mod_flag])
-   AC_CACHE_CHECK([for flag to alter module search path],[mod_flag],
-     [mkdir conftestdir
-      cd conftestdir
-      AC_COMPILE_IFELSE([AC_LANG_SOURCE([      module cnftst
-       implicit none
-       integer :: i
-      end module cnftst])],,
-        [AC_MSG_ERROR([Cannot compile fortran modules])])
-      cd ..
-      for i in -I -M -module -p; do
-        FCFLAGS_save=$FCFLAGS
-        FCFLAGS="$FCFLAGS ${i}conftestdir"
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[dnl
-       use cnftst
-       implicit none
-       i = 0
+# _AS_TR_ARG_PREPARE
+# -----------------
+AC_DEFUN([_ASX_TR_ARG_PREPARE],
+[AS_REQUIRE([_AS_CR_PREPARE])dnl
+# Sed expression to map a string onto a valid argument string part.
+asx_tr_arg="eval sed 'y%*+%pp%;s%[[^-$as_cr_alnum]]%-%g'"
 ])
-             ],[AS_VAR_SET([mod_flag],[$i]) ; FCFLAGS=$FCFLAGS_save ; break],
-             [:])
-        FCFLAGS=$FCFLAGS_save
-      done
-      FCFLAGS=$FCFLAGS_save
-      rm -rf conftestdir
-      AS_VAR_SET_IF([mod_flag],dnl
-        [m4_default([$1],[:])],dnl
-        [m4_default([$2],[AC_MSG_ERROR([Cannot find flag to alter module search path])])])])
-   FC_MOD_FLAG=AS_VAR_GET([mod_flag])
-   AC_SUBST([FC_MOD_FLAG])
-   AS_VAR_POPDEF([mod_flag])dnl
-])# ACX_SL_FC_MOD_PATH_FLAG
+
+
+# AS_TR_ARG(EXPRESSION)
+# --------------------
+# Transform EXPRESSION into a nice-looking argument suffix, i.e.
+# for AC_ARG_WITH or AC_ARG_ENABLE.
+# sh/m4 polymorphic
+AC_DEFUN([ASX_TR_ARG],
+[AS_REQUIRE([_$0_PREPARE])dnl
+AS_LITERAL_IF([$1],
+	      [m4_bpatsubst(m4_translit([m4_translit([$1], [A-Z], [a-z])], [*+], [pp]),
+			    [[^a-zA-Z0-9-]], [-])],
+	      [`echo "$1" | $asx_tr_arg`])])
 dnl
 dnl Local Variables:
 dnl mode: autoconf
diff --git a/libcdi/m4/libtool.m4 b/libcdi/m4/libtool.m4
index 44e0ecf..fb7ebda 100644
--- a/libcdi/m4/libtool.m4
+++ b/libcdi/m4/libtool.m4
@@ -4817,6 +4817,8 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
 	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
 	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
diff --git a/libcdi/m4/starlink_fpp.m4 b/libcdi/m4/starlink_fpp.m4
index 423ede9..e09f132 100644
--- a/libcdi/m4/starlink_fpp.m4
+++ b/libcdi/m4/starlink_fpp.m4
@@ -108,8 +108,7 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_SIMPLE],
          [AC_LANG_PROGRAM(,[@%:@define OK
 @%:@ifndef OK
       syntax error
-@%:@endif
-])])#_ACX_SL_LANG_PROGRAM_FPP_SIMPLE
+@%:@endif])])#_ACX_SL_LANG_PROGRAM_FPP_SIMPLE
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_ONLY
@@ -123,19 +122,16 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_ONLY],
       REAL A
 @%:@else
       syntax error
-@%:@endif
-])])#_ACX_SL_LANG_PROGRAM_FPP_ONLY
+@%:@endif])])#_ACX_SL_LANG_PROGRAM_FPP_ONLY
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_D
 # ---------------------------
 # Like _ACX_SL_LANG_PROGRAM_FPP_SIMPLE, but OK is passed via -D switch
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_D],
-[AC_LANG_PROGRAM([],[
-@%:@ifndef OK
+[AC_LANG_PROGRAM([],[@%:@ifndef OK
       syntax error
-@%:@endif
-])])#_ACX_SL_LANG_PROGRAM_FPP_D
+@%:@endif])])#_ACX_SL_LANG_PROGRAM_FPP_D
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_I
@@ -143,13 +139,11 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_D],
 # Test for #include statement
 # If unsupported, this should give a type error
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_I],
-[AC_LANG_PROGRAM([],[
-      IMPLICIT CHARACTER (c)
-!     Comments in test programs should be freeform compliant just in case.
-!     conftest.inc contains the Fortran statement "REAL cc"
+  [AC_LANG_PROGRAM(,[      IMPLICIT CHARACTER (c)
+       !     Comments in test programs should be freeform compliant just in case.
+       !     conftest.inc contains the Fortran statement "REAL cc"
 @%:@include "conftest.inc"
-      cc=1.
-])])#_ACX_SL_LANG_PROGRAM_FPP_I
+      cc=1.])])#_ACX_SL_LANG_PROGRAM_FPP_I
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_SUBS
@@ -157,12 +151,10 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_I],
 # Test whether cpp symbols are expanded in Fortran code lines
 # If not, this should give a type error
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_SUBS],
-[AC_LANG_PROGRAM(,[
-@%:@define NM xxxx
+[AC_LANG_PROGRAM(,[@%:@define NM xxxx
       IMPLICIT CHARACTER (n)
       REAL xxxx
-      NM=1.
-])])#_ACX_SL_LANG_PROGRAM_FPP_SUBS
+      NM=1.])])#_ACX_SL_LANG_PROGRAM_FPP_SUBS
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_WRAP
@@ -171,39 +163,38 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_SUBS],
 # to macro substitution.
 # If not, this gives an "unterminated character constant" error
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_WRAP],
-[AC_LANG_PROGRAM(,[m4_case(_AC_LANG,[Fortran],
+  [AC_LANG_PROGRAM(,
+     [m4_case(_AC_LANG,
+        [Fortran],
 [@%:@define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
       CHARACTER(LEN=80) :: A
-      A=LONG
-],[Fortran 77],
+      A=LONG],
+        [Fortran 77],
 [@%:@define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
       CHARACTER*80 A
-      A=LONG
-],[m4_fatal([$0: current language is not Fortran: ] _AC_LANG)])])])#_ACX_SL_LANG_PROGRAM_FPP_WRAP
+      A=LONG],
+        [m4_fatal([$0: current language is not Fortran: ] _AC_LANG)])])])#_ACX_SL_LANG_PROGRAM_FPP_WRAP
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_CSTYLE
 # ---------------------------
 # Test program for C style comments
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_CSTYLE],
-[AC_LANG_PROGRAM(,[
-      A=1. /* C-style comment */
-])])#_ACX_SL_LANG_PROGRAM_FPP_CSTYLE
+[AC_LANG_PROGRAM(,[      A=1. /* C-style comment */])])#_ACX_SL_LANG_PROGRAM_FPP_CSTYLE
 
 # _ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE
 # ---------------------------
 # Test program for C++ style comments
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE],
-[AC_LANG_SOURCE([m4_case(_AC_LANG,[Fortran],dnl
+  [AC_LANG_SOURCE([m4_case(_AC_LANG,
+        [Fortran],
 [      PROGRAM MAIN
       CHARACTER(LEN=10) :: C
-      C = "abcde" // "fghij"; END PROGRAM
-],[Fortran 77],
+      C = "abcde" // "fghij"; END PROGRAM],
+        [Fortran 77],
 [      PROGRAM MAIN
       CHARACTER*10 C
-      C = "abcde" // "fghij"; END PROGRAM
-])])
-])#_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE
+      C = "abcde" // "fghij"; END PROGRAM])])])#_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE
 
 # _ACX_SL_SET_FPP_FEATURE_VARS ([feature list])
 # --------------------------------------
@@ -274,9 +265,9 @@ AC_DEFUN([_ACX_SL_TEST_FPP],
         [# we have Fortran!  See if the file can be compiled:
          mv $ac_tmp conftest.$ac_ext
          AC_COMPILE_IFELSE(, [_AC_MSG_LOG_CONFTEST
-            $3],dnl
+            $3],
            [_AC_MSG_LOG_CONFTEST
-            $4])],dnl
+            $4])],
         [mv $ac_tmp conftest.$ac_ext
          _AC_MSG_LOG_CONFTEST
          $4])])
@@ -293,19 +284,19 @@ dnl preprocessing failed. So this command doesn't work.
 # _ACX_SL_PROG_FPP([SUFFIX], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
 # ------------
 # Try to figure out how to preprocess files with the given suffix
-# just like the selected Fortran compiler does
+# for use with the selected Fortran compiler
 #
 # Must be run after _ACX_SL_PROG_FC_CPP
-AC_DEFUN([_ACX_SL_PROG_FPP],dnl
+AC_DEFUN([_ACX_SL_PROG_FPP],
   [acx_sl_fpp_srcext=m4_default([$1],[${ac_fc_srcext-F}])
-   AS_VAR_PUSHDEF([acx_sl_prog_fpp],dnl
+   AS_VAR_PUSHDEF([acx_sl_prog_fpp],
      [acx_sl_cv_prog_fpp_]_AC_LANG_ABBREV[_]m4_default([$1],[${ac_fc_srcext-f}]))
-   AC_CACHE_CHECK([how to preprocess Fortran files with suffix $acx_sl_fpp_srcext],dnl
-[acx_sl_prog_fpp],
+   AC_CACHE_CHECK([how to preprocess Fortran files with suffix $acx_sl_fpp_srcext],
+     [acx_sl_prog_fpp],
      [AS_VAR_SET([acx_sl_prog_fpp], [])
       # Let the user specify FPP
       AS_IF([test -n "$FPP"],
-        [_ACX_SL_TEST_FPP([$FPP],[$acx_sl_fpp_srcext],dnl
+        [_ACX_SL_TEST_FPP([$FPP],[$acx_sl_fpp_srcext],
            [AS_VAR_SET([acx_sl_prog_fpp], ["$FPP"])],
            [AC_MSG_WARN([user-specified \$FPP ($FPP) does not work])
             FPP=])])
@@ -314,9 +305,12 @@ AC_DEFUN([_ACX_SL_PROG_FPP],dnl
            `cd $srcdir ; pwd`/util/xlfpreproc-wrapper \
            `cd $srcdir ; pwd`/util/sunf95preproc-wrapper \
            `cd $srcdir ; pwd`/util/crayftnpreproc-wrapper \
-           "$FC -F" "$FC -F -fpp" "$FC -E" "$FC -E -cpp" \
+           "$FC -F" "$FC -F -fpp" "$FC -E" "$FC -E" "$FC -E -cpp" \
            "$FC $FCFLAGS -F" "$FC $FCFLAGS -E" "$FC $FCFLAGS -E" \
-           "$FC $FCFLAGS -E -cpp" "$FC $FCFLAGS -x f95-cpp-input -E -P"
+           "$FC $FCFLAGS -E -cpp" "$FC $FCFLAGS -x f95-cpp-input -E -P" \
+           "${F77-f77} -F" "${F77-f77} -E" 'fpp' \
+           "$CPP" "$CPP -x c" 'cpp' '/lib/cpp' \
+           '/usr/ccs/lib/cpp' 'g77 -E' '${CC-cc} -E'
          do
            _ACX_SL_TEST_FPP([$ac_fpp],[$acx_sl_fpp_srcext],[FPP="$ac_fpp"
               break])
@@ -376,9 +370,9 @@ fi
 #    [ACTION-IF-COMPILABLE],[ACTION-IF-NOT-COMPILABLE])
 # helper macro to run the preprocessor or compile directly
 # with preprocessor flags
-m4_define([_ACX_FPP_COMPILE_IFELSE],dnl
-  [m4_if([$2],[direct],dnl
-     [cp conftest.$acx_sl_fpp_srcext conftest.${ac_ext}.tmp],dnl
+m4_define([_ACX_FPP_COMPILE_IFELSE],
+  [m4_if([$2],[direct],
+     [cp conftest.$acx_sl_fpp_srcext conftest.${ac_ext}.tmp],
      [_AC_RUN_LOG([$FPP $FPPFLAGS m4_ifval([$1],[$1 ])conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp],
         [echo Running preprocessor $FPP $FPPFLAGS m4_ifval([$1],[$1 ])conftest.$acx_sl_fpp_srcext])])
@@ -406,10 +400,10 @@ m4_define([_ACX_FPP_COMPILE_IFELSE],dnl
 #
 AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
   [AS_VAR_PUSHDEF([acx_sl_fpp_ok], [acx_sl_cv_]_AC_LANG_ABBREV[_$2_ok])
-   AC_CACHE_CHECK([if ]m4_case([$2],[direct],[compilation with $FC],dnl
-[indirect],[preprocessing with $FPP],dnl
-[m4_fatal([$0: only direct or indirect method supported: ']$2['])])[ of Fortran source supports required preprocessor features],dnl
-[acx_sl_fpp_ok],dnl
+   AC_CACHE_CHECK([if ]m4_case([$2],[direct],[compilation with $FC],
+[indirect],[preprocessing with $FPP],
+[m4_fatal([$0: only direct or indirect method supported: ']$2['])])[ of Fortran source supports required preprocessor features],
+[acx_sl_fpp_ok],
      [AS_VAR_SET([acx_sl_fpp_ok], [yes])
       # Set up ac_fpp_need_* flags based on features in $1
       acx_sl_fpp_srcext=m4_default([$3],[${ac_fc_srcext-F}])
@@ -421,7 +415,7 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
       ACX_ASSERT_LANG_IS_FORTRAN_VARIANT
       ac_save_FCFLAGS=$FCFLAGS
 
-      m4_case([$2],[direct],[],[indirect],[],dnl
+      m4_case([$2],[direct],[],[indirect],[],
          [m4_fatal([$0: only direct or indirect method supported: ] $2)])
 
       # We need to skip the following tests if we're trying direct compilation
@@ -429,7 +423,7 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
       AS_IF([test x$ac_fpp_need_d = xyes],
         [acx_sl_prog_fc_cpp_d=no
          _AS_ECHO_LOG([Trying flag to create preprocessor defines.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_D])
          # Normally we expect to be able to define preprocessor macros
          # with -D, but this might be IBM xlf compiler, which needs
@@ -439,7 +433,7 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
          do
            AS_IF([test x"$FPP_DEFOPT" != x ],
              [cp conftest.${acx_sl_fpp_srcext}.bak conftest.$acx_sl_fpp_srcext
-              _ACX_FPP_COMPILE_IFELSE([${FPP_DEFOPT}OK],[$2],dnl
+              _ACX_FPP_COMPILE_IFELSE([${FPP_DEFOPT}OK],[$2],
                 [acx_sl_prog_fc_cpp_d=yes; break])])
          done
          FCFLAGS=$ac_save_FCFLAGS
@@ -455,10 +449,9 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
          _AS_ECHO_LOG([Trying flag to add directories to preprocessor search path.])
          AS_MKDIR_P([conftst])
          cd conftst
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([inc],dnl
-           [AC_LANG_SOURCE([!     This statement overrides the IMPLICIT statement in the program
-         REAL cc
-])])
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([inc],
+           [AC_LANG_SOURCE([       !     This statement overrides the IMPLICIT statement in the program
+      REAL cc])])
          cd ..
          ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],[_ACX_SL_LANG_PROGRAM_FPP_I])
          mv conftest.$acx_sl_fpp_srcext conftest.${acx_sl_fpp_srcext}.bak
@@ -466,7 +459,7 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
          do
            AS_IF([test x"$FPP_INCOPT" != x ],
              [cp conftest.${acx_sl_fpp_srcext}.bak conftest.$acx_sl_fpp_srcext
-              _ACX_FPP_COMPILE_IFELSE([${FPP_INCOPT}conftst],[$2],dnl
+              _ACX_FPP_COMPILE_IFELSE([${FPP_INCOPT}conftst],[$2],
                 [acx_sl_prog_fc_cpp_i=yes
                  break])])
          done
@@ -484,7 +477,7 @@ dnl
          _AS_ECHO_LOG([Testing preprocessor expansion in Fortran code.])
          ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_SUBS])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
            [acx_sl_prog_fc_cpp_subs=yes],[AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test successful.])],
@@ -495,9 +488,9 @@ dnl
       AS_IF([test $ac_fpp_need_wrap = yes],
         [acx_sl_prog_fc_cpp_wrap=no
          _AS_ECHO_LOG([Testing wether preprocessor wraps long lines.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_WRAP])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
            [acx_sl_prog_fc_cpp_wrap=yes], [AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test successful.])],
@@ -507,9 +500,9 @@ dnl
 dnl
       AS_IF([test $ac_fpp_need_CSTYLE = yes],
         [_AS_ECHO_LOG([Testing wether preprocessor removes C-style comments.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_CSTYLE])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
            [acx_sl_prog_fc_cpp_CSTYLE=yes], [AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test successful.])],
@@ -518,9 +511,9 @@ dnl
 dnl
       AS_IF([test $ac_fpp_need_cstyle = yes],
         [_AS_ECHO_LOG([Testing wether preprocessor leaves C-style comments in place.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_CSTYLE])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
            [acx_sl_prog_fc_cpp_CSTYLE=yes], [AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test failed.])],
@@ -529,9 +522,9 @@ dnl
 dnl
       AS_IF([test $ac_fpp_need_cxxstyle = yes],
         [_AS_ECHO_LOG([Testing if preprocessor leaves C++-style comments in place.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
            [acx_sl_prog_fc_cpp_cxxstyle=yes],[AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test successful.])],
@@ -540,10 +533,10 @@ dnl
 dnl
       AS_IF([test $ac_fpp_need_CXXSTYLE = yes],
         [_AS_ECHO_LOG([Testing if preprocessor suppresses C++-style comments.])
-         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],dnl
+         ACX_LANG_OTHER_SUFFIX_CONFTEST([$acx_sl_fpp_srcext],
            [_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE])
-         _ACX_FPP_COMPILE_IFELSE(,[$2],dnl
-           [acx_sl_prog_fc_cpp_cxxstyle=yes],dnl
+         _ACX_FPP_COMPILE_IFELSE(,[$2],
+           [acx_sl_prog_fc_cpp_cxxstyle=yes],
            [AS_VAR_SET([acx_sl_fpp_ok], [no])])
          AS_IF([test x[]AS_VAR_GET([acx_sl_fpp_ok]) = xyes],
            [_AS_ECHO_LOG([Test failed.])],
@@ -631,7 +624,7 @@ dnl AC_REQUIRE([AC_PROG_CPP([cpp])])dnl
    # ac_prog_fc_cpp_*, which we copy to cv variables afterwards.  This
    # allows this macro to be reusable for other cv variables (see
    # below)
-   ACX_SL_PROG_FC_FPP_FEATURES([$1],[indirect],[$2],,dnl
+   ACX_SL_PROG_FC_FPP_FEATURES([$1],[indirect],[$2],,
       [AC_MSG_FAILURE([required Fortran preprocessor not available])])
   ])# AC_PROG_FPP
 
@@ -661,7 +654,7 @@ AC_DEFUN([ACX_FC_INTEGRAL_FPP],
         [acx_sl_prog_fc_cpp=yes],[FC=f95
          AS_VAR_SET([acx_sl_fpp_ok], [no])])
      ])
-   ACX_SL_PROG_FC_FPP_FEATURES([$1],[indirect],[$2],,dnl
+   ACX_SL_PROG_FC_FPP_FEATURES([$1],[indirect],[$2],,
       [AC_MSG_FAILURE([required Fortran preprocessor not available])])
    ac_first_save_FPPFLAGS=$FPPFLAGS
    FPPFLAGS="$FPPFLAGS $FPPFLAGS_F"
diff --git a/libcdi/src/Makefile.am b/libcdi/src/Makefile.am
index 26fadd0..ceaa0d1 100644
--- a/libcdi/src/Makefile.am
+++ b/libcdi/src/Makefile.am
@@ -11,7 +11,7 @@ else
   noinst_LTLIBRARIES += libcdi.la
 endif
 
-AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
 
 libcdi_la_SOURCES = 	 \
 	basetime.c     	 \
@@ -39,6 +39,7 @@ libcdi_la_SOURCES = 	 \
 	cksum.h		\
 	cdi_cksum.c	\
 	cdi_cksum.h	\
+	create_uuid.h	 \
 	dtypes.h	 \
 	error.c        	 \
 	error.h	 	 \
@@ -50,10 +51,14 @@ libcdi_la_SOURCES = 	 \
 	gaussgrid.h	 \
 	gribapi.c  	 \
 	gribapi.h	 \
+	gribapi_utilities.c \
+	gribapi_utilities.h \
 	grid.c           \
 	grid.h	 	 \
 	ieg.h	 	 \
 	ieglib.c         \
+	input_file.c	\
+	input_file.h	\
 	institution.c  	 \
 	institution.h  	 \
 	model.c        	 \
@@ -62,6 +67,10 @@ libcdi_la_SOURCES = 	 \
 	namespace.h      \
 	serialize.h	\
 	serialize.c	\
+	proprietarySystemWorkarounds.c \
+	proprietarySystemWorkarounds.h \
+	referenceCounting.c \
+	referenceCounting.h \
 	resource_handle.c\
 	resource_handle.h\
 	service.h	 \
@@ -111,6 +120,16 @@ libcdi_la_SOURCES = 	 \
         stream.c         \
         swap.c
 
+if HAVE_LIBGRIB_API
+libcdi_la_SOURCES +=        \
+	iterator.c          \
+	iterator.h          \
+	iterator_fallback.c \
+	iterator_fallback.h \
+	iterator_grib.c     \
+	iterator_grib.h
+endif
+
 libcdiresunpack_la_SOURCES = \
 	resource_unpack.c
 
@@ -155,11 +174,10 @@ libcdipio_la_SOURCES =							\
 	pio_cdf_int.c							\
 	pio_cdf_int.h
 
-libcdipio_la_LIBADD    = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS)
-
+libcdipio_la_LIBADD    = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB)
 
-#libcdi_la_CPPFLAGS  = @CPPFLAGS@
-libcdi_la_LIBADD    =
+libcdi_la_LIBADD    = $(UUID_C_LIB)
+libcdi_la_CFLAGS    = -DpgiFortran
 #
 #cdilib.c:
 #	$(top_srcdir)/src/make_cdilib $(top_srcdir)/src
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 68ad6c2..e2cad83 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -80,17 +80,25 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @ENABLE_CDI_LIB_FALSE at am__append_1 = libcdi.la
- at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_2 = libcdipio.la
- at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_3 = cdipio.h cdipio.inc
- at ENABLE_CDI_LIB_FALSE@@USE_MPI_TRUE at am__append_4 = libcdipio.la
- at ENABLE_CDI_LIB_TRUE@am__append_5 = pkgconfig/cdi.pc
- at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_6 = pkgconfig/cdipio.pc
- at CREATE_ISOC_TRUE@am__append_7 = mo_cdi.$(OBJEXT)
+ at HAVE_LIBGRIB_API_TRUE@am__append_2 = \
+ at HAVE_LIBGRIB_API_TRUE@	iterator.c          \
+ at HAVE_LIBGRIB_API_TRUE@	iterator.h          \
+ at HAVE_LIBGRIB_API_TRUE@	iterator_fallback.c \
+ at HAVE_LIBGRIB_API_TRUE@	iterator_fallback.h \
+ at HAVE_LIBGRIB_API_TRUE@	iterator_grib.c     \
+ at HAVE_LIBGRIB_API_TRUE@	iterator_grib.h
+
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_3 = libcdipio.la
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_4 = cdipio.h cdipio.inc
+ at ENABLE_CDI_LIB_FALSE@@USE_MPI_TRUE at am__append_5 = libcdipio.la
+ at ENABLE_CDI_LIB_TRUE@am__append_6 = pkgconfig/cdi.pc
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_7 = pkgconfig/cdipio.pc
+ at CREATE_ISOC_TRUE@am__append_8 = mo_cdi.$(OBJEXT)
 #CLEANFILES += cdilib.c
- at CREATE_ISOC_TRUE@am__append_8 = mo_cdi.$(FCMODEXT) mo_cdi.$(OBJEXT) mo_cdi.f90
- at ENABLE_CDI_LIB_TRUE@am__append_9 = pkgconfig/cdi.pc
- at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_10 = pkgconfig/cdipio.pc
+ at CREATE_ISOC_TRUE@am__append_9 = mo_cdi.$(FCMODEXT) mo_cdi.$(OBJEXT) mo_cdi.f90
+ at ENABLE_CDI_LIB_TRUE@am__append_10 = pkgconfig/cdi.pc
 @ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_11 = pkgconfig/cdipio.pc
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_12 = pkgconfig/cdipio.pc
 subdir = src
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(srcdir)/config.h.in $(top_srcdir)/config/mkinstalldirs \
@@ -98,17 +106,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -145,29 +162,72 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
-libcdi_la_DEPENDENCIES =
-am_libcdi_la_OBJECTS = basetime.lo binary.lo calendar.lo cdf.lo \
-	cdf_int.lo cdi_error.lo cdi_util.lo cdiFortran.lo \
-	cgribexlib.lo dmemory.lo cksum.lo cdi_cksum.lo error.lo \
-	extralib.lo file.lo gaussgrid.lo gribapi.lo grid.lo ieglib.lo \
-	institution.lo model.lo namespace.lo serialize.lo \
-	resource_handle.lo servicelib.lo stream_cdf.lo \
-	stream_cgribex.lo stream_ext.lo stream_grb.lo \
-	stream_gribapi.lo stream_history.lo stream_ieg.lo \
-	stream_fcommon.lo cdi_int.lo stream_record.lo stream_srv.lo \
-	stream_var.lo table.lo taxis.lo timebase.lo tsteps.lo util.lo \
-	varscan.lo version.lo vlist.lo vlist_att.lo vlist_var.lo \
-	zaxis.lo stream.lo swap.lo
+am__DEPENDENCIES_1 =
+libcdi_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__libcdi_la_SOURCES_DIST = basetime.c basetime.h binary.c binary.h \
+	calendar.c calendar.h cdf.c cdf.h cdf_int.c cdf_int.h cdi.h \
+	cdi_error.c cdi_limits.h cdi_util.c cdiFortran.c cfortran.h \
+	cgribex.h cgribexlib.c datetime.h dmemory.c dmemory.h cksum.c \
+	cksum.h cdi_cksum.c cdi_cksum.h create_uuid.h dtypes.h error.c \
+	error.h extra.h extralib.c file.c file.h gaussgrid.c \
+	gaussgrid.h gribapi.c gribapi.h gribapi_utilities.c \
+	gribapi_utilities.h grid.c grid.h ieg.h ieglib.c input_file.c \
+	input_file.h institution.c institution.h model.c model.h \
+	namespace.c namespace.h serialize.h serialize.c \
+	proprietarySystemWorkarounds.c proprietarySystemWorkarounds.h \
+	referenceCounting.c referenceCounting.h resource_handle.c \
+	resource_handle.h service.h servicelib.c stream_cdf.c \
+	stream_cdf.h stream_cgribex.c stream_cgribex.h stream_ext.c \
+	stream_ext.h stream_grb.c stream_grb.h stream_gribapi.c \
+	stream_gribapi.h stream_history.c stream_ieg.c stream_ieg.h \
+	stream_fcommon.c stream_fcommon.h cdi_int.c cdi_int.h \
+	stream_record.c stream_srv.c stream_srv.h stream_var.c swap.h \
+	table.c table.h tablepar.h taxis.c taxis.h timebase.c \
+	timebase.h tsteps.c util.c varscan.c varscan.h version.c \
+	vlist.c vlist.h vlist_att.c vlist_att.h vlist_var.c \
+	vlist_var.h zaxis.c zaxis.h stream.c swap.c iterator.c \
+	iterator.h iterator_fallback.c iterator_fallback.h \
+	iterator_grib.c iterator_grib.h
+ at HAVE_LIBGRIB_API_TRUE@am__objects_1 = libcdi_la-iterator.lo \
+ at HAVE_LIBGRIB_API_TRUE@	libcdi_la-iterator_fallback.lo \
+ at HAVE_LIBGRIB_API_TRUE@	libcdi_la-iterator_grib.lo
+am_libcdi_la_OBJECTS = libcdi_la-basetime.lo libcdi_la-binary.lo \
+	libcdi_la-calendar.lo libcdi_la-cdf.lo libcdi_la-cdf_int.lo \
+	libcdi_la-cdi_error.lo libcdi_la-cdi_util.lo \
+	libcdi_la-cdiFortran.lo libcdi_la-cgribexlib.lo \
+	libcdi_la-dmemory.lo libcdi_la-cksum.lo libcdi_la-cdi_cksum.lo \
+	libcdi_la-error.lo libcdi_la-extralib.lo libcdi_la-file.lo \
+	libcdi_la-gaussgrid.lo libcdi_la-gribapi.lo \
+	libcdi_la-gribapi_utilities.lo libcdi_la-grid.lo \
+	libcdi_la-ieglib.lo libcdi_la-input_file.lo \
+	libcdi_la-institution.lo libcdi_la-model.lo \
+	libcdi_la-namespace.lo libcdi_la-serialize.lo \
+	libcdi_la-proprietarySystemWorkarounds.lo \
+	libcdi_la-referenceCounting.lo libcdi_la-resource_handle.lo \
+	libcdi_la-servicelib.lo libcdi_la-stream_cdf.lo \
+	libcdi_la-stream_cgribex.lo libcdi_la-stream_ext.lo \
+	libcdi_la-stream_grb.lo libcdi_la-stream_gribapi.lo \
+	libcdi_la-stream_history.lo libcdi_la-stream_ieg.lo \
+	libcdi_la-stream_fcommon.lo libcdi_la-cdi_int.lo \
+	libcdi_la-stream_record.lo libcdi_la-stream_srv.lo \
+	libcdi_la-stream_var.lo libcdi_la-table.lo libcdi_la-taxis.lo \
+	libcdi_la-timebase.lo libcdi_la-tsteps.lo libcdi_la-util.lo \
+	libcdi_la-varscan.lo libcdi_la-version.lo libcdi_la-vlist.lo \
+	libcdi_la-vlist_att.lo libcdi_la-vlist_var.lo \
+	libcdi_la-zaxis.lo libcdi_la-stream.lo libcdi_la-swap.lo \
+	$(am__objects_1)
 libcdi_la_OBJECTS = $(am_libcdi_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
+libcdi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcdi_la_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 @ENABLE_CDI_LIB_FALSE at am_libcdi_la_rpath =
 @ENABLE_CDI_LIB_TRUE at am_libcdi_la_rpath = -rpath $(libdir)
-am__DEPENDENCIES_1 =
 libcdipio_la_DEPENDENCIES = libcdi.la $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am_libcdipio_la_OBJECTS = cdipioFortran.lo pio.lo pio_comm.lo \
 	pio_dbuffer.lo pio_interface.lo pio_mpinonb.lo \
 	pio_record_send.lo pio_posixasynch.lo \
@@ -217,7 +277,7 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libcdi_la_SOURCES) $(libcdipio_la_SOURCES) \
 	$(libcdiresunpack_la_SOURCES)
-DIST_SOURCES = $(libcdi_la_SOURCES) $(libcdipio_la_SOURCES) \
+DIST_SOURCES = $(am__libcdi_la_SOURCES_DIST) $(libcdipio_la_SOURCES) \
 	$(libcdiresunpack_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -281,6 +341,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -328,6 +389,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
@@ -438,108 +504,32 @@ top_srcdir = @top_srcdir@
 #
 EXTRA_DIST = cdilib.c mo_cdi.f90
 noinst_LTLIBRARIES = libcdiresunpack.la $(am__append_1) \
-	$(am__append_4)
- at ENABLE_CDI_LIB_TRUE@lib_LTLIBRARIES = libcdi.la $(am__append_2)
- at ENABLE_CDI_LIB_TRUE@include_HEADERS = cdi.h cdi.inc $(am__append_3)
-AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
-libcdi_la_SOURCES = \
-	basetime.c     	 \
-	basetime.h	 \
-	binary.c	 \
-	binary.h	 \
-	calendar.c 	 \
-	calendar.h	 \
-	cdf.c            \
-	cdf.h	 	 \
-	cdf_int.c	 \
-	cdf_int.h	 \
-	cdi.h	 	 \
-	cdi_error.c      \
-	cdi_limits.h	 \
-	cdi_util.c       \
-	cdiFortran.c     \
-	cfortran.h       \
-	cgribex.h	 \
-	cgribexlib.c  	 \
-	datetime.h	 \
-	dmemory.c      	 \
-	dmemory.h	 \
-	cksum.c		\
-	cksum.h		\
-	cdi_cksum.c	\
-	cdi_cksum.h	\
-	dtypes.h	 \
-	error.c        	 \
-	error.h	 	 \
-	extra.h	 	 \
-	extralib.c       \
-	file.c         	 \
-	file.h	 	 \
-	gaussgrid.c      \
-	gaussgrid.h	 \
-	gribapi.c  	 \
-	gribapi.h	 \
-	grid.c           \
-	grid.h	 	 \
-	ieg.h	 	 \
-	ieglib.c         \
-	institution.c  	 \
-	institution.h  	 \
-	model.c        	 \
-	model.h        	 \
-	namespace.c      \
-	namespace.h      \
-	serialize.h	\
-	serialize.c	\
-	resource_handle.c\
-	resource_handle.h\
-	service.h	 \
-	servicelib.c     \
-	stream_cdf.c     \
-	stream_cdf.h	 \
-	stream_cgribex.c \
-	stream_cgribex.h \
-	stream_ext.c     \
-	stream_ext.h	 \
-	stream_grb.c     \
-	stream_grb.h     \
-	stream_gribapi.c \
-	stream_gribapi.h \
-	stream_history.c \
-	stream_ieg.c     \
-	stream_ieg.h	 \
-	stream_fcommon.c \
-	stream_fcommon.h \
-	cdi_int.c        \
-	cdi_int.h	 \
-	stream_record.c  \
-	stream_srv.c     \
-	stream_srv.h	 \
-	stream_var.c     \
-	swap.h	 	 \
-	table.c        	 \
-	table.h	 	 \
-	tablepar.h	 \
-	taxis.c          \
-	taxis.h	         \
-	timebase.c 	 \
-	timebase.h	 \
-	tsteps.c         \
-	util.c         	 \
-	varscan.c      	 \
-	varscan.h        \
-	version.c      	 \
-	vlist.c 	 \
-	vlist.h	         \
-	vlist_att.c 	 \
-	vlist_att.h 	 \
-	vlist_var.c 	 \
-	vlist_var.h	 \
-	zaxis.c		 \
-	zaxis.h		 \
-        stream.c         \
-        swap.c
-
+	$(am__append_5)
+ at ENABLE_CDI_LIB_TRUE@lib_LTLIBRARIES = libcdi.la $(am__append_3)
+ at ENABLE_CDI_LIB_TRUE@include_HEADERS = cdi.h cdi.inc $(am__append_4)
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
+libcdi_la_SOURCES = basetime.c basetime.h binary.c binary.h calendar.c \
+	calendar.h cdf.c cdf.h cdf_int.c cdf_int.h cdi.h cdi_error.c \
+	cdi_limits.h cdi_util.c cdiFortran.c cfortran.h cgribex.h \
+	cgribexlib.c datetime.h dmemory.c dmemory.h cksum.c cksum.h \
+	cdi_cksum.c cdi_cksum.h create_uuid.h dtypes.h error.c error.h \
+	extra.h extralib.c file.c file.h gaussgrid.c gaussgrid.h \
+	gribapi.c gribapi.h gribapi_utilities.c gribapi_utilities.h \
+	grid.c grid.h ieg.h ieglib.c input_file.c input_file.h \
+	institution.c institution.h model.c model.h namespace.c \
+	namespace.h serialize.h serialize.c \
+	proprietarySystemWorkarounds.c proprietarySystemWorkarounds.h \
+	referenceCounting.c referenceCounting.h resource_handle.c \
+	resource_handle.h service.h servicelib.c stream_cdf.c \
+	stream_cdf.h stream_cgribex.c stream_cgribex.h stream_ext.c \
+	stream_ext.h stream_grb.c stream_grb.h stream_gribapi.c \
+	stream_gribapi.h stream_history.c stream_ieg.c stream_ieg.h \
+	stream_fcommon.c stream_fcommon.h cdi_int.c cdi_int.h \
+	stream_record.c stream_srv.c stream_srv.h stream_var.c swap.h \
+	table.c table.h tablepar.h taxis.c taxis.h timebase.c \
+	timebase.h tsteps.c util.c varscan.c varscan.h version.c \
+	vlist.c vlist.h vlist_att.c vlist_att.h vlist_var.c \
+	vlist_var.h zaxis.c zaxis.h stream.c swap.c $(am__append_2)
 libcdiresunpack_la_SOURCES = \
 	resource_unpack.c
 
@@ -575,21 +565,20 @@ libcdipio_la_SOURCES = \
 	pio_cdf_int.c							\
 	pio_cdf_int.h
 
-libcdipio_la_LIBADD = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS)
-
-#libcdi_la_CPPFLAGS  = @CPPFLAGS@
-libcdi_la_LIBADD = 
+libcdipio_la_LIBADD = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS) $(MPI_C_LIB)
+libcdi_la_LIBADD = $(UUID_C_LIB)
+libcdi_la_CFLAGS = -DpgiFortran
 #
 #cdilib.c:
 #	$(top_srcdir)/src/make_cdilib $(top_srcdir)/src
 #
 #cdilib.o: cdilib.c
 #	$(COMPILE) -c $<
-LOCALTARGETS = $(am__append_5) $(am__append_6) $(am__append_7)
+LOCALTARGETS = $(am__append_6) $(am__append_7) $(am__append_8)
 #
-CLEANFILES = `ls *~` $(am__append_8) $(am__append_9) $(am__append_10)
+CLEANFILES = `ls *~` $(am__append_9) $(am__append_10) $(am__append_11)
 @ENABLE_CDI_LIB_TRUE at PKGCONFIG_FILES = pkgconfig/cdi.pc \
- at ENABLE_CDI_LIB_TRUE@	$(am__append_11)
+ at ENABLE_CDI_LIB_TRUE@	$(am__append_12)
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -688,7 +677,7 @@ clean-noinstLTLIBRARIES:
 	}
 
 libcdi.la: $(libcdi_la_OBJECTS) $(libcdi_la_DEPENDENCIES) $(EXTRA_libcdi_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(LINK) $(am_libcdi_la_rpath) $(libcdi_la_OBJECTS) $(libcdi_la_LIBADD) $(LIBS)
+	$(AM_V_CCLD)$(libcdi_la_LINK) $(am_libcdi_la_rpath) $(libcdi_la_OBJECTS) $(libcdi_la_LIBADD) $(LIBS)
 
 libcdipio.la: $(libcdipio_la_OBJECTS) $(libcdipio_la_DEPENDENCIES) $(EXTRA_libcdipio_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(LINK) $(am_libcdipio_la_rpath) $(libcdipio_la_OBJECTS) $(libcdipio_la_LIBADD) $(LIBS)
@@ -702,30 +691,64 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/basetime.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/binary.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/calendar.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdf.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdf_int.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdiFortran.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_cksum.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_error.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_int.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_util.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdipioFortran.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cgribexlib.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dmemory.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/error.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extralib.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/file.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gaussgrid.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gribapi.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/grid.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ieglib.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/institution.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/model.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/namespace.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-basetime.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-binary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-calendar.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdf_int.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdiFortran.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdi_cksum.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdi_error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdi_int.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cdi_util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cgribexlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-cksum.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-dmemory.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-extralib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-file.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-gaussgrid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-gribapi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-gribapi_utilities.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-grid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-ieglib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-input_file.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-institution.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-iterator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-iterator_fallback.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-iterator_grib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-model.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-namespace.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-proprietarySystemWorkarounds.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-referenceCounting.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-resource_handle.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-serialize.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-servicelib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_cdf.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_cgribex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_ext.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_fcommon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_grb.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_gribapi.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_history.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_ieg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_record.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_srv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-stream_var.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-swap.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-table.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-taxis.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-timebase.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-tsteps.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-varscan.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-version.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-vlist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-vlist_att.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-vlist_var.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdi_la-zaxis.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_cdf_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_client.Plo at am__quote@
@@ -741,34 +764,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_serialize.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_server.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_util.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resource_handle.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resource_unpack.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/serialize.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/servicelib.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_cdf.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_cgribex.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_ext.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_fcommon.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_grb.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_gribapi.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_history.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_ieg.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_record.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_srv.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_var.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/swap.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/table.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/taxis.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/timebase.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tsteps.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/util.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/varscan.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/version.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/vlist.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/vlist_att.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/vlist_var.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/zaxis.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -791,6 +787,405 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+libcdi_la-basetime.lo: basetime.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-basetime.lo -MD -MP -MF $(DEPDIR)/libcdi_la-basetime.Tpo -c -o libcdi_la-basetime.lo `test -f 'basetime.c' || echo '$(srcdir)/'`basetime.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-basetime.Tpo $(DEPDIR)/libcdi_la-basetime.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='basetime.c' object='libcdi_la-basetime.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-basetime.lo `test -f 'basetime.c' || echo '$(srcdir)/'`basetime.c
+
+libcdi_la-binary.lo: binary.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-binary.lo -MD -MP -MF $(DEPDIR)/libcdi_la-binary.Tpo -c -o libcdi_la-binary.lo `test -f 'binary.c' || echo '$(srcdir)/'`binary.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-binary.Tpo $(DEPDIR)/libcdi_la-binary.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='binary.c' object='libcdi_la-binary.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-binary.lo `test -f 'binary.c' || echo '$(srcdir)/'`binary.c
+
+libcdi_la-calendar.lo: calendar.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-calendar.lo -MD -MP -MF $(DEPDIR)/libcdi_la-calendar.Tpo -c -o libcdi_la-calendar.lo `test -f 'calendar.c' || echo '$(srcdir)/'`calendar.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-calendar.Tpo $(DEPDIR)/libcdi_la-calendar.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='calendar.c' object='libcdi_la-calendar.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-calendar.lo `test -f 'calendar.c' || echo '$(srcdir)/'`calendar.c
+
+libcdi_la-cdf.lo: cdf.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdf.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdf.Tpo -c -o libcdi_la-cdf.lo `test -f 'cdf.c' || echo '$(srcdir)/'`cdf.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdf.Tpo $(DEPDIR)/libcdi_la-cdf.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdf.c' object='libcdi_la-cdf.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdf.lo `test -f 'cdf.c' || echo '$(srcdir)/'`cdf.c
+
+libcdi_la-cdf_int.lo: cdf_int.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdf_int.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdf_int.Tpo -c -o libcdi_la-cdf_int.lo `test -f 'cdf_int.c' || echo '$(srcdir)/'`cdf_int.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdf_int.Tpo $(DEPDIR)/libcdi_la-cdf_int.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdf_int.c' object='libcdi_la-cdf_int.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdf_int.lo `test -f 'cdf_int.c' || echo '$(srcdir)/'`cdf_int.c
+
+libcdi_la-cdi_error.lo: cdi_error.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdi_error.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdi_error.Tpo -c -o libcdi_la-cdi_error.lo `test -f 'cdi_error.c' || echo '$(srcdir)/'`cdi_error.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdi_error.Tpo $(DEPDIR)/libcdi_la-cdi_error.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdi_error.c' object='libcdi_la-cdi_error.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdi_error.lo `test -f 'cdi_error.c' || echo '$(srcdir)/'`cdi_error.c
+
+libcdi_la-cdi_util.lo: cdi_util.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdi_util.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdi_util.Tpo -c -o libcdi_la-cdi_util.lo `test -f 'cdi_util.c' || echo '$(srcdir)/'`cdi_util.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdi_util.Tpo $(DEPDIR)/libcdi_la-cdi_util.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdi_util.c' object='libcdi_la-cdi_util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdi_util.lo `test -f 'cdi_util.c' || echo '$(srcdir)/'`cdi_util.c
+
+libcdi_la-cdiFortran.lo: cdiFortran.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdiFortran.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdiFortran.Tpo -c -o libcdi_la-cdiFortran.lo `test -f 'cdiFortran.c' || echo '$(srcdir)/'`cdiFortran.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdiFortran.Tpo $(DEPDIR)/libcdi_la-cdiFortran.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdiFortran.c' object='libcdi_la-cdiFortran.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdiFortran.lo `test -f 'cdiFortran.c' || echo '$(srcdir)/'`cdiFortran.c
+
+libcdi_la-cgribexlib.lo: cgribexlib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cgribexlib.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cgribexlib.Tpo -c -o libcdi_la-cgribexlib.lo `test -f 'cgribexlib.c' || echo '$(srcdir)/'`cgribexlib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cgribexlib.Tpo $(DEPDIR)/libcdi_la-cgribexlib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cgribexlib.c' object='libcdi_la-cgribexlib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cgribexlib.lo `test -f 'cgribexlib.c' || echo '$(srcdir)/'`cgribexlib.c
+
+libcdi_la-dmemory.lo: dmemory.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-dmemory.lo -MD -MP -MF $(DEPDIR)/libcdi_la-dmemory.Tpo -c -o libcdi_la-dmemory.lo `test -f 'dmemory.c' || echo '$(srcdir)/'`dmemory.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-dmemory.Tpo $(DEPDIR)/libcdi_la-dmemory.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='dmemory.c' object='libcdi_la-dmemory.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-dmemory.lo `test -f 'dmemory.c' || echo '$(srcdir)/'`dmemory.c
+
+libcdi_la-cksum.lo: cksum.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cksum.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cksum.Tpo -c -o libcdi_la-cksum.lo `test -f 'cksum.c' || echo '$(srcdir)/'`cksum.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cksum.Tpo $(DEPDIR)/libcdi_la-cksum.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cksum.c' object='libcdi_la-cksum.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cksum.lo `test -f 'cksum.c' || echo '$(srcdir)/'`cksum.c
+
+libcdi_la-cdi_cksum.lo: cdi_cksum.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdi_cksum.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdi_cksum.Tpo -c -o libcdi_la-cdi_cksum.lo `test -f 'cdi_cksum.c' || echo '$(srcdir)/'`cdi_cksum.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdi_cksum.Tpo $(DEPDIR)/libcdi_la-cdi_cksum.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdi_cksum.c' object='libcdi_la-cdi_cksum.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdi_cksum.lo `test -f 'cdi_cksum.c' || echo '$(srcdir)/'`cdi_cksum.c
+
+libcdi_la-error.lo: error.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-error.lo -MD -MP -MF $(DEPDIR)/libcdi_la-error.Tpo -c -o libcdi_la-error.lo `test -f 'error.c' || echo '$(srcdir)/'`error.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-error.Tpo $(DEPDIR)/libcdi_la-error.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='error.c' object='libcdi_la-error.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-error.lo `test -f 'error.c' || echo '$(srcdir)/'`error.c
+
+libcdi_la-extralib.lo: extralib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-extralib.lo -MD -MP -MF $(DEPDIR)/libcdi_la-extralib.Tpo -c -o libcdi_la-extralib.lo `test -f 'extralib.c' || echo '$(srcdir)/'`extralib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-extralib.Tpo $(DEPDIR)/libcdi_la-extralib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='extralib.c' object='libcdi_la-extralib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-extralib.lo `test -f 'extralib.c' || echo '$(srcdir)/'`extralib.c
+
+libcdi_la-file.lo: file.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-file.lo -MD -MP -MF $(DEPDIR)/libcdi_la-file.Tpo -c -o libcdi_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-file.Tpo $(DEPDIR)/libcdi_la-file.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='file.c' object='libcdi_la-file.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-file.lo `test -f 'file.c' || echo '$(srcdir)/'`file.c
+
+libcdi_la-gaussgrid.lo: gaussgrid.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-gaussgrid.lo -MD -MP -MF $(DEPDIR)/libcdi_la-gaussgrid.Tpo -c -o libcdi_la-gaussgrid.lo `test -f 'gaussgrid.c' || echo '$(srcdir)/'`gaussgrid.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-gaussgrid.Tpo $(DEPDIR)/libcdi_la-gaussgrid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gaussgrid.c' object='libcdi_la-gaussgrid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-gaussgrid.lo `test -f 'gaussgrid.c' || echo '$(srcdir)/'`gaussgrid.c
+
+libcdi_la-gribapi.lo: gribapi.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-gribapi.lo -MD -MP -MF $(DEPDIR)/libcdi_la-gribapi.Tpo -c -o libcdi_la-gribapi.lo `test -f 'gribapi.c' || echo '$(srcdir)/'`gribapi.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-gribapi.Tpo $(DEPDIR)/libcdi_la-gribapi.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gribapi.c' object='libcdi_la-gribapi.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-gribapi.lo `test -f 'gribapi.c' || echo '$(srcdir)/'`gribapi.c
+
+libcdi_la-gribapi_utilities.lo: gribapi_utilities.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-gribapi_utilities.lo -MD -MP -MF $(DEPDIR)/libcdi_la-gribapi_utilities.Tpo -c -o libcdi_la-gribapi_utilities.lo `test -f 'gribapi_utilities.c' || echo '$(srcdir)/'`gribapi_utilities.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-gribapi_utilities.Tpo $(DEPDIR)/libcdi_la-gribapi_utilities.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gribapi_utilities.c' object='libcdi_la-gribapi_utilities.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-gribapi_utilities.lo `test -f 'gribapi_utilities.c' || echo '$(srcdir)/'`gribapi_utilities.c
+
+libcdi_la-grid.lo: grid.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-grid.lo -MD -MP -MF $(DEPDIR)/libcdi_la-grid.Tpo -c -o libcdi_la-grid.lo `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-grid.Tpo $(DEPDIR)/libcdi_la-grid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid.c' object='libcdi_la-grid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-grid.lo `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
+
+libcdi_la-ieglib.lo: ieglib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-ieglib.lo -MD -MP -MF $(DEPDIR)/libcdi_la-ieglib.Tpo -c -o libcdi_la-ieglib.lo `test -f 'ieglib.c' || echo '$(srcdir)/'`ieglib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-ieglib.Tpo $(DEPDIR)/libcdi_la-ieglib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ieglib.c' object='libcdi_la-ieglib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-ieglib.lo `test -f 'ieglib.c' || echo '$(srcdir)/'`ieglib.c
+
+libcdi_la-input_file.lo: input_file.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-input_file.lo -MD -MP -MF $(DEPDIR)/libcdi_la-input_file.Tpo -c -o libcdi_la-input_file.lo `test -f 'input_file.c' || echo '$(srcdir)/'`input_file.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-input_file.Tpo $(DEPDIR)/libcdi_la-input_file.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='input_file.c' object='libcdi_la-input_file.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-input_file.lo `test -f 'input_file.c' || echo '$(srcdir)/'`input_file.c
+
+libcdi_la-institution.lo: institution.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-institution.lo -MD -MP -MF $(DEPDIR)/libcdi_la-institution.Tpo -c -o libcdi_la-institution.lo `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-institution.Tpo $(DEPDIR)/libcdi_la-institution.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='institution.c' object='libcdi_la-institution.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-institution.lo `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
+
+libcdi_la-model.lo: model.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-model.lo -MD -MP -MF $(DEPDIR)/libcdi_la-model.Tpo -c -o libcdi_la-model.lo `test -f 'model.c' || echo '$(srcdir)/'`model.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-model.Tpo $(DEPDIR)/libcdi_la-model.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='model.c' object='libcdi_la-model.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-model.lo `test -f 'model.c' || echo '$(srcdir)/'`model.c
+
+libcdi_la-namespace.lo: namespace.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-namespace.lo -MD -MP -MF $(DEPDIR)/libcdi_la-namespace.Tpo -c -o libcdi_la-namespace.lo `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-namespace.Tpo $(DEPDIR)/libcdi_la-namespace.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='namespace.c' object='libcdi_la-namespace.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-namespace.lo `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c
+
+libcdi_la-serialize.lo: serialize.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-serialize.lo -MD -MP -MF $(DEPDIR)/libcdi_la-serialize.Tpo -c -o libcdi_la-serialize.lo `test -f 'serialize.c' || echo '$(srcdir)/'`serialize.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-serialize.Tpo $(DEPDIR)/libcdi_la-serialize.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='serialize.c' object='libcdi_la-serialize.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-serialize.lo `test -f 'serialize.c' || echo '$(srcdir)/'`serialize.c
+
+libcdi_la-proprietarySystemWorkarounds.lo: proprietarySystemWorkarounds.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-proprietarySystemWorkarounds.lo -MD -MP -MF $(DEPDIR)/libcdi_la-proprietarySystemWorkarounds.Tpo -c -o libcdi_la-proprietarySystemWorkarounds.lo `test -f 'proprietarySystemWorkarounds.c' || echo '$(srcdir)/'`proprietarySystemWorkarounds.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-proprietarySystemWorkarounds.Tpo $(DEPDIR)/libcdi_la-proprietarySystemWorkarounds.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='proprietarySystemWorkarounds.c' object='libcdi_la-proprietarySystemWorkarounds.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-proprietarySystemWorkarounds.lo `test -f 'proprietarySystemWorkarounds.c' || echo '$(srcdir)/'`proprietarySystemWorkarounds.c
+
+libcdi_la-referenceCounting.lo: referenceCounting.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-referenceCounting.lo -MD -MP -MF $(DEPDIR)/libcdi_la-referenceCounting.Tpo -c -o libcdi_la-referenceCounting.lo `test -f 'referenceCounting.c' || echo '$(srcdir)/'`referenceCounting.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-referenceCounting.Tpo $(DEPDIR)/libcdi_la-referenceCounting.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='referenceCounting.c' object='libcdi_la-referenceCounting.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-referenceCounting.lo `test -f 'referenceCounting.c' || echo '$(srcdir)/'`referenceCounting.c
+
+libcdi_la-resource_handle.lo: resource_handle.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-resource_handle.lo -MD -MP -MF $(DEPDIR)/libcdi_la-resource_handle.Tpo -c -o libcdi_la-resource_handle.lo `test -f 'resource_handle.c' || echo '$(srcdir)/'`resource_handle.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-resource_handle.Tpo $(DEPDIR)/libcdi_la-resource_handle.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='resource_handle.c' object='libcdi_la-resource_handle.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-resource_handle.lo `test -f 'resource_handle.c' || echo '$(srcdir)/'`resource_handle.c
+
+libcdi_la-servicelib.lo: servicelib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-servicelib.lo -MD -MP -MF $(DEPDIR)/libcdi_la-servicelib.Tpo -c -o libcdi_la-servicelib.lo `test -f 'servicelib.c' || echo '$(srcdir)/'`servicelib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-servicelib.Tpo $(DEPDIR)/libcdi_la-servicelib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='servicelib.c' object='libcdi_la-servicelib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-servicelib.lo `test -f 'servicelib.c' || echo '$(srcdir)/'`servicelib.c
+
+libcdi_la-stream_cdf.lo: stream_cdf.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_cdf.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_cdf.Tpo -c -o libcdi_la-stream_cdf.lo `test -f 'stream_cdf.c' || echo '$(srcdir)/'`stream_cdf.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_cdf.Tpo $(DEPDIR)/libcdi_la-stream_cdf.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_cdf.c' object='libcdi_la-stream_cdf.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_cdf.lo `test -f 'stream_cdf.c' || echo '$(srcdir)/'`stream_cdf.c
+
+libcdi_la-stream_cgribex.lo: stream_cgribex.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_cgribex.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_cgribex.Tpo -c -o libcdi_la-stream_cgribex.lo `test -f 'stream_cgribex.c' || echo '$(srcdir)/'`stream_cgribex.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_cgribex.Tpo $(DEPDIR)/libcdi_la-stream_cgribex.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_cgribex.c' object='libcdi_la-stream_cgribex.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_cgribex.lo `test -f 'stream_cgribex.c' || echo '$(srcdir)/'`stream_cgribex.c
+
+libcdi_la-stream_ext.lo: stream_ext.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_ext.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_ext.Tpo -c -o libcdi_la-stream_ext.lo `test -f 'stream_ext.c' || echo '$(srcdir)/'`stream_ext.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_ext.Tpo $(DEPDIR)/libcdi_la-stream_ext.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_ext.c' object='libcdi_la-stream_ext.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_ext.lo `test -f 'stream_ext.c' || echo '$(srcdir)/'`stream_ext.c
+
+libcdi_la-stream_grb.lo: stream_grb.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_grb.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_grb.Tpo -c -o libcdi_la-stream_grb.lo `test -f 'stream_grb.c' || echo '$(srcdir)/'`stream_grb.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_grb.Tpo $(DEPDIR)/libcdi_la-stream_grb.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_grb.c' object='libcdi_la-stream_grb.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_grb.lo `test -f 'stream_grb.c' || echo '$(srcdir)/'`stream_grb.c
+
+libcdi_la-stream_gribapi.lo: stream_gribapi.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_gribapi.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_gribapi.Tpo -c -o libcdi_la-stream_gribapi.lo `test -f 'stream_gribapi.c' || echo '$(srcdir)/'`stream_gribapi.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_gribapi.Tpo $(DEPDIR)/libcdi_la-stream_gribapi.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_gribapi.c' object='libcdi_la-stream_gribapi.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_gribapi.lo `test -f 'stream_gribapi.c' || echo '$(srcdir)/'`stream_gribapi.c
+
+libcdi_la-stream_history.lo: stream_history.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_history.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_history.Tpo -c -o libcdi_la-stream_history.lo `test -f 'stream_history.c' || echo '$(srcdir)/'`stream_history.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_history.Tpo $(DEPDIR)/libcdi_la-stream_history.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_history.c' object='libcdi_la-stream_history.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_history.lo `test -f 'stream_history.c' || echo '$(srcdir)/'`stream_history.c
+
+libcdi_la-stream_ieg.lo: stream_ieg.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_ieg.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_ieg.Tpo -c -o libcdi_la-stream_ieg.lo `test -f 'stream_ieg.c' || echo '$(srcdir)/'`stream_ieg.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_ieg.Tpo $(DEPDIR)/libcdi_la-stream_ieg.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_ieg.c' object='libcdi_la-stream_ieg.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_ieg.lo `test -f 'stream_ieg.c' || echo '$(srcdir)/'`stream_ieg.c
+
+libcdi_la-stream_fcommon.lo: stream_fcommon.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_fcommon.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_fcommon.Tpo -c -o libcdi_la-stream_fcommon.lo `test -f 'stream_fcommon.c' || echo '$(srcdir)/'`stream_fcommon.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_fcommon.Tpo $(DEPDIR)/libcdi_la-stream_fcommon.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_fcommon.c' object='libcdi_la-stream_fcommon.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_fcommon.lo `test -f 'stream_fcommon.c' || echo '$(srcdir)/'`stream_fcommon.c
+
+libcdi_la-cdi_int.lo: cdi_int.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-cdi_int.lo -MD -MP -MF $(DEPDIR)/libcdi_la-cdi_int.Tpo -c -o libcdi_la-cdi_int.lo `test -f 'cdi_int.c' || echo '$(srcdir)/'`cdi_int.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-cdi_int.Tpo $(DEPDIR)/libcdi_la-cdi_int.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdi_int.c' object='libcdi_la-cdi_int.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-cdi_int.lo `test -f 'cdi_int.c' || echo '$(srcdir)/'`cdi_int.c
+
+libcdi_la-stream_record.lo: stream_record.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_record.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_record.Tpo -c -o libcdi_la-stream_record.lo `test -f 'stream_record.c' || echo '$(srcdir)/'`stream_record.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_record.Tpo $(DEPDIR)/libcdi_la-stream_record.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_record.c' object='libcdi_la-stream_record.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_record.lo `test -f 'stream_record.c' || echo '$(srcdir)/'`stream_record.c
+
+libcdi_la-stream_srv.lo: stream_srv.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_srv.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_srv.Tpo -c -o libcdi_la-stream_srv.lo `test -f 'stream_srv.c' || echo '$(srcdir)/'`stream_srv.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_srv.Tpo $(DEPDIR)/libcdi_la-stream_srv.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_srv.c' object='libcdi_la-stream_srv.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_srv.lo `test -f 'stream_srv.c' || echo '$(srcdir)/'`stream_srv.c
+
+libcdi_la-stream_var.lo: stream_var.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream_var.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream_var.Tpo -c -o libcdi_la-stream_var.lo `test -f 'stream_var.c' || echo '$(srcdir)/'`stream_var.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream_var.Tpo $(DEPDIR)/libcdi_la-stream_var.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream_var.c' object='libcdi_la-stream_var.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream_var.lo `test -f 'stream_var.c' || echo '$(srcdir)/'`stream_var.c
+
+libcdi_la-table.lo: table.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-table.lo -MD -MP -MF $(DEPDIR)/libcdi_la-table.Tpo -c -o libcdi_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-table.Tpo $(DEPDIR)/libcdi_la-table.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table.c' object='libcdi_la-table.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c
+
+libcdi_la-taxis.lo: taxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-taxis.lo -MD -MP -MF $(DEPDIR)/libcdi_la-taxis.Tpo -c -o libcdi_la-taxis.lo `test -f 'taxis.c' || echo '$(srcdir)/'`taxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-taxis.Tpo $(DEPDIR)/libcdi_la-taxis.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='taxis.c' object='libcdi_la-taxis.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-taxis.lo `test -f 'taxis.c' || echo '$(srcdir)/'`taxis.c
+
+libcdi_la-timebase.lo: timebase.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-timebase.lo -MD -MP -MF $(DEPDIR)/libcdi_la-timebase.Tpo -c -o libcdi_la-timebase.lo `test -f 'timebase.c' || echo '$(srcdir)/'`timebase.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-timebase.Tpo $(DEPDIR)/libcdi_la-timebase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='timebase.c' object='libcdi_la-timebase.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-timebase.lo `test -f 'timebase.c' || echo '$(srcdir)/'`timebase.c
+
+libcdi_la-tsteps.lo: tsteps.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-tsteps.lo -MD -MP -MF $(DEPDIR)/libcdi_la-tsteps.Tpo -c -o libcdi_la-tsteps.lo `test -f 'tsteps.c' || echo '$(srcdir)/'`tsteps.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-tsteps.Tpo $(DEPDIR)/libcdi_la-tsteps.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tsteps.c' object='libcdi_la-tsteps.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-tsteps.lo `test -f 'tsteps.c' || echo '$(srcdir)/'`tsteps.c
+
+libcdi_la-util.lo: util.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-util.lo -MD -MP -MF $(DEPDIR)/libcdi_la-util.Tpo -c -o libcdi_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-util.Tpo $(DEPDIR)/libcdi_la-util.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='util.c' object='libcdi_la-util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
+
+libcdi_la-varscan.lo: varscan.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-varscan.lo -MD -MP -MF $(DEPDIR)/libcdi_la-varscan.Tpo -c -o libcdi_la-varscan.lo `test -f 'varscan.c' || echo '$(srcdir)/'`varscan.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-varscan.Tpo $(DEPDIR)/libcdi_la-varscan.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='varscan.c' object='libcdi_la-varscan.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-varscan.lo `test -f 'varscan.c' || echo '$(srcdir)/'`varscan.c
+
+libcdi_la-version.lo: version.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-version.lo -MD -MP -MF $(DEPDIR)/libcdi_la-version.Tpo -c -o libcdi_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-version.Tpo $(DEPDIR)/libcdi_la-version.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='version.c' object='libcdi_la-version.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-version.lo `test -f 'version.c' || echo '$(srcdir)/'`version.c
+
+libcdi_la-vlist.lo: vlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-vlist.lo -MD -MP -MF $(DEPDIR)/libcdi_la-vlist.Tpo -c -o libcdi_la-vlist.lo `test -f 'vlist.c' || echo '$(srcdir)/'`vlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-vlist.Tpo $(DEPDIR)/libcdi_la-vlist.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vlist.c' object='libcdi_la-vlist.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-vlist.lo `test -f 'vlist.c' || echo '$(srcdir)/'`vlist.c
+
+libcdi_la-vlist_att.lo: vlist_att.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-vlist_att.lo -MD -MP -MF $(DEPDIR)/libcdi_la-vlist_att.Tpo -c -o libcdi_la-vlist_att.lo `test -f 'vlist_att.c' || echo '$(srcdir)/'`vlist_att.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-vlist_att.Tpo $(DEPDIR)/libcdi_la-vlist_att.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vlist_att.c' object='libcdi_la-vlist_att.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-vlist_att.lo `test -f 'vlist_att.c' || echo '$(srcdir)/'`vlist_att.c
+
+libcdi_la-vlist_var.lo: vlist_var.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-vlist_var.lo -MD -MP -MF $(DEPDIR)/libcdi_la-vlist_var.Tpo -c -o libcdi_la-vlist_var.lo `test -f 'vlist_var.c' || echo '$(srcdir)/'`vlist_var.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-vlist_var.Tpo $(DEPDIR)/libcdi_la-vlist_var.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vlist_var.c' object='libcdi_la-vlist_var.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-vlist_var.lo `test -f 'vlist_var.c' || echo '$(srcdir)/'`vlist_var.c
+
+libcdi_la-zaxis.lo: zaxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-zaxis.lo -MD -MP -MF $(DEPDIR)/libcdi_la-zaxis.Tpo -c -o libcdi_la-zaxis.lo `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-zaxis.Tpo $(DEPDIR)/libcdi_la-zaxis.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='zaxis.c' object='libcdi_la-zaxis.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-zaxis.lo `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
+
+libcdi_la-stream.lo: stream.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-stream.lo -MD -MP -MF $(DEPDIR)/libcdi_la-stream.Tpo -c -o libcdi_la-stream.lo `test -f 'stream.c' || echo '$(srcdir)/'`stream.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-stream.Tpo $(DEPDIR)/libcdi_la-stream.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stream.c' object='libcdi_la-stream.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-stream.lo `test -f 'stream.c' || echo '$(srcdir)/'`stream.c
+
+libcdi_la-swap.lo: swap.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-swap.lo -MD -MP -MF $(DEPDIR)/libcdi_la-swap.Tpo -c -o libcdi_la-swap.lo `test -f 'swap.c' || echo '$(srcdir)/'`swap.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-swap.Tpo $(DEPDIR)/libcdi_la-swap.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swap.c' object='libcdi_la-swap.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-swap.lo `test -f 'swap.c' || echo '$(srcdir)/'`swap.c
+
+libcdi_la-iterator.lo: iterator.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-iterator.lo -MD -MP -MF $(DEPDIR)/libcdi_la-iterator.Tpo -c -o libcdi_la-iterator.lo `test -f 'iterator.c' || echo '$(srcdir)/'`iterator.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-iterator.Tpo $(DEPDIR)/libcdi_la-iterator.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='iterator.c' object='libcdi_la-iterator.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-iterator.lo `test -f 'iterator.c' || echo '$(srcdir)/'`iterator.c
+
+libcdi_la-iterator_fallback.lo: iterator_fallback.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-iterator_fallback.lo -MD -MP -MF $(DEPDIR)/libcdi_la-iterator_fallback.Tpo -c -o libcdi_la-iterator_fallback.lo `test -f 'iterator_fallback.c' || echo '$(srcdir)/'`iterator_fallback.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-iterator_fallback.Tpo $(DEPDIR)/libcdi_la-iterator_fallback.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='iterator_fallback.c' object='libcdi_la-iterator_fallback.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-iterator_fallback.lo `test -f 'iterator_fallback.c' || echo '$(srcdir)/'`iterator_fallback.c
+
+libcdi_la-iterator_grib.lo: iterator_grib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -MT libcdi_la-iterator_grib.lo -MD -MP -MF $(DEPDIR)/libcdi_la-iterator_grib.Tpo -c -o libcdi_la-iterator_grib.lo `test -f 'iterator_grib.c' || echo '$(srcdir)/'`iterator_grib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdi_la-iterator_grib.Tpo $(DEPDIR)/libcdi_la-iterator_grib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='iterator_grib.c' object='libcdi_la-iterator_grib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcdi_la_CFLAGS) $(CFLAGS) -c -o libcdi_la-iterator_grib.lo `test -f 'iterator_grib.c' || echo '$(srcdir)/'`iterator_grib.c
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/libcdi/src/cdf.c b/libcdi/src/cdf.c
index edf6763..6832576 100644
--- a/libcdi/src/cdf.c
+++ b/libcdi/src/cdf.c
@@ -79,7 +79,7 @@ void cdfComment(int ncid)
 	strcat(comment, "??");
       else
 	strncat(comment, libvers, size);
-      strcat(comment, " (https://code.zmaw.de/projects/cdi)");
+      strcat(comment, " (http://mpimet.mpg.de/cdi)");
     }
 
   cdf_put_att_text(ncid, NC_GLOBAL, "CDI", strlen(comment), comment);
diff --git a/libcdi/src/cdf_int.c b/libcdi/src/cdf_int.c
index 714c95e..58d3d25 100644
--- a/libcdi/src/cdf_int.c
+++ b/libcdi/src/cdf_int.c
@@ -701,8 +701,7 @@ void cdf_put_att_text(int ncid, int varid, const char *name, size_t len,
   status = nc_put_att_text(ncid, varid, name, len, tp);
 
   if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s text = %s",
-	    ncid, varid, name, tp);
+    Message("ncid = %d varid = %d att = %s text = %.*s", ncid, varid, name, (int)len, tp);
 
   if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
diff --git a/libcdi/src/cdf_int.h b/libcdi/src/cdf_int.h
index 59ef922..759d447 100644
--- a/libcdi/src/cdf_int.h
+++ b/libcdi/src/cdf_int.h
@@ -4,7 +4,7 @@
 #if  defined  (HAVE_LIBNETCDF)
 
 #include <stdlib.h>
-#include "netcdf.h"
+#include <netcdf.h>
 
 void cdf_create (const char *path, int cmode, int *idp);
 int  cdf_open   (const char *path, int omode, int *idp);
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 5e64a05..8b1dc0e 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -31,6 +31,7 @@ extern "C" {
 /* Error identifier */
 
 #define	 CDI_NOERR        	  0   /* No Error                             */
+#define  CDI_EEOF                -1   /* The end of file was encountered      */
 #define  CDI_ESYSTEM            -10   /* Operating system error               */
 #define  CDI_EINVAL             -20   /* Invalid argument                     */
 #define  CDI_EUFTYPE            -21   /* Unsupported file type                */
@@ -222,6 +223,15 @@ extern "C" {
 /* number of unsigned char needed to store UUID */
 #define  CDI_UUID_SIZE           16
 
+/* Structs that are used to return data to the user */
+
+typedef struct CdiParam { int discipline; int category; int number; } CdiParam;
+
+
+/* Opaque types */
+typedef struct CdiIterator CdiIterator;
+typedef struct CdiGribIterator CdiGribIterator;
+
 /* CDI control routines */
 
 void    cdiReset(void);
@@ -319,8 +329,9 @@ int     streamInqTimestep(int streamID, int tsID);
 /*      PIO: query currently set timestep id  */
 int     streamInqCurTimestepID(int streamID);
 
-char   *streamFilename(int streamID);
-char   *streamFilesuffix(int filetype);
+const char* streamFilename(int streamID);
+const char* streamFilesuffix(int filetype);
+
 off_t   streamNvals(int streamID);
 
 int     streamInqNvars ( int streamID );
@@ -343,8 +354,7 @@ void    streamWriteVarSliceF(int streamID, int varID, int levelID, const float *
 void    streamReadVarSlice(int streamID, int varID, int levelID, double *data_vec, int *nmiss);
 void    streamReadVarSliceF(int streamID, int varID, int levelID, float *data_vec, int *nmiss);
 
-void    streamWriteVarChunk(int streamID, int varID, const int rect[][2],
-                            const double *data_vec, int nmiss);
+void    streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double *data_vec, int nmiss);
 
 
 /* STREAM record I/O routines */
@@ -358,6 +368,61 @@ void    streamCopyRecord(int streamIDdest, int streamIDsrc);
 
 void    streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
 
+
+/* File driven I/O (may yield better performance than using the streamXXX functions) */
+
+//Creation & Destruction
+CdiIterator* cdiIterator_new(const char* path);  //Requires a subsequent call to cdiIteratorNextField() to point the iterator at the first field.
+CdiIterator* cdiIterator_clone(CdiIterator* me);
+char* cdiIterator_serialize(CdiIterator* me);  //Returns a malloc'ed string.
+CdiIterator* cdiIterator_deserialize(const char* description);  //description is a string that was returned by cdiIteratorSerialize(). Returns a copy of the original iterator.
+void cdiIterator_print(CdiIterator* me, FILE* stream);
+void cdiIterator_delete(CdiIterator* me);
+
+//Advancing an iterator
+int cdiIterator_nextField(CdiIterator* me);      //Points the iterator at the next field, returns CDI_EEOF if there are no more fields in the file.
+
+//Introspecting metadata
+//All outXXX arguments to these functions may be NULL.
+char* cdiIterator_inqStartTime(CdiIterator* me);      //Returns the (start) time as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+char* cdiIterator_inqEndTime(CdiIterator* me);      //Returns the end time of an integration period as an ISO-8601 coded string, or NULL if there is no end time. The caller is responsible to free() the returned string.
+char* cdiIterator_inqVTime(CdiIterator* me);      //Returns the validity date as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);      //callers are responsible to free() strings that they request
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);       //outValue2 is only written to if the level is a hybrid level
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[CDI_UUID_SIZE]);   //outUuid must point to a buffer of 16 bytes, returns an error code if no generalized zaxis is used.
+CdiParam cdiIterator_inqParam(CdiIterator* me);
+int cdiIterator_inqDatatype(CdiIterator* me);
+int cdiIterator_inqTsteptype(CdiIterator* me);
+char* cdiIterator_inqVariableName(CdiIterator* me);        //The caller is responsible to free() the returned buffer.
+int cdiIterator_inqGridId(CdiIterator* me);         //The returned id is only valid until the next call to cdiIteratorNextField().
+
+//Reading data
+void cdiIterator_readField(CdiIterator* me, double* data_vec, size_t* nmiss);
+void cdiIterator_readFieldF(CdiIterator* me, float* data_vec, size_t* nmiss);
+//TODO[NH]: Add functions to read partial fields.
+
+
+//Direct access to grib fields
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me);  //Returns NULL if the associated file is not a GRIB file.
+void cdiGribIterator_delete(CdiGribIterator* me);
+
+//Callthroughs to GRIB-API
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* value); //Same semantics as grib_get_long().
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* value); //Same semantics as grib_get_double().
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_length().
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* value, size_t* length);       //Same semantics as grib_get_string().
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_size().
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* value, size_t* array_size);       //Same semantics as grib_get_long_array().
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* value, size_t* array_size);       //Same semantics as grib_get_double_array().
+
+//Convenience functions for accessing GRIB-API keys
+int cdiGribIterator_inqEdition(CdiGribIterator* me);
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue); //Returns the default value if the given key is not present.
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue); //Returns the default value if the given key is not present.
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key);        //Returns a malloc'ed string.
+
 /* VLIST routines */
 
 /*      vlistCreate: Create a variable list */
@@ -486,6 +551,9 @@ void    vlistDefVarName(int vlistID, int varID, const char *name);
 /*      vlistInqVarName: Get the name of a Variable */
 void    vlistInqVarName(int vlistID, int varID, char *name);
 
+/*      vlistCopyVarName: Safe and convenient version of vlistInqVarName */
+char* vlistCopyVarName(int vlistId, int varId);
+
 /*      vlistDefVarStdname: Define the standard name of a Variable */
 void    vlistDefVarStdname(int vlistID, int varID, const char *stdname);
 
@@ -601,7 +669,7 @@ int     gridInqMaskGME(int gridID, int *mask_vec);
 void    gridDefMask(int gridID, const int *mask_vec);
 int     gridInqMask(int gridID, int *mask_vec);
 
-void    gridPrint(int gridID, int opt);
+void    gridPrint(int gridID, int index, int opt);
 
 /*      gridCreate: Create a horizontal Grid */
 int     gridCreate(int gridtype, int size);
@@ -787,7 +855,7 @@ void    gridDefYbounds(int gridID, const double *ybounds_vec);
 /*      gridInqYbounds: Get the bounds of a Y-axis */
 int     gridInqYbounds(int gridID, double *ybounds_vec);
 
-void    gridDefRowlon(int gridID, int nrowlon, const int rowlon_vec[]);
+void    gridDefRowlon(int gridID, int nrowlon, const int* rowlon_vec);
 void    gridInqRowlon(int gridID, int *rowlon_vec);
 void    gridChangeType(int gridID, int gridtype);
 
@@ -815,7 +883,7 @@ int     zaxisDuplicate(int zaxisID);
 
 void    zaxisResize(int zaxisID, int size);
 
-void    zaxisPrint(int zaxisID);
+void    zaxisPrint(int zaxisID, int index);
 
 /*      zaxisDefLevels: Define the levels of a Z-axis */
 void    zaxisDefLevels(int zaxisID, const double *levels_vec);
@@ -975,7 +1043,7 @@ int     taxisInqType(int taxisID);
 
 int     taxisInqNumavg(int taxisID);
 
-char   *tunitNamePtr(int tunitID);
+const char* tunitNamePtr(int tunitID);
 
 
 /* Institut routines */
@@ -986,7 +1054,7 @@ int     institutInqNumber(void);
 int     institutInqCenter(int instID);
 int     institutInqSubcenter(int instID);
 const char *institutInqNamePtr(int instID);
-char   *institutInqLongnamePtr(int instID);
+const char* institutInqLongnamePtr(int instID);
 
 /* Model routines */
 
@@ -1004,7 +1072,7 @@ void    tableWrite(const char *filename, int tableID);
 int     tableRead(const char *tablefile);
 int     tableDef(int modelID, int tablenum, const char *tablename);
 
-char   *tableInqNamePtr(int tableID);
+const char* tableInqNamePtr(int tableID);
 void    tableDefEntry(int tableID, int code, const char *name, const char *longname, const char *units);
 
 int     tableInq(int modelID, int tablenum, const char *tablename);
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index 884181c..866891a 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -1,10 +1,10 @@
 ! This file was automatically generated, don't edit!
 !
-! Fortran interface for CDI library version 1.6.7
+! Fortran interface for CDI library version 1.6.9
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   December 2014
+! Uwe Schulzweida, MPI-MET, Hamburg,   April 2015
 !
 
       INTEGER    CDI_MAX_NAME          
@@ -31,6 +31,8 @@
 !
       INTEGER    CDI_NOERR             
       PARAMETER (CDI_NOERR              =  0)
+      INTEGER    CDI_EEOF              
+      PARAMETER (CDI_EEOF               = -1)
       INTEGER    CDI_ESYSTEM           
       PARAMETER (CDI_ESYSTEM            = -10)
       INTEGER    CDI_EINVAL            
@@ -185,6 +187,8 @@
       PARAMETER (DATATYPE_CPX           = 254)
       INTEGER    DATATYPE_UCHAR        
       PARAMETER (DATATYPE_UCHAR         = 255)
+      INTEGER    DATATYPE_LONG         
+      PARAMETER (DATATYPE_LONG          = 256)
 !
 !  Chunks
 !
@@ -375,6 +379,12 @@
       INTEGER    CDI_UUID_SIZE         
       PARAMETER (CDI_UUID_SIZE          = 16)
 !
+!  Structs that are used to return data to the user
+!
+!
+!  Opaque types
+!
+!
 !  CDI control routines
 !
 !                     cdiReset
@@ -568,14 +578,6 @@
 !                                    (INTEGER         streamID)
       EXTERNAL        streamInqCurTimestepID
 
-      CHARACTER(80)   streamFilename
-!                                    (INTEGER         streamID)
-      EXTERNAL        streamFilename
-
-      CHARACTER(80)   streamFilesuffix
-!                                    (INTEGER         filetype)
-      EXTERNAL        streamFilesuffix
-
       INTEGER         streamInqNvars
 !                                    (INTEGER         streamID)
       EXTERNAL        streamInqNvars
@@ -690,6 +692,9 @@
       EXTERNAL        streamCopyRecord
 
 !
+!  File driven I/O (may yield better performance than using the streamXXX functions)
+!
+!
 !  VLIST routines
 !
       INTEGER         vlistCreate
@@ -1378,6 +1383,7 @@
 
 !                     gridPrint
 !                                    (INTEGER         gridID,
+!                                     INTEGER         index,
 !                                     INTEGER         opt)
       EXTERNAL        gridPrint
 
@@ -1780,12 +1786,6 @@
 !                                     DOUBLEPRECISION ybounds_vec)
       EXTERNAL        gridInqYbounds
 
-!                     gridDefRowlon
-!                                    (INTEGER         gridID,
-!                                     INTEGER         nrowlon,
-!                                     INTEGER         rowlon_vec)
-      EXTERNAL        gridDefRowlon
-
 !                     gridInqRowlon
 !                                    (INTEGER         gridID,
 !                                     INTEGER         rowlon_vec)
@@ -1840,7 +1840,8 @@
       EXTERNAL        zaxisResize
 
 !                     zaxisPrint
-!                                    (INTEGER         zaxisID)
+!                                    (INTEGER         zaxisID,
+!                                     INTEGER         index)
       EXTERNAL        zaxisPrint
 
 !                     zaxisDefLevels
@@ -2174,10 +2175,6 @@
 !                                    (INTEGER         taxisID)
       EXTERNAL        taxisInqNumavg
 
-      CHARACTER(80)   tunitNamePtr
-!                                    (INTEGER         tunitID)
-      EXTERNAL        tunitNamePtr
-
 !
 !  Institut routines
 !
@@ -2210,10 +2207,6 @@
 !                                    (INTEGER         instID)
       EXTERNAL        institutInqNamePtr
 
-      CHARACTER(80)   institutInqLongnamePtr
-!                                    (INTEGER         instID)
-      EXTERNAL        institutInqLongnamePtr
-
 !
 !  Model routines
 !
@@ -2264,10 +2257,6 @@
 !                                     CHARACTER*(*)   tablename)
       EXTERNAL        tableDef
 
-      CHARACTER(80)   tableInqNamePtr
-!                                    (INTEGER         tableID)
-      EXTERNAL        tableInqNamePtr
-
 !                     tableDefEntry
 !                                    (INTEGER         tableID,
 !                                     INTEGER         code,
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index e69d3ce..baec75b 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -60,6 +60,12 @@
 /*  number of unsigned char needed to store UUID  */
 
 
+/*  Structs that are used to return data to the user  */
+
+
+/*  Opaque types  */
+
+
 /*  CDI control routines  */
 
 FCALLSCSUB0 (cdiReset, CDIRESET, cdireset)
@@ -118,8 +124,6 @@ FCALLSCFUN1 (INT, streamInqCompLevel, STREAMINQCOMPLEVEL, streaminqcomplevel, IN
 FCALLSCFUN2 (INT, streamDefTimestep, STREAMDEFTIMESTEP, streamdeftimestep, INT, INT)
 FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT, INT)
 FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
-FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
-FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
 FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
 
 /*  STREAM var I/O routines  */
@@ -143,6 +147,9 @@ FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, PF
 FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, PDOUBLE, PINT)
 FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
 
+/*  File driven I/O (may yield better performance than using the streamXXX functions)  */
+
+
 /*  VLIST routines  */
 
 FCALLSCFUN0 (INT, vlistCreate, VLISTCREATE, vlistcreate)
@@ -281,7 +288,7 @@ FCALLSCSUB2 (gridDefMaskGME, GRIDDEFMASKGME, griddefmaskgme, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, PINT)
 FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, PINT)
-FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
+FCALLSCSUB3 (gridPrint, GRIDPRINT, gridprint, INT, INT, INT)
 FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
 FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
 FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
@@ -373,7 +380,6 @@ FCALLSCSUB2 (gridDefXbounds, GRIDDEFXBOUNDS, griddefxbounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqXbounds, GRIDINQXBOUNDS, gridinqxbounds, INT, PDOUBLE)
 FCALLSCSUB2 (gridDefYbounds, GRIDDEFYBOUNDS, griddefybounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqYbounds, GRIDINQYBOUNDS, gridinqybounds, INT, PDOUBLE)
-FCALLSCSUB3 (gridDefRowlon, GRIDDEFROWLON, griddefrowlon, INT, INT, INTV)
 FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, PINT)
 FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
 FCALLSCSUB2 (gridDefComplexPacking, GRIDDEFCOMPLEXPACKING, griddefcomplexpacking, INT, INT)
@@ -388,7 +394,7 @@ FCALLSCFUN1 (INT, zaxisInqType, ZAXISINQTYPE, zaxisinqtype, INT)
 FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
 FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
 FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
-FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
+FCALLSCSUB2 (zaxisPrint, ZAXISPRINT, zaxisprint, INT, INT)
 FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, PDOUBLE)
 FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
@@ -461,7 +467,6 @@ FCALLSCFUN1 (DOUBLE, taxisInqForecastPeriod, TAXISINQFORECASTPERIOD, taxisinqfor
 FCALLSCSUB2 (taxisDefNumavg, TAXISDEFNUMAVG, taxisdefnumavg, INT, INT)
 FCALLSCFUN1 (INT, taxisInqType, TAXISINQTYPE, taxisinqtype, INT)
 FCALLSCFUN1 (INT, taxisInqNumavg, TAXISINQNUMAVG, taxisinqnumavg, INT)
-FCALLSCFUN1 (STRING, tunitNamePtr, TUNITNAMEPTR, tunitnameptr, INT)
 
 /*  Institut routines  */
 
@@ -471,7 +476,6 @@ FCALLSCFUN0 (INT, institutInqNumber, INSTITUTINQNUMBER, institutinqnumber)
 FCALLSCFUN1 (INT, institutInqCenter, INSTITUTINQCENTER, institutinqcenter, INT)
 FCALLSCFUN1 (INT, institutInqSubcenter, INSTITUTINQSUBCENTER, institutinqsubcenter, INT)
 FCALLSCFUN1 (STRING, institutInqNamePtr, INSTITUTINQNAMEPTR, institutinqnameptr, INT)
-FCALLSCFUN1 (STRING, institutInqLongnamePtr, INSTITUTINQLONGNAMEPTR, institutinqlongnameptr, INT)
 
 /*  Model routines  */
 
@@ -487,7 +491,6 @@ FCALLSCSUB2 (tableWriteC, TABLEWRITEC, tablewritec, STRING, INT)
 FCALLSCSUB2 (tableWrite, TABLEWRITE, tablewrite, STRING, INT)
 FCALLSCFUN1 (INT, tableRead, TABLEREAD, tableread, STRING)
 FCALLSCFUN3 (INT, tableDef, TABLEDEF, tabledef, INT, INT, STRING)
-FCALLSCFUN1 (STRING, tableInqNamePtr, TABLEINQNAMEPTR, tableinqnameptr, INT)
 FCALLSCSUB5 (tableDefEntry, TABLEDEFENTRY, tabledefentry, INT, INT, STRING, STRING, STRING)
 FCALLSCFUN3 (INT, tableInq, TABLEINQ, tableinq, INT, INT, STRING)
 FCALLSCFUN0 (INT, tableInqNumber, TABLEINQNUMBER, tableinqnumber)
diff --git a/libcdi/src/cdi_int.c b/libcdi/src/cdi_int.c
index a915d73..53d2afa 100644
--- a/libcdi/src/cdi_int.c
+++ b/libcdi/src/cdi_int.c
@@ -389,12 +389,6 @@ const char *strfiletype(int filetype)
 }
 
 
-int streamSize(void)
-{
-  return reshCountType ( &streamOps );
-}
-
-
 void cdiDefGlobal(const char *string, int val)
 {
   if      ( strcmp(string, "REGULARGRID")      == 0 ) cdiDataUnreduced = val;
diff --git a/libcdi/src/cdi_int.h b/libcdi/src/cdi_int.h
index ecc6e05..d85041d 100644
--- a/libcdi/src/cdi_int.h
+++ b/libcdi/src/cdi_int.h
@@ -318,21 +318,22 @@ int     cdiInqAccesstype(int streamID);
 
 int     getByteswap(int byteorder);
 
-int     streamSize ();
-void    streamGetIndexList ( int, int * );
+void cdiStreamGetIndexList(unsigned numIDs, int IDs[numIDs]);
 
 
 void  cdiInitialize(void);
 
 void uuid2str(const unsigned char *uuid, char *uuidstr);
 int str2uuid(const char *uuidstr, unsigned char *uuid);
-static inline int
-cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+
+static inline int cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
 {
   static const unsigned char uuid_nil[CDI_UUID_SIZE];
   return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
 }
 
+char* cdiEscapeSpaces(const char* string);
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd);
 
 #define CDI_UNIT_PA   1
 #define CDI_UNIT_HPA  2
@@ -373,6 +374,11 @@ void cdiStreamSync_(stream_t *streamptr);
 
 char *cdiUnitNamePtr(int cdi_unit);
 
+void zaxisGetIndexList(int nzaxis, int *zaxisIndexList);
+
+void zaxisDefLtype2(int zaxisID, int ltype2);
+int  zaxisInqLtype2(int zaxisID);
+
 #endif  /* _CDI_INT_H */
 /*
  * Local Variables:
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index 1c6280b..a6185d8 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2014-12-10, do not edit */
+/* Automatically generated by m214003 at 2015-04-27, do not edit */
 
-/* CDILIB_VERSION="1.6.7" */
+/* CDILIB_VERSION="1.6.9" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -58,14 +58,75 @@
 #  define  HAVE_LIBIEG       1
 #endif
 
-#ifndef _CDI_LIMITS_H
-#define _CDI_LIMITS_H
+#ifndef _ERROR_H
+#define _ERROR_H
 
-#define  MAX_GRIDS_PS    128  /* maximum number of different grids per stream */
-#define  MAX_ZAXES_PS    128  /* maximum number of different zaxes per stream */
-#define  MAX_ATTRIBUTES  256  /* maximum number of attributes per variable    */
+#include <stdarg.h>
+#include <stdlib.h>
 
-#endif  /* _CDI_LIMITS_H */
+#ifndef  WITH_CALLER_NAME
+#define  WITH_CALLER_NAME
+#endif
+
+#define  _FATAL     1     /* Error flag: exit on error  */
+#define  _VERBOSE   2     /* Error flag: report errors  */
+#define  _DEBUG     4     /* Error flag: debug          */
+
+extern int _ExitOnError;  /* If set to 1, exit on error (default 1)       */
+extern int _Verbose;      /* If set to 1, errors are reported (default 1) */
+extern int _Debug;        /* If set to 1, debuggig (default 0)            */
+
+void SysError_(const char *caller, const char *fmt, ...);
+void    Error_(const char *caller, const char *fmt, ...);
+void  Warning_(const char *caller, const char *fmt, ...);
+/* delegate used by Warning_ unless mode is PIO */
+void cdiWarning(const char *caller, const char *fmt, va_list ap);
+void  Message_(const char *caller, const char *fmt, ...);
+
+#if  defined  WITH_CALLER_NAME
+#  define  SysError(...)  SysError_(__func__, __VA_ARGS__)
+#  define    Errorc(...)     Error_(  caller, __VA_ARGS__)
+#  define     Error(...)     Error_(__func__, __VA_ARGS__)
+#  define   Warning(...)   Warning_(__func__, __VA_ARGS__)
+#  define  Messagec(...)   Message_(  caller, __VA_ARGS__)
+#  define   Message(...)   Message_(__func__, __VA_ARGS__)
+#else
+#  define  SysError(...)  SysError_((void *), __VA_ARGS__)
+#  define    Errorc(...)     Error_((void *), __VA_ARGS__)
+#  define     Error(...)     Error_((void *), __VA_ARGS__)
+#  define   Warning(...)   Warning_((void *), __VA_ARGS__)
+#  define  Messagec(...)   Message_((void *), __VA_ARGS__)
+#  define   Message(...)   Message_((void *), __VA_ARGS__)
+#endif
+
+/* If we're not using GNU C, elide __attribute__ */
+#ifndef __GNUC__
+#  define  __attribute__(x)  /*NOTHING*/
+#endif
+
+void cdiAbortC(const char *caller, const char *filename,
+               const char *functionname, int line,
+               const char *errorString, ... )
+  __attribute__((noreturn));
+#define xabortC(caller, ...)                                    \
+  cdiAbortC(caller, __FILE__, __func__, __LINE__, __VA_ARGS__ )
+#define xabort(...)                                             \
+  cdiAbortC(NULL, __FILE__, __func__, __LINE__, __VA_ARGS__ )
+#define cdiAbort(file, func, line, ...)                 \
+  cdiAbortC(NULL, (file), (func), (line), __VA_ARGS__)
+
+#define xassert(arg) do {                       \
+    if ((arg)) { } else {                       \
+      xabort("assertion `" #arg "` failed");}   \
+  } while(0)
+
+void
+cdiAbortC_serial(const char *caller, const char *filename,
+                 const char *functionname, int line,
+                 const char *errorString, va_list ap)
+  __attribute__((noreturn));
+
+#endif  /* _ERROR_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -75,766 +136,279 @@
  * require-trailing-newline: t
  * End:
  */
-#ifndef RESOURCE_HANDLE_H
-#define RESOURCE_HANDLE_H
+/*
+  CDI C header file
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+  This is the only file that must be included to use the CDI library from C.
+*/
 
-#include <stdio.h>
+#ifndef  CDI_H_
+#define  CDI_H_
 
+#include <stdio.h>
+#include <sys/types.h>
 /*
- * CDI internal handling of resource handles given to user code
- */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+*/
+#define  CDI_MAX_NAME           256   /* max length of a name                 */
 
-/*
- * for reasons of compatibility with cfortran.h, the handle type is: int
- */
-typedef int cdiResH;
+#define  CDI_UNDEFID             -1
+#define  CDI_GLOBAL              -1   /* Global var ID for vlist              */
 
-/* return 0 on equality, not 0 otherwise */
-typedef int    ( * valCompareFunc     )( void *, void * );
-typedef void   ( * valDestroyFunc     )( void * );
-typedef void   ( * valPrintFunc       )( void *, FILE * );
-typedef int    ( * valGetPackSizeFunc )( void *, void *context );
-typedef void   ( * valPackFunc        )( void *, void *buf, int size, int *pos, void *context );
-typedef int    ( * valTxCodeFunc      )( void );
+/* Byte order */
 
-typedef struct {
-  valCompareFunc     valCompare;
-  valDestroyFunc     valDestroy;
-  valPrintFunc       valPrint;
-  valGetPackSizeFunc valGetPackSize;
-  valPackFunc        valPack;
-  valTxCodeFunc      valTxCode;
-}resOps;
+#define  CDI_BIGENDIAN            0   /* Byte order BIGENDIAN                 */
+#define  CDI_LITTLEENDIAN         1   /* Byte order LITTLEENDIAN              */
 
-enum {
-  RESH_IN_USE_BIT = 1 << 0,
-  RESH_SYNC_BIT = 1 << 1,
-  /* resource holds no value */
-  RESH_UNUSED = 0,
-  /* resource was deleted and needs to be synced */
-  RESH_DESYNC_DELETED
-    = RESH_SYNC_BIT,
-  /* resource is synchronized */
-  RESH_IN_USE
-    = RESH_IN_USE_BIT,
-  /* resource is in use, desynchronized and needs to be synced */
-  RESH_DESYNC_IN_USE
-    = RESH_IN_USE_BIT | RESH_SYNC_BIT,
-};
+#define  CDI_REAL                 1   /* Real numbers                         */
+#define  CDI_COMP                 2   /* Complex numbers                      */
+#define  CDI_BOTH                 3   /* Both numbers                         */
 
-void   reshListCreate(int namespaceID);
-void   reshListDestruct(int namespaceID);
-int    reshPut ( void *, const resOps * );
-void reshReplace(cdiResH resH, void *p, const resOps *ops);
-void   reshRemove ( cdiResH, const resOps * );
-/*> doesn't check resource type */
-void reshDestroy(cdiResH);
+/* Error identifier */
 
-int    reshCountType ( const resOps * );
+#define	 CDI_NOERR        	  0   /* No Error                             */
+#define  CDI_EEOF                -1   /* The end of file was encountered      */
+#define  CDI_ESYSTEM            -10   /* Operating system error               */
+#define  CDI_EINVAL             -20   /* Invalid argument                     */
+#define  CDI_EUFTYPE            -21   /* Unsupported file type                */
+#define  CDI_ELIBNAVAIL         -22   /* xxx library not available            */
+#define  CDI_EUFSTRUCT          -23   /* Unsupported file structure           */
+#define  CDI_EUNC4              -24   /* Unsupported netCDF4 structure        */
+#define  CDI_ELIMIT             -99   /* Internal limits exceeded             */
 
-void * reshGetValue(const char* caller, const char* expressionString, cdiResH id, const resOps* ops);
-#define reshGetVal(resH, ops)  reshGetValue(__func__, #resH, resH, ops)
+/* File types */
 
+#define  FILETYPE_UNDEF          -1   /* Unknown/not yet defined file type */
+#define  FILETYPE_GRB             1   /* File type GRIB                       */
+#define  FILETYPE_GRB2            2   /* File type GRIB version 2             */
+#define  FILETYPE_NC              3   /* File type netCDF                     */
+#define  FILETYPE_NC2             4   /* File type netCDF version 2 (64-bit)  */
+#define  FILETYPE_NC4             5   /* File type netCDF version 4           */
+#define  FILETYPE_NC4C            6   /* File type netCDF version 4 (classic) */
+#define  FILETYPE_SRV             7   /* File type SERVICE                    */
+#define  FILETYPE_EXT             8   /* File type EXTRA                      */
+#define  FILETYPE_IEG             9   /* File type IEG                        */
 
-void   reshGetResHListOfType ( int, int *, const resOps * );
+/* Compress types */
 
-enum cdiApplyRet {
-  CDI_APPLY_ERROR = -1,
-  CDI_APPLY_STOP,
-  CDI_APPLY_GO_ON,
-};
-enum cdiApplyRet
-cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
-                                      void *data), void *data);
-enum cdiApplyRet
-cdiResHFilterApply(const resOps *p,
-                   enum cdiApplyRet (*func)(int id, void *res,
-                                            void *data),
-                   void *data);
+#define  COMPRESS_NONE            0
+#define  COMPRESS_SZIP            1
+#define  COMPRESS_GZIP            2
+#define  COMPRESS_BZIP2           3
+#define  COMPRESS_ZIP             4
+#define  COMPRESS_JPEG            5
 
-void   reshPackBufferCreate ( char **, int *, void *context );
-void   reshPackBufferDestroy ( char ** );
-int    reshResourceGetPackSize_intern(int resh, const resOps *ops, void *context, const char* caller, const char* expressionString);
-#define reshResourceGetPackSize(resh, ops, context) reshResourceGetPackSize_intern(resh, ops, context, __func__, #resh)
-void   reshPackResource_intern(int resh, const resOps *ops, void *buf, int buf_size, int *position, void *context, const char* caller, const char* expressionString);
-#define reshPackResource(resh, ops, buf, buf_size, position, context) reshPackResource_intern(resh, ops, buf, buf_size, position, context, __func__, #resh)
+/* external data types */
 
-void   reshSetStatus ( cdiResH, const resOps *, int );
-int    reshGetStatus ( cdiResH, const resOps * );
+#define  DATATYPE_PACK            0
+#define  DATATYPE_PACK1           1
+#define  DATATYPE_PACK2           2
+#define  DATATYPE_PACK3           3
+#define  DATATYPE_PACK4           4
+#define  DATATYPE_PACK5           5
+#define  DATATYPE_PACK6           6
+#define  DATATYPE_PACK7           7
+#define  DATATYPE_PACK8           8
+#define  DATATYPE_PACK9           9
+#define  DATATYPE_PACK10         10
+#define  DATATYPE_PACK11         11
+#define  DATATYPE_PACK12         12
+#define  DATATYPE_PACK13         13
+#define  DATATYPE_PACK14         14
+#define  DATATYPE_PACK15         15
+#define  DATATYPE_PACK16         16
+#define  DATATYPE_PACK17         17
+#define  DATATYPE_PACK18         18
+#define  DATATYPE_PACK19         19
+#define  DATATYPE_PACK20         20
+#define  DATATYPE_PACK21         21
+#define  DATATYPE_PACK22         22
+#define  DATATYPE_PACK23         23
+#define  DATATYPE_PACK24         24
+#define  DATATYPE_PACK25         25
+#define  DATATYPE_PACK26         26
+#define  DATATYPE_PACK27         27
+#define  DATATYPE_PACK28         28
+#define  DATATYPE_PACK29         29
+#define  DATATYPE_PACK30         30
+#define  DATATYPE_PACK31         31
+#define  DATATYPE_PACK32         32
+#define  DATATYPE_CPX32          64
+#define  DATATYPE_CPX64         128
+#define  DATATYPE_FLT32         132
+#define  DATATYPE_FLT64         164
+#define  DATATYPE_INT8          208
+#define  DATATYPE_INT16         216
+#define  DATATYPE_INT32         232
+#define  DATATYPE_UINT8         308
+#define  DATATYPE_UINT16        316
+#define  DATATYPE_UINT32        332
 
-void   reshLock   ( void );
-void   reshUnlock ( void );
+/* internal data types */
+#define  DATATYPE_INT           251
+#define  DATATYPE_FLT           252
+#define  DATATYPE_TXT           253
+#define  DATATYPE_CPX           254
+#define  DATATYPE_UCHAR         255
+#define  DATATYPE_LONG          256
 
-enum reshListMismatch {
-  cdiResHListOccupationMismatch,
-  cdiResHListResourceTypeMismatch,
-  cdiResHListResourceContentMismatch,
-};
+/* Chunks */
 
-int reshListCompare(int nsp0, int nsp1);
-void reshListPrint(FILE *fp);
+#define  CHUNK_AUTO                 1  /* use default chunk size                                */
+#define  CHUNK_GRID                 2
+#define  CHUNK_LINES                3
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _TAXIS_H
-#define _TAXIS_H
+/* GRID types */
 
-#ifndef RESOURCE_HANDLE_H
-#include "resource_handle.h"
-#endif
+#define  GRID_GENERIC               1  /* Generic grid                                          */
+#define  GRID_GAUSSIAN              2  /* Regular Gaussian lon/lat grid                         */
+#define  GRID_GAUSSIAN_REDUCED      3  /* Reduced Gaussian lon/lat grid                         */
+#define  GRID_LONLAT                4  /* Regular longitude/latitude grid                       */
+#define  GRID_SPECTRAL              5  /* Spherical harmonic coefficients                       */
+#define  GRID_FOURIER               6  /* Fourier coefficients                                  */
+#define  GRID_GME                   7  /* Icosahedral-hexagonal GME grid                        */
+#define  GRID_TRAJECTORY            8  /* Trajectory                                            */
+#define  GRID_UNSTRUCTURED          9  /* General unstructured grid                             */
+#define  GRID_CURVILINEAR          10  /* Curvilinear grid                                      */
+#define  GRID_LCC                  11  /* Lambert Conformal Conic (GRIB)                        */
+#define  GRID_LCC2                 12  /* Lambert Conformal Conic (PROJ)                        */
+#define  GRID_LAEA                 13  /* Lambert Azimuthal Equal Area                          */
+#define  GRID_SINUSOIDAL           14  /* Sinusoidal                                            */
+#define  GRID_PROJECTION           15  /* Projected coordiantes                                 */
 
-typedef struct {
-  /* Date format  YYYYMMDD */
-  /* Time format    hhmmss */
-  int     self;
-  int     used;
-  int     type;           // time type
-  int     vdate;          // verification date
-  int     vtime;          // verification time
-  int     rdate;          // reference date
-  int     rtime;          // reference time
-  int     fdate;          // forecast reference date
-  int     ftime;          // forecast reference time
-  int     calendar;
-  int     unit;           // time unit
-  int     numavg;
-  int     climatology;
-  int     has_bounds;
-  int     vdate_lb;       // lower bounds of vdate
-  int     vtime_lb;       // lower bounds of vtime
-  int     vdate_ub;       // upper bounds of vdate
-  int     vtime_ub;       // upper bounds of vtime
-  int     fc_unit;        // forecast time unit
-  double  fc_period;      // forecast time period
-  char*   name;
-  char*   longname;
-}
-taxis_t;
+/* ZAXIS types */
 
-void     ptaxisInit(taxis_t* taxis);
-void     ptaxisCopy(taxis_t* dest, taxis_t* source);
-taxis_t* taxisPtr(int taxisID);
-void     cdiSetForecastPeriod(double timevalue, taxis_t *taxis);
-void     cdiDecodeTimeval(double timevalue, taxis_t* taxis, int* date, int* time);
-double   cdiEncodeTimeval(int date, int time, taxis_t* taxis);
-void     timeval2vtime(double timevalue, taxis_t* taxis, int* vdate, int* vtime);
-double   vtime2timeval(int vdate, int vtime, taxis_t *taxis);
+#define  ZAXIS_SURFACE              0  /* Surface level                                         */
+#define  ZAXIS_GENERIC              1  /* Generic level                                         */
+#define  ZAXIS_HYBRID               2  /* Hybrid level                                          */
+#define  ZAXIS_HYBRID_HALF          3  /* Hybrid half level                                     */
+#define  ZAXIS_PRESSURE             4  /* Isobaric pressure level in Pascal                     */
+#define  ZAXIS_HEIGHT               5  /* Height above ground in meters                         */
+#define  ZAXIS_DEPTH_BELOW_SEA      6  /* Depth below sea level in meters                       */
+#define  ZAXIS_DEPTH_BELOW_LAND     7  /* Depth below land surface in centimeters               */
+#define  ZAXIS_ISENTROPIC           8  /* Isentropic                                            */
+#define  ZAXIS_TRAJECTORY           9  /* Trajectory                                            */
+#define  ZAXIS_ALTITUDE            10  /* Altitude above mean sea level in meters               */
+#define  ZAXIS_SIGMA               11  /* Sigma level                                           */
+#define  ZAXIS_MEANSEA             12  /* Mean sea level                                        */
+#define  ZAXIS_TOA                 13  /* Norminal top of atmosphere                            */
+#define  ZAXIS_SEA_BOTTOM          14  /* Sea bottom                                            */
+#define  ZAXIS_ATMOSPHERE          15  /* Entire atmosphere                                     */
+#define  ZAXIS_CLOUD_BASE          16  /* Cloud base level                                      */
+#define  ZAXIS_CLOUD_TOP           17  /* Level of cloud tops                                   */
+#define  ZAXIS_ISOTHERM_ZERO       18  /* Level of 0o C isotherm                                */
+#define  ZAXIS_SNOW                19  /* Snow level                                            */
+#define  ZAXIS_LAKE_BOTTOM         20  /* Lake or River Bottom                                  */
+#define  ZAXIS_SEDIMENT_BOTTOM     21  /* Bottom Of Sediment Layer                              */
+#define  ZAXIS_SEDIMENT_BOTTOM_TA  22  /* Bottom Of Thermally Active Sediment Layer             */
+#define  ZAXIS_SEDIMENT_BOTTOM_TW  23  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
+#define  ZAXIS_MIX_LAYER           24  /* Mixing Layer                                          */
+#define  ZAXIS_REFERENCE           25  /* zaxis reference number                                */
 
-void    ptaxisDefName(taxis_t *taxisptr, const char *name);
-void    ptaxisDefLongname(taxis_t *taxisptr, const char *name);
-void    taxisDestroyKernel(taxis_t *taxisptr);
-#if !defined (SX)
-extern const resOps taxisOps;
-#endif
+/* TIME types */
 
-int
-taxisUnpack(char *unpackBuffer, int unpackBufferSize, int *unpackBufferPos,
-            int originNamespace, void *context, int checkForSameID);
+#define  TIME_CONSTANT              0  /* obsolate, use TSTEP_CONSTANT                          */
+#define  TIME_VARIABLE              1  /* obsolate, use TSTEP_INSTANT                           */
 
-#endif  /* _TAXIS_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _DTYPES_H
-#define _DTYPES_H
+/* TSTEP types */
 
-#include <stdio.h>
-#include <limits.h>
+#define  TSTEP_CONSTANT             0  /* Constant            */
+#define  TSTEP_INSTANT              1  /* Instant             */
+#define  TSTEP_AVG                  2  /* Average             */
+#define  TSTEP_ACCUM                3  /* Accumulation        */
+#define  TSTEP_MAX                  4  /* Maximum             */
+#define  TSTEP_MIN                  5  /* Minimum             */
+#define  TSTEP_DIFF                 6  /* Difference          */
+#define  TSTEP_RMS                  7  /* Root mean square    */
+#define  TSTEP_SD                   8  /* Standard deviation  */
+#define  TSTEP_COV                  9  /* Covariance          */
+#define  TSTEP_RATIO               10  /* Ratio               */
+#define  TSTEP_RANGE               11
+#define  TSTEP_INSTANT2            12
+#define  TSTEP_INSTANT3            13
 
-/* INT32 */
+/* TAXIS types */
 
-#if ! defined (INT_MAX)
-#  error INT_MAX undefined
-#endif
+#define  TAXIS_ABSOLUTE           1
+#define  TAXIS_RELATIVE           2
+#define  TAXIS_FORECAST           3
 
-#undef  INT32
-#if  INT_MAX == 2147483647L
-#  define  INT32  int
-#elif LONG_MAX == 2147483647L
-#  define  INT32  long
-#endif
+/* TUNIT types */
 
-/* INT64 */
+#define  TUNIT_SECOND             1
+#define  TUNIT_MINUTE             2
+#define  TUNIT_QUARTER            3
+#define  TUNIT_30MINUTES          4
+#define  TUNIT_HOUR               5
+#define  TUNIT_3HOURS             6
+#define  TUNIT_6HOURS             7
+#define  TUNIT_12HOURS            8
+#define  TUNIT_DAY                9
+#define  TUNIT_MONTH             10
+#define  TUNIT_YEAR              11
 
-#if ! defined (LONG_MAX)
-#  error LONG_MAX undefined
-#endif
+/* CALENDAR types */
 
-#undef  INT64
-#if  LONG_MAX > 2147483647L
-#  define  INT64  long
-#else
-#  define  INT64  long long
-#endif
+#define  CALENDAR_STANDARD        0  /* don't change this value (used also in cgribexlib)! */
+#define  CALENDAR_PROLEPTIC       1
+#define  CALENDAR_360DAYS         2
+#define  CALENDAR_365DAYS         3
+#define  CALENDAR_366DAYS         4
+#define  CALENDAR_NONE            5
 
-/* FLT32 */
+/* number of unsigned char needed to store UUID */
+#define  CDI_UUID_SIZE           16
 
-#undef   FLT32
-#define  FLT32  float
+/* Structs that are used to return data to the user */
 
-/* FLT64 */
+typedef struct CdiParam { int discipline; int category; int number; } CdiParam;
 
-#undef   FLT64
-#define  FLT64  double
 
-/* UINT32 and UINT64 */
+/* Opaque types */
+typedef struct CdiIterator CdiIterator;
+typedef struct CdiGribIterator CdiGribIterator;
 
-#define  UINT32   unsigned INT32
-#define  UINT64   unsigned INT64
+/* CDI control routines */
 
-#endif  /* _DTYPES_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _FILE_H
-#define _FILE_H
+void    cdiReset(void);
 
-#include <stdio.h>
-#include <sys/types.h>
+const char *cdiStringError(int cdiErrno);
 
+void    cdiDebug(int debug);
 
-#define  FILE_UNDEFID      -1
+const char *cdiLibraryVersion(void);
+void    cdiPrintVersion(void);
 
-#define  FILE_TYPE_OPEN     1
-#define  FILE_TYPE_FOPEN    2
+int     cdiHaveFiletype(int filetype);
 
-/* buffer types for FILE_TYPE_OPEN */
-#define  FILE_BUFTYPE_STD   1
-#define  FILE_BUFTYPE_MMAP  2
+void    cdiDefMissval(double missval);
+double  cdiInqMissval(void);
+void    cdiDefGlobal(const char *string, int val);
 
-const
-char  *fileLibraryVersion(void);
+int     namespaceNew();
+void    namespaceSetActive(int namespaceID);
+void    namespaceDelete(int namespaceID);
 
-void   fileDebug(int debug);
 
-void  *filePtr(int fileID);
+/* CDI converter routines */
 
-int    fileSetBufferType(int fileID, int type);
-void   fileSetBufferSize(int fileID, long buffersize);
+/* parameter */
 
-int    fileOpen(const char *filename, const char *mode);
-int    fileOpen_serial(const char *filename, const char *mode);
-int    fileClose(int fileID);
-int    fileClose_serial(int fileID);
+void    cdiParamToString(int param, char *paramstr, int maxlen);
 
-char  *fileInqName(int fileID);
-int    fileInqMode(int fileID);
+void    cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis);
+int     cdiEncodeParam(int pnum, int pcat, int pdis);
 
-int    fileFlush(int fileID);
-void   fileClearerr(int fileID);
-int    fileEOF(int fileID);
-int    filePtrEOF(void *fileptr);
-void   fileRewind(int fileID);
+/* date format:  YYYYMMDD */
+/* time format:    hhmmss */
 
-off_t  fileGetPos(int fileID);
-int    fileSetPos(int fileID, off_t offset, int whence);
+void    cdiDecodeDate(int date, int *year, int *month, int *day);
+int     cdiEncodeDate(int year, int month, int day);
 
-int    fileGetc(int fileID);
-int    filePtrGetc(void *fileptr);
-
-size_t filePtrRead(void *fileptr, void *restrict ptr, size_t size);
-size_t fileRead(int fileID, void *restrict ptr, size_t size);
-size_t fileWrite(int fileID, const void *restrict ptr, size_t size);
-
-#endif  /* _FILE_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _SERVICE_H
-#define _SERVICE_H
-
-
-typedef struct {
-  int    checked;
-  int    byteswap;
-  int    header[8];
-  int    hprec;      /* header precision */
-  int    dprec;      /* data   precision */
-  size_t datasize;
-  size_t buffersize;
-  void  *buffer;
-}
-srvrec_t;
-
-
-const char *srvLibraryVersion(void);
-
-void srvDebug(int debug);
-
-int  srvCheckFiletype(int fileID, int *swap);
-
-srvrec_t *srvNew(void);
-void srvDelete(srvrec_t *srvp);
-
-int  srvRead(int fileID, srvrec_t *srvp);
-void srvWrite(int fileID, srvrec_t *srvp);
-
-int  srvInqHeader(srvrec_t *srvp, int *header);
-int  srvInqDataSP(srvrec_t *srvp, float *data);
-int  srvInqDataDP(srvrec_t *srvp, double *data);
-
-int  srvDefHeader(srvrec_t *srvp, const int *header);
-int  srvDefDataSP(srvrec_t *srvp, const float *data);
-int  srvDefDataDP(srvrec_t *srvp, const double *data);
-
-
-#endif  /* _SERVICE_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _EXTRA_H
-#define _EXTRA_H
-
-#define  EXT_REAL   1
-#define  EXT_COMP   2
-
-
-typedef struct {
-  int    checked;
-  int    byteswap;
-  int    header[4];
-  int    prec;      /* single or double precison */
-  int    number;    /* real or complex */
-  size_t datasize;
-  size_t buffersize;
-  void  *buffer;
-}
-extrec_t;
-
-
-const char *extLibraryVersion(void);
-
-void extDebug(int debug);
-
-int  extCheckFiletype(int fileID, int *swap);
-
-void *extNew(void);
-void extDelete(void *ext);
-
-int  extRead(int fileID, void *ext);
-int  extWrite(int fileID, void *ext);
-
-int  extInqHeader(void *ext, int *header);
-int  extInqDataSP(void *ext, float *data);
-int  extInqDataDP(void *ext, double *data);
-
-int  extDefHeader(void *ext, const int *header);
-int  extDefDataSP(void *ext, const float *data);
-int  extDefDataDP(void *ext, const double *data);
-
-#endif  /* _EXTRA_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _IEG_H
-#define _IEG_H
-
-/* Level Types */
-#define  IEG_LTYPE_SURFACE               1
-#define  IEG_LTYPE_99                   99
-#define  IEG_LTYPE_ISOBARIC            100
-#define  IEG_LTYPE_MEANSEA             102
-#define  IEG_LTYPE_ALTITUDE            103
-#define  IEG_LTYPE_HEIGHT              105
-#define  IEG_LTYPE_SIGMA               107
-#define  IEG_LTYPE_HYBRID              109
-#define  IEG_LTYPE_HYBRID_LAYER        110
-#define  IEG_LTYPE_LANDDEPTH           111
-#define  IEG_LTYPE_LANDDEPTH_LAYER     112
-#define  IEG_LTYPE_SEADEPTH            160
-#define  IEG_LTYPE_99_MARGIN          1000
-
-/*
- *  Data representation type (Grid Type) [Table 6]
- */
-#define  IEG_GTYPE_LATLON             0  /*  latitude/longitude                       */
-#define  IEG_GTYPE_LATLON_ROT        10  /*  rotated latitude/longitude               */
-
-#define  IEG_P_CodeTable(x)   (x[ 5])  /*  Version number of code table                 */
-#define  IEG_P_Parameter(x)   (x[ 6])  /*  Parameter indicator                          */
-#define  IEG_P_LevelType(x)   (x[ 7])  /*  Type of level indicator                      */
-#define  IEG_P_Level1(x)      (x[ 8])  /*  Level 1                                      */
-#define  IEG_P_Level2(x)      (x[ 9])  /*  Level 2                                      */
-#define  IEG_P_Year(x)        (x[10])  /*  Year of century (YY)                         */
-#define  IEG_P_Month(x)       (x[11])  /*  Month (MM)                                   */
-#define  IEG_P_Day(x)         (x[12])  /*  Day (DD)                                     */
-#define  IEG_P_Hour(x)        (x[13])  /*  Hour (HH)                                    */
-#define  IEG_P_Minute(x)      (x[14])  /*  Minute (MM)                                  */
-
-/*
- *  Macros for the grid definition section ( Section 2 )
- */
-#define  IEG_G_Size(x)        (x[ 0])
-#define  IEG_G_NumVCP(x)      (x[3] == 10 ? (x[0]-42)/4 : (x[0]-32)/4)
-#define  IEG_G_GridType(x)    (x[ 3])  /*  Data representation type */
-#define  IEG_G_NumLon(x)      (x[ 4])  /*  Number of points along a parallel (Ni)       */
-#define  IEG_G_NumLat(x)      (x[ 5])  /*  Number of points along a meridian (Nj)       */
-#define  IEG_G_FirstLat(x)    (x[ 6])  /*  Latitude of the first grid point             */
-#define  IEG_G_FirstLon(x)    (x[ 7])  /*  Longitude of the first grid point            */
-#define  IEG_G_ResFlag(x)     (x[ 8])  /*  Resolution flag: 128 regular grid            */
-#define  IEG_G_LastLat(x)     (x[ 9])  /*  Latitude of the last grid point              */
-#define  IEG_G_LastLon(x)     (x[10])  /*  Longitude of the last grid point             */
-#define  IEG_G_LonIncr(x)     (x[11])  /*  i direction increment                        */
-#define  IEG_G_LatIncr(x)     (x[12])  /*  j direction increment                        */
-#define  IEG_G_ScanFlag(x)    (x[13])
-#define  IEG_G_LatSP(x)       (x[16])  /*  Latitude of the southern pole of rotation    */
-#define  IEG_G_LonSP(x)       (x[17])  /*  Longitude of the southern pole of rotation   */
-#define  IEG_G_ResFac(x)      (x[18])  /*  Resolution factor                            */
-
-
-typedef struct {
-  int    checked;
-  int    byteswap;
-  int    dprec;      /* data   precision */
-  double refval;
-  int    ipdb[37];
-  int    igdb[22];
-  double vct[100];
-  size_t datasize;
-  size_t buffersize;
-  void  *buffer;
-}
-iegrec_t;
-
-
-const char *iegLibraryVersion(void);
-
-void iegDebug(int debug);
-int  iegCheckFiletype(int fileID, int *swap);
-
-iegrec_t *iegNew(void);
-void iegDelete(iegrec_t *iegp);
-void iegInit(iegrec_t *iegp);
-void iegInitMem(iegrec_t *iegp);
-
-int  iegRead(int fileID, iegrec_t *iegp);
-int  iegWrite(int fileID, iegrec_t *iegp);
-
-void iegCopyMeta(iegrec_t *diegp, iegrec_t *siegp);
-int  iegInqHeader(iegrec_t *iegp, int *header);
-int  iegInqDataSP(iegrec_t *iegp, float *data);
-int  iegInqDataDP(iegrec_t *iegp, double *data);
-
-int  iegDefHeader(iegrec_t *iegp, const int *header);
-int  iegDefDataSP(iegrec_t *iegp, const float *data);
-int  iegDefDataDP(iegrec_t *iegp, const double *data);
-
-
-#endif  /* _IEG_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-/*
-  CDI C header file
-
-  This is the only file that must be included to use the CDI library from C.
-*/
-
-#ifndef  CDI_H_
-#define  CDI_H_
-
-#include <stdio.h>
-#include <sys/types.h>
-/*
-#if defined(__cplusplus)
-extern "C" {
-#endif
-*/
-#define  CDI_MAX_NAME           256   /* max length of a name                 */
-
-#define  CDI_UNDEFID             -1
-#define  CDI_GLOBAL              -1   /* Global var ID for vlist              */
-
-/* Byte order */
-
-#define  CDI_BIGENDIAN            0   /* Byte order BIGENDIAN                 */
-#define  CDI_LITTLEENDIAN         1   /* Byte order LITTLEENDIAN              */
-
-#define  CDI_REAL                 1   /* Real numbers                         */
-#define  CDI_COMP                 2   /* Complex numbers                      */
-#define  CDI_BOTH                 3   /* Both numbers                         */
-
-/* Error identifier */
-
-#define	 CDI_NOERR        	  0   /* No Error                             */
-#define  CDI_ESYSTEM            -10   /* Operating system error               */
-#define  CDI_EINVAL             -20   /* Invalid argument                     */
-#define  CDI_EUFTYPE            -21   /* Unsupported file type                */
-#define  CDI_ELIBNAVAIL         -22   /* xxx library not available            */
-#define  CDI_EUFSTRUCT          -23   /* Unsupported file structure           */
-#define  CDI_EUNC4              -24   /* Unsupported netCDF4 structure        */
-#define  CDI_ELIMIT             -99   /* Internal limits exceeded             */
-
-/* File types */
-
-#define  FILETYPE_UNDEF          -1   /* Unknown/not yet defined file type */
-#define  FILETYPE_GRB             1   /* File type GRIB                       */
-#define  FILETYPE_GRB2            2   /* File type GRIB version 2             */
-#define  FILETYPE_NC              3   /* File type netCDF                     */
-#define  FILETYPE_NC2             4   /* File type netCDF version 2 (64-bit)  */
-#define  FILETYPE_NC4             5   /* File type netCDF version 4           */
-#define  FILETYPE_NC4C            6   /* File type netCDF version 4 (classic) */
-#define  FILETYPE_SRV             7   /* File type SERVICE                    */
-#define  FILETYPE_EXT             8   /* File type EXTRA                      */
-#define  FILETYPE_IEG             9   /* File type IEG                        */
-
-/* Compress types */
-
-#define  COMPRESS_NONE            0
-#define  COMPRESS_SZIP            1
-#define  COMPRESS_GZIP            2
-#define  COMPRESS_BZIP2           3
-#define  COMPRESS_ZIP             4
-#define  COMPRESS_JPEG            5
-
-/* external data types */
-
-#define  DATATYPE_PACK            0
-#define  DATATYPE_PACK1           1
-#define  DATATYPE_PACK2           2
-#define  DATATYPE_PACK3           3
-#define  DATATYPE_PACK4           4
-#define  DATATYPE_PACK5           5
-#define  DATATYPE_PACK6           6
-#define  DATATYPE_PACK7           7
-#define  DATATYPE_PACK8           8
-#define  DATATYPE_PACK9           9
-#define  DATATYPE_PACK10         10
-#define  DATATYPE_PACK11         11
-#define  DATATYPE_PACK12         12
-#define  DATATYPE_PACK13         13
-#define  DATATYPE_PACK14         14
-#define  DATATYPE_PACK15         15
-#define  DATATYPE_PACK16         16
-#define  DATATYPE_PACK17         17
-#define  DATATYPE_PACK18         18
-#define  DATATYPE_PACK19         19
-#define  DATATYPE_PACK20         20
-#define  DATATYPE_PACK21         21
-#define  DATATYPE_PACK22         22
-#define  DATATYPE_PACK23         23
-#define  DATATYPE_PACK24         24
-#define  DATATYPE_PACK25         25
-#define  DATATYPE_PACK26         26
-#define  DATATYPE_PACK27         27
-#define  DATATYPE_PACK28         28
-#define  DATATYPE_PACK29         29
-#define  DATATYPE_PACK30         30
-#define  DATATYPE_PACK31         31
-#define  DATATYPE_PACK32         32
-#define  DATATYPE_CPX32          64
-#define  DATATYPE_CPX64         128
-#define  DATATYPE_FLT32         132
-#define  DATATYPE_FLT64         164
-#define  DATATYPE_INT8          208
-#define  DATATYPE_INT16         216
-#define  DATATYPE_INT32         232
-#define  DATATYPE_UINT8         308
-#define  DATATYPE_UINT16        316
-#define  DATATYPE_UINT32        332
-
-/* internal data types */
-#define  DATATYPE_INT           251
-#define  DATATYPE_FLT           252
-#define  DATATYPE_TXT           253
-#define  DATATYPE_CPX           254
-#define  DATATYPE_UCHAR         255
-#define  DATATYPE_LONG          256
-
-/* Chunks */
-
-#define  CHUNK_AUTO                 1  /* use default chunk size                                */
-#define  CHUNK_GRID                 2
-#define  CHUNK_LINES                3
-
-/* GRID types */
-
-#define  GRID_GENERIC               1  /* Generic grid                                          */
-#define  GRID_GAUSSIAN              2  /* Regular Gaussian lon/lat grid                         */
-#define  GRID_GAUSSIAN_REDUCED      3  /* Reduced Gaussian lon/lat grid                         */
-#define  GRID_LONLAT                4  /* Regular longitude/latitude grid                       */
-#define  GRID_SPECTRAL              5  /* Spherical harmonic coefficients                       */
-#define  GRID_FOURIER               6  /* Fourier coefficients                                  */
-#define  GRID_GME                   7  /* Icosahedral-hexagonal GME grid                        */
-#define  GRID_TRAJECTORY            8  /* Trajectory                                            */
-#define  GRID_UNSTRUCTURED          9  /* General unstructured grid                             */
-#define  GRID_CURVILINEAR          10  /* Curvilinear grid                                      */
-#define  GRID_LCC                  11  /* Lambert Conformal Conic (GRIB)                        */
-#define  GRID_LCC2                 12  /* Lambert Conformal Conic (PROJ)                        */
-#define  GRID_LAEA                 13  /* Lambert Azimuthal Equal Area                          */
-#define  GRID_SINUSOIDAL           14  /* Sinusoidal                                            */
-#define  GRID_PROJECTION           15  /* Projected coordiantes                                 */
-
-/* ZAXIS types */
-
-#define  ZAXIS_SURFACE              0  /* Surface level                                         */
-#define  ZAXIS_GENERIC              1  /* Generic level                                         */
-#define  ZAXIS_HYBRID               2  /* Hybrid level                                          */
-#define  ZAXIS_HYBRID_HALF          3  /* Hybrid half level                                     */
-#define  ZAXIS_PRESSURE             4  /* Isobaric pressure level in Pascal                     */
-#define  ZAXIS_HEIGHT               5  /* Height above ground in meters                         */
-#define  ZAXIS_DEPTH_BELOW_SEA      6  /* Depth below sea level in meters                       */
-#define  ZAXIS_DEPTH_BELOW_LAND     7  /* Depth below land surface in centimeters               */
-#define  ZAXIS_ISENTROPIC           8  /* Isentropic                                            */
-#define  ZAXIS_TRAJECTORY           9  /* Trajectory                                            */
-#define  ZAXIS_ALTITUDE            10  /* Altitude above mean sea level in meters               */
-#define  ZAXIS_SIGMA               11  /* Sigma level                                           */
-#define  ZAXIS_MEANSEA             12  /* Mean sea level                                        */
-#define  ZAXIS_TOA                 13  /* Norminal top of atmosphere                            */
-#define  ZAXIS_SEA_BOTTOM          14  /* Sea bottom                                            */
-#define  ZAXIS_ATMOSPHERE          15  /* Entire atmosphere                                     */
-#define  ZAXIS_CLOUD_BASE          16  /* Cloud base level                                      */
-#define  ZAXIS_CLOUD_TOP           17  /* Level of cloud tops                                   */
-#define  ZAXIS_ISOTHERM_ZERO       18  /* Level of 0o C isotherm                                */
-#define  ZAXIS_SNOW                19  /* Snow level                                            */
-#define  ZAXIS_LAKE_BOTTOM         20  /* Lake or River Bottom                                  */
-#define  ZAXIS_SEDIMENT_BOTTOM     21  /* Bottom Of Sediment Layer                              */
-#define  ZAXIS_SEDIMENT_BOTTOM_TA  22  /* Bottom Of Thermally Active Sediment Layer             */
-#define  ZAXIS_SEDIMENT_BOTTOM_TW  23  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
-#define  ZAXIS_MIX_LAYER           24  /* Mixing Layer                                          */
-#define  ZAXIS_REFERENCE           25  /* zaxis reference number                                */
-
-/* TIME types */
-
-#define  TIME_CONSTANT              0  /* obsolate, use TSTEP_CONSTANT                          */
-#define  TIME_VARIABLE              1  /* obsolate, use TSTEP_INSTANT                           */
-
-/* TSTEP types */
-
-#define  TSTEP_CONSTANT             0  /* Constant            */
-#define  TSTEP_INSTANT              1  /* Instant             */
-#define  TSTEP_AVG                  2  /* Average             */
-#define  TSTEP_ACCUM                3  /* Accumulation        */
-#define  TSTEP_MAX                  4  /* Maximum             */
-#define  TSTEP_MIN                  5  /* Minimum             */
-#define  TSTEP_DIFF                 6  /* Difference          */
-#define  TSTEP_RMS                  7  /* Root mean square    */
-#define  TSTEP_SD                   8  /* Standard deviation  */
-#define  TSTEP_COV                  9  /* Covariance          */
-#define  TSTEP_RATIO               10  /* Ratio               */
-#define  TSTEP_RANGE               11
-#define  TSTEP_INSTANT2            12
-#define  TSTEP_INSTANT3            13
-
-/* TAXIS types */
-
-#define  TAXIS_ABSOLUTE           1
-#define  TAXIS_RELATIVE           2
-#define  TAXIS_FORECAST           3
-
-/* TUNIT types */
-
-#define  TUNIT_SECOND             1
-#define  TUNIT_MINUTE             2
-#define  TUNIT_QUARTER            3
-#define  TUNIT_30MINUTES          4
-#define  TUNIT_HOUR               5
-#define  TUNIT_3HOURS             6
-#define  TUNIT_6HOURS             7
-#define  TUNIT_12HOURS            8
-#define  TUNIT_DAY                9
-#define  TUNIT_MONTH             10
-#define  TUNIT_YEAR              11
-
-/* CALENDAR types */
-
-#define  CALENDAR_STANDARD        0  /* don't change this value (used also in cgribexlib)! */
-#define  CALENDAR_PROLEPTIC       1
-#define  CALENDAR_360DAYS         2
-#define  CALENDAR_365DAYS         3
-#define  CALENDAR_366DAYS         4
-#define  CALENDAR_NONE            5
-
-/* number of unsigned char needed to store UUID */
-#define  CDI_UUID_SIZE           16
-
-/* CDI control routines */
-
-void    cdiReset(void);
-
-const char *cdiStringError(int cdiErrno);
-
-void    cdiDebug(int debug);
-
-const char *cdiLibraryVersion(void);
-void    cdiPrintVersion(void);
-
-int     cdiHaveFiletype(int filetype);
-
-void    cdiDefMissval(double missval);
-double  cdiInqMissval(void);
-void    cdiDefGlobal(const char *string, int val);
-
-int     namespaceNew();
-void    namespaceSetActive(int namespaceID);
-void    namespaceDelete(int namespaceID);
-
-
-/* CDI converter routines */
-
-/* parameter */
-
-void    cdiParamToString(int param, char *paramstr, int maxlen);
-
-void    cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis);
-int     cdiEncodeParam(int pnum, int pcat, int pdis);
-
-/* date format:  YYYYMMDD */
-/* time format:    hhmmss */
-
-void    cdiDecodeDate(int date, int *year, int *month, int *day);
-int     cdiEncodeDate(int year, int month, int day);
-
-void    cdiDecodeTime(int time, int *hour, int *minute, int *second);
-int     cdiEncodeTime(int hour, int minute, int second);
+void    cdiDecodeTime(int time, int *hour, int *minute, int *second);
+int     cdiEncodeTime(int hour, int minute, int second);
 
 
 /* STREAM control routines */
@@ -893,8 +467,9 @@ int     streamInqTimestep(int streamID, int tsID);
 /*      PIO: query currently set timestep id  */
 int     streamInqCurTimestepID(int streamID);
 
-char   *streamFilename(int streamID);
-char   *streamFilesuffix(int filetype);
+const char* streamFilename(int streamID);
+const char* streamFilesuffix(int filetype);
+
 off_t   streamNvals(int streamID);
 
 int     streamInqNvars ( int streamID );
@@ -917,8 +492,7 @@ void    streamWriteVarSliceF(int streamID, int varID, int levelID, const float *
 void    streamReadVarSlice(int streamID, int varID, int levelID, double *data_vec, int *nmiss);
 void    streamReadVarSliceF(int streamID, int varID, int levelID, float *data_vec, int *nmiss);
 
-void    streamWriteVarChunk(int streamID, int varID, const int rect[][2],
-                            const double *data_vec, int nmiss);
+void    streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double *data_vec, int nmiss);
 
 
 /* STREAM record I/O routines */
@@ -932,6 +506,61 @@ void    streamCopyRecord(int streamIDdest, int streamIDsrc);
 
 void    streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
 
+
+/* File driven I/O (may yield better performance than using the streamXXX functions) */
+
+//Creation & Destruction
+CdiIterator* cdiIterator_new(const char* path);  //Requires a subsequent call to cdiIteratorNextField() to point the iterator at the first field.
+CdiIterator* cdiIterator_clone(CdiIterator* me);
+char* cdiIterator_serialize(CdiIterator* me);  //Returns a malloc'ed string.
+CdiIterator* cdiIterator_deserialize(const char* description);  //description is a string that was returned by cdiIteratorSerialize(). Returns a copy of the original iterator.
+void cdiIterator_print(CdiIterator* me, FILE* stream);
+void cdiIterator_delete(CdiIterator* me);
+
+//Advancing an iterator
+int cdiIterator_nextField(CdiIterator* me);      //Points the iterator at the next field, returns CDI_EEOF if there are no more fields in the file.
+
+//Introspecting metadata
+//All outXXX arguments to these functions may be NULL.
+char* cdiIterator_inqStartTime(CdiIterator* me);      //Returns the (start) time as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+char* cdiIterator_inqEndTime(CdiIterator* me);      //Returns the end time of an integration period as an ISO-8601 coded string, or NULL if there is no end time. The caller is responsible to free() the returned string.
+char* cdiIterator_inqVTime(CdiIterator* me);      //Returns the validity date as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);      //callers are responsible to free() strings that they request
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);       //outValue2 is only written to if the level is a hybrid level
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[CDI_UUID_SIZE]);   //outUuid must point to a buffer of 16 bytes, returns an error code if no generalized zaxis is used.
+CdiParam cdiIterator_inqParam(CdiIterator* me);
+int cdiIterator_inqDatatype(CdiIterator* me);
+int cdiIterator_inqTsteptype(CdiIterator* me);
+char* cdiIterator_inqVariableName(CdiIterator* me);        //The caller is responsible to free() the returned buffer.
+int cdiIterator_inqGridId(CdiIterator* me);         //The returned id is only valid until the next call to cdiIteratorNextField().
+
+//Reading data
+void cdiIterator_readField(CdiIterator* me, double* data_vec, size_t* nmiss);
+void cdiIterator_readFieldF(CdiIterator* me, float* data_vec, size_t* nmiss);
+//TODO[NH]: Add functions to read partial fields.
+
+
+//Direct access to grib fields
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me);  //Returns NULL if the associated file is not a GRIB file.
+void cdiGribIterator_delete(CdiGribIterator* me);
+
+//Callthroughs to GRIB-API
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* value); //Same semantics as grib_get_long().
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* value); //Same semantics as grib_get_double().
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_length().
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* value, size_t* length);       //Same semantics as grib_get_string().
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_size().
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* value, size_t* array_size);       //Same semantics as grib_get_long_array().
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* value, size_t* array_size);       //Same semantics as grib_get_double_array().
+
+//Convenience functions for accessing GRIB-API keys
+int cdiGribIterator_inqEdition(CdiGribIterator* me);
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue); //Returns the default value if the given key is not present.
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue); //Returns the default value if the given key is not present.
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key);        //Returns a malloc'ed string.
+
 /* VLIST routines */
 
 /*      vlistCreate: Create a variable list */
@@ -1060,6 +689,9 @@ void    vlistDefVarName(int vlistID, int varID, const char *name);
 /*      vlistInqVarName: Get the name of a Variable */
 void    vlistInqVarName(int vlistID, int varID, char *name);
 
+/*      vlistCopyVarName: Safe and convenient version of vlistInqVarName */
+char* vlistCopyVarName(int vlistId, int varId);
+
 /*      vlistDefVarStdname: Define the standard name of a Variable */
 void    vlistDefVarStdname(int vlistID, int varID, const char *stdname);
 
@@ -1175,7 +807,7 @@ int     gridInqMaskGME(int gridID, int *mask_vec);
 void    gridDefMask(int gridID, const int *mask_vec);
 int     gridInqMask(int gridID, int *mask_vec);
 
-void    gridPrint(int gridID, int opt);
+void    gridPrint(int gridID, int index, int opt);
 
 /*      gridCreate: Create a horizontal Grid */
 int     gridCreate(int gridtype, int size);
@@ -1361,7 +993,7 @@ void    gridDefYbounds(int gridID, const double *ybounds_vec);
 /*      gridInqYbounds: Get the bounds of a Y-axis */
 int     gridInqYbounds(int gridID, double *ybounds_vec);
 
-void    gridDefRowlon(int gridID, int nrowlon, const int rowlon_vec[]);
+void    gridDefRowlon(int gridID, int nrowlon, const int* rowlon_vec);
 void    gridInqRowlon(int gridID, int *rowlon_vec);
 void    gridChangeType(int gridID, int gridtype);
 
@@ -1389,7 +1021,7 @@ int     zaxisDuplicate(int zaxisID);
 
 void    zaxisResize(int zaxisID, int size);
 
-void    zaxisPrint(int zaxisID);
+void    zaxisPrint(int zaxisID, int index);
 
 /*      zaxisDefLevels: Define the levels of a Z-axis */
 void    zaxisDefLevels(int zaxisID, const double *levels_vec);
@@ -1549,7 +1181,7 @@ int     taxisInqType(int taxisID);
 
 int     taxisInqNumavg(int taxisID);
 
-char   *tunitNamePtr(int tunitID);
+const char* tunitNamePtr(int tunitID);
 
 
 /* Institut routines */
@@ -1560,7 +1192,7 @@ int     institutInqNumber(void);
 int     institutInqCenter(int instID);
 int     institutInqSubcenter(int instID);
 const char *institutInqNamePtr(int instID);
-char   *institutInqLongnamePtr(int instID);
+const char* institutInqLongnamePtr(int instID);
 
 /* Model routines */
 
@@ -1578,7 +1210,7 @@ void    tableWrite(const char *filename, int tableID);
 int     tableRead(const char *tablefile);
 int     tableDef(int modelID, int tablenum, const char *tablename);
 
-char   *tableInqNamePtr(int tableID);
+const char* tableInqNamePtr(int tableID);
 void    tableDefEntry(int tableID, int code, const char *name, const char *longname, const char *units);
 
 int     tableInq(int modelID, int tablenum, const char *tablename);
@@ -1622,40 +1254,63 @@ void gribapiLibraryVersion(int *major_version, int *minor_version, int *revision
  * require-trailing-newline: t
  * End:
  */
-#ifndef  _TIMEBASE_H
-#define  _TIMEBASE_H
-
-#include <inttypes.h>
+#ifndef _BASETIME_H
+#define _BASETIME_H
 
-/* date format:  YYYYMMDD */
-/* time format:  hhmmss   */
+//#define USE_TIMECACHE 1
+#define MAX_TIMECACHE_SIZE 1024
 
-void decode_julday(int calendar, int julday, int *year, int *mon, int *day);
-int  encode_julday(int calendar, int year, int month, int day);
+typedef struct {
+  int size;
+  int startid;
+  int maxvals;
+  double cache[MAX_TIMECACHE_SIZE];
+}
+timecache_t;
 
-int date_to_julday(int calendar, int date);
-int julday_to_date(int calendar, int julday);
+typedef struct {
+  int   ncvarid;
+  int   ncdimid;
+  int   ncvarboundsid;
+  int   leadtimeid;
+  int   lwrf;     /* TRUE for time axis in WRF format */
+  timecache_t *timevar_cache;
+}
+basetime_t;
 
-int time_to_sec(int time);
-int sec_to_time(int secofday);
+void basetimeInit(basetime_t *basetime);
 
-void   julday_add_seconds(int64_t seconds, int *julday, int *secofday);
-void   julday_add(int days, int secs, int *julday, int *secofday);
-double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs);
+#endif  /* _BASETIME_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday);
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second);
+#include <stdio.h>
 
-#endif  /* _TIMEBASE_H */
-#ifndef _CALENDAR_H
-#define _CALENDAR_H
 
-void encode_caldaysec(int calendar, int year, int month, int day, int hour, int minute, int second,
-		      int *julday, int *secofday);
-void decode_caldaysec(int calendar, int julday, int secofday, 
-		      int *year, int *month, int *day, int *hour, int *minute, int *second);
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
 
-#endif  /* _CALENDAR_H */
+void basetimeInit(basetime_t *basetime)
+{
+  if ( basetime == NULL )
+    Error("Internal problem! Basetime not allocated.");
+
+  basetime->ncvarid       = UNDEFID;
+  basetime->ncdimid       = UNDEFID;
+  basetime->ncvarboundsid = UNDEFID;
+  basetime->leadtimeid    = UNDEFID;
+  basetime->lwrf          = 0;
+  basetime->timevar_cache = NULL;
+}
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -1665,33 +1320,57 @@ void decode_caldaysec(int calendar, int julday, int secofday,
  * require-trailing-newline: t
  * End:
  */
-#ifndef _BASETIME_H
-#define _BASETIME_H
+#ifndef _FILE_H
+#define _FILE_H
 
-//#define USE_TIMECACHE 1
-#define MAX_TIMECACHE_SIZE 1024
+#include <stdio.h>
+#include <sys/types.h>
 
-typedef struct {
-  int size;
-  int startid;
-  int maxvals;
-  double cache[MAX_TIMECACHE_SIZE];
-}
-timecache_t;
 
-typedef struct {
-  int   ncvarid;
-  int   ncdimid;
-  int   ncvarboundsid;
-  int   leadtimeid;
-  int   lwrf;     /* TRUE for time axis in WRF format */
-  timecache_t *timevar_cache;
-}
-basetime_t;
+#define  FILE_UNDEFID      -1
 
-void basetimeInit(basetime_t *basetime);
+#define  FILE_TYPE_OPEN     1
+#define  FILE_TYPE_FOPEN    2
 
-#endif  /* _BASETIME_H */
+/* buffer types for FILE_TYPE_OPEN */
+#define  FILE_BUFTYPE_STD   1
+#define  FILE_BUFTYPE_MMAP  2
+
+const
+char  *fileLibraryVersion(void);
+
+void   fileDebug(int debug);
+
+void  *filePtr(int fileID);
+
+int    fileSetBufferType(int fileID, int type);
+void   fileSetBufferSize(int fileID, long buffersize);
+
+int    fileOpen(const char *filename, const char *mode);
+int    fileOpen_serial(const char *filename, const char *mode);
+int    fileClose(int fileID);
+int    fileClose_serial(int fileID);
+
+char  *fileInqName(int fileID);
+int    fileInqMode(int fileID);
+
+int    fileFlush(int fileID);
+void   fileClearerr(int fileID);
+int    fileEOF(int fileID);
+int    filePtrEOF(void *fileptr);
+void   fileRewind(int fileID);
+
+off_t  fileGetPos(int fileID);
+int    fileSetPos(int fileID, off_t offset, int whence);
+
+int    fileGetc(int fileID);
+int    filePtrGetc(void *fileptr);
+
+size_t filePtrRead(void *fileptr, void *restrict ptr, size_t size);
+size_t fileRead(int fileID, void *restrict ptr, size_t size);
+size_t fileWrite(int fileID, const void *restrict ptr, size_t size);
+
+#endif  /* _FILE_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -1701,12 +1380,9 @@ void basetimeInit(basetime_t *basetime);
  * require-trailing-newline: t
  * End:
  */
-typedef struct
-{
-  long date;
-  long time;
-}
-DateTime;
+
+void swap4byte(void *ptr, size_t size);
+void swap8byte(void *ptr, size_t size);
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -1716,83 +1392,54 @@ DateTime;
  * require-trailing-newline: t
  * End:
  */
-#ifndef NAMESPACE_H
-#define NAMESPACE_H
+#ifndef _DTYPES_H
+#define _DTYPES_H
 
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
+#include <stdio.h>
+#include <limits.h>
+
+/* INT32 */
+
+#if ! defined (INT_MAX)
+#  error INT_MAX undefined
 #endif
 
+#undef  INT32
+#if  INT_MAX == 2147483647L
+#  define  INT32  int
+#elif LONG_MAX == 2147483647L
+#  define  INT32  long
+#endif
 
-typedef enum {
-  STAGE_DEFINITION = 0,
-  STAGE_TIMELOOP   = 1,
-  STAGE_CLEANUP    = 2,
-  STAGE_UNUSED     = 3,
-} statusCode;
+/* INT64 */
 
-typedef struct {
-  int idx;
-  int nsp;
-} namespaceTuple_t;
+#if ! defined (LONG_MAX)
+#  error LONG_MAX undefined
+#endif
 
-enum namespaceSwitch
-{
-  NSSWITCH_NO_SUCH_SWITCH = -1,
-  NSSWITCH_ABORT,
-  NSSWITCH_WARNING,
-  NSSWITCH_SERIALIZE_GET_SIZE,
-  NSSWITCH_SERIALIZE_PACK,
-  NSSWITCH_SERIALIZE_UNPACK,
-  NSSWITCH_FILE_OPEN,
-  NSSWITCH_FILE_WRITE,
-  NSSWITCH_FILE_CLOSE,
-  NSSWITCH_STREAM_OPEN_BACKEND,
-  NSSWITCH_STREAM_DEF_VLIST_,
-  NSSWITCH_STREAM_WRITE_VAR_,
-  NSSWITCH_STREAM_WRITE_VAR_CHUNK_,
-  NSSWITCH_STREAM_WRITE_VAR_PART_,
-  NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_,
-  NSSWITCH_STREAM_CLOSE_BACKEND,
-  NSSWITCH_STREAM_DEF_TIMESTEP_,
-  NSSWITCH_STREAM_SYNC,
-#ifdef HAVE_LIBNETCDF
-  NSSWITCH_NC__CREATE,
-  NSSWITCH_CDF_DEF_VAR,
-  NSSWITCH_CDF_DEF_TIMESTEP,
-  NSSWITCH_CDF_STREAM_SETUP,
+#undef  INT64
+#if  LONG_MAX > 2147483647L
+#  define  INT64  long
+#else
+#  define  INT64  long long
 #endif
-  NUM_NAMESPACE_SWITCH,
-};
 
-union namespaceSwitchValue
-{
-  void *data;
-  void (*func)();
-};
+/* FLT32 */
 
-#define NSSW_FUNC(p) ((union namespaceSwitchValue){ .func = (void (*)())(p) })
-#define NSSW_DATA(p) ((union namespaceSwitchValue){ .data = (void *)(p) })
+#undef   FLT32
+#define  FLT32  float
 
-int              namespaceNew();
-void             namespaceDelete(int namespaceID);
-void             namespaceCleanup      ( void );
-int              namespaceGetNumber    ( void );
-void namespaceSetActive(int namespaceID);
-int              namespaceGetActive    ( void );
-int              namespaceIdxEncode    ( namespaceTuple_t );
-int              namespaceIdxEncode2   ( int, int );
-namespaceTuple_t namespaceResHDecode   ( int );
-int              namespaceAdaptKey     ( int originResH, int originNamespace);
-int              namespaceAdaptKey2    ( int );
-void             namespaceDefResStatus ( statusCode );
-statusCode       namespaceInqResStatus ( void );
-void namespaceSwitchSet(enum namespaceSwitch sw,
-                        union namespaceSwitchValue value);
-union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw);
+/* FLT64 */
 
+#undef   FLT64
+#define  FLT64  double
 
-#endif
+/* UINT32 and UINT64 */
+
+#define  UINT32   unsigned INT32
+#define  UINT64   unsigned INT64
+
+#endif  /* _DTYPES_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -1802,238 +1449,295 @@ union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw);
  * require-trailing-newline: t
  * End:
  */
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
+#ifndef _BINARY_H
+#define _BINARY_H
+
+#include <stdio.h>
+
+#ifndef _DTYPES_H
 #endif
 
-#include <inttypes.h>
-#include <sys/types.h>
 
-void
-memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
+UINT32 get_UINT32(unsigned char *x);
+UINT32 get_SUINT32(unsigned char *x);
+UINT64 get_UINT64(unsigned char *x);
+UINT64 get_SUINT64(unsigned char *x);
 
-void
-memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
-               size_t elem_size);
 
-uint32_t
-memcrc_finish(uint32_t *state, off_t total_size);
+size_t binReadF77Block(int fileID, int byteswap);
+void   binWriteF77Block(int fileID, int byteswap, size_t blocksize);
 
-uint32_t
-memcrc(const unsigned char *b, size_t n);
+int binReadInt32(int fileID, int byteswap, size_t size, INT32 *ptr);
+int binReadInt64(int fileID, int byteswap, size_t size, INT64 *ptr);
 
-#ifndef CDI_CKSUM_H_
-#define CDI_CKSUM_H_
+int binWriteInt32(int fileID, int byteswap, size_t size, INT32 *ptr);
+int binWriteInt64(int fileID, int byteswap, size_t size, INT64 *ptr);
 
-#include <inttypes.h>
+int binReadFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
+int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
 
-uint32_t cdiCheckSum(int type, int count, const void *data);
+int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
+int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
 
-#endif
+#endif  /* _BINARY_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
 #if defined (HAVE_CONFIG_H)
-#  include "config.h"
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
 
-#if !defined (NAMESPACE_H)
-#include "namespace.h"
-#endif
 
-int _ExitOnError   = 1;	/* If set to 1, exit on error       */
-int _Verbose = 1;	/* If set to 1, errors are reported */
-int _Debug   = 0;       /* If set to 1, debugging           */
+#undef  IsBigendian
+#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
 
 
-void SysError_(const char *caller, const char *fmt, ...)
+UINT32 get_UINT32(unsigned char *x)
 {
-  va_list args;
-
-  va_start(args, fmt);
+  /* IsBigendian returns 1 for big endian byte order */
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  printf("\n");
-   fprintf(stderr, "Error (%s) : ", caller);
-  vfprintf(stderr, fmt, args);
-   fprintf(stderr, "\n");
+  if ( IsBigendian() )
+    return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
+  else
+    return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
+}
 
-  va_end(args);
 
-  if ( errno )
-    perror("System error message ");
+UINT32 get_SUINT32(unsigned char *x)
+{
+  /* IsBigendian returns 1 for big endian byte order */
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  exit(EXIT_FAILURE);
+  if ( IsBigendian() )
+    return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
+  else
+    return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
 }
 
 
-void Error_(const char *caller, const char *fmt, ...)
+UINT64 get_UINT64(unsigned char *x)
 {
-  va_list args;
+  /* IsBigendian returns 1 for big endian byte order */
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  va_start(args, fmt);
+  if ( IsBigendian() )
+    return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
+		    ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
+  else
+    return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
+		    ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
+}
 
-  printf("\n");
-   fprintf(stderr, "Error (%s) : ", caller);
-  vfprintf(stderr, fmt, args);
-   fprintf(stderr, "\n");
 
-  va_end(args);
+UINT64 get_SUINT64(unsigned char *x)
+{
+  /* IsBigendian returns 1 for big endian byte order */
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  if ( _ExitOnError ) exit(EXIT_FAILURE);
+  if ( IsBigendian() )
+    return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
+		    ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
+  else
+    return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
+		    ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
 }
 
-typedef void (*cdiAbortCFunc)(const char * caller, const char * filename,
-                              const char *functionname, int line,
-                              const char * errorString, va_list ap)
-#ifdef __GNUC__
-  __attribute__((noreturn))
-#endif
-;
 
-void cdiAbortC(const char * caller, const char * filename,
-               const char *functionname, int line,
-               const char * errorString, ... )
+size_t binReadF77Block(int fileID, int byteswap)
 {
-  va_list ap;
-  va_start(ap, errorString);
-  cdiAbortCFunc cdiAbortC_p
-    = (cdiAbortCFunc)namespaceSwitchGet(NSSWITCH_ABORT).func;
-  cdiAbortC_p(caller, filename, functionname, line, errorString, ap);
-  va_end(ap);
-}
+  unsigned char f77block[4];
+  size_t blocklen = 0;
 
-void
-cdiAbortC_serial(const char *caller, const char *filename,
-                 const char *functionname, int line,
-                 const char *errorString, va_list ap)
-{
-  fprintf(stderr, "ERROR, %s, %s, line %d%s%s\nerrorString: \"",
-          functionname, filename, line, caller?", called from ":"",
-          caller?caller:"");
-  vfprintf(stderr, errorString, ap);
-  fputs("\"\n", stderr);
-  exit(EXIT_FAILURE);
+  if ( fileRead(fileID, f77block, 4) == 4 )
+    {
+      if ( byteswap )
+	blocklen = get_SUINT32(f77block);
+      else
+	blocklen =  get_UINT32(f77block);
+    }
+
+  return (blocklen);
 }
 
-typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
-                               va_list ap);
 
-void Warning_(const char *caller, const char *fmt, ...)
+void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
 {
-  va_list args;
-
-  va_start(args, fmt);
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
+  unsigned char f77block[4];
 
-  if ( _Verbose )
+  if ( IsBigendian() )
     {
-      cdiWarningFunc cdiWarning_p
-        = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
-      cdiWarning_p(caller, fmt, args);
+      if ( byteswap )
+	{
+	  f77block[0] = (unsigned char) (blocksize);
+	  f77block[1] = (unsigned char) (blocksize >>  8);
+	  f77block[2] = (unsigned char) (blocksize >> 16);
+	  f77block[3] = (unsigned char) (blocksize >> 24);
+	}
+      else
+	{
+	  f77block[3] = (unsigned char) (blocksize);
+	  f77block[2] = (unsigned char) (blocksize >>  8);
+	  f77block[1] = (unsigned char) (blocksize >> 16);
+	  f77block[0] = (unsigned char) (blocksize >> 24);
+	}
+    }
+  else
+    {
+      if ( byteswap )
+	{
+	  f77block[3] = (unsigned char) (blocksize);
+	  f77block[2] = (unsigned char) (blocksize >>  8);
+	  f77block[1] = (unsigned char) (blocksize >> 16);
+	  f77block[0] = (unsigned char) (blocksize >> 24);
+	}
+      else
+	{
+	  f77block[0] = (unsigned char) (blocksize);
+	  f77block[1] = (unsigned char) (blocksize >>  8);
+	  f77block[2] = (unsigned char) (blocksize >> 16);
+	  f77block[3] = (unsigned char) (blocksize >> 24);
+	}
     }
 
-  va_end(args);
+  if ( fileWrite(fileID, f77block, 4) != 4 )
+    Error("write failed on %s", fileInqName(fileID));
 }
 
-void cdiWarning(const char *caller, const char *fmt, va_list ap)
+
+int binReadInt32(int fileID, int byteswap, size_t size, INT32 *ptr)
 {
-  fprintf(stderr, "Warning (%s) : ", caller);
-  vfprintf(stderr, fmt, ap);
-  fputc('\n', stderr);
+  if ( sizeof(INT32) == 4 )
+    {
+      fileRead(fileID, (void *) ptr, 4*size);
+      if ( byteswap ) swap4byte(ptr, size);
+    }
+  else
+    {
+      Error("not implemented for %d byte integer", sizeof(INT32));
+    }
+
+  return (0);
 }
 
 
-void Message_(const char *caller, const char *fmt, ...)
+int binReadInt64(int fileID, int byteswap, size_t size, INT64 *ptr)
 {
-  va_list args;
+  if ( sizeof(INT64) == 8 )
+    {
+      fileRead(fileID, (void *) ptr, 8*size);
+      if ( byteswap ) swap8byte(ptr, size);
+    }
+  else
+    {
+      Error("not implemented for %d byte integer", sizeof(INT64));
+    }
 
-  va_start(args, fmt);
+  return (0);
+}
 
-   fprintf(stdout, "%-18s : ", caller);
-  vfprintf(stdout, fmt, args);
-   fprintf(stdout, "\n");
 
-  va_end(args);
+int binReadFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr)
+{
+  if ( sizeof(FLT32) == 4 )
+    {
+      fileRead(fileID, (void *) ptr, 4*size);
+      if ( byteswap ) swap4byte(ptr, size);
+    }
+  else
+    {
+      Error("not implemented for %d byte float", sizeof(FLT32));
+    }
+
+  return (0);
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _ERROR_H
-#define _ERROR_H
 
-#include <stdarg.h>
-#include <stdlib.h>
 
-#ifndef  WITH_CALLER_NAME
-#define  WITH_CALLER_NAME
-#endif
+int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr)
+{
+  if ( sizeof(FLT64) == 8 )
+    {
+      fileRead(fileID, (void *) ptr, 8*size);
+      if ( byteswap ) swap8byte(ptr, size);
+    }
+  else
+    {
+      Error("not implemented for %d byte float", sizeof(FLT64));
+    }
 
-#define  _FATAL     1     /* Error flag: exit on error  */
-#define  _VERBOSE   2     /* Error flag: report errors  */
-#define  _DEBUG     4     /* Error flag: debug          */
+  return (0);
+}
 
-extern int _ExitOnError;  /* If set to 1, exit on error (default 1)       */
-extern int _Verbose;      /* If set to 1, errors are reported (default 1) */
-extern int _Debug;        /* If set to 1, debuggig (default 0)            */
 
-void SysError_(const char *caller, const char *fmt, ...);
-void    Error_(const char *caller, const char *fmt, ...);
-void  Warning_(const char *caller, const char *fmt, ...);
-/* delegate used by Warning_ unless mode is PIO */
-void cdiWarning(const char *caller, const char *fmt, va_list ap);
-void  Message_(const char *caller, const char *fmt, ...);
+int binWriteInt32(int fileID, int byteswap, size_t size, INT32 *ptr)
+{
+  if ( sizeof(INT32) == 4 )
+    {
+      if ( byteswap ) swap4byte(ptr, size);
+      fileWrite(fileID, (void *) ptr, 4*size);
+    }
+  else
+    {
+      Error("not implemented for %d byte integer", sizeof(INT32));
+    }
 
-#if  defined  WITH_CALLER_NAME
-#  define  SysError(...)  SysError_(__func__, __VA_ARGS__)
-#  define    Errorc(...)     Error_(  caller, __VA_ARGS__)
-#  define     Error(...)     Error_(__func__, __VA_ARGS__)
-#  define   Warning(...)   Warning_(__func__, __VA_ARGS__)
-#  define  Messagec(...)   Message_(  caller, __VA_ARGS__)
-#  define   Message(...)   Message_(__func__, __VA_ARGS__)
-#else
-#  define  SysError(...)  SysError_((void *), __VA_ARGS__)
-#  define    Errorc(...)     Error_((void *), __VA_ARGS__)
-#  define     Error(...)     Error_((void *), __VA_ARGS__)
-#  define   Warning(...)   Warning_((void *), __VA_ARGS__)
-#  define  Messagec(...)   Message_((void *), __VA_ARGS__)
-#  define   Message(...)   Message_((void *), __VA_ARGS__)
-#endif
+  return (0);
+}
 
-/* If we're not using GNU C, elide __attribute__ */
-#ifndef __GNUC__
-#  define  __attribute__(x)  /*NOTHING*/
-#endif
 
-void cdiAbortC(const char *caller, const char *filename,
-               const char *functionname, int line,
-               const char *errorString, ... )
-  __attribute__((noreturn));
-#define xabortC(caller, ...)                                    \
-  cdiAbortC(caller, __FILE__, __func__, __LINE__, __VA_ARGS__ )
-#define xabort(...)                                             \
-  cdiAbortC(NULL, __FILE__, __func__, __LINE__, __VA_ARGS__ )
-#define cdiAbort(file, func, line, ...)                 \
-  cdiAbortC(NULL, (file), (func), (line), __VA_ARGS__)
+int binWriteInt64(int fileID, int byteswap, size_t size, INT64 *ptr)
+{
+  if ( sizeof(INT64) == 8 )
+    {
+      if ( byteswap ) swap8byte(ptr, size);
+      fileWrite(fileID, (void *) ptr, 8*size);
+    }
+  else
+    {
+      Error("not implemented for %d byte integer", sizeof(INT64));
+    }
 
-#define xassert(arg) do {                       \
-    if ((arg)) { } else {                       \
-      xabort("assertion failed");}              \
-  } while(0)
+  return (0);
+}
 
-void
-cdiAbortC_serial(const char *caller, const char *filename,
-                 const char *functionname, int line,
-                 const char *errorString, va_list ap)
-  __attribute__((noreturn));
 
-#endif  /* _ERROR_H */
+int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr)
+{
+  if ( sizeof(FLT32) == 4 )
+    {
+      if ( byteswap ) swap4byte(ptr, size);
+      fileWrite(fileID, (void *) ptr, 4*size);
+    }
+  else
+    {
+      Error("not implemented for %d byte float", sizeof(FLT32));
+    }
+
+  return (0);
+}
+
+
+int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr)
+{
+  if ( sizeof(FLT64) == 8 )
+    {
+      if ( byteswap ) swap8byte(ptr, size);
+      fileWrite(fileID, (void *) ptr, 8*size);
+    }
+  else
+    {
+      Error("not implemented for %d byte float", sizeof(FLT64));
+    }
+
+  return (0);
+}
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2043,718 +1747,358 @@ cdiAbortC_serial(const char *caller, const char *filename,
  * require-trailing-newline: t
  * End:
  */
-#ifndef _CDI_INT_H
-#define _CDI_INT_H
+#ifndef  _TIMEBASE_H
+#define  _TIMEBASE_H
 
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
-#endif
+#include <inttypes.h>
 
-#include <assert.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
+/* date format:  YYYYMMDD */
+/* time format:  hhmmss   */
 
-/* dummy use of unused parameters to silence compiler warnings */
-#define  UNUSED(x) (void)x
+void decode_julday(int calendar, int julday, int *year, int *mon, int *day);
+int  encode_julday(int calendar, int year, int month, int day);
 
-#ifndef strdupx
-#ifndef strdup
-char *strdup(const char *s);
-#endif
-#define strdupx  strdup
-/*
-#define strdupx(s)			          \
-({					      	  \
-   const char *__old = (s);			  \
-   size_t __len = strlen(__old) + 1;		  \
-   char *__new = (char *) malloc(__len);	  \
-   (char *) memcpy(__new, __old, __len);	  \
-})
-*/
-#endif
+int date_to_julday(int calendar, int date);
+int julday_to_date(int calendar, int julday);
 
-#ifndef  M_PI
-#define  M_PI        3.14159265358979323846  /* pi */
-#endif
+int time_to_sec(int time);
+int sec_to_time(int secofday);
 
+void   julday_add_seconds(int64_t seconds, int *julday, int *secofday);
+void   julday_add(int days, int secs, int *julday, int *secofday);
+double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs);
 
-#ifndef  _ERROR_H
-#  include "error.h"
-#endif
-#ifndef _BASETIME_H
-#  include "basetime.h"
-#endif
-#ifndef _TIMEBASE_H
-#  include "timebase.h"
-#endif
-#ifndef  _TAXIS_H
-#  include "taxis.h"
-#endif
-#ifndef  _CDI_LIMITS_H
-#  include "cdi_limits.h"
-#endif
-#ifndef  _SERVICE_H
-#  include "service.h"
-#endif
-#ifndef  _EXTRA_H
-#  include "extra.h"
-#endif
-#ifndef  _IEG_H
-#  include "ieg.h"
-#endif
-#ifndef RESOURCE_HANDLE_H
-#  include "resource_handle.h"
-#endif
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday);
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second);
 
-#include "cdi.h"
+#endif  /* _TIMEBASE_H */
+#include <limits.h>
+#include <stdio.h>
 
-#define check_parg(arg)  if ( arg == 0 ) Warning("Argument '" #arg "' not allocated!")
 
-#if defined (__xlC__) /* performance problems on IBM */
-#ifndef DBL_IS_NAN
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#else
-#ifndef DBL_IS_NAN
-#if  defined  (HAVE_DECL_ISNAN)
-#  define DBL_IS_NAN(x)     (isnan(x))
-#elif  defined  (FP_NAN)
-#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
-#else
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#endif
-#endif
 
-#ifndef DBL_IS_EQUAL
-/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
-#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)):!(x < y || y < x))
-#endif
+static int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
+static int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-#ifndef IS_EQUAL
-#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
-#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
-#endif
 
+int calendar_dpy(int calendar)
+{
+  int dpy = 0;
 
-#define  FALSE  0
-#define  TRUE   1
+  if      ( calendar == CALENDAR_360DAYS ) dpy = 360;
+  else if ( calendar == CALENDAR_365DAYS ) dpy = 365;
+  else if ( calendar == CALENDAR_366DAYS ) dpy = 366;
 
-#define  TYPE_REC  0
-#define  TYPE_VAR  1
+  return (dpy);
+}
 
-#define  MEMTYPE_DOUBLE  1
-#define  MEMTYPE_FLOAT   2
 
-typedef struct
+int days_per_month(int calendar, int year, int month)
 {
-  void     *buffer;             /* gribapi, cgribex */
-  size_t    buffersize;         /* gribapi, cgribex */
-  off_t     position;           /* ieg */
-  int       param;              /* srv */
-  int       level;              /* ext, srv */
-  int       date;               /* ext, srv */
-  int       time;               /* srv */
-  int       gridID;             /* ieg, ext */
-  int       varID;              /* ieg */
-  int       levelID;            /* ieg  */
-  int       prec;               /* ext, srv */
-  int       sec0[2];            /* cgribex */
-  int       sec1[1024];         /* cgribex */
-  int       sec2[4096];         /* cgribex */
-  int       sec3[2];            /* cgribex */
-  int       sec4[512];          /* cgribex */
-  void     *exsep;              /* ieg, ext, srv */
-}
-Record;
+  int dayspermonth = 0;
+  int *dpm = NULL;
+  int dpy;
 
+  dpy = calendar_dpy(calendar);
 
-typedef struct
-{
-  off_t     position;
-  size_t    size;
-  int       zip;
-  int       param;
-  int       ilevel;
-  int       ilevel2;
-  int       ltype;
-  int       tsteptype;
-  short     used;
-  short     varID;
-  short     levelID;
-  char      varname[32]; /* needed for grib decoding with GRIB_API */
-}
-record_t;
+  if      ( dpy == 360 ) dpm = month_360;
+  else if ( dpy == 365 ) dpm = month_365;
+  else                   dpm = month_366;
 
+  if ( month >= 1 && month <= 12 )
+    dayspermonth = dpm[month-1];
+  /*
+  else
+    fprintf(stderr, "days_per_month: month %d out of range\n", month);
+  */
+  if ( dpy == 0 && month == 2 )
+    {
+      if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
+	dayspermonth = 29;
+      else
+	dayspermonth = 28;
+    }
 
-typedef struct {
-  record_t *records;
-  int       recordSize;  /* number of allocated records           */
-  int      *recIDs;      /* IDs of non constant records           */
-  int       nrecs;       /* number of used records                */
-                         /* tsID=0 nallrecs                       */
-                         /* tsID>0 number of non constant records */
-  int       nallrecs;    /* number of all records                 */
-  int       curRecID;    /* current record ID                     */
-  long      next;
-  off_t     position;    /* timestep file position                */
-  taxis_t   taxis;
+  return (dayspermonth);
 }
-tsteps_t;
 
 
-typedef struct {
-  int       ncvarid;
-  int       nlevs;
-  int      *level;       /* record IDs */
-  int      *lindex;      /* level index */
-  int       defmiss;     /* TRUE if missval is defined in file */
+int days_per_year(int calendar, int year)
+{
+  int daysperyear;
+  int dpy;
 
-  int       isUsed;
-  int       gridID;
-  int       zaxisID;
-  int       tsteptype;   /* TSTEP_* */
-}
-svarinfo_t;
+  dpy = calendar_dpy(calendar);
 
+  if ( dpy == 0 )
+    {
+      if ( calendar == CALENDAR_STANDARD )
+	{
+	  if ( year == 1582 )
+	    dpy = 355;
+	  else if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
+	    dpy = 366;
+	  else
+	    dpy = 365;
+	}
+      else
+	{
+	  if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
+	    dpy = 366;
+	  else
+	    dpy = 365;
+	}
+    }
 
-typedef struct {
-  int       ilev;
-  int       mlev;
-  int       ilevID;
-  int       mlevID;
+  daysperyear = dpy;
+  
+  return (daysperyear);
 }
-VCT;
 
 
-typedef struct {
-  int         self;
-  int         accesstype;   /* TYPE_REC or TYPE_VAR */
-  int         accessmode;
-  int         filetype;
-  int         byteorder;
-  int         fileID;
-  int         filemode;
-  off_t       numvals;
-  char       *filename;
-  Record     *record;
-  int         nrecs;        /* number of records                  */
-  int         nvars;        /* number of variables                */
-  svarinfo_t *vars;
-  int         varsAllocated;
-  int         curTsID;      /* current timestep ID */
-  int         rtsteps;      /* number of tsteps accessed       */
-  long        ntsteps;      /* number of tsteps : only set if all records accessed */
-  tsteps_t   *tsteps;
-  int         tstepsTableSize;
-  int         tstepsNextID;
-  basetime_t  basetime;
-  int         ncmode;
-  int         vlistID;
-  int         xdimID[MAX_GRIDS_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
-  int         ydimID[MAX_GRIDS_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
-  int         zaxisID[MAX_ZAXES_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->zaxisIDs
-  int         ncxvarID[MAX_GRIDS_PS];
-  int         ncyvarID[MAX_GRIDS_PS];
-  int         ncavarID[MAX_GRIDS_PS];
-  int         historyID;
-  int         globalatts;
-  int         localatts;
-  VCT         vct;
-  int         unreduced;
-  int         sortname;
-  int         have_missval;
-  int         comptype;      // compression type
-  int         complevel;     // compression level
-#if defined (GRIBCONTAINER2D)
-  void      **gribContainers;
-#else
-  void       *gribContainers;
-#endif
-  int         vlistIDorig;
-  /* only used by MPI-parallelized version of library */
-  int       ownerRank;    // MPI rank of owner process
-  /* ---------------------------------- */
-  /* Local change: 2013-02-18, FP (DWD) */
-  /* ---------------------------------- */
+static void decode_day(int dpy, int days, int *year, int *month, int *day)
+{
+  int i = 0;
+  int *dpm = NULL;
 
-  void *gh; // grib handle
-}
-stream_t;
+  *year = (days-1) / dpy;
+  days -= (*year*dpy);
 
+  if      ( dpy == 360 ) dpm = month_360;
+  else if ( dpy == 365 ) dpm = month_365;
+  else if ( dpy == 366 ) dpm = month_366;
 
-extern int CDI_Debug;      /* If set to 1, debuggig (default 0)            */
-extern int cdiGribApiDebug;
-extern double cdiDefaultMissval;
-extern int cdiDefaultInstID;
-extern int cdiDefaultModelID;
-extern int cdiDefaultTableID;
-extern int cdiDefaultLeveltype;
-//extern int cdiNcMissingValue;
-extern int cdiNcChunksizehint;
-extern int cdiChunkType;
-extern int cdiSplitLtype105;
-extern int cdiDataUnreduced;
-extern int cdiSortName;
-extern int cdiHaveMissval;
-extern int STREAM_Debug;
+  if ( dpm )
+    for ( i = 0; i < 12; i++ )
+      {
+	if ( days > dpm[i] ) days -= dpm[i];
+	else break;
+      }
 
+  *month = i + 1;
+  *day   = days;
+}
 
-extern char *cdiPartabPath;
-extern int   cdiPartabIntern;
-extern const resOps streamOps;
 
-static inline stream_t *
-stream_to_pointer(int idx)
+static int encode_day(int dpy, int year, int month, int day)
 {
-  return reshGetVal(idx, &streamOps);
-}
+  int i;
+  int *dpm = NULL;
+  long rval = (long)dpy * year + day;
 
-static inline void
-stream_check_ptr(const char *caller, stream_t *streamptr)
-{
-  if ( streamptr == NULL )
-    Errorc("stream undefined!");
-}
+  if      ( dpy == 360 ) dpm = month_360;
+  else if ( dpy == 365 ) dpm = month_365;
+  else if ( dpy == 366 ) dpm = month_366;
 
-int     streamInqFileID(int streamID);
+  if ( dpm ) for ( i = 0; i < month-1; i++ ) rval += dpm[i];
+  if (rval > INT_MAX || rval < INT_MIN)
+    Error("Unhandled date: %ld", rval);
 
-void    gridDefHasDims(int gridID, int hasdims);
-int     gridInqHasDims(int gridID);
-const char *gridNamePtr(int gridtype);
-char   *zaxisNamePtr(int leveltype);
-int     zaxisInqLevelID(int zaxisID, double level);
+  return (int)rval;
+}
 
-void    streamCheckID(const char *caller, int streamID);
 
-void    streamDefineTaxis(int streamID);
+int date_to_calday(int calendar, int date)
+{
+  int calday;
+  int dpy;
+  int year, month, day;
 
-int     streamsNewEntry(int filetype);
-void    streamsInitEntry(int streamID);
-void    cdiStreamSetupVlist(stream_t *streamptr, int vlistID, int vlistIDorig);
-int     stream_new_var(stream_t *streamptr, int gridID, int zaxisID);
+  dpy = calendar_dpy(calendar);
 
-int     tstepsNewEntry(stream_t *streamptr);
+  cdiDecodeDate(date, &year, &month, &day);
 
-const char *strfiletype(int filetype);
+  if ( dpy == 360 || dpy == 365 || dpy == 366 )
+    calday = encode_day(dpy, year, month, day);
+  else
+    calday = encode_julday(calendar, year, month, day);
 
-void    cdi_generate_vars(stream_t *streamptr);
+  return (calday);
+}
 
-void    vlist_check_contents(int vlistID);
 
-void    cdi_create_records(stream_t *streamptr, int tsID);
+int calday_to_date(int calendar, int calday)
+{
+  int date;
+  int dpy;
+  int year, month, day;
 
-int     recordNewEntry(stream_t *streamptr, int tsID);
+  dpy = calendar_dpy(calendar);
 
-void    cdiCreateTimesteps(stream_t *streamptr);
+  if ( dpy == 360 || dpy == 365 || dpy == 366 )
+    decode_day(dpy, calday, &year, &month, &day);
+  else
+    decode_julday(calendar, calday, &year, &month, &day);
 
-void    recordInitEntry(record_t *record);
+  date = cdiEncodeDate(year, month, day);
 
-void    cdiCheckZaxis(int zaxisID);
+  return (date);
+}
 
-void    cdiPrintDatatypes(void);
 
-void    cdiDefAccesstype(int streamID, int type);
-int     cdiInqAccesstype(int streamID);
+void encode_caldaysec(int calendar, int year, int month, int day, int hour, int minute, int second,
+		      int *julday, int *secofday)
+{
+  int dpy;
 
-int     getByteswap(int byteorder);
+  dpy = calendar_dpy(calendar);
 
-int     streamSize ();
-void    streamGetIndexList ( int, int * );
+  if ( dpy == 360 || dpy == 365 || dpy == 366 )
+    *julday = encode_day(dpy, year, month, day);
+  else
+    *julday = encode_julday(calendar, year, month, day);
 
+  *secofday = hour*3600 + minute*60 + second;
+}
 
-void  cdiInitialize(void);
 
-void uuid2str(const unsigned char *uuid, char *uuidstr);
-int str2uuid(const char *uuidstr, unsigned char *uuid);
-static inline int
-cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+void decode_caldaysec(int calendar, int julday, int secofday, 
+		      int *year, int *month, int *day, int *hour, int *minute, int *second)
 {
-  static const unsigned char uuid_nil[CDI_UUID_SIZE];
-  return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
-}
-
+  int dpy;
 
-#define CDI_UNIT_PA   1
-#define CDI_UNIT_HPA  2
-#define CDI_UNIT_MM   3
-#define CDI_UNIT_CM   4
-#define CDI_UNIT_DM   5
-#define CDI_UNIT_M    6
+  dpy = calendar_dpy(calendar);
 
-struct streamAssoc
-{
-  int streamID, vlistID, vlistIDorig;
-};
-
-struct streamAssoc
-streamUnpack(char * unpackBuffer, int unpackBufferSize,
-             int * unpackBufferPos, int originNamespace, void *context);
-
-int
-cdiStreamOpenDefaultDelegate(const char *filename, const char *filemode,
-                             int filetype, stream_t *streamptr,
-                             int recordBufIsToBeCreated);
-
-void
-cdiStreamDefVlist_(int streamID, int vlistID);
-void
-cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data,
-                   int nmiss);
-void
-cdiStreamwriteVarChunk_(int streamID, int varID, int memtype,
-                        const int rect[][2], const void *data, int nmiss);
-void
-cdiStreamCloseDefaultDelegate(stream_t *streamptr,
-                              int recordBufIsToBeDeleted);
-
-int cdiStreamDefTimestep_(stream_t *streamptr, int tsID);
-
-void cdiStreamSync_(stream_t *streamptr);
-
-char *cdiUnitNamePtr(int cdi_unit);
-
-#endif  /* _CDI_INT_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _CGRIBEX_H
-#define _CGRIBEX_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#define  GRIB_MISSVAL  -9.E33
-
-/* GRIB1 Level Types */
-#define  GRIB1_LTYPE_SURFACE               1
-#define  GRIB1_LTYPE_CLOUD_BASE            2
-#define  GRIB1_LTYPE_CLOUD_TOP             3
-#define  GRIB1_LTYPE_ISOTHERM0             4
-#define  GRIB1_LTYPE_TOA                   8
-#define  GRIB1_LTYPE_SEA_BOTTOM            9
-#define  GRIB1_LTYPE_ATMOSPHERE           10
-#define  GRIB1_LTYPE_99                   99
-#define  GRIB1_LTYPE_ISOBARIC            100
-#define  GRIB1_LTYPE_MEANSEA             102
-#define  GRIB1_LTYPE_ALTITUDE            103
-#define  GRIB1_LTYPE_HEIGHT              105
-#define  GRIB1_LTYPE_SIGMA               107
-#define  GRIB1_LTYPE_SIGMA_LAYER         108
-#define  GRIB1_LTYPE_HYBRID              109
-#define  GRIB1_LTYPE_HYBRID_LAYER        110
-#define  GRIB1_LTYPE_LANDDEPTH           111
-#define  GRIB1_LTYPE_LANDDEPTH_LAYER     112
-#define  GRIB1_LTYPE_ISENTROPIC          113
-#define  GRIB1_LTYPE_SEADEPTH            160  /* Depth Below Sea Level                                 */
-#define  GRIB1_LTYPE_LAKE_BOTTOM         162  /* Lake or River Bottom                                  */
-#define  GRIB1_LTYPE_SEDIMENT_BOTTOM     163  /* Bottom Of Sediment Layer                              */
-#define  GRIB1_LTYPE_SEDIMENT_BOTTOM_TA  164  /* Bottom Of Thermally Active Sediment Layer             */
-#define  GRIB1_LTYPE_SEDIMENT_BOTTOM_TW  165  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
-#define  GRIB1_LTYPE_MIX_LAYER           166  /* Mixing Layer                                          */
-#define  GRIB1_LTYPE_99_MARGIN          1000
-
-/* GRIB1 Data representation type (Grid Type) [Table 6] */
-#define  GRIB1_GTYPE_LATLON                0  /*  latitude/longitude                                   */
-#define  GRIB1_GTYPE_LATLON_ROT           10  /*  rotated latitude/longitude                           */
-#define  GRIB1_GTYPE_LATLON_STR           20  /*  stretched latitude/longitude                         */
-#define  GRIB1_GTYPE_LATLON_ROTSTR        30  /*  rotated and stretched latitude/longitude             */
-#define  GRIB1_GTYPE_GAUSSIAN              4  /*  gaussian grid                                        */
-#define  GRIB1_GTYPE_GAUSSIAN_ROT         14  /*  rotated gaussian grid                                */
-#define  GRIB1_GTYPE_GAUSSIAN_STR         24  /*  stretched gaussian grid                              */
-#define  GRIB1_GTYPE_GAUSSIAN_ROTSTR      34  /*  rotated and stretched gaussian grid                  */
-#define  GRIB1_GTYPE_LCC                   3  /*  Lambert conformal                                    */
-#define  GRIB1_GTYPE_SPECTRAL             50  /*  spherical harmonics                                  */
-#define  GRIB1_GTYPE_GME                 192  /*  hexagonal GME grid                                   */
-
-/*
- *  Macros for the indicator section ( Section 0 )
- */
-#define  ISEC0_GRIB_Len             (isec0[ 0])  /*  Number of octets in the GRIB message              */
-#define  ISEC0_GRIB_Version         (isec0[ 1])  /*  GRIB edition number                               */
-
-
-/*
- *  Macros for the product definition section ( Section 1 )
- */
-#define  ISEC1_TABLE4_MINUTE      0
-#define  ISEC1_TABLE4_HOUR        1
-#define  ISEC1_TABLE4_DAY         2
-#define  ISEC1_TABLE4_3HOURS     10
-#define  ISEC1_TABLE4_6HOURS     11
-#define  ISEC1_TABLE4_12HOURS    12
-#define  ISEC1_TABLE4_QUARTER    13
-#define  ISEC1_TABLE4_30MINUTES  14
-
-
-#define  ISEC1_CodeTable            (isec1[ 0])  /*  Version number of code table                 */
-#define  ISEC1_CenterID             (isec1[ 1])  /*  Identification of centre                     */
-#define  ISEC1_ModelID              (isec1[ 2])  /*  Identification of model                      */
-#define  ISEC1_GridDefinition       (isec1[ 3])  /*  Grid definition                              */
-#define  ISEC1_Sec2Or3Flag          (isec1[ 4])  /*  Section 2 or 3 included                      */
-#define  ISEC1_Parameter            (isec1[ 5])  /*  Parameter indicator                          */
-#define  ISEC1_LevelType            (isec1[ 6])  /*  Type of level indicator                      */
-#define  ISEC1_Level1               (isec1[ 7])  /*  Level 1                                      */
-#define  ISEC1_Level2               (isec1[ 8])  /*  Level 2                                      */
-#define  ISEC1_Year                 (isec1[ 9])  /*  Year of century (YY)                         */
-#define  ISEC1_Month                (isec1[10])  /*  Month (MM)                                   */
-#define  ISEC1_Day                  (isec1[11])  /*  Day (DD)                                     */
-#define  ISEC1_Hour                 (isec1[12])  /*  Hour (HH)                                    */
-#define  ISEC1_Minute               (isec1[13])  /*  Minute (MM)                                  */
-#define  ISEC1_TimeUnit             (isec1[14])  /*  Time unit indicator                          */
-#define  ISEC1_TimePeriod1          (isec1[15])  /*  P1 Time period                               */
-#define  ISEC1_TimePeriod2          (isec1[16])  /*  P2 Time period                               */
-#define  ISEC1_TimeRange            (isec1[17])  /*  Time range indicator                         */
-#define  ISEC1_AvgNum               (isec1[18])  /*  Number of products included in an average    */
-#define  ISEC1_AvgMiss              (isec1[19])  /*  Number of products missing from an average   */
-#define  ISEC1_Century              (isec1[20])  /*  Century                                      */
-#define  ISEC1_SubCenterID          (isec1[21])  /*  Subcenter identifier                         */
-#define  ISEC1_DecScaleFactor       (isec1[22])  /*  Decimal scale factor                         */
-#define  ISEC1_LocalFLag            (isec1[23])  /*  Flag field to indicate local use in isec1    */
-
-#define  ISEC1_ECMWF_LocalExtension (isec1[36])
-#define  ISEC1_ECMWF_Class          (isec1[37])
-
-
-/*
- *  Macros for the grid definition section ( Section 2 )
- */
-#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
-
-/* Triangular grids */
-
-#define  ISEC2_GME_NI2              (isec2[ 1])  /*  Number of factor 2 in factorisation of Ni    */
-#define  ISEC2_GME_NI3              (isec2[ 2])  /*  Number of factor 3 in factorisation of Ni    */
-#define  ISEC2_GME_ND               (isec2[ 3])  /*  Nubmer of diamonds                           */
-#define  ISEC2_GME_NI               (isec2[ 4])  /*  Number of tri. subdiv. of the icosahedron    */
-#define  ISEC2_GME_AFlag            (isec2[ 5])  /*  Flag for orientation of diamonds (Table A)   */
-#define  ISEC2_GME_LatPP            (isec2[ 6])  /*  Latitude of pole point                       */
-#define  ISEC2_GME_LonPP            (isec2[ 7])  /*  Longitude of pole point                      */
-#define  ISEC2_GME_LonMPL           (isec2[ 8])  /*  Longitude of the first diamond               */
-#define  ISEC2_GME_BFlag            (isec2[ 9])  /*  Flag for storage sequence (Table B)          */
-
-/* Spherical harmonic coeficients */
-
-#define  ISEC2_PentaJ               (isec2[ 1])  /*  J pentagonal resolution parameter            */
-#define  ISEC2_PentaK               (isec2[ 2])  /*  K pentagonal resolution parameter            */
-#define  ISEC2_PentaM               (isec2[ 3])  /*  M pentagonal resolution parameter            */
-#define  ISEC2_RepType              (isec2[ 4])  /*  Representation type                          */
-#define  ISEC2_RepMode              (isec2[ 5])  /*  Representation mode                          */
-
-/* Gaussian grids */
-
-#define  ISEC2_NumLon               (isec2[ 1])  /*  Number of points along a parallel (Ni)       */
-#define  ISEC2_NumLat               (isec2[ 2])  /*  Number of points along a meridian (Nj)       */
-#define  ISEC2_FirstLat             (isec2[ 3])  /*  Latitude of the first grid point             */
-#define  ISEC2_FirstLon             (isec2[ 4])  /*  Longitude of the first grid point            */
-#define  ISEC2_ResFlag              (isec2[ 5])  /*  Resolution flag: 128 regular grid            */
-#define  ISEC2_LastLat              (isec2[ 6])  /*  Latitude of the last grid point              */
-#define  ISEC2_LastLon              (isec2[ 7])  /*  Longitude of the last grid point             */
-#define  ISEC2_LonIncr              (isec2[ 8])  /*  i direction increment                        */
-#define  ISEC2_LatIncr              (isec2[ 9])  /*  j direction increment                        */
-#define  ISEC2_NumPar               (isec2[ 9])  /*  Number of parallels between a pole and the E.*/
-#define  ISEC2_ScanFlag             (isec2[10])  /*  Scanning mode flags                          */
-#define  ISEC2_NumVCP               (isec2[11])  /*  Number of vertical coordinate parameters     */
-
-/* Lambert */
-#define  ISEC2_Lambert_Lov          (isec2[ 6])  /*  Orientation of the grid                      */
-#define  ISEC2_Lambert_dx           (isec2[ 8])  /*  X-direction grid length                      */
-#define  ISEC2_Lambert_dy           (isec2[ 9])  /*  Y-direction grid length                      */
-#define  ISEC2_Lambert_ProjFlag     (isec2[12])  /*  Projection centre flag                       */
-#define  ISEC2_Lambert_LatS1        (isec2[13])  /*  First lat at which the secant cone cuts the sphere */
-#define  ISEC2_Lambert_LatS2        (isec2[14])  /*  Second lat at which the secant cone cuts the sphere */
-#define  ISEC2_Lambert_LatSP        (isec2[19])  /*  Latitude of the southern pole                */
-#define  ISEC2_Lambert_LonSP        (isec2[20])  /*  Longitude of the southern pole               */
-
-
-#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
-
-#define  ISEC2_RowLonPtr            (&isec2[22])
-#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
-
-/* */
+  if ( dpy == 360 || dpy == 365 || dpy == 366 )
+    decode_day(dpy, julday, year, month, day);
+  else
+    decode_julday(calendar, julday, year, month, day);
 
-#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
-#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
+  *hour   = secofday/3600;
+  *minute = secofday/60 - *hour*60;
+  *second = secofday - *hour*3600 - *minute*60;
+}
 
-#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
-#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
 
-/*
- *  Macros for the bit map section ( Section 3 )
- */
-#define  ISEC3_PredefBitmap         (isec3[ 0])  /* Predefined bitmap                             */
-#define  ISEC3_MissVal              (isec3[ 1])  /* Missing data value for integers               */
-#define  FSEC3_MissVal              (fsec3[ 1])  /* Missing data value for floats                 */
+#ifdef TEST
+int main(void)
+{
+  int calendar = CALENDAR_STANDARD;
+  int nmin;
+  int vdate0, vtime0;
+  int vdate, vtime;
+  int ijulinc;
+  int i, j = 0;
+  int year, mon, day, hour, minute, second;
+  int calday, secofday;
 
-/*
- *  Macros for the binary data section ( Section 4 )
- */
-#define  ISEC4_NumValues            (isec4[ 0])  /* Number of data values for encode/decode       */
-#define  ISEC4_NumBits              (isec4[ 1])  /* Number of bits used for each encoded value    */
-#define  ISEC4_NumNonMissValues     (isec4[20])  /* Number of non-missing values                  */
+  /* 1 - Check valid range of years */
 
+  nmin = 11000;
+  vdate0 = -80001201;
+  vtime0 = 120500;
 
+  printf("start time: %8d %4d\n", vdate0, vtime0);
 
+  for ( i = 0; i < nmin; i++ )
+    {
+      cdiDecodeDate(vdate0, &year, &mon, &day);
+      cdiDecodeTime(vtime0, &hour, &minute, &second);
 
-void  gribFixZSE(int flag);     /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
-void  gribSetConst(int flag);   /* 1: Don't pack constant fields on regular grids */
-void  gribSetDebug(int debug);  /* 1: Debugging */
-void  gribSetRound(int round);
-void  gribSetRefDP(double refval);
-void  gribSetRefSP(float  refval);
-void  gribSetValueCheck(int vcheck);
+      calday  = date_to_calday(calendar, vdate0);
+      secofday = time_to_sec(vtime0);
 
+      vdate = calday_to_date(calendar, calday);
+      vtime = sec_to_time(secofday);
 
-void  gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
-               float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
-               int kleng, int *kword, char *hoper, int *kret);
+      if ( vdate0 != vdate || vtime0 != vtime )
+	printf("%4d %8d %4d %8d %4d %9d %9d\n",
+	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);
 
-void  gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
-               double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
-               int kleng, int *kword, char *hoper, int *kret);
+      year++;
+      vdate0 = cdiEncodeDate(year, mon, day);
+      vtime0 = cdiEncodeTime(hour, minute, second);
+    }
 
+  printf("stop time: %8d %4d\n", vdate0, vtime0);
 
-const char *cgribexLibraryVersion(void);
+  /* 2 - Check time increment of one minute */
 
-void  gribDebug(int debug);
-void  gribSetCalendar(int calendar);
+  nmin = 120000;
+  ijulinc = 60;
+  vdate0 = 20001201;
+  vtime0 = 0;
 
-void  gribDateTime(int *isec1, int *date, int *time);
-int   gribRefDate(int *isec1);
-int   gribRefTime(int *isec1);
-int   gribTimeIsFC(int *isec1);
+  printf("start time: %8d %4d\n", vdate0, vtime0);
 
-void  gribPrintSec0(int *isec0);
-void  gribPrintSec1(int *isec0, int *isec1);
-void  gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
-void  gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2);
-void  gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
-void  gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3);
-void  gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
-void  gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4);
-void  gribPrintSec4Wave(int *isec4);
+  calday = date_to_calday(calendar, vdate0);
+  secofday = time_to_sec(vtime0);
+  for ( i = 0; i < nmin; i++ )
+    {
+      cdiDecodeDate(vdate0, &year, &mon, &day);
+      cdiDecodeTime(vtime0, &hour, &minute, &second);
 
-void  gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
+      if ( ++minute >= 60 )
+	{
+	  minute = 0;
+	  if ( ++hour >= 24 )
+	    {
+	      hour = 0;
+	      if ( ++day >= 32 )
+		{
+		  day = 1;
+		  if ( ++mon >= 13 )
+		    {
+		      mon = 1;
+		      year++;
+		    }
+		}
+	    }
+	}
 
-int   gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize);
+      vdate0 = cdiEncodeDate(year, mon, day);
+      vtime0 = cdiEncodeTime(hour, minute, second);
 
-int   gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int   gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int   gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+      julday_add_seconds(ijulinc, &calday, &secofday);
 
-int   gribOpen(const char *filename, const char *mode);
-void  gribClose(int fileID);
+      vdate = calday_to_date(calendar, calday);
+      vtime = sec_to_time(secofday);
+      if ( vdate0 != vdate || vtime0 != vtime )
+	printf("%4d %8d %4d %8d %4d %9d %9d\n",
+	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);
+    }
 
-int   gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
-int   gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
-off_t gribGetPos(int fileID);
-int   gribGetSize(int fileID);
-int   gribCheckSeek(int fileID, long *offset, int *version);
-int   gribFileSeek(int fileID, long *offset);
-int   gribReadSize(int fileID);
-int   gribVersion(unsigned char *buffer, size_t buffersize);
+  printf("stop time: %8d %4d\n", vdate0, vtime0);
 
-int   grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
+  return (0);
+}
+#endif
 
-double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
 
-#endif  /* _CGRIBEX_H */ 
+#ifdef TEST2
+int main(void)
+{
+  int calendar = CALENDAR_STANDARD;
+  int i;
+  int calday, secofday;
+  int year, month, day, hour, minute, second;
+  int value = 30;
+  int factor = 86400;
 
-#ifndef _GRIBAPI_H
-#define _GRIBAPI_H
+  calendar = CALENDAR_360DAYS;
 
-#ifdef HAVE_LIBGRIB_API
-#  include "error.h"
-#  include <grib_api.h>
-#endif
+  year=1979; month=1; day=15; hour=12; minute=30; second = 0;
 
-#define  GRIBAPI_MISSVAL  -9.E33
+  printf("calendar = %d\n", calendar);
+  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
 
-/* GRIB2 Level Types */
-#define  GRIB2_LTYPE_SURFACE               1
-#define  GRIB2_LTYPE_CLOUD_BASE            2
-#define  GRIB2_LTYPE_CLOUD_TOP             3
-#define  GRIB2_LTYPE_ISOTHERM0             4
-#define  GRIB2_LTYPE_TOA                   8
-#define  GRIB2_LTYPE_SEA_BOTTOM            9
-#define  GRIB2_LTYPE_ATMOSPHERE           10
-#define  GRIB2_LTYPE_ISOBARIC            100
-#define  GRIB2_LTYPE_MEANSEA             101
-#define  GRIB2_LTYPE_ALTITUDE            102
-#define  GRIB2_LTYPE_HEIGHT              103
-#define  GRIB2_LTYPE_SIGMA               104
-#define  GRIB2_LTYPE_HYBRID              105
-#define  GRIB2_LTYPE_LANDDEPTH           106
-#define  GRIB2_LTYPE_ISENTROPIC          107
-#define  GRIB2_LTYPE_SNOW                114
-#define  GRIB2_LTYPE_REFERENCE           150
-#define  GRIB2_LTYPE_SEADEPTH            160  /* Depth Below Sea Level                                 */
-#define  GRIB2_LTYPE_LAKE_BOTTOM         162  /* Lake or River Bottom                                  */
-#define  GRIB2_LTYPE_SEDIMENT_BOTTOM     163  /* Bottom Of Sediment Layer                              */
-#define  GRIB2_LTYPE_SEDIMENT_BOTTOM_TA  164  /* Bottom Of Thermally Active Sediment Layer             */
-#define  GRIB2_LTYPE_SEDIMENT_BOTTOM_TW  165  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
-#define  GRIB2_LTYPE_MIX_LAYER           166  /* Mixing Layer                                          */
+  encode_caldaysec(calendar, year, month, day, hour, minute, second, &calday, &secofday);
 
-/* GRIB2 Data representation type (Grid Type) */
-#define  GRIB2_GTYPE_LATLON                0  /*  latitude/longitude                                   */
-#define  GRIB2_GTYPE_LATLON_ROT            1  /*  rotated latitude/longitude                           */
-#define  GRIB2_GTYPE_LATLON_STR            2  /*  stretched latitude/longitude                         */
-#define  GRIB2_GTYPE_LATLON_ROTSTR         3  /*  rotated and stretched latitude/longitude             */
-#define  GRIB2_GTYPE_GAUSSIAN             40  /*  gaussian grid                                        */
-#define  GRIB2_GTYPE_GAUSSIAN_ROT         41  /*  rotated gaussian grid                                */
-#define  GRIB2_GTYPE_GAUSSIAN_STR         42  /*  stretched gaussian grid                              */
-#define  GRIB2_GTYPE_GAUSSIAN_ROTSTR      43  /*  rotated and stretched gaussian grid                  */
-#define  GRIB2_GTYPE_LCC                  30  /*  Lambert conformal                                    */
-#define  GRIB2_GTYPE_SPECTRAL             50  /*  spherical harmonics                                  */
-#define  GRIB2_GTYPE_GME                 100  /*  hexagonal GME grid                                   */
-#define  GRIB2_GTYPE_UNSTRUCTURED        101  /*  General Unstructured Grid                            */
+  decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
+  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, calday, secofday);
 
-const char *gribapiLibraryVersionString(void);
-void gribContainersNew(stream_t * streamptr);
-void gribContainersDelete(stream_t * streamptr);
-#ifdef HAVE_LIBGRIB_API
-static inline void *gribHandleNew(int editionNumber)
-{
-  void *gh =
-    (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
+  for ( i = 0; i < 420; i++ )
+    {
 
-  if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
-  return gh;
-}
+      decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
+      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
+      julday_add_seconds(value*factor, &calday, &secofday);
+    }
 
-static inline void gribHandleDelete(void *gh)
-{
-  grib_handle_delete(gh);
+  return (0);
 }
-#else
-#define gribHandleNew(editionNumber) (NULL)
-#define gribHandleDelete(gh)
 #endif
-
-typedef struct {
-  int init;
-  void *gribHandle;
-}
-gribContainer_t;
-
-#endif  /* _GRIBAPI_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2764,21 +2108,20 @@ gribContainer_t;
  * require-trailing-newline: t
  * End:
  */
-#ifndef _STREAM_CGRIBEX_H
-#define _STREAM_CGRIBEX_H
+#ifndef _CDF_H
+#define _CDF_H
 
-int cgribexScanTimestep1(stream_t * streamptr);
-int cgribexScanTimestep2(stream_t * streamptr);
-int cgribexScanTimestep(stream_t * streamptr);
+void cdfDebug(int debug);
 
-int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, double missval);
+const char *cdfLibraryVersion(void);
+const char *hdfLibraryVersion(void);
 
-size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		     int vdate, int vtime, int tsteptype, int numavg, 
-		     long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize);
+int  cdfOpen(const char *filename, const char *mode);
+int  cdfOpen64(const char *filename, const char *mode);
+int  cdf4Open(const char *filename, const char *mode, int *filetype);
+void cdfClose(int fileID);
 
-#endif  /* _STREAM_CGRIBEX_H */
+#endif  /* _CDF_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2788,58 +2131,109 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
  * require-trailing-newline: t
  * End:
  */
-#ifndef _STREAM_GRIBAPI_H
-#define _STREAM_GRIBAPI_H
+#ifndef RESOURCE_HANDLE_H
+#define RESOURCE_HANDLE_H
 
-int gribapiScanTimestep1(stream_t * streamptr);
-int gribapiScanTimestep2(stream_t * streamptr);
-int gribapiScanTimestep(stream_t * streamptr);
+#ifdef HAVE_CONFIG_H
+#endif
 
-int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, double missval, int vlistID, int varID);
+#include <stdio.h>
 
-size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		     int vdate, int vtime, int tsteptype, int numavg, 
-		     long datasize, const double *data, int nmiss, unsigned char **gribbuffer, size_t *gribbuffersize,
-		     int ljpeg, void *gribContainer);
+/*
+ * CDI internal handling of resource handles given to user code
+ */
 
-#endif  /* _STREAM_GRIBAPI_H */
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
+ * for reasons of compatibility with cfortran.h, the handle type is: int
  */
-#ifndef _STREAM_GRB_H
-#define _STREAM_GRB_H
+typedef int cdiResH;
 
-int   grbBitsPerValue(int datatype);
+/* return 0 on equality, not 0 otherwise */
+typedef int    ( * valCompareFunc     )( void *, void * );
+typedef void   ( * valDestroyFunc     )( void * );
+typedef void   ( * valPrintFunc       )( void *, FILE * );
+typedef int    ( * valGetPackSizeFunc )( void *, void *context );
+typedef void   ( * valPackFunc        )( void *, void *buf, int size, int *pos, void *context );
+typedef int    ( * valTxCodeFunc      )( void );
 
-int   grbInqContents(stream_t * streamptr);
-int   grbInqTimestep(stream_t * streamptr, int tsID);
+typedef struct {
+  valCompareFunc     valCompare;
+  valDestroyFunc     valDestroy;
+  valPrintFunc       valPrint;
+  valGetPackSizeFunc valGetPackSize;
+  valPackFunc        valPack;
+  valTxCodeFunc      valTxCode;
+}resOps;
 
-int   grbInqRecord(stream_t * streamptr, int *varID, int *levelID);
-void  grbDefRecord(stream_t * streamptr);
-void  grbReadRecord(stream_t * streamptr, double *data, int *nmiss);
-void  grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss);
-void  grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1);
+enum {
+  RESH_IN_USE_BIT = 1 << 0,
+  RESH_SYNC_BIT = 1 << 1,
+  /* resource holds no value */
+  RESH_UNUSED = 0,
+  /* resource was deleted and needs to be synced */
+  RESH_DESYNC_DELETED
+    = RESH_SYNC_BIT,
+  /* resource is synchronized */
+  RESH_IN_USE
+    = RESH_IN_USE_BIT,
+  /* resource is in use, desynchronized and needs to be synced */
+  RESH_DESYNC_IN_USE
+    = RESH_IN_USE_BIT | RESH_SYNC_BIT,
+};
 
-void  grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss);
-void  grb_write_var(stream_t * streamptr, int varID, int memtype, const void *data, int nmiss);
+void   reshListCreate(int namespaceID);
+void   reshListDestruct(int namespaceID);
+int    reshPut ( void *, const resOps * );
+void reshReplace(cdiResH resH, void *p, const resOps *ops);
+void   reshRemove ( cdiResH, const resOps * );
+/*> doesn't check resource type */
+void reshDestroy(cdiResH);
 
-void  grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss);
-void  grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+unsigned reshCountType(const resOps *resTypeOps);
 
-int   grib1ltypeToZaxisType(int grib_ltype);
-int   grib2ltypeToZaxisType(int grib_ltype);
+void * reshGetValue(const char* caller, const char* expressionString, cdiResH id, const resOps* ops);
+#define reshGetVal(resH, ops)  reshGetValue(__func__, #resH, resH, ops)
 
-int   zaxisTypeToGrib1ltype(int zaxistype);
-int   zaxisTypeToGrib2ltype(int zaxistype);
 
-#endif  /* _STREAM_GRB_H */
+void reshGetResHListOfType(unsigned numIDs, int IDs[numIDs], const resOps *ops);
+
+enum cdiApplyRet {
+  CDI_APPLY_ERROR = -1,
+  CDI_APPLY_STOP,
+  CDI_APPLY_GO_ON,
+};
+enum cdiApplyRet
+cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
+                                      void *data), void *data);
+enum cdiApplyRet
+cdiResHFilterApply(const resOps *p,
+                   enum cdiApplyRet (*func)(int id, void *res,
+                                            void *data),
+                   void *data);
+
+void   reshPackBufferCreate ( char **, int *, void *context );
+void   reshPackBufferDestroy ( char ** );
+int    reshResourceGetPackSize_intern(int resh, const resOps *ops, void *context, const char* caller, const char* expressionString);
+#define reshResourceGetPackSize(resh, ops, context) reshResourceGetPackSize_intern(resh, ops, context, __func__, #resh)
+void   reshPackResource_intern(int resh, const resOps *ops, void *buf, int buf_size, int *position, void *context, const char* caller, const char* expressionString);
+#define reshPackResource(resh, ops, buf, buf_size, position, context) reshPackResource_intern(resh, ops, buf, buf_size, position, context, __func__, #resh)
+
+void   reshSetStatus ( cdiResH, const resOps *, int );
+int    reshGetStatus ( cdiResH, const resOps * );
+
+void   reshLock   ( void );
+void   reshUnlock ( void );
+
+enum reshListMismatch {
+  cdiResHListOccupationMismatch,
+  cdiResHListResourceTypeMismatch,
+  cdiResHListResourceContentMismatch,
+};
+
+int reshListCompare(int nsp0, int nsp1);
+void reshListPrint(FILE *fp);
+
+#endif
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2849,38 +2243,78 @@ int   zaxisTypeToGrib2ltype(int zaxistype);
  * require-trailing-newline: t
  * End:
  */
-#ifndef _STREAM_CDF_H
-#define _STREAM_CDF_H
-
-void   cdfDefVars(stream_t *streamptr);
-void   cdfDefTimestep(stream_t *streamptr, int tsID);
-int    cdfInqTimestep(stream_t *streamptr, int tsID);
-int    cdfInqContents(stream_t *streamptr);
-void   cdfDefHistory(stream_t *streamptr, int size, const char *history);
-int    cdfInqHistorySize(stream_t *streamptr);
-void   cdfInqHistoryString(stream_t *streamptr, char *history);
+#ifndef _TAXIS_H
+#define _TAXIS_H
 
-void   cdfEndDef(stream_t * streamptr);
-void   cdfDefRecord(stream_t * streamptr);
+#ifndef RESOURCE_HANDLE_H
+#endif
 
-void   cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+typedef struct {
+  /* Date format  YYYYMMDD */
+  /* Time format    hhmmss */
+  int     self;
+  int     used;
+  int     type;           // time type
+  int     vdate;          // verification date
+  int     vtime;          // verification time
+  int     rdate;          // reference date
+  int     rtime;          // reference time
+  int     fdate;          // forecast reference date
+  int     ftime;          // forecast reference time
+  int     calendar;
+  int     unit;           // time unit
+  int     numavg;
+  int     climatology;
+  int     has_bounds;
+  int     vdate_lb;       // lower bounds of vdate
+  int     vtime_lb;       // lower bounds of vtime
+  int     vdate_ub;       // upper bounds of vdate
+  int     vtime_ub;       // upper bounds of vtime
+  int     fc_unit;        // forecast time unit
+  double  fc_period;      // forecast time period
+  char*   name;
+  char*   longname;
+}
+taxis_t;
 
-void   cdfReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void   cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
+void     ptaxisInit(taxis_t* taxis);
+void     ptaxisCopy(taxis_t* dest, taxis_t* source);
+taxis_t* taxisPtr(int taxisID);
+void     cdiSetForecastPeriod(double timevalue, taxis_t *taxis);
+void     cdiDecodeTimeval(double timevalue, taxis_t* taxis, int* date, int* time);
+double   cdiEncodeTimeval(int date, int time, taxis_t* taxis);
+void     timeval2vtime(double timevalue, taxis_t* taxis, int* vdate, int* vtime);
+double   vtime2timeval(int vdate, int vtime, taxis_t *taxis);
 
-void   cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss);
-void   cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss);
+void    ptaxisDefName(taxis_t *taxisptr, const char *name);
+void    ptaxisDefLongname(taxis_t *taxisptr, const char *name);
+void    taxisDestroyKernel(taxis_t *taxisptr);
+#if !defined (SX)
+extern const resOps taxisOps;
+#endif
 
-void   cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
+int
+taxisUnpack(char *unpackBuffer, int unpackBufferSize, int *unpackBufferPos,
+            int originNamespace, void *context, int checkForSameID);
 
-void   cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
-void   cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss);
-void   cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
+#endif  /* _TAXIS_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _CDI_LIMITS_H
+#define _CDI_LIMITS_H
 
-void   cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
-                           const int rect[][2], const void *data, int nmiss);
+#define  MAX_GRIDS_PS    128  /* maximum number of different grids per stream */
+#define  MAX_ZAXES_PS    128  /* maximum number of different zaxes per stream */
+#define  MAX_ATTRIBUTES  256  /* maximum number of attributes per variable    */
 
-#endif
+#endif  /* _CDI_LIMITS_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2890,30 +2324,45 @@ void   cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
  * require-trailing-newline: t
  * End:
  */
-#ifndef _TABLEPAR_H
-#define _TABLEPAR_H
+#ifndef _SERVICE_H
+#define _SERVICE_H
 
-enum {
-  TABLE_DUP_NAME = 1 << 0,
-  TABLE_DUP_LONGNAME = 1 << 1,
-  TABLE_DUP_UNITS = 1 << 2,
-};
 
-typedef struct
-{
-  int   id;	     /* Parameter number (GRIB) */
-  int dupflags;      /* keep track of which attributes got strdup'ed */
-  const char *name;	     /* Parameter name */
-  const char *longname;    /* Parameter long name */
-  const char *units;	     /* Parameter units */
+typedef struct {
+  int    checked;
+  int    byteswap;
+  int    header[8];
+  int    hprec;      /* header precision */
+  int    dprec;      /* data   precision */
+  size_t datasize;
+  size_t buffersize;
+  void  *buffer;
 }
-PAR;
+srvrec_t;
 
 
-static void tableLink(int tableID, const PAR *pars, int npars);
-int tableDef(int modelID, int tablegribID, const char *tablename);
+const char *srvLibraryVersion(void);
 
-#endif
+void srvDebug(int debug);
+
+int  srvCheckFiletype(int fileID, int *swap);
+
+srvrec_t *srvNew(void);
+void srvDelete(srvrec_t *srvp);
+
+int  srvRead(int fileID, srvrec_t *srvp);
+void srvWrite(int fileID, srvrec_t *srvp);
+
+int  srvInqHeader(srvrec_t *srvp, int *header);
+int  srvInqDataSP(srvrec_t *srvp, float *data);
+int  srvInqDataDP(srvrec_t *srvp, double *data);
+
+int  srvDefHeader(srvrec_t *srvp, const int *header);
+int  srvDefDataSP(srvrec_t *srvp, const float *data);
+int  srvDefDataDP(srvrec_t *srvp, const double *data);
+
+
+#endif  /* _SERVICE_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2923,1545 +2372,868 @@ int tableDef(int modelID, int tablegribID, const char *tablename);
  * require-trailing-newline: t
  * End:
  */
-#ifndef _TABLE_H
-#define _TABLE_H
+#ifndef _EXTRA_H
+#define _EXTRA_H
 
-static const PAR echam4[] = {
-  {   4, 0, "precip",      "total precipitation",                      "m/s"      },
-  {  34, 0, "low_cld",     "low cloud",                                 NULL      },
-  {  35, 0, "mid_cld",     "mid cloud",                                 NULL      },
-  {  36, 0, "hih_cld",     "high cloud",                                NULL      },
-  { 129, 0, "geosp",       "surface geopotential (orography)",         "m^2/s^2"  },
-  { 130, 0, "t",           "temperature",                              "K"        },
-  { 131, 0, "u",           "u-velocity",                               "m/s"      },
-  { 132, 0, "v",           "v-velocity",                               "m/s"      },
-  { 133, 0, "sq",          "specific humidity",                        "kg/kg"    },
-  { 134, 0, "aps",         "Surface pressure",                         "Pa"       },
-  { 135, 0, "omega",       "vertical velocity",                        "Pa/s"     },
-  { 138, 0, "svo",         "vorticity",                                "1/s"      },
-  { 139, 0, "ts",          "surface temperature",                      "K"        },
-  { 140, 0, "ws",          "soil wetness",                             "m"        },
-  { 141, 0, "sn",          "snow depth",                               "m"        },
-  { 142, 0, "aprl",        "large scale precipitation",                "m/s"      },
-  { 143, 0, "aprc",        "convective  precipitation",                "m/s"      },
-  { 144, 0, "aprs",        "snow fall",                                "m/s"      },
-  { 145, 0, "vdis",        "boundary layer dissipation",               "W/m^2"    },
-  { 146, 0, "ahfs",        "surface sensible heat flux",               "W/m^2"    },
-  { 147, 0, "ahfl",        "surface latent heat flux",                 "W/m^2"    },
-  { 148, 0, "stream",      "streamfunction",                           "m^2/s"    },
-  { 149, 0, "velopot",     "velocity potential",                       "m^2/s"    },
-  { 151, 0, "slp",         "mean sea level pressure",                  "Pa"       },
-  { 152, 0, "lsp",         "log surface pressure",                      NULL      },
-  { 153, 0, "sx",          "liquid water content",                     "kg/kg"    },
-  { 155, 0, "sd",          "divergence",                               "1/s"      },
-  { 156, 0, "geopoth",     "geopotential height",                      "m"        },
-  { 157, 0, "rhumidity",   "relative humidity",                        "fraction" },
-  { 158, 0, "var158",      "tendency of surface pressure",             "Pa/s"     },
-  { 159, 0, "ustar3",      "ustar3",                                   "m^3/s^3"  },
-  { 160, 0, "runoff",      "surface runoff",                           "m/s"      },
-  { 161, 0, "alwc",        "liquid water content",                     "kg/kg"    },
-  { 162, 0, "aclc",        "cloud cover",                              "fraction" },
-  { 163, 0, "aclcv",       "total cloud cover",                        "fraction" },
-  { 164, 0, "aclcov",      "total cloud cover",                        "fraction" },
-  { 165, 0, "u10",         "10m u-velocity",                           "m/s"      },
-  { 166, 0, "v10",         "10m v-velocity",                           "m/s"      },
-  { 167, 0, "temp2",       "2m temperature",                           "K"        },
-  { 168, 0, "dew2",        "2m dew point temperature",                 "K"        },
-  { 169, 0, "tsurf",       "surface temperature",                      "K"        },
-  { 170, 0, "td",          "deep soil temperature",                    "K"        },
-  { 171, 0, "wind10",      "10m windspeed",                            "m/s"      },
-  { 172, 0, "slm",         "land sea mask",                            "fraction" },
-  { 173, 0, "az0",         "surface roughness length",                 "m"        },
-  { 174, 0, "alb",         "surface background albedo",                "fraction" },
-  { 175, 0, "albedo",      "surface albedo",                           "fraction" },
-  { 176, 0, "srads",       "net surface solar radiation",              "W/m^2"    },
-  { 177, 0, "trads",       "net surface thermal radiation",            "W/m^2"    },
-  { 178, 0, "srad0",       "net top solar radiation",                  "W/m^2"    },
-  { 179, 0, "trad0",       "top thermal radiation (OLR)",              "W/m^2"    },
-  { 180, 0, "ustr",        "surface u-stress",                         "Pa"       },
-  { 181, 0, "vstr",        "surface v-stress",                         "Pa"       },
-  { 182, 0, "evap",        "surface evaporation",                      "m/s"      },
-  { 183, 0, "tdcl",        "soil temperature",                         "K"        },
-  { 185, 0, "srafs",       "net surf. solar radiation   (clear sky)",  "W/m^2"    },
-  { 186, 0, "trafs",       "net surf. thermal radiation (clear sky)",  "W/m^2"    },
-  { 187, 0, "sraf0",       "net top solar radiation     (clear sky)",  "W/m^2"    },
-  { 188, 0, "traf0",       "net top thermal radiation   (clear sky)",  "W/m^2"    },
-  { 189, 0, "sclfs",       "surface solar cloud forcing",              "W/m^2"    },
-  { 190, 0, "tclfs",       "surface thermal cloud forcing",            "W/m^2"    },
-  { 191, 0, "sclf0",       "top solar cloud forcing",                  "W/m^2"    },
-  { 192, 0, "tclf0",       "top thermal cloud forcing",                "W/m^2"    },
-  { 193, 0, "wl",          "skin reservoir content",                   "m"        },
-  { 194, 0, "wlm1",        "skin reservoir content of plants",         "m"        },
-  { 195, 0, "ustrgw",      "u-gravity wave stress",                    "Pa"       },
-  { 196, 0, "vstrgw",      "v-gravity wave stress",                    "Pa"       },
-  { 197, 0, "vdisgw",      "gravity wave dissipation",                 "W/m^2"    },
-  { 198, 0, "vgrat",       "vegetation ratio",                         "fraction" },
-  { 199, 0, "varor",       "orographic variance",                      "m^2"      },
-  { 200, 0, "vlt",         "leaf area index",                           NULL      },
-  { 201, 0, "t2max",       "maximum 2m-temperature",                   "K"        },
-  { 202, 0, "t2min",       "minimum 2m-temperature",                   "K"        },
-  { 203, 0, "srad0u",      "top solar radiation upward",               "W/m^2"    },
-  { 204, 0, "sradsu",      "surface solar radiation upward",           "W/m^2"    },
-  { 205, 0, "tradsu",      "surface thermal radiation upward",         "W/m^2"    },
-  { 206, 0, "tsn",         "snow temperature",                         "K"        },
-  { 207, 0, "td3",         "soil temperature 3",                       "K"        },
-  { 208, 0, "td4",         "soil temperature 4",                       "K"        },
-  { 209, 0, "td5",         "soil temperature 5",                       "K"        },
-  { 210, 0, "seaice",      "sea ice cover",                            "fraction" },
-  { 211, 0, "siced",       "sea ice depth",                            "m"        },
-  { 212, 0, "forest",      "vegetation type",                          "fraction" },
-  { 213, 0, "teff",        "(effective) sea-ice skin temperature",     "K"        },
-  { 214, 0, "tsmax",       "maximum surface temperature",              "K"        },
-  { 215, 0, "tsmin",       "minimum surface temperature",              "K"        },
-  { 216, 0, "wimax",       "maximum 10m-wind speed",                   "m/s"      },
-  { 217, 0, "topmax",      "maximum height of convective cloud tops",  "Pa"       },
-  { 218, 0, "snmel",       "snow melt",                                "m/s"      },
-  { 219, 0, "runtoc",      "surface runoff into ocean",                 NULL      },
-  { 220, 0, "tslin",       "land: residual surface heat budget",       "W/m^2"    },
-  { 221, 0, "dsnac",       "snow depth change",                        "m/s"      },
-  { 222, 0, "alwcac",      "liquid water content",                     "kg/kg"    },
-  { 223, 0, "aclcac",      "cloud cover",                              "fraction" },
-  { 224, 0, "tke",         "turbulent kinetic energy",                  NULL      },
-  { 225, 0, "tkem1",       "turbulent kinetic energy (t-1)",            NULL      },
-  { 226, 0, "fao",         "FAO data set (soil data flags)",            NULL      },
-  { 227, 0, "rgcgn",       "heat capacity of soil",                     NULL      },
-  { 228, 0, "sodif",       "soil diffusivity",                          NULL      },
-  { 229, 0, "wsmx",        "field capacity of soil",                   "m"        },
-  { 230, 0, "qvi",         "vertically integrated specific humidity",  "kg/m^2"   },
-  { 231, 0, "alwcvi",      "vertically integrated liquid water cont.", "kg/m^2"   },
-  { 232, 0, "glac",        "glacier mask",                             "fraction" },
-  { 233, 0, "runlnd",      "surface runoff not running into ocean",     NULL      },
-  { 259, 0, "windspeed",   "windspeed (sqrt(u^2+v^2))",                 NULL      },
-  { 260, 0, "precip",      "total precipitation",                      "m/s"      },
-  { 261, 0, "net_top",     "total top radiation",                       NULL      },
-  { 262, 0, "net_bot",     "total surface radiation",                   NULL      },
-  { 263, 0, "net_heat",    "net surface heat flux",                     NULL      },
-  { 264, 0, "net_water",   "total surface water",                       NULL      },
-  { 268, 0, "sw_atm",       NULL,                                       NULL      },
-  { 269, 0, "lw_atm",       NULL,                                       NULL      },
-  { 270, 0, "net_atm",      NULL,                                       NULL      },
-  { 271, 0, "surf_runoff", "surface runoff",                            NULL      },
-  { 275, 0, "fresh_water",  NULL,                                       NULL      },
-};
+#define  EXT_REAL   1
+#define  EXT_COMP   2
 
-static const PAR echam5[] = {
-  {   4, 0, "precip",     "total precipitation",                       "kg/m^2s" },
-  {  79, 0, "swnirac",    "net surface NIR flux acc.",                 "W/m^2"   },
-  {  80, 0, "swdifnirac", "fraction of diffuse NIR acc.",              "W/m^2"   },
-  {  81, 0, "swvisac",    "net surface visible flux acc.",             "W/m^2"   },
-  {  82, 0, "swdifvisac", "fraction of diffuse visible acc.",          "W/m^2"   },
-  {  83, 0, "ocu",        "ocean eastw. velocity (coupled mode)",      "m/s"     },
-  {  84, 0, "ocv",        "ocean northw. velocity (coupled mode)",     "m/s"     },
-  {  85, 0, "tradl",      "net LW radiation 200mb",                    "W/m^2"   },
-  {  86, 0, "sradl",      "net SW radiation 200mb",                    "W/m^2"   },
-  {  87, 0, "trafl",      "net LW radiation 200mb (clear sky)",        "W/m^2"   },
-  {  88, 0, "srafl",      "net SW radiation 200mb (clear sky)",        "W/m^2"   },
-  {  89, 0, "amlcorac",   "mixed layer flux correction",               "W/m^2"   },
-  {  90, 0, "amlheatac",  "mixed layer heat content",                  "J/m^2"   },
-  {  91, 0, "trfliac",    "net LW radiation over ice",                 "W/m^2"   },
-  {  92, 0, "trflwac",    "net LW radiation over water",               "W/m^2"   },
-  {  93, 0, "trfllac",    "net LW radiation over land",                "W/m^2"   },
-  {  94, 0, "sofliac",    "net SW radiation over ice",                 "W/m^2"   },
-  {  95, 0, "soflwac",    "net SW radiation over water",               "W/m^2"   },
-  {  96, 0, "sofllac",    "net SW radiation over land",                "W/m^2"   },
-  {  97, 0, "friac",      "ice cover (fraction of grid box)",           NULL     },
-  { 102, 0, "tsi",        "surface temperature of ice",                "K"       },
-  { 103, 0, "tsw",        "surface temperature of water",              "K"       },
-  { 104, 0, "ustri",      "zonal      wind stress over ice",           "Pa"      },
-  { 105, 0, "vstri",      "meridional wind stress over ice",           "Pa"      },
-  { 106, 0, "ustrw",      "zonal      wind stress over water",         "Pa"      },
-  { 107, 0, "vstrw",      "meridional wind stress over water",         "Pa"      },
-  { 108, 0, "ustrl",      "zonal      wind stress over land",          "Pa"      },
-  { 109, 0, "vstrl",      "meridional wind stress over land",          "Pa"      },
-  { 110, 0, "ahfliac",    "latent heat flux over ice",                 "W/m^2"   },
-  { 111, 0, "ahflwac",    "latent heat flux over water",               "W/m^2"   },
-  { 112, 0, "ahfllac",    "latent heat flux over land",                "W/m^2"   },
-  { 113, 0, "evapiac",    "evaporation over ice",                      "kg/m^2s" },
-  { 114, 0, "evapwac",    "evaporation over water",                    "kg/m^2s" },
-  { 115, 0, "evaplac",    "evaporation over land",                     "kg/m^2s" },
-  { 116, 0, "az0i",       "roughness length over ice",                 "m"       },
-  { 117, 0, "az0w",       "roughness length over water",               "m"       },
-  { 118, 0, "az0l",       "roughness length over land",                "m"       },
-  { 119, 0, "ahfsiac",    "sensible heat flux over ice",               "W/m^2"   },
-  { 120, 0, "ahfswac",    "sensible heat flux over water",             "W/m^2"   },
-  { 121, 0, "ahfslac",    "sensible heat flux over land",              "W/m^2"   },
-  { 122, 0, "alsoi",      "albedo of ice",                              NULL     },
-  { 123, 0, "alsow",      "albedo of water",                            NULL     },
-  { 124, 0, "alsol",      "albedo of land",                             NULL     },
-  { 125, 0, "ahfice",     "conductive heat flux through ice",          "W/m^2"   },
-  { 126, 0, "qres",       "residual heat flux for melting sea ice",    "W/m^2"   },
-  { 127, 0, "alake",      "lake fraction",                              NULL     },
-  { 128, 0, "rintop",     "low level inversion",                        NULL     },
-  { 129, 0, "geosp",      "surface geopotential (orography)",          "m^2/s^2" },
-  { 130, 0, "t",          "temperature",                               "K"       },
-  { 131, 0, "u",          "u-velocity",                                "m/s"     },
-  { 132, 0, "v",          "v-velocity",                                "m/s"     },
-  { 133, 0, "q",          "specific humidity",                         "kg/kg"   },
-  { 134, 0, "aps",        "surface pressure",                          "Pa"      },
-  { 135, 0, "omega",      "vertical velocity",                         "Pa/s"    },
-  { 136, 0, "acdnc",      "cloud droplet number concentration",        "1/m^3"   },
-  { 137, 0, "apmeb",      "(P-E) error",                               "kg/m^2s" },
-  { 138, 0, "svo",        "vorticity",                                 "1/s"     },
-  { 139, 0, "tslm1",      "surface temperature of land",               "K"       },
-  { 140, 0, "ws",         "soil wetness",                              "m"       },
-  { 141, 0, "sn",         "water equivalent snow depth",               "m"       },
-  { 142, 0, "aprl",       "large scale precipitation",                 "kg/m^2s" },
-  { 143, 0, "aprc",       "convective  precipitation",                 "kg/m^2s" },
-  { 144, 0, "aprs",       "snow fall",                                 "kg/m^2s" },
-  { 145, 0, "vdis",       "boundary layer dissipation",                "W/m^2"   },
-  { 146, 0, "ahfs",       "sensible heat flux",                        "W/m^2"   },
-  { 147, 0, "ahfl",       "latent heat flux",                          "W/m^2"   },
-  { 148, 0, "stream",     "streamfunction",                            "m^2/s"   },
-  { 149, 0, "velopot",    "velocity potential",                        "m^2/s"   },
-  { 150, 0, "xivi",       "vertically integrated cloud ice",           "kg/m^2"  },
-  { 151, 0, "slp",        "mean sea level pressure",                   "Pa"      },
-  { 152, 0, "lsp",        "log surface pressure",                       NULL     },
-  { 153, 0, "xl",         "cloud water",                               "kg/kg"   },
-  { 154, 0, "xi",         "cloud ice",                                 "kg/kg"   },
-  { 155, 0, "sd",         "divergence",                                "1/s"     },
-  { 156, 0, "geopoth",    "geopotential height",                       "m"       },
-  { 157, 0, "rhumidity",  "relative humidity",                          NULL     },
-  { 159, 0, "wind10w",    "10m windspeed over water",                  "m/s"     },
-  { 160, 0, "runoff",     "surface runoff and drainage",               "kg/m^2s" },
-  { 161, 0, "drain",      "drainage",                                  "kg/m^2s" },
-  { 162, 0, "aclc",       "cloud cover",                                NULL     },
-  { 164, 0, "aclcov",     "total cloud cover",                          NULL     },
-  { 165, 0, "u10",        "10m u-velocity",                            "m/s"     },
-  { 166, 0, "v10",        "10m v-velocity",                            "m/s"     },
-  { 167, 0, "temp2",      "2m temperature",                            "K"       },
-  { 168, 0, "dew2",       "2m dew point temperature",                  "K"       },
-  { 169, 0, "tsurf",      "surface temperature",                       "K"       },
-  { 170, 0, "xvar",       "variance of total water amount",            "kg/kg"   },
-  { 171, 0, "wind10",     "10m windspeed",                             "m/s"     },
-  { 172, 0, "slm",        "land sea mask (1. = land, 0. = sea/lakes)",  NULL     },
-  { 173, 0, "az0",        "roughness length",                          "m"       },
-  { 174, 0, "alb",        "surface background albedo",                  NULL     },
-  { 175, 0, "albedo",     "surface albedo",                             NULL     },
-  { 176, 0, "srads",      "net surface SW radiation",                  "W/m^2"   },
-  { 177, 0, "trads",      "net surface LW radiation",                  "W/m^2"   },
-  { 178, 0, "srad0",      "net top SW radiation",                      "W/m^2"   },
-  { 179, 0, "trad0",      "net top LW radiation (-OLR)",               "W/m^2"   },
-  { 180, 0, "ustr",       "u-stress",                                  "Pa"      },
-  { 181, 0, "vstr",       "v-stress",                                  "Pa"      },
-  { 182, 0, "evap",       "evaporation",                               "kg/m^2s" },
-  { 183, 0, "xskew",      "skewness of total water amount qv+qi+ql",    NULL     },
-  { 184, 0, "srad0d",     "top incoming SW radiation",                 "W/m^2"   },
-  { 185, 0, "srafs",      "net surface SW radiation (clear sky)",      "W/m^2"   },
-  { 186, 0, "trafs",      "net surface LW radiation (clear sky)",      "W/m^2"   },
-  { 187, 0, "sraf0",      "net top SW radiation   (clear sky)",        "W/m^2"   },
-  { 188, 0, "traf0",      "net top LW radiation   (clear sky)",        "W/m^2"   },
-  { 189, 0, "sclfs",      "net surface SW cloud forcing (176-185)",    "W/m^2"   },
-  { 190, 0, "tclfs",      "net surface LW cloud forcing (177-186)",    "W/m^2"   },
-  { 191, 0, "sclf0",      "net SW top cloud forcing (178-187)",        "W/m^2"   },
-  { 192, 0, "tclf0",      "net LW top cloud forcing (179-188)",        "W/m^2"   },
-  { 193, 0, "wl",         "skin reservoir content",                    "m"       },
-  { 194, 0, "slf",        "fractional land cover",                      NULL     },
-  { 195, 0, "ustrgw",     "u-gravity wave stress",                     "Pa"      },
-  { 196, 0, "vstrgw",     "v-gravity wave stress",                     "Pa"      },
-  { 197, 0, "vdisgw",     "gravity wave dissipation",                  "W/m^2"   },
-  { 198, 0, "vgrat",      "vegetation ratio",                           NULL     },
-  { 199, 0, "orostd",     "orographic standard deviation",             "m"       },
-  { 200, 0, "vlt",        "leaf area index",                            NULL     },
-  { 201, 0, "t2max",      "maximum 2m-temperature",                    "K"       },
-  { 202, 0, "t2min",      "minimum 2m-temperature",                    "K"       },
-  { 203, 0, "srad0u",     "top SW radiation upward",                   "W/m^2"   },
-  { 204, 0, "sradsu",     "surface SW radiation upward",               "W/m^2"   },
-  { 205, 0, "tradsu",     "surface LW radiation upward",               "W/m^2"   },
-  { 206, 0, "grndflux",   "surface ground heat flux",                   NULL     },
-  { 207, 0, "tsoil",      "deep soil temperatures (5 layers)",         "K"       },
-  { 208, 0, "ahfcon",     "conductive heat flux through ice",          "W/m^2"   },
-  { 209, 0, "ahfres",     "res. heat flux for melting ice",            "W/m^2"   },
-  { 210, 0, "seaice",     "ice cover (fraction of ice+water)",          NULL     },
-  { 211, 0, "siced",      "ice thickness",                             "m"       },
-  { 212, 0, "forest",     "forest fraction",                            NULL     },
-  { 213, 0, "gld",        "glacier thickness",                         "m"       },
-  { 214, 0, "sni",        "water equivalent of snow on ice",           "m"       },
-  { 215, 0, "rogl",       "glacier runoff",                            "kg/m^2s" },
-  { 216, 0, "wimax",      "maximum 10m-wind speed",                    "m/s"     },
-  { 217, 0, "topmax",     "maximum height of convective cloud tops",   "Pa"      },
-  { 218, 0, "snmel",      "snow melt",                                 "kg/m^2s" },
-  { 219, 0, "runtoc",     "surface runoff into ocean",                 "kg/m^2s" },
-  { 220, 0, "runlnd",     "surface runoff not running into ocean",     "kg/m^2s" },
-  { 221, 0, "apmegl",     "P-E over land ice",                         "kg/m^2s" },
-  { 222, 0, "snacl",      "snow accumulation over land",               "kg/m^2s" },
-  { 223, 0, "aclcac",     "cloud cover",                                NULL     },
-  { 224, 0, "tke",        "turbulent kinetic energy",                  "m^2/s^2" },
-  { 225, 0, "tkem1",      "turbulent kinetic energy (t-1)",            "m^2/s^2" },
-  { 226, 0, "fao",        "FAO data set (soil data flags) 0...5",       NULL     },
-  { 227, 0, "rgcgn",      "heat capacity of soil",                      NULL     },
-  { 228, 0, "sodif",      "soil diffusivity",                          "m^2/s"   },
-  { 229, 0, "wsmx",       "field capacity of soil",                    "m"       },
-  { 230, 0, "qvi",        "vertically integrated water vapor",         "kg/m^2"  },
-  { 231, 0, "xlvi",       "vertically integrated cloud water",         "kg/m^2"  },
-  { 232, 0, "glac",       "fraction of land covered by glaciers",       NULL     },
-  { 233, 0, "snc",        "snow depth at the canopy",                  "m"       },
-  { 234, 0, "rtype",      "type of convection",                        "0...3"   },
-  { 235, 0, "abso4",      "anthropogenic sulfur burden",               "kg/m^2"  },
-  { 236, 0, "ao3",        "ipcc ozone",                                "kg/m^2"  },
-  { 237, 0, "tropo",      "WMO defined tropopause height",             "Pa"      },
-  { 259, 0, "windspeed",  "windspeed (sqrt(u^2+v^2))",                 "m/s"     },
-  { 260, 0, "precip",     "total precipitation  (142+143)",            "kg/m^2s" },
-  { 261, 0, "net_top",    "total top radiation  (178+179)",            "W/m^2"   },
-  { 262, 0, "net_bot",    "total surface radiation (176+177)",         "W/m^2"   },
-  { 272, 0, "mastrfu",    "mass stream function",                      "kg/s"    },
-};
 
-static const PAR echam6[] = {
-  {   4, 0, "precip",         "total precipitation",                       "kg m-2 s-1" },
-  {  34, 0, "low_cld",        "low cloud",                                  NULL        },
-  {  35, 0, "mid_cld",        "mid cloud",                                  NULL        },
-  {  36, 0, "hih_cld",        "high cloud",                                 NULL        },
-  {  68, 0, "fage",           "aging factor of snow on ice",                NULL        },
-  {  69, 0, "snifrac",        "fraction of ice covered with snow",          NULL        },
-  {  70, 0, "barefrac",       "bare ice fraction",                          NULL        },
-  {  71, 0, "alsom",          "albedo of melt ponds",                       NULL        },
-  {  72, 0, "alsobs",         "albedo of bare ice and snow",                NULL        },
-  {  73, 0, "sicepdw",        "melt pond depth on sea-ice",                "m"          },
-  {  74, 0, "sicepdi",        "ice thickness on melt pond",                "m"          },
-  {  75, 0, "tsicepdi",       "ice temperature on frozen melt pond",       "K"          },
-  {  76, 0, "sicepres",       "residual heat flux",                        "W m-2"      },
-  {  77, 0, "ameltdepth",     "total melt pond depth",                     "m"          },
-  {  78, 0, "ameltfrac",      "fractional area of melt ponds on sea-ice",   NULL        },
-  {  79, 0, "albedo_vis_dir", "surface albedo visible range direct",        NULL        },
-  {  80, 0, "albedo_nir_dir", "surface albedo NIR range direct",            NULL        },
-  {  81, 0, "albedo_vis_dif", "surface albedo visible range diffuse",       NULL        },
-  {  82, 0, "albedo_nir_dif", "surface albedo NIR range diffuse",           NULL        },
-  {  83, 0, "ocu",            "ocean eastw. velocity (coupled mode)",      "m/s"        },
-  {  84, 0, "ocv",            "ocean northw. velocity (coupled mode)",     "m/s"        },
-  {  85, 0, "tradl",          "thermal radiation 200mb",                   "W m-2"      },
-  {  86, 0, "sradl",          "solar radiation 200mb",                     "W m-2"      },
-  {  87, 0, "trafl",          "thermal radiation 200mb (clear sky)",       "W m-2"      },
-  {  88, 0, "srafl",          "solar radiation 200mb (clear sky)",         "W m-2"      },
-  {  89, 0, "amlcorac",       "mixed layer flux correction",               "W m-2"      },
-  {  90, 0, "amlheatac",      "mixed layer heat content",                  "J m-2"      },
-  {  91, 0, "trfliac",        "LW flux over ice",                          "W m-2"      },
-  {  92, 0, "trflwac",        "LW flux over water",                        "W m-2"      },
-  {  93, 0, "trfllac",        "LW flux over land",                         "W m-2"      },
-  {  94, 0, "sofliac",        "SW flux over ice",                          "W m-2"      },
-  {  95, 0, "soflwac",        "SW flux over water",                        "W m-2"      },
-  {  96, 0, "sofllac",        "SW flux over land",                         "W m-2"      },
-  {  97, 0, "friac",          "ice cover (fraction of grid box)",           NULL        },
-  { 102, 0, "tsi",            "surface temperature of ice",                "K"          },
-  { 103, 0, "tsw",            "surface temperature of water",              "K"          },
-  { 104, 0, "ustri",          "zonal      wind stress over ice",           "Pa"         },
-  { 105, 0, "vstri",          "meridional wind stress over ice",           "Pa"         },
-  { 106, 0, "ustrw",          "zonal      wind stress over water",         "Pa"         },
-  { 107, 0, "vstrw",          "meridional wind stress over water",         "Pa"         },
-  { 108, 0, "ustrl",          "zonal      wind stress over land",          "Pa"         },
-  { 109, 0, "vstrl",          "meridional wind stress over land",          "Pa"         },
-  { 110, 0, "ahfliac",        "latent heat flux over ice",                 "W m-2"      },
-  { 111, 0, "ahflwac",        "latent heat flux over water",               "W m-2"      },
-  { 112, 0, "ahfllac",        "latent heat flux over land",                "W m-2"      },
-  { 113, 0, "evapiac",        "evaporation over ice",                      "kg m-2 s-1" },
-  { 114, 0, "evapwac",        "evaporation over water",                    "kg m-2 s-1" },
-  { 115, 0, "evaplac",        "evaporation over land",                     "kg m-2 s-1" },
-  { 116, 0, "az0i",           "roughness length over ice",                 "m"          },
-  { 117, 0, "az0w",           "roughness length over water",               "m"          },
-  { 118, 0, "az0l",           "roughness length over land",                "m"          },
-  { 119, 0, "ahfsiac",        "sensible heat flux over ice",               "W m-2"      },
-  { 120, 0, "ahfswac",        "sensible heat flux over water",             "W m-2"      },
-  { 121, 0, "ahfslac",        "sensible heat flux over land",              "W m-2"      },
-  { 122, 0, "alsoi",          "albedo of ice",                              NULL        },
-  { 123, 0, "alsow",          "albedo of water",                            NULL        },
-  { 124, 0, "alsol",          "albedo of land",                             NULL        },
-  { 125, 0, "ahfice",         "conductive heat flux",                      "W m-2"      },
-  { 126, 0, "qres",           "residual heat flux for melting sea ice",    "W m-2"      },
-  { 127, 0, "alake",          "lake fraction of grid box",                 "fraction"   },
-  { 128, 0, "rintop",         "low level inversion",                        NULL        },
-  { 129, 0, "geosp",          "surface geopotential (orography)",          "m^2/s^2"    },
-  { 130, 0, "t",              "temperature",                               "K"          },
-  { 131, 0, "u",              "u-velocity",                                "m/s"        },
-  { 132, 0, "v",              "v-velocity",                                "m/s"        },
-  { 133, 0, "q",              "specific humidity",                         "kg/kg"      },
-  { 134, 0, "aps",            "surface pressure",                          "Pa"         },
-  { 135, 0, "omega",          "vertical velocity",                         "Pa/s"       },
-  { 136, 0, "acdnc",          "cloud droplet number concentration",        "1 m-3"      },
-  { 137, 0, "apmeb",          "vert. integr. tendencies of water",         "kg m-2 s-1" },
-  { 138, 0, "svo",            "vorticity",                                 "1/s"        },
-  { 139, 0, "tslm1",          "surface temperature of land",               "K"          },
-  { 140, 0, "ws",             "soil wetness",                              "m"          },
-  { 141, 0, "sn",             "snow depth",                                "m"          },
-  { 142, 0, "aprl",           "large scale precipitation",                 "kg m-2 s-1" },
-  { 143, 0, "aprc",           "convective  precipitation",                 "kg m-2 s-1" },
-  { 144, 0, "aprs",           "snow fall",                                 "kg m-2 s-1" },
-  { 145, 0, "vdis",           "boundary layer dissipation",                "W m-2"      },
-  { 146, 0, "ahfs",           "sensible heat flux",                        "W m-2"      },
-  { 147, 0, "ahfl",           "latent heat flux",                          "W m-2"      },
-  { 148, 0, "stream",         "streamfunction",                            "m^2/s"      },
-  { 149, 0, "velopot",        "velocity potential",                        "m^2/s"      },
-  { 150, 0, "xivi",           "vertically integrated cloud ice",           "kg m-2"     },
-  { 151, 0, "slp",            "mean sea level pressure",                   "Pa"         },
-  { 152, 0, "lsp",            "log surface pressure",                       NULL        },
-  { 153, 0, "xl",             "cloud water",                               "kg/kg"      },
-  { 154, 0, "xi",             "cloud ice",                                 "kg/kg"      },
-  { 155, 0, "sd",             "divergence",                                "1/s"        },
-  { 156, 0, "geopoth",        "geopotential height",                       "m"          },
-  { 157, 0, "rhumidity",      "relative humidity",                         "fraction"   },
-  { 158, 0, "var158",         "tendency of surface pressure",              "Pa/s"       },
-  { 159, 0, "wind10w",        "10m windspeed over water",                  "m/s"        },
-  { 160, 0, "runoff",         "surface runoff and drainage",               "kg m-2 s-1" },
-  { 161, 0, "drain",          "drainage",                                  "kg m-2 s-1" },
-  { 162, 0, "aclc",           "cloud cover",                                NULL        },
-  { 163, 0, "aclcv",          "total cloud cover",                          NULL        },
-  { 164, 0, "aclcov",         "total cloud cover (mean)",                   NULL        },
-  { 165, 0, "u10",            "10m u-velocity",                            "m/s"        },
-  { 166, 0, "v10",            "10m v-velocity",                            "m/s"        },
-  { 167, 0, "temp2",          "2m temperature",                            "K"          },
-  { 168, 0, "dew2",           "2m dew point temperature",                  "K"          },
-  { 169, 0, "tsurf",          "surface temperature",                       "K"          },
-  { 170, 0, "xvar",           "variance of total water amount qv+qi+ql",   "kg/kg"      },
-  { 171, 0, "wind10",         "10m windspeed",                             "m/s"        },
-  { 172, 0, "slm",            "land sea mask (1. = land, 0. = sea/lakes)",  NULL        },
-  { 173, 0, "az0",            "roughness length",                          "m"          },
-  { 174, 0, "alb",            "surface background albedo",                  NULL        },
-  { 175, 0, "albedo",         "surface albedo",                             NULL        },
-  { 176, 0, "srads",          "net surface solar radiation",               "W m-2"      },
-  { 177, 0, "trads",          "net surface thermal radiation",             "W m-2"      },
-  { 178, 0, "srad0",          "net top solar radiation",                   "W m-2"      },
-  { 179, 0, "trad0",          "top thermal radiation (OLR)",               "W m-2"      },
-  { 180, 0, "ustr",           "u-stress",                                  "Pa"         },
-  { 181, 0, "vstr",           "v-stress",                                  "Pa"         },
-  { 182, 0, "evap",           "evaporation",                               "kg m-2 s-1" },
-  { 183, 0, "xskew",          "skewness of total water amount qv+qi+ql",    NULL        },
-  { 184, 0, "srad0d",         "top incoming solar radiation",              "W m-2"      },
-  { 185, 0, "srafs",          "net surf. solar radiation   (clear sky)",   "W m-2"      },
-  { 186, 0, "trafs",          "net surf. thermal radiation (clear sky)",   "W m-2"      },
-  { 187, 0, "sraf0",          "net top solar radiation     (clear sky)",   "W m-2"      },
-  { 188, 0, "traf0",          "net top thermal radiation   (clear sky)",   "W m-2"      },
-  { 189, 0, "sclfs",          "surface solar cloud forcing",               "W m-2"      },
-  { 190, 0, "tclfs",          "surface thermal cloud forcing",             "W m-2"      },
-  { 191, 0, "sclf0",          "SW top cloud forcing (178-187)",            "W m-2"      },
-  { 192, 0, "tclf0",          "LW top cloud forcing (179-188)",            "W m-2"      },
-  { 193, 0, "wl",             "skin reservoir content",                    "m"          },
-  { 194, 0, "slf",            "sea land fraction",                          NULL        },
-  { 195, 0, "ustrgw",         "u-gravity wave stress",                     "Pa"         },
-  { 196, 0, "vstrgw",         "v-gravity wave stress",                     "Pa"         },
-  { 197, 0, "vdisgw",         "gravity wave dissipation",                  "W m-2"      },
-  { 198, 0, "vgrat",          "vegetation ratio",                           NULL        },
-  { 199, 0, "orostd",         "orographic standard deviation",             "m"          },
-  { 200, 0, "vlt",            "leaf area index",                            NULL        },
-  { 201, 0, "t2max",          "maximum 2m-temperature",                    "K"          },
-  { 202, 0, "t2min",          "minimum 2m-temperature",                    "K"          },
-  { 203, 0, "srad0u",         "top solar radiation upward",                "W m-2"      },
-  { 204, 0, "sradsu",         "surface solar radiation upward",            "W m-2"      },
-  { 205, 0, "tradsu",         "surface thermal radiation upward",          "W m-2"      },
-  { 206, 0, "grndflux",       "surface ground heat flux",                   NULL        },
-  { 207, 0, "tsoil",          "deep soil temperatures (5 layers)",         "K"          },
-  { 208, 0, "ahfcon",         "conductive heat flux through ice",          "W m-2"      },
-  { 209, 0, "ahfres",         "melting of ice",                            "W m-2"      },
-  { 210, 0, "seaice",         "ice cover (fraction of 1-SLM)",              NULL        },
-  { 211, 0, "siced",          "ice depth",                                 "m"          },
-  { 212, 0, "forest",         "forest fraction",                            NULL        },
-  { 213, 0, "gld",            "glacier depth",                             "m"          },
-  { 214, 0, "sni",            "water equivalent of snow on ice",           "m"          },
-  { 215, 0, "rogl",           "glacier runoff",                            "kg m-2 s-1" },
-  { 216, 0, "wimax",          "maximum 10m-wind speed",                    "m/s"        },
-  { 217, 0, "topmax",         "maximum height of convective cloud tops",   "Pa"         },
-  { 218, 0, "snmel",          "snow melt",                                 "kg m-2 s-1" },
-  { 219, 0, "runtoc",         "surface runoff into ocean",                 "kg m-2 s-1" },
-  { 220, 0, "runlnd",         "surface runoff not running into ocean",     "kg m-2 s-1" },
-  { 221, 0, "apmegl",         "P-E over land ice",                         "kg m-2 s-1" },
-  { 222, 0, "snacl",          "snow accumulation over land",               "kg m-2 s-1" },
-  { 223, 0, "aclcac",         "cloud cover",                                NULL        },
-  { 224, 0, "tke",            "turbulent kinetic energy",                  "m^2/s^2"    },
-  { 225, 0, "tkem1",          "turbulent kinetic energy (t-1)",            "m^2/s^2"    },
-  { 226, 0, "fao",            "FAO data set (soil data flags)",            "0...5"      },
-  { 227, 0, "rgcgn",          "heat capacity of soil",                      NULL        },
-  { 228, 0, "sodif",          "diffusivity of soil and land ice",          "m^2/s"      },
-  { 229, 0, "wsmx",           "field capacity of soil",                    "m"          },
-  { 230, 0, "qvi",            "vertically integrated water vapor",         "kg m-2"     },
-  { 231, 0, "xlvi",           "vertically integrated cloud water",         "kg m-2"     },
-  { 232, 0, "glac",           "fraction of land covered by glaciers",       NULL        },
-  { 233, 0, "snc",            "snow depth at the canopy",                  "m"          },
-  { 234, 0, "rtype",          "type of convection",                        "0...3"      },
-  { 235, 0, "abso4",          "antropogenic sulfur burden",                "kg m-2"     },
-  { 236, 0, "ao3",            "ipcc ozone",                                "kg m-2"     },
-  { 237, 0, "tropo",          "WMO defined tropopause height",             "Pa"         },
-  { 259, 0, "windspeed",      "windspeed (sqrt(u^2+v^2))",                 "m/s"        },
-  { 260, 0, "precip",         "total precipitation  (142+143)",            "kg m-2 s-1" },
-  { 261, 0, "net_top",        "total top radiation  (178+179)",            "W m-2"      },
-  { 262, 0, "net_bot",        "total surface radiation (176+177)",         "W m-2"      },
-  { 272, 0, "mastfru",        "mass stream function",                      "kg/s"       },
-};
+typedef struct {
+  int    checked;
+  int    byteswap;
+  int    header[4];
+  int    prec;      /* single or double precison */
+  int    number;    /* real or complex */
+  size_t datasize;
+  size_t buffersize;
+  void  *buffer;
+}
+extrec_t;
 
-static const PAR mpiom1[] = {
-  {   2, 0, "THO",      "temperature",                     "C"        },
-  {   5, 0, "SAO",      "salinity",                        "psu"      },
-  {   3, 0, "UKO",      "zon. velocity",                   "m/s"      },
-  {   4, 0, "VKE",      "mer. velocity",                   "m/s"      },
-  { 303, 0, "UKOMFL",   "zon. velocity (divergence free)", "m/s"      },
-  { 304, 0, "VKEMFL",   "mer. velocity (divergence free)", "m/s"      },
-  {   7, 0, "WO",       "ver. velocity",                   "m/s"      },
-  {   8, 0, "RHO",      "insitu density",                  "kg/m**3"  },
-  {   6, 0, "PO",       "pressure",                        "Pa"       },
-  {  67, 0, "EMINPO",   "freshwaterflux by restoring",     "m/s"      },
-  {  70, 0, "FLUM",     "total heatflux",                  "W/m**2"   },
-  {  79, 0, "PEM",      "total freshwaterflux",            "m/s"      },
-  {  13, 0, "SICTHO",   "ice thickness",                   "m"        },
-  {  15, 0, "SICOMO",   "ice compactness",                 "frac."    },
-  {  35, 0, "SICUO",    "zon. ice velocity",               "m/s"      },
-  {  36, 0, "SICVE",    "mer. ice velocity",               "m/s"      },
-  {  92, 0, "TAFO",     "surface air temperature",         "C"        },
-  { 164, 0, "FCLOU",    "cloud cover",                      NULL      },
-  {  52, 0, "TXO",      "surface u-stress",                "Pa/1025." },
-  {  53, 0, "TYE",      "surface v-stress",                "Pa/1025." },
-  { 260, 0, "FPREC",    "prescr. precipitation",           "m/s"      },
-  {  80, 0, "FSWR",     "downward shortwave rad.",         "W/m**2"   },
-  {  81, 0, "FTDEW",    "dewpoint temperature",            "K"        },
-  { 171, 0, "FU10",     "10m windspeed",                   "m/s"      },
-  { 141, 0, "SICSNO",   "snow thickness",                  "m"        },
-  { 176, 0, "QSWO",     "heat flux shortwave",             "W/m**2"   },
-  { 177, 0, "QLWO",     "heat flux longwave",              "W/m**2"   },
-  { 147, 0, "QLAO",     "heat flux latent",                "W/m**2"   },
-  { 146, 0, "QSEO",     "heat flux sensible",              "W/m**2"   },
-  {  65, 0, "PRECO",    "net freshwater flux + runoff",    "m/s"      },
-  {   1, 0, "ZO",       "sealevel",                        "m"        },
-  {  82, 0, "Z1O",      "sealevel change",                 "m"        },
-  {  69, 0, "KCONDEP",  "depth of convection",             "level"    },
-  {  27, 0, "PSIUWE",   "hor. bar. streamfunction",        "Sv"       },
-  {  83, 0, "AMLD",     "mixed layer depth",               "m"        },
-  { 172, 0, "WETO",     "landseamask (pressure points)",    NULL      },
-  { 507, 0, "AMSUE",    "landseamask (vector points v)",    NULL      },
-  { 508, 0, "AMSUO",    "landseamask (vector points u)",    NULL      },
-  {  84, 0, "DEPTO",    "depth at pressure points",        "m"        },
-  { 484, 0, "DEUTO",    "depth at vector points (u)",      "m"        },
-  { 584, 0, "DEUTE",    "depth at vector points (v)",      "m"        },
-  { 184, 0, "DDUO",     "level thickness (vector u )",     "m"        },
-  { 284, 0, "DDUE",     "level thickness (vector v )",     "m"        },
-  { 384, 0, "DDPO",     "level thickness (pressure )",     "m"        },
-  {  85, 0, "DLXP",     "grid distance x",                 "m"        },
-  {  86, 0, "DLYP",     "grid distance y",                 "m"        },
-  { 185, 0, "DLXU",     "grid distance x  (vector u)",     "m"        },
-  { 186, 0, "DLYU",     "grid distance y  (vector u)",     "m"        },
-  { 285, 0, "DLXV",     "grid distance x  (vector v)",     "m"        },
-  { 286, 0, "DLYV",     "grid distance y  (vector v)",     "m"        },
-  {  54, 0, "GILA",     "latitude in radiants",            "rad"      },
-  {  55, 0, "GIPH",     "longitude in radiants",           "rad"      },
-  { 354, 0, "ALAT",     "latitude in degrees (pressure)",  "deg"      },
-  { 355, 0, "ALON",     "longitude in degrees (pressure)", "deg"      },
-  { 154, 0, "ALATU",    "latitude in degrees (vector u)",  "deg"      },
-  { 155, 0, "ALONU",    "longitude in degrees (vector u)", "deg"      },
-  { 254, 0, "ALATV",    "latitude in degrees (vector v)",  "deg"      },
-  { 255, 0, "ALONV",    "longitude in degrees (vector v)", "deg"      },
-  { 110, 0, "AVO",      "vertical impuls diffusion",       "m**2/s"   },
-  { 111, 0, "DVO",      "vertical T,S diffusion",          "m**2/s"   },
-  { 142, 0, "SICTRU",   "seaice transport x",              "m**2/s"   },
-  { 143, 0, "SICTRV",   "seaice transport y",              "m**2/s"   },
-  { 612, 0, "WTMIX",    "wind mixing",                     "m**2/s"   },
-  { 183, 0, "zmld",     "mixed layer depth (SJ)",          "m"        },
-  { 207, 0, "WGO",      "GM vertical velocity",            "m/s"      },
-  { 305, 0, "rivrun",   "RiverRunoff",                     "m/s"      },
-  { 158, 0, "TMCDO",    "mon. mean depth of convection",   "level"    },
-  { 247, 0, "DQSWO",    "heatflux sw over water",          "W/m**2"   },
-  { 248, 0, "DQLWO",    "heatflux lw over water",          "W/m**2"   },
-  { 249, 0, "DQSEO",    "heatflux se over water",          "W/m**2"   },
-  { 250, 0, "DQLAO",    "heatflux la over water",          "W/m**2"   },
-  { 251, 0, "DQTHO",    "heatflux net over water",         "W/m**2"   },
-  { 252, 0, "DQSWI",    "heatflux sw over seaice",         "W/m**2"   },
-  { 253, 0, "DQLWI",    "heatflux lw over seaice",         "W/m**2"   },
-  { 254, 0, "DQSEI",    "heatflux se over seaice",         "W/m**2"   },
-  { 255, 0, "DQLAI",    "heatflux la over seaice",         "W/m**2"   },
-  { 256, 0, "DQTHI",    "heatflux net over seaice",        "W/m**2"   },
-  { 257, 0, "DTICEO",   "Equi. temp over seaice",          "K"        },
-  { 270, 0, "AOFLNHWO", "oasis net heat flux water",       "W/m**2"   },
-  { 271, 0, "AOFLSHWO", "oasis downward short wave",       "W/m**2"   },
-  { 272, 0, "AOFLRHIO", "oasis residual heat flux ice",    "W/m**2"   },
-  { 273, 0, "AOFLCHIO", "oasis conduct. heat flux ice",    "W/m**2"   },
-  { 274, 0, "AOFLFRWO", "oasis fluid fresh water flux",    "m/s"      },
-  { 275, 0, "AOFLFRIO", "oasis solid fresh water flux",    "m/s"      },
-  { 276, 0, "AOFLTXWO", "oasis wind stress water x",       "Pa/102"   },
-  { 277, 0, "AOFLTYWO", "oasis wind stress water y",       "Pa/102"   },
-  { 278, 0, "AOFLTXIO", "oasis wind stress ice x",         "Pa/102"   },
-  { 279, 0, "AOFLTYIO", "oasis wind stress ice x",         "Pa/102"   },
-  { 280, 0, "AOFLWSVO", "oasis wind speed",                "m/s"      },
-};
 
-static const PAR ecmwf[] = {
-  {   1, 0, "STRF",   "Stream function",                                            "m**2 s**-1"            },
-  {   2, 0, "VPOT",   "Velocity potential",                                         "m**2 s**-1"            },
-  {   3, 0, "PT",     "Potential temperature",                                      "K"                     },
-  {   4, 0, "EQPT",   "Equivalent potential temperature",                           "K"                     },
-  {   5, 0, "SEPT",   "Saturated equivalent potential temperature",                 "K"                     },
-  {  11, 0, "UDVW",   "U component of divergent wind",                              "m s**-1"               },
-  {  12, 0, "VDVW",   "V component of divergent wind",                              "m s**-1"               },
-  {  13, 0, "URTW",   "U component of rotational wind",                             "m s**-1"               },
-  {  14, 0, "VRTW",   "V component of rotational wind",                             "m s**-1"               },
-  {  21, 0, "UCTP",   "Unbalanced component of temperature",                        "K"                     },
-  {  22, 0, "UCLN",   "Unbalanced component of logarithm of surface pressure",       NULL                   },
-  {  23, 0, "UCDV",   "Unbalanced component of divergence",                         "s**-1"                 },
-  {  26, 0, "CL",     "Lake cover",                                                  NULL                   },
-  {  27, 0, "CVL",    "Low vegetation cover",                                        NULL                   },
-  {  28, 0, "CVH",    "High vegetation cover",                                       NULL                   },
-  {  29, 0, "TVL",    "Type of low vegetation",                                      NULL                   },
-  {  30, 0, "TVH",    "Type of high vegetation",                                     NULL                   },
-  {  31, 0, "CI",     "Sea-ice cover",                                               NULL                   },
-  {  32, 0, "ASN",    "Snow albedo",                                                 NULL                   },
-  {  33, 0, "RSN",    "Snow density kg",                                            "m**-3"                 },
-  {  34, 0, "SSTK",   "Sea surface temperature",                                    "K"                     },
-  {  35, 0, "ISTL1",  "Ice surface temperature layer 1",                            "K"                     },
-  {  36, 0, "ISTL2",  "Ice surface temperature layer 2",                            "K"                     },
-  {  37, 0, "ISTL3",  "Ice surface temperature layer 3",                            "K"                     },
-  {  38, 0, "ISTL4",  "Ice surface temperature layer 4",                            "K"                     },
-  {  39, 0, "SWVL1",  "Volumetric soil water layer 1",                              "m**3 m**-3"            },
-  {  40, 0, "SWVL2",  "Volumetric soil water layer 2",                              "m**3 m**-3"            },
-  {  41, 0, "SWVL3",  "Volumetric soil water layer 3",                              "m**3 m**-3"            },
-  {  42, 0, "SWVL4",  "Volumetric soil water layer 4",                              "m**3 m**-3"            },
-  {  43, 0, "SLT",    "Soil type",                                                   NULL                   },
-  {  44, 0, "ES",     "Snow evaporation m of water",                                 NULL                   },
-  {  45, 0, "SMLT",   "Snowmelt m of water",                                         NULL                   },
-  {  46, 0, "SDUR",   "Solar duration",                                             "s"                     },
-  {  47, 0, "DSRP",   "Direct solar radiation",                                     "w m**-2"               },
-  {  48, 0, "MAGSS",  "Magnitude of surface stress",                                "N m**-2 s"             },
-  {  49, 0, "WG10",   "Wind gust at 10 metres",                                     "m s**-1"               },
-  {  50, 0, "LSPF",   "Large-scale precipitation fraction",                         "s"                     },
-  {  51, 0, "MX2T24", "Maximum 2 metre temperature",                                "K"                     },
-  {  52, 0, "MN2T24", "Minimum 2 metre temperature",                                "K"                     },
-  {  53, 0, "MONT",   "Montgomery potential",                                       "m**2 s**-2"            },
-  {  54, 0, "PRES",   "Pressure",                                                   "Pa"                    },
-  {  55, 0, "MN2T24", "Mean 2 metre temperature past 24 hours",                     "K"                     },
-  {  56, 0, "MN2D24", "Mean 2 metre dewpoint temperature past 24 hours",            "K"                     },
-  {  60, 0, "PV",     "Potential vorticity",                                        "K m**2 kg**-1 s**-1"   },
-  { 127, 0, "AT",     "Atmospheric tide",                                            NULL                   },
-  { 128, 0, "BV",     "Budget values",                                               NULL                   },
-  { 129, 0, "Z",      "Geopotential",                                               "m**2 s**-2"            },
-  { 130, 0, "T",      "Temperature",                                                "K"                     },
-  { 131, 0, "U",      "U velocity",                                                 "m s**-1"               },
-  { 132, 0, "V",      "V velocity",                                                 "m s**-1"               },
-  { 133, 0, "Q",      "Specific humidity",                                          "kg kg**-1"             },
-  { 134, 0, "SP",     "Surface pressure",                                           "Pa"                    },
-  { 135, 0, "W",      "Vertical velocity",                                          "Pa s**-1"              },
-  { 136, 0, "TCW",    "Total column water",                                         "kg m**-2"              },
-  { 137, 0, "TCWV",   "Total column water vapour",                                  "kg m**-2"              },
-  { 138, 0, "VO",     "Vorticity (relative)",                                       "s**-1"                 },
-  { 139, 0, "STL1",   "Soil temperature level 1",                                   "K"                     },
-  { 140, 0, "SWL1",   "Soil wetness level 1 m of water",                             NULL                   },
-  { 141, 0, "SD",     "Snow depth         1 m of water equivalent",                  NULL                   },
-  { 142, 0, "LSP",    "Stratiform precipitation (Large scale precipitation)",       "m"                     },
-  { 143, 0, "CP",     "Convective precipitation",                                   "m"                     },
-  { 144, 0, "SF",     "Snowfall (convective + stratiform)",                         "m"                     },
-  { 145, 0, "BLD",    "Boundary layer dissipation",                                 "W m**-2 s"             },
-  { 146, 0, "SSHF",   "Surface sensible heat flux",                                 "W m**-2 s"             },
-  { 147, 0, "SLHF",   "Surface latent heat flux",                                   "W m**-2 s"             },
-  { 148, 0, "CHNK",   "Charnock",                                                    NULL                   },
-  { 149, 0, "SNR",    "Surface net radiation",                                      "W m**-2 s"             },
-  { 150, 0, "TNR",    "Top net radiation",                                           NULL                   },
-  { 151, 0, "MSL",    "Mean sea-level pressure",                                    "Pa"                    },
-  { 152, 0, "LNSP",   "Logarithm of surface pressure",                               NULL                   },
-  { 153, 0, "SWHR",   "Short-wave heating rate",                                    "K"                     },
-  { 154, 0, "LWHR",   "Long-wave heating rate",                                     "K"                     },
-  { 155, 0, "D",      "Divergence",                                                 "s**-1"                 },
-  { 156, 0, "GH",     "Height m Geopotential height",                                NULL                   },
-  { 157, 0, "R",      "Relative humidity",                                          "%"                     },
-  { 158, 0, "TSP",    "Tendency of surface pressure",                               "Pa s**-1"              },
-  { 159, 0, "BLH",    "Boundary layer height",                                      "m"                     },
-  { 160, 0, "SDOR",   "Standard deviation of orography",                             NULL                   },
-  { 161, 0, "ISOR",   "Anisotropy of sub-gridscale orography",                       NULL                   },
-  { 162, 0, "ANOR",   "Angle of sub-gridscale orography",                           "rad"                   },
-  { 163, 0, "SLOR",   "Slope of sub-gridscale orography",                            NULL                   },
-  { 164, 0, "TCC",    "Total cloud cover",                                           NULL                   },
-  { 165, 0, "U10M",   "10 metre U wind component",                                  "m s**-1"               },
-  { 166, 0, "V10M",   "10 metre V wind component",                                  "m s**-1"               },
-  { 167, 0, "T2M",    "2 metre temperature",                                        "K"                     },
-  { 168, 0, "D2M",    "2 metre dewpoint temperature",                               "K"                     },
-  { 169, 0, "SSRD",   "Surface solar radiation downwards",                          "W m**-2 s"             },
-  { 170, 0, "STL2",   "Soil temperature level 2",                                   "K"                     },
-  { 171, 0, "SWL2",   "Soil wetness level 2",                                       "m of water"            },
-  { 172, 0, "LSM",    "Land/sea mask",                                               NULL                   },
-  { 173, 0, "SR",     "Surface roughness",                                          "m"                     },
-  { 174, 0, "AL",     "Albedo",                                                      NULL                   },
-  { 175, 0, "STRD",   "Surface thermal radiation downwards",                        "W m**-2 s"             },
-  { 176, 0, "SSR",    "Surface solar radiation",                                    "W m**-2 s"             },
-  { 177, 0, "STR",    "Surface thermal radiation",                                  "W m**-2 s"             },
-  { 178, 0, "TSR",    "Top solar radiation",                                        "W m**-2 s"             },
-  { 179, 0, "TTR",    "Top thermal radiation",                                      "W m**-2 s"             },
-  { 180, 0, "EWSS",   "East/West surface stress",                                   "N m**-2 s"             },
-  { 181, 0, "NSSS",   "North/South surface stress",                                 "N m**-2 s"             },
-  { 182, 0, "E",      "Evaporation",                                                "m of water"            },
-  { 183, 0, "STL3",   "Soil temperature level 3",                                   "K"                     },
-  { 184, 0, "SWL3",   "Soil wetness level 3",                                       "m of water"            },
-  { 185, 0, "CCC",    "Convective cloud cover",                                      NULL                   },
-  { 186, 0, "LCC",    "Low cloud cover",                                             NULL                   },
-  { 187, 0, "MCC",    "Medium cloud cover",                                          NULL                   },
-  { 188, 0, "HCC",    "High cloud cover",                                            NULL                   },
-  { 189, 0, "SUND",   "Sunshine duration",                                          "s"                     },
-  { 190, 0, "EWOV",   "EW component of subgrid orographic variance",                "m**2"                  },
-  { 191, 0, "NSOV",   "NS component of subgrid orographic variance",                "m**2"                  },
-  { 192, 0, "NWOV",   "NWSE component of subgrid orographic variance",              "m**2"                  },
-  { 193, 0, "NEOV",   "NESW component of subgrid orographic variance",              "m**2"                  },
-  { 194, 0, "BTMP",   "Brightness temperature",                                     "K"                     },
-  { 195, 0, "LGWS",   "Lat. component of gravity wave stress",                      "N m**-2 s"             },
-  { 196, 0, "MGWS",   "Meridional component of gravity wave stress",                "N m**-2 s"             },
-  { 197, 0, "GWD",    "Gravity wave dissipation",                                   "W m**-2 s"             },
-  { 198, 0, "SRC",    "Skin reservoir content",                                     "m of water"            },
-  { 199, 0, "VEG",    "Vegetation fraction",                                         NULL                   },
-  { 200, 0, "VSO",    "Variance of sub-gridscale orography",                        "m**2"                  },
-  { 201, 0, "MX2T",   "Maximum 2 metre temperature since previous post-processing", "K"                     },
-  { 202, 0, "MN2T",   "Minimum 2 metre temperature since previous post-processing", "K"                     },
-  { 203, 0, "O3",     "Ozone mass mixing ratio",                                    "kg kg**-1"             },
-  { 204, 0, "PAW",    "Precipiation analysis weights",                               NULL                   },
-  { 205, 0, "RO",     "Runoff",                                                     "m"                     },
-  { 206, 0, "TCO3",   "Total column ozone",                                         "kg m**-2"              },
-  { 207, 0, "WS10",   "10 meter windspeed",                                         "m s**-1"               },
-  { 208, 0, "TSRC",   "Top net solar radiation, clear sky",                         "W m**-2"               },
-  { 209, 0, "TTRC",   "Top net thermal radiation, clear sky",                       "W m**-2"               },
-  { 210, 0, "SSRC",   "Surface net solar radiation, clear sky",                     "W m**-2"               },
-  { 211, 0, "STRC",   "Surface net thermal radiation, clear sky",                   "W m**-2"               },
-  { 212, 0, "SI",     "Solar insolation",                                           "W m**-2"               },
-  { 214, 0, "DHR",    "Diabatic heating by radiation",                              "K"                     },
-  { 215, 0, "DHVD",   "Diabatic heating by vertical diffusion",                     "K"                     },
-  { 216, 0, "DHCC",   "Diabatic heating by cumulus convection",                     "K"                     },
-  { 217, 0, "DHLC",   "Diabatic heating large-scale condensation",                  "K"                     },
-  { 218, 0, "VDZW",   "Vertical diffusion of zonal wind",                           "m s**-1"               },
-  { 219, 0, "VDMW",   "Vertical diffusion of meridional wind",                      "m s**-1"               },
-  { 220, 0, "EWGD",   "EW gravity wave drag tendency",                              "m s**-1"               },
-  { 221, 0, "NSGD",   "NS gravity wave drag tendency",                              "m s**-1"               },
-  { 222, 0, "CTZW",   "Convective tendency of zonal wind",                          "m s**-1"               },
-  { 223, 0, "CTMW",   "Convective tendency of meridional wind",                     "m s**-1"               },
-  { 224, 0, "VDH",    "Vertical diffusion of humidity",                             "kg kg**-1"             },
-  { 225, 0, "HTCC",   "Humidity tendency by cumulus convection",                    "kg kg**-1"             },
-  { 226, 0, "HTLC",   "Humidity tendency large-scale condensation",                 "kg kg**-1"             },
-  { 227, 0, "CRNH",   "Change from removing negative humidity",                     "kg kg**-1"             },
-  { 228, 0, "TP",     "Total precipitation",                                        "m"                     },
-  { 229, 0, "IEWS",   "Instantaneous X surface stress",                             "N m**-2"               },
-  { 230, 0, "INSS",   "Instantaneous Y surface stress",                             "N m**-2"               },
-  { 231, 0, "ISHF",   "Instantaneous surface heat flux",                            "W m**-2"               },
-  { 232, 0, "IE",     "Instantaneous moisture flux",                                "kg m**-2 s"            },
-  { 233, 0, "ASQ",    "Apparent surface humidity",                                  "kg kg**-1"             },
-  { 234, 0, "LSRH",   "Logarithm of surface roughness length for heat",              NULL                   },
-  { 235, 0, "SKT",    "Skin temperature",                                           "K"                     },
-  { 236, 0, "STL4",   "Soil temperature level 4",                                   "K"                     },
-  { 237, 0, "SWL4",   "Soil wetness level 4",                                       "m"                     },
-  { 238, 0, "TSN",    "Temperature of snow layer",                                  "K"                     },
-  { 239, 0, "CSF",    "Convective snowfall",                                        "m of water equivalent" },
-  { 240, 0, "LSF",    "Large-scale snowfall",                                       "m of water equivalent" },
-  { 241, 0, "ACF",    "Accumulated cloud fraction tendency",                         NULL                   },
-  { 242, 0, "ALW",    "Accumulated liquid water tendency",                           NULL                   },
-  { 243, 0, "FAL",    "Forecast albedo",                                             NULL                   },
-  { 244, 0, "FSR",    "Forecast surface roughness",                                 "m"                     },
-  { 245, 0, "FLSR",   "Forecast log of surface roughness for heat",                  NULL                   },
-  { 246, 0, "CLWC",   "Cloud liquid water content",                                 "kg kg**-1"             },
-  { 247, 0, "CIWC",   "Cloud ice water content",                                    "kg kg**-1"             },
-  { 248, 0, "CC",     "Cloud cover",                                                 NULL                   },
-  { 249, 0, "AIW",    "Accumulated ice water tendency",                              NULL                   },
-  { 250, 0, "ICE",    "Ice age",                                                     NULL                   },
-  { 251, 0, "ATTE",   "Adiabatic tendency of temperature",                          "K"                     },
-  { 252, 0, "ATHE",   "Adiabatic tendency of humidity",                             "kg kg**-1"             },
-  { 253, 0, "ATZE",   "Adiabatic tendency of zonal wind",                           "m s**-1"               },
-  { 254, 0, "ATMW",   "Adiabatic tendency of meridional wind",                      "m s**-1"               },
-};
+const char *extLibraryVersion(void);
 
-static const PAR remo[] = {
-  {  14, 0, "FTKVM",     "turbulent transfer coefficient of momentum in the atmosphere",   NULL           },
-  {  15, 0, "FTKVH",     "turbulent transfer coefficient of heat in the atmosphere",       NULL           },
-  {  38, 0, "U10ER",     "10m u-velocity",                                                "m/s"           },
-  {  39, 0, "V10ER",     "10m v-velocity",                                                "m/s"           },
-  {  40, 0, "CAPE",      "convetive available potential energy",                           NULL           },
-  {  41, 0, "GHPBL",     "height of the planetary boudary layer",                         "gpm"           },
-  {  42, 0, "BETA",      "BETA",                                                           NULL           },
-  {  43, 0, "WMINLOK",   "WMINLOK",                                                        NULL           },
-  {  44, 0, "WMAXLOK",   "WMAXLOK",                                                        NULL           },
-  {  45, 0, "VBM10M",    "maximum of the expected gust velocity near the surface",        "m/s"           },
-  {  46, 0, "BFLHS",     "surface sensible heat flux",                                    "W/m**2"        },
-  {  47, 0, "BFLQDS",    "surface latent heat flux",                                      "W/m**2"        },
-  {  48, 0, "TMCM",      "turbulent transfer coefficient of momentum at the surface",      NULL           },
-  {  49, 0, "TRSOL",     "TRSOL",                                                          NULL           },
-  {  50, 0, "TMCH",      "turbulent transfer coefficient of heat at the surface",          NULL           },
-  {  51, 0, "EMTEF",     "EMTEF",                                                          NULL           },
-  {  52, 0, "TRSOF",     "TRSOF",                                                          NULL           },
-  {  53, 0, "DRAIN",     "drainage",                                                      "mm"            },
-  {  54, 0, "TSL",       "surface temperature (land)",                                    "K"             },
-  {  55, 0, "TSW",       "surface temperature (water)",                                   "K"             },
-  {  56, 0, "TSI",       "surface temperature (ice)",                                     "K"             },
-  {  57, 0, "USTRL",     "surface u-stress (land)",                                       "Pa"            },
-  {  58, 0, "USTRW",     "surface u-stress (water)",                                      "Pa"            },
-  {  59, 0, "USTRI",     "surface u-stress (ice)",                                        "Pa"            },
-  {  60, 0, "VSTRL",     "surface v-stress (land)",                                       "Pa"            },
-  {  61, 0, "VSTRW",     "surface v-stress (water)",                                      "Pa"            },
-  {  62, 0, "VSTRI",     "surface v-stress (ice)",                                        "Pa"            },
-  {  63, 0, "EVAPL",     "surface evaporation (land)",                                    "mm"            },
-  {  64, 0, "EVAPW",     "surface evaporation (water)",                                   "mm"            },
-  {  65, 0, "EVAPI",     "surface evaporation (ice)",                                     "mm"            },
-  {  66, 0, "AHFLL",     "surface latent heat flux (land)",                               "W/m**2"        },
-  {  67, 0, "AHFLW",     "surface latent heat flux (water)",                              "W/m**2"        },
-  {  68, 0, "AHFLI",     "surface latent heat flux (ice)",                                "W/m**2"        },
-  {  69, 0, "AHFSL",     "surface sensible heat flux (land)",                             "W/m**2"        },
-  {  70, 0, "AHFSW",     "surface sensible heat flux (water)",                            "W/m**2"        },
-  {  71, 0, "AHFSI",     "surface sensible heat flux (ice)",                              "W/m**2"        },
-  {  72, 0, "AZ0L",      "surface roughness length (land)",                               "m"             },
-  {  73, 0, "AZ0W",      "surface roughness length (water)",                              "m"             },
-  {  74, 0, "AZ0I",      "surface roughness length (ice)",                                "m"             },
-  {  75, 0, "ALSOL",     "surface albedo (land)",                                         "fract."        },
-  {  76, 0, "ALSOW",     "surface albedo (water)",                                        "fract."        },
-  {  77, 0, "ALSOI",     "surface albedo (ice)",                                          "fract."        },
-  {  81, 0, "TMCHL",     "turbulent transfer coefficient of heat at the surface (land)",   NULL           },
-  {  82, 0, "TMCHW",     "turbulent transfer coefficient of heat at the surface (water)",  NULL           },
-  {  83, 0, "TMCHI",     "turbulent transfer coefficient of heat at the surface (ice)",    NULL           },
-  {  84, 0, "QDBL",      "specific humidity surface (land)",                              "kg/kg"         },
-  {  85, 0, "QDBW",      "specific humidity surface (water)",                             "kg/kg"         },
-  {  86, 0, "QDBI",      "specific humidity surface (ice)",                               "kg/kg"         },
-  {  87, 0, "BFLHSL",    "surface sensible heat flux (land)",                             "W/m**2"        },
-  {  88, 0, "BFLHSW",    "surface sensible heat flux (water)",                            "W/m**2"        },
-  {  89, 0, "BFLHSI",    "surface sensible heat flux (ice)",                              "W/m**2"        },
-  {  90, 0, "BFLQDSL",   "surface latent heat flux (land)",                               "W/m**2"        },
-  {  91, 0, "BFLQDSW",   "surface latent heat flux (water)",                              "W/m**2"        },
-  {  92, 0, "BFLQDSI",   "surface latent heat flux (ice)",                                "W/m**2"        },
-  {  93, 0, "AHFICE",    "sea-ice: conductive heat",                                      "W/m"           },
-  {  94, 0, "QRES",      "residual heat flux for melting sea ice",                        "W/m**2"        },
-  {  95, 0, "SRFL",      "SRFL",                                                           NULL           },
-  {  96, 0, "QDBOXS",    "horizontal transport of water vapour",                          "kg/m**2"       },
-  {  97, 0, "QWBOXS",    "horizontal transport of cloud water",                           "kg/m**2"       },
-  {  98, 0, "EKBOXS",    "horizontal transport of kinetic energy",                        "(3600*J)/m**2" },
-  {  99, 0, "FHBOXS",    "horizontal transport of sensible heat",                         "(3600*J)/m**2" },
-  { 100, 0, "FIBOXS",    "horizontal transport of potential energy",                      "(3600*J)/m**2" },
-  { 101, 0, "TLAMBDA",   "heat conductivity of dry soil",                                 "W/(K*m)"       },
-  { 103, 0, "DLAMBDA",   "parameter for increasing the heat conductivity of the soil",     NULL           },
-  { 104, 0, "PORVOL",    "pore volume",                                                    NULL           },
-  { 105, 0, "FCAP",      "field capacity of soil",                                         NULL           },
-  { 106, 0, "WI3",       "fraction of frozen soil",                                        NULL           },
-  { 107, 0, "WI4",       "fraction of frozen soil",                                        NULL           },
-  { 108, 0, "WI5",       "fraction of frozen soil",                                        NULL           },
-  { 109, 0, "WI",        "fraction of frozen soil",                                        NULL           },
-  { 110, 0, "WICL",      "fraction of frozen soil",                                        NULL           },
-  { 112, 0, "QDB",       "specific humidity surface",                                     "kg/kg"         },
-  { 129, 0, "FIB",       "surface geopotential (orography)",                              "m"             },
-  { 130, 0, "T",         "temperature",                                                   "K"             },
-  { 131, 0, "U",         "u-velocity",                                                    "m/s"           },
-  { 132, 0, "V",         "v-velocity",                                                    "m/s"           },
-  { 133, 0, "QD",        "specific humidity",                                             "kg/kg"         },
-  { 134, 0, "PS",        "Surface pressure",                                              "Pa"            },
-  { 135, 0, "VERVEL",    "Vertical velocity",                                             "Pa/s"          },
-  { 138, 0, "SVO",       "vorticity",                                                     "1/s"           },
-  { 139, 0, "TS",        "surface temperature",                                           "K"             },
-  { 140, 0, "WS",        "soil wetness",                                                  "m"             },
-  { 141, 0, "SN",        "snow depth",                                                    "m"             },
-  { 142, 0, "APRL",      "large scale precipitation",                                     "mm"            },
-  { 143, 0, "APRC",      "convective  precipitation",                                     "mm"            },
-  { 144, 0, "APRS",      "snow fall",                                                     "mm"            },
-  { 145, 0, "VDIS",      "boundary layer dissipation",                                    "W/m**2"        },
-  { 146, 0, "AHFS",      "surface sensible heat flux",                                    "W/m**2"        },
-  { 147, 0, "AHFL",      "surface latent heat flux",                                      "W/m**2"        },
-  { 148, 0, "STREAM",    "streamfunction",                                                "m**2/s"        },
-  { 149, 0, "VELOPOT",   "velocity potential",                                            "m**2/s"        },
-  { 151, 0, "PSRED",     "mean sea level pressure",                                       "Pa"            },
-  { 152, 0, "LSP",       "log surface pressure",                                           NULL           },
-  { 153, 0, "QW",        "liquid water content",                                          "kg/kg"         },
-  { 155, 0, "SD",        "divergence",                                                    "1/s"           },
-  { 156, 0, "FI",        "geopotential height",                                           "gpm"           },
-  { 159, 0, "USTAR3",    "ustar**3",                                                      "m**3/s**3"     },
-  { 160, 0, "RUNOFF",    "surface runoff",                                                "mm"            },
-  { 162, 0, "ACLC",      "cloud cover",                                                   "fract."        },
-  { 163, 0, "ACLCV",     "total cloud cover",                                             "fract."        },
-  { 164, 0, "ACLCOV",    "total cloud cover",                                             "fract."        },
-  { 165, 0, "U10",       "10m u-velocity",                                                "m/s"           },
-  { 166, 0, "V10",       "10m v-velocity",                                                "m/s"           },
-  { 167, 0, "TEMP2",     "2m temperature",                                                "K"             },
-  { 168, 0, "DEW2",      "2m dew point temperature",                                      "K"             },
-  { 169, 0, "TSURF",     "surface temperature (land)",                                    "K"             },
-  { 170, 0, "TD",        "deep soil temperature",                                         "K"             },
-  { 171, 0, "WIND10",    "10m windspeed",                                                 "m/s"           },
-  { 172, 0, "BLA",       "land sea mask",                                                 "fract."        },
-  { 173, 0, "AZ0",       "surface roughness length",                                      "m"             },
-  { 174, 0, "ALB",       "surface background albedo",                                     "fract."        },
-  { 175, 0, "ALBEDO",    "surface albedo",                                                "fract."        },
-  { 176, 0, "SRADS",     "net surface solar radiation",                                   "W/m**2"        },
-  { 177, 0, "TRADS",     "net surface thermal radiation",                                 "W/m**2"        },
-  { 178, 0, "SRAD0",     "net top solar radiation",                                       "W/m**2"        },
-  { 179, 0, "TRAD0",     "top thermal radiation (OLR)",                                   "W/m**2"        },
-  { 180, 0, "USTR",      "surface u-stress",                                              "Pa"            },
-  { 181, 0, "VSTR",      "surface v-stress",                                              "Pa"            },
-  { 182, 0, "EVAP",      "surface evaporation",                                           "mm"            },
-  { 183, 0, "TDCL",      "soil temperature",                                              "K"             },
-  { 185, 0, "SRAFS",     "net surf. solar radiation   (clear sky)",                       "W/m**2"        },
-  { 186, 0, "TRAFS",     "net surf. thermal radiation (clear sky)",                       "W/m**2"        },
-  { 187, 0, "SRAF0",     "net top solar radiation     (clear sky)",                       "W/m**2"        },
-  { 188, 0, "TRAF0",     "net top thermal radiation   (clear sky)",                       "W/m**2"        },
-  { 189, 0, "SCLFS",     "surface solar cloud forcing",                                   "W/m**2"        },
-  { 190, 0, "TCLFS",     "surface thermal cloud forcing",                                 "W/m**2"        },
-  { 191, 0, "SCLF0",     "top solar cloud forcing",                                       "W/m**2"        },
-  { 192, 0, "TCLF0",     "top thermal cloud forcing",                                     "W/m**2"        },
-  { 194, 0, "WL",        "skin reservoir content",                                        "m"             },
-  { 195, 0, "USTRGW",    "u-gravity wave stress",                                         "Pa"            },
-  { 196, 0, "VSTRGW",    "v-gravity wave stress",                                         "Pa"            },
-  { 197, 0, "VDISGW",    "gravity wave dissipation",                                      "W/m**2"        },
-  { 198, 0, "VGRAT",     "vegetation ratio",                                               NULL           },
-  { 199, 0, "VAROR",     "orographic variance (for surface runoff)",                       NULL           },
-  { 200, 0, "VLT",       "leaf area index",                                                NULL           },
-  { 201, 0, "T2MAX",     "maximum 2m-temperature",                                        "K"             },
-  { 202, 0, "T2MIN",     "minimum 2m-temperature",                                        "K"             },
-  { 203, 0, "SRAD0U",    "top solar radiation upward",                                    "W/m**2"        },
-  { 204, 0, "SRADSU",    "surface solar radiation upward",                                "W/m**2"        },
-  { 205, 0, "TRADSU",    "surface thermal radiation upward",                              "W/m**2"        },
-  { 206, 0, "TSN",       "snow temperature",                                              "K"             },
-  { 207, 0, "TD3",       "soil temperature",                                              "K"             },
-  { 208, 0, "TD4",       "soil temperature",                                              "K"             },
-  { 209, 0, "TD5",       "soil temperature",                                              "K"             },
-  { 210, 0, "SEAICE",    "sea ice cover",                                                 "fract."        },
-  { 211, 0, "SICED",     "sea ice depth",                                                 "m"             },
-  { 212, 0, "FOREST",    "vegetation type",                                                NULL           },
-  { 213, 0, "TEFF",      "(effective) sea-ice skin temperature",                          "K"             },
-  { 214, 0, "TSMAX",     "maximum surface temperature",                                   "K"             },
-  { 215, 0, "TSMIN",     "minimum surface temperature",                                   "K"             },
-  { 216, 0, "WIMAX",     "maximum 10m-wind speed",                                        "m/s"           },
-  { 217, 0, "TOPMAX",    "maximum height of convective cloud tops",                       "Pa"            },
-  { 218, 0, "SNMEL",     "snow melt",                                                     "mm"            },
-  { 220, 0, "TSLIN",     "land: residual surface heat budget",                            "W/m**2"        },
-  { 221, 0, "DSNAC",     "snow depth change",                                             "mm"            },
-  { 222, 0, "EMTER",     "EMTER",                                                          NULL           },
-  { 223, 0, "ACLCAC",    "cloud cover",                                                   "fract."        },
-  { 224, 0, "TKE",       "turbulent kinetic energy",                                       NULL           },
-  { 226, 0, "FAO",       "FAO data set (soil data flags)",                                 NULL           },
-  { 227, 0, "RGCGN",     "heat capacity of soil",                                          NULL           },
-  { 229, 0, "WSMX",      "field capacity of soil",                                         NULL           },
-  { 230, 0, "QVI",       "vertically integrated specific humidity",                       "kg/m**2"       },
-  { 231, 0, "ALWCVI",    "vertically integrated liquid water cont.",                      "kg/m**2"       },
-  { 232, 0, "GLAC",      "glacier mask",                                                   NULL           },
-  { 253, 0, "PHI",       "latitude in real coordinates",                                  "degrees_north" },
-  { 254, 0, "RLA",       "longitude in real coordinates",                                 "degrees_east"  },
-  { 259, 0, "WINDSPEED", "windspeed (sqrt(u**2+v**2))",                                    NULL           },
-  { 260, 0, "PRECIP",    "total precipitation",                                            NULL           },
-};
+void extDebug(int debug);
+
+int  extCheckFiletype(int fileID, int *swap);
+
+void *extNew(void);
+void extDelete(void *ext);
+
+int  extRead(int fileID, void *ext);
+int  extWrite(int fileID, void *ext);
+
+int  extInqHeader(void *ext, int *header);
+int  extInqDataSP(void *ext, float *data);
+int  extInqDataDP(void *ext, double *data);
+
+int  extDefHeader(void *ext, const int *header);
+int  extDefDataSP(void *ext, const float *data);
+int  extDefDataDP(void *ext, const double *data);
+
+#endif  /* _EXTRA_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _IEG_H
+#define _IEG_H
+
+/* Level Types */
+#define  IEG_LTYPE_SURFACE               1
+#define  IEG_LTYPE_99                   99
+#define  IEG_LTYPE_ISOBARIC            100
+#define  IEG_LTYPE_MEANSEA             102
+#define  IEG_LTYPE_ALTITUDE            103
+#define  IEG_LTYPE_HEIGHT              105
+#define  IEG_LTYPE_SIGMA               107
+#define  IEG_LTYPE_HYBRID              109
+#define  IEG_LTYPE_HYBRID_LAYER        110
+#define  IEG_LTYPE_LANDDEPTH           111
+#define  IEG_LTYPE_LANDDEPTH_LAYER     112
+#define  IEG_LTYPE_SEADEPTH            160
+#define  IEG_LTYPE_99_MARGIN          1000
+
+/*
+ *  Data representation type (Grid Type) [Table 6]
+ */
+#define  IEG_GTYPE_LATLON             0  /*  latitude/longitude                       */
+#define  IEG_GTYPE_LATLON_ROT        10  /*  rotated latitude/longitude               */
+
+#define  IEG_P_CodeTable(x)   (x[ 5])  /*  Version number of code table                 */
+#define  IEG_P_Parameter(x)   (x[ 6])  /*  Parameter indicator                          */
+#define  IEG_P_LevelType(x)   (x[ 7])  /*  Type of level indicator                      */
+#define  IEG_P_Level1(x)      (x[ 8])  /*  Level 1                                      */
+#define  IEG_P_Level2(x)      (x[ 9])  /*  Level 2                                      */
+#define  IEG_P_Year(x)        (x[10])  /*  Year of century (YY)                         */
+#define  IEG_P_Month(x)       (x[11])  /*  Month (MM)                                   */
+#define  IEG_P_Day(x)         (x[12])  /*  Day (DD)                                     */
+#define  IEG_P_Hour(x)        (x[13])  /*  Hour (HH)                                    */
+#define  IEG_P_Minute(x)      (x[14])  /*  Minute (MM)                                  */
+
+/*
+ *  Macros for the grid definition section ( Section 2 )
+ */
+#define  IEG_G_Size(x)        (x[ 0])
+#define  IEG_G_NumVCP(x)      (x[3] == 10 ? (x[0]-42)/4 : (x[0]-32)/4)
+#define  IEG_G_GridType(x)    (x[ 3])  /*  Data representation type */
+#define  IEG_G_NumLon(x)      (x[ 4])  /*  Number of points along a parallel (Ni)       */
+#define  IEG_G_NumLat(x)      (x[ 5])  /*  Number of points along a meridian (Nj)       */
+#define  IEG_G_FirstLat(x)    (x[ 6])  /*  Latitude of the first grid point             */
+#define  IEG_G_FirstLon(x)    (x[ 7])  /*  Longitude of the first grid point            */
+#define  IEG_G_ResFlag(x)     (x[ 8])  /*  Resolution flag: 128 regular grid            */
+#define  IEG_G_LastLat(x)     (x[ 9])  /*  Latitude of the last grid point              */
+#define  IEG_G_LastLon(x)     (x[10])  /*  Longitude of the last grid point             */
+#define  IEG_G_LonIncr(x)     (x[11])  /*  i direction increment                        */
+#define  IEG_G_LatIncr(x)     (x[12])  /*  j direction increment                        */
+#define  IEG_G_ScanFlag(x)    (x[13])
+#define  IEG_G_LatSP(x)       (x[16])  /*  Latitude of the southern pole of rotation    */
+#define  IEG_G_LonSP(x)       (x[17])  /*  Longitude of the southern pole of rotation   */
+#define  IEG_G_ResFac(x)      (x[18])  /*  Resolution factor                            */
+
+
+typedef struct {
+  int    checked;
+  int    byteswap;
+  int    dprec;      /* data   precision */
+  double refval;
+  int    ipdb[37];
+  int    igdb[22];
+  double vct[100];
+  size_t datasize;
+  size_t buffersize;
+  void  *buffer;
+}
+iegrec_t;
+
+
+const char *iegLibraryVersion(void);
+
+void iegDebug(int debug);
+int  iegCheckFiletype(int fileID, int *swap);
+
+iegrec_t *iegNew(void);
+void iegDelete(iegrec_t *iegp);
+void iegInit(iegrec_t *iegp);
+void iegInitMem(iegrec_t *iegp);
+
+int  iegRead(int fileID, iegrec_t *iegp);
+int  iegWrite(int fileID, iegrec_t *iegp);
+
+void iegCopyMeta(iegrec_t *diegp, iegrec_t *siegp);
+int  iegInqHeader(iegrec_t *iegp, int *header);
+int  iegInqDataSP(iegrec_t *iegp, float *data);
+int  iegInqDataDP(iegrec_t *iegp, double *data);
+
+int  iegDefHeader(iegrec_t *iegp, const int *header);
+int  iegDefDataSP(iegrec_t *iegp, const float *data);
+int  iegDefDataDP(iegrec_t *iegp, const double *data);
+
+
+#endif  /* _IEG_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _CDI_INT_H
+#define _CDI_INT_H
+
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+
+/* dummy use of unused parameters to silence compiler warnings */
+#define  UNUSED(x) (void)x
+
+#ifndef strdupx
+#ifndef strdup
+char *strdup(const char *s);
+#endif
+#define strdupx  strdup
+/*
+#define strdupx(s)			          \
+({					      	  \
+   const char *__old = (s);			  \
+   size_t __len = strlen(__old) + 1;		  \
+   char *__new = (char *) malloc(__len);	  \
+   (char *) memcpy(__new, __old, __len);	  \
+})
+*/
+#endif
+
+#ifndef  M_PI
+#define  M_PI        3.14159265358979323846  /* pi */
+#endif
+
+
+#ifndef  _ERROR_H
+#endif
+#ifndef _BASETIME_H
+#endif
+#ifndef _TIMEBASE_H
+#endif
+#ifndef  _TAXIS_H
+#endif
+#ifndef  _CDI_LIMITS_H
+#endif
+#ifndef  _SERVICE_H
+#endif
+#ifndef  _EXTRA_H
+#endif
+#ifndef  _IEG_H
+#endif
+#ifndef RESOURCE_HANDLE_H
+#endif
+
+
+#define check_parg(arg)  if ( arg == 0 ) Warning("Argument '" #arg "' not allocated!")
+
+#if defined (__xlC__) /* performance problems on IBM */
+#ifndef DBL_IS_NAN
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#else
+#ifndef DBL_IS_NAN
+#if  defined  (HAVE_DECL_ISNAN)
+#  define DBL_IS_NAN(x)     (isnan(x))
+#elif  defined  (FP_NAN)
+#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
+#else
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#endif
+#endif
+
+#ifndef DBL_IS_EQUAL
+/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
+#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)):!(x < y || y < x))
+#endif
+
+#ifndef IS_EQUAL
+#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
+#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
+#endif
+
+
+#define  FALSE  0
+#define  TRUE   1
+
+#define  TYPE_REC  0
+#define  TYPE_VAR  1
+
+#define  MEMTYPE_DOUBLE  1
+#define  MEMTYPE_FLOAT   2
+
+typedef struct
+{
+  void     *buffer;             /* gribapi, cgribex */
+  size_t    buffersize;         /* gribapi, cgribex */
+  off_t     position;           /* ieg */
+  int       param;              /* srv */
+  int       level;              /* ext, srv */
+  int       date;               /* ext, srv */
+  int       time;               /* srv */
+  int       gridID;             /* ieg, ext */
+  int       varID;              /* ieg */
+  int       levelID;            /* ieg  */
+  int       prec;               /* ext, srv */
+  int       sec0[2];            /* cgribex */
+  int       sec1[1024];         /* cgribex */
+  int       sec2[4096];         /* cgribex */
+  int       sec3[2];            /* cgribex */
+  int       sec4[512];          /* cgribex */
+  void     *exsep;              /* ieg, ext, srv */
+}
+Record;
 
-static const PAR cosmo002[] = {
-  {   1, 0, "P",         "pressure",                                          "Pa"         },
-  {   2, 0, "PMSL",      "mean sea level pressure",                           "Pa"         },
-  {   3, 0, "DPSDT",     "surface pressure change",                           "Pa s-1"     },
-  {   6, 0, "FI",        "geopotential",                                      "m2 s-2"     },
-  {   8, 0, "HH",        "height",                                            "m"          },
-  {  10, 0, "TO3",       "vertical integrated ozone content",                 "Dobson"     },
-  {  11, 0, "T",         "temperature",                                       "K"          },
-  {  15, 0, "TMAX",      "2m maximum temperature",                            "K"          },
-  {  16, 0, "TMIN",      "2m minimum temperature",                            "K"          },
-  {  17, 0, "TD",        "2m dew point temperature",                          "K"          },
-  {  31, 0, "DD",        "undefined",                                         "undefined"  },
-  {  32, 0, "FF",        "undefined",                                         "undefined"  },
-  {  33, 0, "U",         "U-component of wind",                               "m s-1"      },
-  {  34, 0, "V",         "V-component of wind",                               "m s-1"      },
-  {  39, 0, "OMEGA",     "omega",                                             "Pa s-1"     },
-  {  40, 0, "W",         "vertical wind velocity",                            "m s-1"      },
-  {  51, 0, "QV",        "specific humidity",                                 "kg kg-1"    },
-  {  52, 0, "RELHUM",    "relative humidity",                                 "%"          },
-  {  54, 0, "TQV",       "precipitable water",                                "kg m-2"     },
-  {  57, 0, "AEVAP",     "surface evaporation",                               "kg m-2"     },
-  {  58, 0, "TQI",       "vertical integrated cloud ice",                     "kg m-2"     },
-  {  59, 0, "TOT_PR",    "total precipitation rate",                          "kg m-2 s-1" },
-  {  61, 0, "TOT_PREC",  "total precipitation amount",                        "kg m-2"     },
-  {  65, 0, "W_SNOW",    "surface snow amount",                               "m"          },
-  {  66, 0, "H_SNOW",    "thickness of snow",                                 "m"          },
-  {  71, 0, "CLCT",      "total cloud cover",                                 "1"          },
-  {  72, 0, "CLC_CON",   "convective cloud area fraction",                    "1"          },
-  {  73, 0, "CLCL",      "low cloud cover",                                   "1"          },
-  {  74, 0, "CLCM",      "medium cloud cover",                                "1"          },
-  {  75, 0, "CLCH",      "high cloud cover",                                  "1"          },
-  {  76, 0, "TQC",       "vertical integrated cloud water",                   "kg m-2"     },
-  {  78, 0, "SNOW_CON",  "convective snowfall",                               "kg m-2"     },
-  {  79, 0, "SNOW_GSP",  "large scale snowfall",                              "kg m-2"     },
-  {  81, 0, "FR_LAND",   "land-sea fraction",                                 "1"          },
-  {  83, 0, "Z0",        "surface roughness length",                          "m"          },
-  {  84, 0, "ALB_RAD",   "surface albedo",                                    "1"          },
-  {  85, 0, "TSOIL",     "soil surface temperature",                          "K"          },
-  {  86, 0, "WSOIL",     "water content of 1. soil layer",                    "m"          },
-  {  87, 0, "PLCOV",     "vegetation area fraction",                          "1"          },
-  {  90, 0, "RUNOFF",    "subsurface runoff",                                 "kg m-2"     },
-  {  91, 0, "FR_ICE",    "sea ice area fraction",                             "1"          },
-  {  92, 0, "H_ICE",     "sea ice thickness",                                 "m"          },
-  { 111, 0, "ASOB",      "averaged surface net downward shortwave radiation", "W m-2"      },
-  { 112, 0, "ATHB",      "averaged surface net downward longwave radiation",  "W m-2"      },
-  { 113, 0, "ASOB",      "averaged TOA net downward shortwave radiation",     "W m-2"      },
-  { 114, 0, "ATHB",      "averaged TOA outgoing longwave radiation",          "W m-2"      },
-  { 115, 0, "ASWDIR",    "direct downward sw radiation at the surface",       "W m-2"      },
-  { 116, 0, "ASWDIFD",   "diffuse downward sw radiation at the surface",      "W m-2"      },
-  { 117, 0, "ASWDIFU",   "diffuse upwnward sw radiation at the surface",      "W m-2"      },
-  { 118, 0, "ALWD",      "downward lw radiation at the surface",              "W m-2"      },
-  { 119, 0, "ALWU",      "upward lw radiation at the surface",                "W m-2"      },
-  { 121, 0, "ALHFL",     "averaged surface latent heat flux",                 "W m-2"      },
-  { 122, 0, "ASHFL",     "averaged surface sensible heat flux",               "W m-2"      },
-  { 124, 0, "AUMFL",     "averaged eastward stress",                          "Pa"         },
-  { 125, 0, "AVMFL",     "averaged northward stress",                         "Pa"         },
-  { 128, 0, "SUNSH",     "undefined",                                         "undefined"  },
-  { 129, 0, "SUNSH2",    "undefined",                                         "undefined"  },
-  { 130, 0, "SUN_SUM",   "undefined",                                         "undefined"  },
-  { 131, 0, "SUN_SUM2",  "undefined",                                         "undefined"  },
-  { 133, 0, "FCOR",      "undefined",                                         "undefined"  },
-  { 134, 0, "SKYVIEW",   "sky-view factor",                                   "1"          },
-  { 137, 0, "SWDIR_COR", "topo correction of direct solar radiarion",         "1"          },
-};
 
-static const PAR cosmo201[] = {
-  {   5, 0, "APAB",      "&",                                                         "W m-2"      },
-  {  13, 0, "SOHR_RAD",  "&",                                                         "K s-1"      },
-  {  14, 0, "THHR_RAD",  "&",                                                         "K s-1"      },
-  {  20, 0, "DURSUN",    "duration of sunshine",                                      "s"          },
-  {  29, 0, "CLC",       "cloud area fraction",                                       "1"          },
-  {  30, 0, "CLC_SGS",   "grid scale cloud area fraction",                            "1"          },
-  {  31, 0, "QC",        "specific cloud liquid water content",                       "kg kg-1"    },
-  {  33, 0, "QI",        "specific cloud ice content",                                "kg kg-1"    },
-  {  35, 0, "QR",        "specific rain content",                                     "kg kg-1"    },
-  {  36, 0, "QS",        "specific snow content",                                     "kg kg-1"    },
-  {  37, 0, "TQR",       "total rain water content vertically integrated",            "kg m-2"     },
-  {  38, 0, "TQS",       "total snow content vertically integrated",                  "kg m-2"     },
-  {  39, 0, "QG",        "specific graupel content",                                  "kg kg-1"    },
-  {  40, 0, "TQG",       "total graupel content vertically integrated",               "kg m-2"     },
-  {  41, 0, "TWATER",    "cloud condensed water content",                             "kg m-2"     },
-  {  42, 0, "TDIV_HUM",  "atmosphere water divergence",                               "kg m-2"     },
-  {  43, 0, "QC_RAD",    "sub scale specific cloud liquid water content",             "kg kg-1"    },
-  {  44, 0, "QI_RAD",    "sub scale specific cloud ice content",                      "kg kg-1"    },
-  {  61, 0, "CLW_CON",   "convective cloud liquid water",                             "1"          },
-  {  68, 0, "HBAS_CON",  "height of convective cloud base",                           "m"          },
-  {  69, 0, "HTOP_CON",  "height of convective cloud top",                            "m"          },
-  {  70, 0, "HBAS_CONI", "height of convective cloud base",                           "m"          },
-  {  71, 0, "HTOP_CONI", "height of convective cloud top",                            "m"          },
-  {  72, 0, "BAS_CON",   "index of convective cloud base",                            "1"          },
-  {  73, 0, "TOP_CON",   "index of convective cloud top",                             "1"          },
-  {  74, 0, "DT_CON",    "convective tendency of temperature",                        "K s-1"      },
-  {  75, 0, "DQV_CON",   "convective tendency of specific humidity",                  "s-1"        },
-  {  78, 0, "DU_CON",    "convective tendency of u-wind component",                   "m s-2"      },
-  {  79, 0, "DV_CON",    "convective tendency of v-wind component",                   "m s-2"      },
-  {  82, 0, "HTOP_DC",   "height of dry convection top",                              "m"          },
-  {  84, 0, "HZEROCL",   "height of freezing level",                                  "m"          },
-  {  85, 0, "SNOWLMT",   "height of the snow fall limit in m above sea level",        "m"          },
-  {  86, 0, "HCBAS",     "height of cloud base",                                      "m"          },
-  {  87, 0, "HCTOP",     "height of cloud top",                                       "m"          },
-  {  91, 0, "C_T_LK",    "&",                                                         "1"          },
-  {  92, 0, "GAMSO_LK",  "&",                                                         "m-1"        },
-  {  93, 0, "DP_BS_LK",  "&",                                                         "m"          },
-  {  94, 0, "H_B1_LK",   "&",                                                         "m"          },
-  {  95, 0, "H_ML_LK",   "&",                                                         "m"          },
-  {  96, 0, "DEPTH_LK",  "lake depth",                                                "m"          },
-  {  97, 0, "FETCH_LK",  "wind fetch over lake",                                      "m"          },
-  {  99, 0, "QRS",       "precipitation water (water loading)",                       "1"          },
-  { 100, 0, "PRR_GSP",   "mass flux density of large scale rainfall",                 "kg m-2 s-1" },
-  { 101, 0, "PRS_GSP",   "mass flux density of large scale snowfall",                 "kg m-2 s-1" },
-  { 102, 0, "RAIN_GSP",  "large scale rainfall",                                      "kg m-2"     },
-  { 111, 0, "PRR_CON",   "mass flux density of convective rainfall",                  "kg m-2 s-1" },
-  { 112, 0, "PRS_CON",   "mass flux density of convective snowfall",                  "kg m-2 s-1" },
-  { 113, 0, "RAIN_CON",  "convective rainfall",                                       "kg m-2"     },
-  { 129, 0, "FRESHSNW",  "freshness of snow",                                         "undefined"  },
-  { 131, 0, "PRG_GSP",   "mass flux density of large scale graupel",                  "kg m-2 s-1" },
-  { 132, 0, "GRAU_GSP",  "large scale graupel",                                       "kg m-2"     },
-  { 133, 0, "RHO_SNOW",  "density of snow",                                           "kg m-3"     },
-  { 139, 0, "PP",        "deviation from reference pressure",                         "Pa"         },
-  { 140, 0, "RCLD",      "standard deviation of saturation deficit",                  "undefined"  },
-  { 143, 0, "CAPE_MU",   "cape of most unstable parcel",                              "J kg-1"     },
-  { 144, 0, "CIN_MU",    "convective inhibition of most unstable parcel",             "J kg-1"     },
-  { 145, 0, "CAPE_ML",   "cape of mean surface layer parcel",                         "J kg-1"     },
-  { 146, 0, "CIN_ML",    "convective inhibition of mean surface layer parcel",        "J kg-1"     },
-  { 147, 0, "TKE_CON",   "convective turbulent kinetic energy",                       "undefined"  },
-  { 148, 0, "TKETENS",   "tendency of turbulent kinetic energy",                      "undefined"  },
-  { 152, 0, "TKE",       "turbulent kinetic energy",                                  "m2 s-2"     },
-  { 153, 0, "TKVM",      "diffusion coefficient of momentum",                         "m2 s-1"     },
-  { 154, 0, "TKVH",      "diffusion coefficient of heat",                             "m2 s-1"     },
-  { 170, 0, "TCM",       "drag coefficient of momentum",                              "1"          },
-  { 171, 0, "TCH",       "drag coefficient of heat",                                  "1"          },
-  { 187, 0, "VMAX",      "maximum turbulent wind gust in 10m",                        "m s-1"      },
-  { 190, 0, "TSOIL",     "&",                                                         "K"          },
-  { 191, 0, "TSOIL",     "&",                                                         "K"          },
-  { 192, 0, "TSOIL",     "&",                                                         "K"          },
-  { 193, 0, "TSOIL",     "mixed layer temperature",                                   "K"          },
-  { 194, 0, "TSOIL",     "mean temperature of water column",                          "K"          },
-  { 197, 0, "TSOIL",     "soil temperature",                                          "K"          },
-  { 198, 0, "W_SO",      "soil water content",                                        "m"          },
-  { 199, 0, "W_SO_ICE",  "soil frozen water content",                                 "m"          },
-  { 200, 0, "W_I",       "canopy water amount",                                       "m"          },
-  { 203, 0, "TSOIL",     "snow surface temperature",                                  "K"          },
-  { 215, 0, "TSOIL",     "temperature of ice upper surface",                          "K"          },
-  { 230, 0, "dBZ",       "unattenuated radar reflectivity in Rayleigh approximation", "1"          },
-  { 240, 0, "MFLX_CON",  "convective mass flux density",                              "kg m-2 s-1" },
-  { 241, 0, "CAPE_CON",  "&",                                                         "J kg-1"     },
-  { 243, 0, "QCVG_CON",  "&",                                                         "s-1"        },
-};
+typedef struct
+{
+  off_t     position;
+  size_t    size;
+  int       zip;
+  int       param;
+  int       ilevel;
+  int       ilevel2;
+  int       ltype;
+  int       tsteptype;
+  short     used;
+  short     varID;
+  short     levelID;
+  char      varname[32]; /* needed for grib decoding with GRIB_API */
+}
+record_t;
 
-static const PAR cosmo202[] = {
-  {  46, 0, "SSO_STDH",  "standard deviation of subgrid scale height",                "m"         },
-  {  47, 0, "SSO_GAMMA", "anisotropy of topography",                                  "-"         },
-  {  48, 0, "SSO_THETA", "angle between principal axis of orography and global east", "-"         },
-  {  49, 0, "SSO_SIGMA", "mean slope of subgrid scale orography",                     "-"         },
-  {  55, 0, "FR_LAKE",   "fraction of inland lake water",                             "1"         },
-  {  57, 0, "SOILTYP",   "soil type",                                                 "1"         },
-  {  61, 0, "LAI",       "leaf area index",                                           "1"         },
-  {  62, 0, "ROOTDP",    "root depth",                                                "m"         },
-  {  64, 0, "HMO3",      "air pressure at ozone maximum",                             "Pa"        },
-  {  65, 0, "VIO3",      "vertical integrated ozone amount",                          "Pa"        },
-  {  67, 0, "PLCOV_MX",  "vegetation area fraction maximum",                          "1"         },
-  {  68, 0, "PLCOV_MN",  "vegetation area fraction minimum",                          "1"         },
-  {  69, 0, "LAI_MX",    "leaf area index maximum",                                   "1"         },
-  {  70, 0, "LAI_MN",    "leaf area index minimum",                                   "1"         },
-  {  75, 0, "FOR_E",     "ground fraction covered by evergreen forest",               "-"         },
-  {  76, 0, "FOR_D",     "ground fraction covered by deciduous forest",               "-"         },
-  { 104, 0, "DQVDT",     "tendency of water vapor",                                   "s-1"       },
-  { 105, 0, "QVSFLX",    "surface flux of water vapour",                              "s-1m-2"    },
-  { 113, 0, "FC",        "coriolis parameter",                                        "s-1"       },
-  { 114, 0, "RLAT",      "latitude",                                                  "radian"    },
-  { 115, 0, "RLON",      "longitude",                                                 "radian"    },
-  { 121, 0, "ZTD",       "integrated total atmospheric refractivity",                 "undefined" },
-  { 122, 0, "ZWD",       "integrated wet atmospheric refractivity",                   "undefined" },
-  { 123, 0, "ZHD",       "integrated dry atmospheric refractivity",                   "undefined" },
-  { 180, 0, "O3",        "ozone mass mixing ratio",                                   "kg kg-1"   },
-  { 200, 0, "I131a",     "undefined",                                                 "undefined" },
-  { 201, 0, "I131a_DD",  "undefined",                                                 "undefined" },
-  { 202, 0, "I131a_WD",  "undefined",                                                 "undefined" },
-  { 203, 0, "Cs137",     "undefined",                                                 "undefined" },
-  { 204, 0, "Cs137_DD",  "undefined",                                                 "undefined" },
-  { 205, 0, "Cs137_WD",  "undefined",                                                 "undefined" },
-  { 206, 0, "Te132",     "undefined",                                                 "undefined" },
-  { 207, 0, "Te132_DD",  "undefined",                                                 "undefined" },
-  { 208, 0, "Te132_WD",  "undefined",                                                 "undefined" },
-  { 209, 0, "Zr95",      "undefined",                                                 "undefined" },
-  { 210, 0, "Zr95_DD",   "undefined",                                                 "undefined" },
-  { 211, 0, "Zr95_WD",   "undefined",                                                 "undefined" },
-  { 212, 0, "Kr85",      "undefined",                                                 "undefined" },
-  { 213, 0, "Kr85_DD",   "undefined",                                                 "undefined" },
-  { 214, 0, "Kr85_WD",   "undefined",                                                 "undefined" },
-  { 215, 0, "TRACER",    "undefined",                                                 "undefined" },
-  { 216, 0, "TRACER_DD", "undefined",                                                 "undefined" },
-  { 217, 0, "TRACER_WD", "undefined",                                                 "undefined" },
-  { 218, 0, "Xe133",     "undefined",                                                 "undefined" },
-  { 219, 0, "Xe133_DD",  "undefined",                                                 "undefined" },
-  { 220, 0, "Xe133_WD",  "undefined",                                                 "undefined" },
-  { 221, 0, "I131g",     "undefined",                                                 "undefined" },
-  { 222, 0, "I131g_DD",  "undefined",                                                 "undefined" },
-  { 223, 0, "I131g_WD",  "undefined",                                                 "undefined" },
-  { 224, 0, "I131o",     "undefined",                                                 "undefined" },
-  { 225, 0, "I131o_DD",  "undefined",                                                 "undefined" },
-  { 226, 0, "I131o_WD",  "undefined",                                                 "undefined" },
-  { 227, 0, "Ba140",     "undefined",                                                 "undefined" },
-  { 228, 0, "Ba140_DD",  "undefined",                                                 "undefined" },
-  { 229, 0, "Ba140_WD",  "undefined",                                                 "undefined" },
-  { 230, 0, "Sr90",      "undefined",                                                 "undefined" },
-  { 231, 0, "Sr90_DD",   "undefined",                                                 "undefined" },
-  { 232, 0, "Sr90_WD",   "undefined",                                                 "undefined" },
-  { 233, 0, "Ru103",     "undefined",                                                 "undefined" },
-  { 234, 0, "Ru103_DD",  "undefined",                                                 "undefined" },
-  { 235, 0, "Ru103_WD",  "undefined",                                                 "undefined" },
-};
 
-static const PAR cosmo203[] = {
-  { 135, 0, "LCL_ML",   "undefined",                  "undefined" },
-  { 136, 0, "LFC_ML",   "undefined",                  "undefined" },
-  { 137, 0, "CAPE_3KM", "undefined",                  "undefined" },
-  { 138, 0, "SWISS00",  "swiss00 index",              "1"         },
-  { 139, 0, "SWISS12",  "swiss12 index",              "1"         },
-  { 147, 0, "SLI",      "surface lifted index",       "K"         },
-  { 149, 0, "SI",       "showalter index",            "K"         },
-  { 155, 0, "BRN",      "undefined",                  "undefined" },
-  { 156, 0, "HPBL",     "undefined",                  "undefined" },
-  { 203, 0, "CLDEPTH",  "normalized cloud depth",     "1"         },
-  { 204, 0, "CLCT_MOD", "modified_total_cloud_cover", "1"         },
-};
+typedef struct {
+  record_t *records;
+  int       recordSize;  /* number of allocated records           */
+  int      *recIDs;      /* IDs of non constant records           */
+  int       nrecs;       /* number of used records                */
+                         /* tsID=0 nallrecs                       */
+                         /* tsID>0 number of non constant records */
+  int       nallrecs;    /* number of all records                 */
+  int       curRecID;    /* current record ID                     */
+  long      next;
+  off_t     position;    /* timestep file position                */
+  taxis_t   taxis;
+}
+tsteps_t;
 
-static const PAR cosmo205[] = {
-  {   1, 0, "SYNME5", "synthetic satellite images Meteosat5", "-" },
-  {   2, 0, "SYNME6", "synthetic satellite images Meteosat6", "-" },
-  {   3, 0, "SYNME7", "synthetic satellite images Meteosat7", "-" },
-  {   4, 0, "SYNMSG", "synthetic satellite images MSG",       "-" },
-};
 
-static const PAR cosmo250[] = {
-  {   1, 0, "QNH",       "sea level air pressure",                                         "hPa"                                },
-  {  11, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
-  {  12, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
-  {  13, 0, "D_T_2M_K",  "kalman correction to 2m temperature",                            "K"                                  },
-  {  14, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
-  {  15, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
-  {  16, 0, "RH_ICE",    "relative humidity over ice",                                     "%"                                  },
-  {  17, 0, "TD",        "dew point temperature",                                          "K"                                  },
-  {  18, 0, "D_TD",      "dew point depression",                                           "K"                                  },
-  {  19, 0, "THETAE",    "equivalent potential temperature",                               "K"                                  },
-  {  20, 0, "TD_2M_K",   "2m dew point temperature",                                       "K"                                  },
-  {  21, 0, "D_TD_2M_K", "kalman correction to 2m dew point temperature",                  "K"                                  },
-  {  22, 0, "TD_2M_OLD", "2m dew point temperature",                                       "K"                                  },
-  {  23, 0, "TD_2M_BUZ", "2m dew point temperature",                                       "K"                                  },
-  {  24, 0, "HI",        "heat index",                                                     "Fahrenheit"                         },
-  {  25, 0, "DURSUN_M",  "maximum duration of sunshine",                                   "s"                                  },
-  {  26, 0, "DURSUN_R",  "relative duration of sunshine",                                  "%"                                  },
-  {  52, 0, "RH_2M_K",   "2m relative humidity",                                           "%"                                  },
-  {  53, 0, "D_RH_2M_K", "kalman correction to 2m relative humidity",                      "%"                                  },
-  {  58, 0, "CLI_RATIO", "cloud ice ratio (Qi/Qc+Qi)",                                     "%"                                  },
-  {  61, 0, "TOT_SNOW",  "total precipitation in snow",                                    "kg/m**2"                            },
-  {  62, 0, "TOT_RAIN",  "total precipitation in rain",                                    "kg/m**2"                            },
-  {  63, 0, "TOT_CON",   "total convective precipitation",                                 "kg/m**2"                            },
-  {  64, 0, "TOT_GSP",   "total large scale precipitation",                                "kg/m**2"                            },
-  {  65, 0, "SNOW_%",    "percentage of precipitation in snow",                            "%"                                  },
-  {  66, 0, "CONV_%",    "percentage of convective precipitation",                         "%"                                  },
-  {  67, 0, "VORTP_ABS", "absolute",                                                       "VORTP_ABS 67 -1 absolute vorticity" },
-  {  68, 0, "VORTP_REL", "relative",                                                       "VORTP_REL 68 -1 relative vorticity" },
-  {  70, 0, "PDIFF_CON", "pressure difference between cloud base and cloud top",           "Pa"                                 },
-  {  71, 0, "TTOP_CON",  "temperature at cloud top",                                       "K"                                  },
-  {  80, 0, "GEM",       "emissivity of the ground",                                       "%"                                  },
-  {  82, 0, "Z0LOC",     "local surface roughness length",                                 "m"                                  },
-  { 110, 0, "LUM",       "luminosity",                                                     "klux"                               },
-  { 111, 0, "GLOB",      "global shortwave radiation at surface",                          "W/m**2"                             },
-  { 112, 0, "LW_IN_TG",  "incoming longwave radiation at surface",                         "W/m**2"                             },
-  { 113, 0, "LW_IN_TS",  "incoming longwave radiation at surface",                         "W/m**2"                             },
-  { 114, 0, "LW_IN_T2M", "incoming longwave radiation at surface",                         "W/m**2"                             },
-  { 115, 0, "SWISS_WE",  "Swiss",                                                          "SWISS_WE 115 1 Swiss coordinates"   },
-  { 116, 0, "SWISS_SN",  "Swiss",                                                          "SWISS_SN 116 1 Swiss coordinates"   },
-  { 150, 0, "KOINDEX",   "KO index",                                                       "K"                                  },
-  { 151, 0, "TTINDEX",   "total-totals index",                                             "K"                                  },
-  { 152, 0, "DCI",       "deep convection index",                                          "K"                                  },
-  { 153, 0, "SWEAT",     "severe weather thread index",                                    "undefined"                          },
-  { 154, 0, "ADEDO2",    "adedokun 2 index",                                               "K"                                  },
-  { 160, 0, "C_TSTORM",  "thunderstorm index using AdaBoost classifier",                   "undefined"                          },
-  { 161, 0, "CN_TSTORM", "thunderstorm probabilty using AdaBoost classifier",              "%"                                  },
-  { 200, 0, "WSHEARL",   "wind shear between surface and 3 km asl",                        "1/s"                                },
-  { 201, 0, "WSHEARM",   "wind shear between surface and 6 km asl",                        "1/s"                                },
-  { 202, 0, "WSHEARU",   "wind shear between 3 km (or surface) and 6 km asl",              "1/s"                                },
-  { 211, 0, "VWIN",      "maximum OLD turbulent wind gust in 10m",                         "m s-1"                              },
-  { 212, 0, "VW10M_20",  "maximum 10m wind speed",                                         "m s-1"                              },
-  { 213, 0, "VW10M_25",  "duration of VWIN_10M above 25 knots",                            "s"                                  },
-  { 214, 0, "VW10M_30",  "duration of VWIN_10M above 30 knots",                            "s"                                  },
-  { 215, 0, "VW10M_35",  "duration of VWIN_10M above 35 knots",                            "s"                                  },
-  { 216, 0, "VW10M_40",  "duration of VWIN_10M above 40 knots",                            "s"                                  },
-  { 217, 0, "VW10M_45",  "duration of VWIN_10M above 45 knots",                            "s"                                  },
-  { 218, 0, "VW10M_50",  "duration of VWIN_10M above 50 knots",                            "s"                                  },
-  { 219, 0, "VOLD",      "maximum turbulent wind gust in 10m",                             "m s-1"                              },
-  { 220, 0, "VJPS",      "maximum turbulent wind gust in 10m",                             "m s-1"                              },
-  { 221, 0, "VBRA",      "maximum Brasseur turbulent wind gust in 10m",                    "m s-1"                              },
-  { 222, 0, "VB10M_20",  "duration of VBRA_10M above 20 knots",                            "s"                                  },
-  { 223, 0, "VB10M_25",  "duration of VBRA_10M above 25 knots",                            "s"                                  },
-  { 224, 0, "VB10M_30",  "duration of VBRA_10M above 30 knots",                            "s"                                  },
-  { 225, 0, "VB10M_35",  "duration of VBRA_10M above 35 knots",                            "s"                                  },
-  { 226, 0, "VB10M_40",  "duration of VBRA_10M above 40 knots",                            "s"                                  },
-  { 227, 0, "VB10M_45",  "duration of VBRA_10M above 45 knots",                            "s"                                  },
-  { 228, 0, "VB10M_50",  "duration of VBRA_10M above 50 knots",                            "s"                                  },
-  { 231, 0, "VCON",      "maximum convective wind gust in 10m",                            "m s-1"                              },
-  { 232, 0, "VC10M_20",  "duration of VCON_10M above 20 knots",                            "s"                                  },
-  { 233, 0, "VC10M_25",  "duration of VCON_10M above 25 knots",                            "s"                                  },
-  { 234, 0, "VC10M_30",  "duration of VCON_10M above 30 knots",                            "s"                                  },
-  { 235, 0, "VC10M_35",  "duration of VCON_10M above 35 knots",                            "s"                                  },
-  { 236, 0, "VC10M_40",  "duration of VCON_10M above 40 knots",                            "s"                                  },
-  { 237, 0, "VC10M_45",  "duration of VCON_10M above 45 knots",                            "s"                                  },
-  { 238, 0, "VC10M_50",  "duration of VCON_10M above 50 knots",                            "s"                                  },
-  { 241, 0, "FMAX",      "maximum wind speed at k=ke",                                     "m s-1"                              },
-  { 242, 0, "USTARMAX",  "maximal u*=SQRT(Drag_coef)*fmax_10m",                            "m s-1"                              },
-  { 243, 0, "GLOB_DIF",  "global diffuse shortwave radiation at the surface",              "W/m**2"                             },
-  { 244, 0, "GLOB_DIR",  "global direct (beam) shortwave radiation at the surface",        "W/m**2"                             },
-  { 245, 0, "GLOB_vE",   "global shortwave radiation on a vertical surface facing east",   "W/m**2"                             },
-  { 246, 0, "GLOB_vS",   "global shortwave radiation on a vertical surface facing south",  "W/m**2"                             },
-  { 247, 0, "GLOB_vW",   "global shortwave radiation on a vertical surface facing west",   "W/m**2"                             },
-  { 248, 0, "GLOB_vN",   "global shortwave radiation on a vertical surface facing north",  "W/m**2"                             },
-  { 249, 0, "LW_TG_vS",  "incoming longwave radiation on a vertical surface facing south", "W/m**2"                             },
-  { 250, 0, "ENTH",      "enthalpy",                                                       "kJ/kg"                              },
-  { 251, 0, "ENTH",      "enthalpy",                                                       "kJ/kg"                              },
-  { 252, 0, "MIXRAT",    "mixing ratio",                                                   "g/kg"                               },
-  { 253, 0, "MIXRAT",    "mixing ratio",                                                   "g/kg"                               },
-  { 254, 0, "TW",        "wet bulb temperature",                                           "degC"                               },
-  { 255, 0, "TW",        "wet bulb temperature",                                           "degC"                               },
-};
+typedef struct {
+  int       ncvarid;
+  int       nlevs;
+  int      *level;       /* record IDs */
+  int      *lindex;      /* level index */
+  int       defmiss;     /* TRUE if missval is defined in file */
+
+  int       isUsed;
+  int       gridID;
+  int       zaxisID;
+  int       tsteptype;   /* TSTEP_* */
+}
+svarinfo_t;
 
 
-static void
-tableDefault(void)
+typedef struct {
+  int       ilev;
+  int       mlev;
+  int       ilevID;
+  int       mlevID;
+}
+VCT;
+
+
+typedef struct {
+  int         self;
+  int         accesstype;   /* TYPE_REC or TYPE_VAR */
+  int         accessmode;
+  int         filetype;
+  int         byteorder;
+  int         fileID;
+  int         filemode;
+  off_t       numvals;
+  char       *filename;
+  Record     *record;
+  int         nrecs;        /* number of records                  */
+  int         nvars;        /* number of variables                */
+  svarinfo_t *vars;
+  int         varsAllocated;
+  int         curTsID;      /* current timestep ID */
+  int         rtsteps;      /* number of tsteps accessed       */
+  long        ntsteps;      /* number of tsteps : only set if all records accessed */
+  tsteps_t   *tsteps;
+  int         tstepsTableSize;
+  int         tstepsNextID;
+  basetime_t  basetime;
+  int         ncmode;
+  int         vlistID;
+  int         xdimID[MAX_GRIDS_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
+  int         ydimID[MAX_GRIDS_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->gridIDs
+  int         zaxisID[MAX_ZAXES_PS];	//Warning: synchronous array to vlist_to_pointer(vlistID)->zaxisIDs
+  int         ncxvarID[MAX_GRIDS_PS];
+  int         ncyvarID[MAX_GRIDS_PS];
+  int         ncavarID[MAX_GRIDS_PS];
+  int         historyID;
+  int         globalatts;
+  int         localatts;
+  VCT         vct;
+  int         unreduced;
+  int         sortname;
+  int         have_missval;
+  int         comptype;      // compression type
+  int         complevel;     // compression level
+#if defined (GRIBCONTAINER2D)
+  void      **gribContainers;
+#else
+  void       *gribContainers;
+#endif
+  int         vlistIDorig;
+  /* only used by MPI-parallelized version of library */
+  int       ownerRank;    // MPI rank of owner process
+  /* ---------------------------------- */
+  /* Local change: 2013-02-18, FP (DWD) */
+  /* ---------------------------------- */
+
+  void *gh; // grib handle
+}
+stream_t;
+
+
+extern int CDI_Debug;      /* If set to 1, debuggig (default 0)            */
+extern int cdiGribApiDebug;
+extern double cdiDefaultMissval;
+extern int cdiDefaultInstID;
+extern int cdiDefaultModelID;
+extern int cdiDefaultTableID;
+extern int cdiDefaultLeveltype;
+//extern int cdiNcMissingValue;
+extern int cdiNcChunksizehint;
+extern int cdiChunkType;
+extern int cdiSplitLtype105;
+extern int cdiDataUnreduced;
+extern int cdiSortName;
+extern int cdiHaveMissval;
+extern int STREAM_Debug;
+
+
+extern char *cdiPartabPath;
+extern int   cdiPartabIntern;
+extern const resOps streamOps;
+
+static inline stream_t *
+stream_to_pointer(int idx)
 {
-  int tableID, instID, modelID;
+  return reshGetVal(idx, &streamOps);
+}
+
+static inline void
+stream_check_ptr(const char *caller, stream_t *streamptr)
+{
+  if ( streamptr == NULL )
+    Errorc("stream undefined!");
+}
+
+int     streamInqFileID(int streamID);
+
+void    gridDefHasDims(int gridID, int hasdims);
+int     gridInqHasDims(int gridID);
+const char *gridNamePtr(int gridtype);
+char   *zaxisNamePtr(int leveltype);
+int     zaxisInqLevelID(int zaxisID, double level);
+
+void    streamCheckID(const char *caller, int streamID);
+
+void    streamDefineTaxis(int streamID);
+
+int     streamsNewEntry(int filetype);
+void    streamsInitEntry(int streamID);
+void    cdiStreamSetupVlist(stream_t *streamptr, int vlistID, int vlistIDorig);
+int     stream_new_var(stream_t *streamptr, int gridID, int zaxisID);
+
+int     tstepsNewEntry(stream_t *streamptr);
+
+const char *strfiletype(int filetype);
+
+void    cdi_generate_vars(stream_t *streamptr);
+
+void    vlist_check_contents(int vlistID);
+
+void    cdi_create_records(stream_t *streamptr, int tsID);
+
+int     recordNewEntry(stream_t *streamptr, int tsID);
+
+void    cdiCreateTimesteps(stream_t *streamptr);
+
+void    recordInitEntry(record_t *record);
+
+void    cdiCheckZaxis(int zaxisID);
+
+void    cdiPrintDatatypes(void);
+
+void    cdiDefAccesstype(int streamID, int type);
+int     cdiInqAccesstype(int streamID);
+
+int     getByteswap(int byteorder);
+
+void cdiStreamGetIndexList(unsigned numIDs, int IDs[numIDs]);
 
 
-  /*
-   *  define table : echam4
-   */
+void  cdiInitialize(void);
 
-  instID  = institutInq(98, 255, "MPIMET", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(98, 255, "MPIMET", NULL);
+void uuid2str(const unsigned char *uuid, char *uuidstr);
+int str2uuid(const char *uuidstr, unsigned char *uuid);
 
-  modelID = modelInq(instID, 0, "ECHAM4");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "ECHAM4");
+static inline int cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+{
+  static const unsigned char uuid_nil[CDI_UUID_SIZE];
+  return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
+}
 
-  tableID = tableDef(modelID, 128, "echam4");
+char* cdiEscapeSpaces(const char* string);
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd);
 
-  tableLink(tableID, echam4, sizeof(echam4) / sizeof(PAR));
+#define CDI_UNIT_PA   1
+#define CDI_UNIT_HPA  2
+#define CDI_UNIT_MM   3
+#define CDI_UNIT_CM   4
+#define CDI_UNIT_DM   5
+#define CDI_UNIT_M    6
 
-  /*
-   *  define table : echam5
-   */
+struct streamAssoc
+{
+  int streamID, vlistID, vlistIDorig;
+};
 
-  instID  = institutInq(0, 0, "MPIMET", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MPIMET", NULL);
+struct streamAssoc
+streamUnpack(char * unpackBuffer, int unpackBufferSize,
+             int * unpackBufferPos, int originNamespace, void *context);
 
-  modelID = modelInq(instID, 0, "ECHAM5");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "ECHAM5");
+int
+cdiStreamOpenDefaultDelegate(const char *filename, const char *filemode,
+                             int filetype, stream_t *streamptr,
+                             int recordBufIsToBeCreated);
 
-  tableID = tableDef(modelID, 128, "echam5");
+void
+cdiStreamDefVlist_(int streamID, int vlistID);
+void
+cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data,
+                   int nmiss);
+void
+cdiStreamwriteVarChunk_(int streamID, int varID, int memtype,
+                        const int rect[][2], const void *data, int nmiss);
+void
+cdiStreamCloseDefaultDelegate(stream_t *streamptr,
+                              int recordBufIsToBeDeleted);
 
-  tableLink(tableID, echam5, sizeof(echam5) / sizeof(PAR));
+int cdiStreamDefTimestep_(stream_t *streamptr, int tsID);
 
-  /*
-   *  define table : echam6
-   */
+void cdiStreamSync_(stream_t *streamptr);
 
-  instID  = institutInq(0, 0, "MPIMET", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MPIMET", NULL);
+char *cdiUnitNamePtr(int cdi_unit);
 
-  modelID = modelInq(instID, 0, "ECHAM6");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "ECHAM6");
+void zaxisGetIndexList(int nzaxis, int *zaxisIndexList);
 
-  tableID = tableDef(modelID, 128, "echam6");
+void zaxisDefLtype2(int zaxisID, int ltype2);
+int  zaxisInqLtype2(int zaxisID);
 
-  tableLink(tableID, echam6, sizeof(echam6) / sizeof(PAR));
+#endif  /* _CDI_INT_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _CDF_INT_H
+#define _CDF_INT_H
 
-  /*
-   *  define table : mpiom1
-   */
+#if  defined  (HAVE_LIBNETCDF)
 
-  instID  = institutInq(0, 0, "MPIMET", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MPIMET", NULL);
+#include <stdlib.h>
+#include <netcdf.h>
 
-  modelID = modelInq(instID, 0, "MPIOM1");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "MPIOM1");
+void cdf_create (const char *path, int cmode, int *idp);
+int  cdf_open   (const char *path, int omode, int *idp);
+void cdf_close  (int ncid);
 
-  tableID = tableDef(modelID, 128, "mpiom1");
+void cdf_redef(int ncid);
+void cdf_enddef(int ncid);
+void cdf__enddef(const int ncid, const size_t hdr_pad);
+void cdf_sync(int ncid);
 
-  tableLink(tableID, mpiom1, sizeof(mpiom1) / sizeof(PAR));
+void cdf_inq (int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int *unlimdimidp);
 
-  /*
-   *  define table : ecmwf
-   */
+void cdf_def_dim (int ncid, const char *name, size_t len, int *idp);
+void cdf_inq_dimid (int ncid, const char *name, int *dimidp);
+void cdf_inq_dim (int ncid, int dimid, char *name, size_t * lengthp);
+void cdf_inq_dimname (int ncid, int dimid, char *name);
+void cdf_inq_dimlen (int ncid, int dimid, size_t * lengthp);
+void cdf_def_var (int ncid, const char *name, nc_type xtype, int ndims, const int dimids[], int *varidp);
+void cdf_def_var_serial(int ncid, const char *name, nc_type xtype, int ndims, const int dimids[], int *varidp);
+void cdf_inq_varid(int ncid, const char *name, int *varidp);
+void cdf_inq_nvars(int ncid, int *nvarsp);
+void cdf_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int dimids[], int *nattsp);
+void cdf_inq_varname (int ncid, int varid, char *name);
+void cdf_inq_vartype (int ncid, int varid, nc_type *xtypep);
+void cdf_inq_varndims (int ncid, int varid, int *ndimsp);
+void cdf_inq_vardimid (int ncid, int varid, int dimids[]);
+void cdf_inq_varnatts (int ncid, int varid, int *nattsp);
 
-  instID  = institutInq(0, 0, "ECMWF", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "ECMWF", NULL);
+void cdf_copy_att (int ncid_in, int varid_in, const char *name, int ncid_out, int varid_out);
+void cdf_put_var_text   (int ncid, int varid, const char *tp);
+void cdf_put_var_uchar  (int ncid, int varid, const unsigned char *up);
+void cdf_put_var_schar  (int ncid, int varid, const signed char *cp);
+void cdf_put_var_short  (int ncid, int varid, const short *sp);
+void cdf_put_var_int    (int ncid, int varid, const int *ip);
+void cdf_put_var_long   (int ncid, int varid, const long *lp);
+void cdf_put_var_float  (int ncid, int varid, const float *fp);
+void cdf_put_var_double (int ncid, int varid, const double *dp);
 
-  modelID = modelInq(instID, 0, "");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "");
+void cdf_get_var_text   (int ncid, int varid, char *tp);
+void cdf_get_var_uchar  (int ncid, int varid, unsigned char *up);
+void cdf_get_var_schar  (int ncid, int varid, signed char *cp);
+void cdf_get_var_short  (int ncid, int varid, short *sp);
+void cdf_get_var_int    (int ncid, int varid, int *ip);
+void cdf_get_var_long   (int ncid, int varid, long *lp);
+void cdf_get_var_float  (int ncid, int varid, float *fp);
+void cdf_get_var_double (int ncid, int varid, double *dp);
 
-  tableID = tableDef(modelID, 128, "ecmwf");
+void cdf_get_var1_text(int ncid, int varid, const size_t index[], char *tp);
 
-  tableLink(tableID, ecmwf, sizeof(ecmwf) / sizeof(PAR));
+void cdf_get_var1_double(int ncid, int varid, const size_t index[], double *dp);
+void cdf_put_var1_double(int ncid, int varid, const size_t index[], const double *dp);
 
-  /*
-   *  define table : remo
-   */
+void cdf_get_vara_uchar(int ncid, int varid, const size_t start[], const size_t count[], unsigned char *tp);
+void cdf_get_vara_text(int ncid, int varid, const size_t start[], const size_t count[], char *tp);
 
-  instID  = institutInq(0, 0, "MPIMET", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MPIMET", NULL);
+void cdf_get_vara_double(int ncid, int varid, const size_t start[], const size_t count[], double *dp);
+void cdf_put_vara_double(int ncid, int varid, const size_t start[], const size_t count[], const double *dp);
 
-  modelID = modelInq(instID, 0, "REMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "REMO");
+void cdf_get_vara_float(int ncid, int varid, const size_t start[], const size_t count[], float *fp);
+void cdf_put_vara_float(int ncid, int varid, const size_t start[], const size_t count[], const float *fp);
 
-  tableID = tableDef(modelID, 128, "remo");
+void cdf_put_att_text(int ncid, int varid, const char *name, size_t len, const char *tp);
+void cdf_put_att_int(int ncid, int varid, const char *name, nc_type xtype, size_t len, const int *ip);
+void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype, size_t len, const double *dp);
 
-  tableLink(tableID, remo, sizeof(remo) / sizeof(PAR));
+void cdf_get_att_string(int ncid, int varid, const char *name, char **tp);
+void cdf_get_att_text  (int ncid, int varid, const char *name, char *tp);
+void cdf_get_att_int   (int ncid, int varid, const char *name, int *ip);
+void cdf_get_att_double(int ncid, int varid, const char *name, double *dp);
 
-  /*
-   *  define table : cosmo002
-   */
+void cdf_inq_att    (int ncid, int varid, const char *name, nc_type * xtypep, size_t * lenp);
+void cdf_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep);
+void cdf_inq_attlen (int ncid, int varid, const char *name, size_t *lenp);
+void cdf_inq_attname(int ncid, int varid, int attnum, char *name);
+void cdf_inq_attid  (int ncid, int varid, const char *name, int *attnump);
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
+typedef int (*cdi_nc__create_funcp)(const char *path, int cmode,
+                                    size_t initialsz, size_t *chunksizehintp,
+                                    int *ncidp);
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
+typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
+                                      nc_type xtype, int ndims,
+                                      const int dimids[], int *varidp);
 
-  tableID = tableDef(modelID, 002, "cosmo002");
+#endif
 
-  tableLink(tableID, cosmo002, sizeof(cosmo002) / sizeof(PAR));
+#endif  /* _CDF_INT_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  /*
-   *  define table : cosmo201
-   */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
 
-  tableID = tableDef(modelID, 201, "cosmo201");
+const char *cdfLibraryVersion(void)
+{
+#if  defined  (HAVE_LIBNETCDF)
+  return (nc_inq_libvers());
+#else
+  return ("library undefined");
+#endif
+}
 
-  tableLink(tableID, cosmo201, sizeof(cosmo201) / sizeof(PAR));
+#if  defined(HAVE_LIBHDF5)
+#if defined(__cplusplus)
+extern "C" {
+#endif
+  int H5get_libversion(unsigned *, unsigned *, unsigned *);
+#if defined(__cplusplus)
+}
+#endif
+#endif
 
-  /*
-   *  define table : cosmo202
-   */
+const char *hdfLibraryVersion(void)
+{
+#if  defined(HAVE_LIBHDF5)
+  static char hdf_libvers[256];
+  unsigned majnum, minnum, relnum;
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
+  H5get_libversion(&majnum, &minnum, &relnum);
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
+  sprintf(hdf_libvers, "%u.%u.%u", majnum, minnum, relnum);
 
-  tableID = tableDef(modelID, 202, "cosmo202");
+  return (hdf_libvers);
+#else
+  return ("library undefined");
+#endif
+}
 
-  tableLink(tableID, cosmo202, sizeof(cosmo202) / sizeof(PAR));
 
-  /*
-   *  define table : cosmo203
-   */
+int CDF_Debug   = 0;    /* If set to 1, debugging           */
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
+void cdfDebug(int debug)
+{
+  CDF_Debug = debug;
 
-  tableID = tableDef(modelID, 203, "cosmo203");
+  if ( CDF_Debug )
+    Message("debug level %d", debug);
+}
 
-  tableLink(tableID, cosmo203, sizeof(cosmo203) / sizeof(PAR));
+#if  defined  (HAVE_LIBNETCDF)
+static
+void cdfComment(int ncid)
+{
+  static char comment[256] = "Climate Data Interface version ";
+  static int init = 0;
 
-  /*
-   *  define table : cosmo205
-   */
+  if ( ! init )
+    {
+      init = 1;
+      const char *libvers = cdiLibraryVersion();
+      const char *blank = strchr(libvers, ' ');
+      size_t size = blank ? (size_t)(blank - libvers) : 0;
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
+      if ( size == 0 || ! isdigit((int) *libvers) )
+	strcat(comment, "??");
+      else
+	strncat(comment, libvers, size);
+      strcat(comment, " (http://mpimet.mpg.de/cdi)");
+    }
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
+  cdf_put_att_text(ncid, NC_GLOBAL, "CDI", strlen(comment), comment);
+  cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.4");
+}
+#endif
 
-  tableID = tableDef(modelID, 205, "cosmo205");
+int cdfOpenFile(const char *filename, const char *mode, int *filetype)
+{
+  int ncid = -1;
+#if  defined  (HAVE_LIBNETCDF)
+  int fmode = tolower(*mode);
+  int writemode = NC_CLOBBER;
+  int readmode = NC_NOWRITE;
+  int status;
 
-  tableLink(tableID, cosmo205, sizeof(cosmo205) / sizeof(PAR));
+  if ( filename == NULL )
+    ncid = CDI_EINVAL;
+  else
+    {
+      switch (fmode)
+	{
+	case 'r':
+	  status = cdf_open(filename, readmode, &ncid);
+	  if ( status > 0 && ncid < 0 ) ncid = CDI_ESYSTEM;
+#if  defined  (HAVE_NETCDF4)
+	  else
+	    {
+	      int format;
+	      (void) nc_inq_format(ncid, &format);
+	      if ( format == NC_FORMAT_NETCDF4_CLASSIC )
+		{
+		  *filetype = FILETYPE_NC4C;
+		}
+	    }
+#endif
+	  break;
+	case 'w':
+#if  defined  (NC_64BIT_OFFSET)
+	  if      ( *filetype == FILETYPE_NC2  ) writemode |= NC_64BIT_OFFSET;
+#endif
+#if  defined  (HAVE_NETCDF4)
+	  if      ( *filetype == FILETYPE_NC4  ) writemode |= NC_NETCDF4;
+	  else if ( *filetype == FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
+#endif
+	  cdf_create(filename, writemode, &ncid);
+	  cdfComment(ncid);
+	  break;
+	case 'a':
+	  cdf_open(filename, NC_WRITE, &ncid);
+	  break;
+	default:
+	  ncid = CDI_EINVAL;
+	}
+    }
+#endif
 
-  /*
-   *  define table : cosmo250
-   */
+  return (ncid);
+}
 
-  instID  = institutInq(0, 0, "MCH", NULL);
-  if ( instID == -1 )
-    instID  = institutDef(0, 0, "MCH", NULL);
 
-  modelID = modelInq(instID, 0, "COSMO");
-  if ( modelID == -1 )
-    modelID = modelDef(instID, 0, "COSMO");
+int cdfOpen(const char *filename, const char *mode)
+{
+  int fileID = 0;
+  int filetype = FILETYPE_NC;
 
-  tableID = tableDef(modelID, 250, "cosmo250");
+  if ( CDF_Debug )
+    Message("Open %s with mode %c", filename, *mode);
 
-  tableLink(tableID, cosmo250, sizeof(cosmo250) / sizeof(PAR));
+  fileID = cdfOpenFile(filename, mode, &filetype);
+
+  if ( CDF_Debug )
+    Message("File %s opened with id %d", filename, fileID);
+
+  return (fileID);
 }
 
-#endif  /* _TABLE_H */
-#ifndef _GAUSSGRID_H
-#define _GAUSSGRID_H
 
-void   gaussaw(double *restrict pa, double *restrict pw, size_t nlat);
+int cdfOpen64(const char *filename, const char *mode)
+{
+  int fileID = -1;
+  int open_file = TRUE;
+  int filetype = FILETYPE_NC2;
 
-#endif  /* _GAUSSGRID_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _GRID_H
-#define _GRID_H
+  if ( CDF_Debug )
+    Message("Open %s with mode %c", filename, *mode);
 
-#include "cdi.h"
+#if  defined  (HAVE_LIBNETCDF)
+#if  ! defined  (NC_64BIT_OFFSET)
+  open_file = FALSE;
+#endif
+#endif
 
-typedef unsigned char mask_t;
+  if ( open_file )
+    {
+      fileID = cdfOpenFile(filename, mode, &filetype);
 
-typedef struct {
-  int     self;
-  int     type;                   /* grid type                      */
-  int     prec;                   /* grid precision                 */
-  int     proj;                   /* grid projection                */
-  mask_t *mask;
-  mask_t *mask_gme;
-  double *xvals;
-  double *yvals;
-  double *area;
-  double *xbounds;
-  double *ybounds;
-  double  xfirst, yfirst;
-  double  xlast, ylast;
-  double  xinc, yinc;
-  double  lcc_originLon;          /* Lambert Conformal Conic        */
-  double  lcc_originLat;
-  double  lcc_lonParY;
-  double  lcc_lat1;
-  double  lcc_lat2;
-  double  lcc_xinc;
-  double  lcc_yinc;
-  int     lcc_projflag;
-  int     lcc_scanflag;
-  int     lcc_defined;
-  double  lcc2_lon_0;             /* Lambert Conformal Conic 2      */
-  double  lcc2_lat_0;
-  double  lcc2_lat_1;
-  double  lcc2_lat_2;
-  double  lcc2_a;
-  int     lcc2_defined;
-  double  laea_lon_0;             /* Lambert Azimuthal Equal Area   */
-  double  laea_lat_0;
-  double  laea_a;
-  int     laea_defined;
-  double  xpole, ypole, angle;    /* rotated north pole             */
-  int     isCyclic;               /* TRUE for global cyclic grids   */
-  int     isRotated;              /* TRUE for rotated grids         */
-  int     xdef;                   /* 0: undefined 1:xvals 2:x0+xinc */
-  int     ydef;                   /* 0: undefined 1:yvals 2:y0+yinc */
-  int     nd, ni, ni2, ni3;       /* parameter for GRID_GME         */
-  int     number, position;       /* parameter for GRID_REFERENCE   */
-  char   *reference;
-  unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference        */
-  int     trunc;                  /* parameter for GRID_SPECTEAL    */
-  int     nvertex;
-  int    *rowlon;
-  int     nrowlon;
-  int     size;
-  int     xsize;                  /* number of values along X */
-  int     ysize;                  /* number of values along Y */
-  int     np;                     /* number of parallels between a pole and the equator */
-  int     locked;
-  int     lcomplex;
-  int     hasdims;
-  char    xname[CDI_MAX_NAME];
-  char    yname[CDI_MAX_NAME];
-  char    xlongname[CDI_MAX_NAME];
-  char    ylongname[CDI_MAX_NAME];
-  char    xstdname[CDI_MAX_NAME];
-  char    ystdname[CDI_MAX_NAME];
-  char    xunits[CDI_MAX_NAME];
-  char    yunits[CDI_MAX_NAME];
-  char   *name;
+      if ( CDF_Debug )
+	Message("File %s opened with id %d", filename, fileID);
+    }
+  else
+    {
+      fileID = CDI_ELIBNAVAIL;
+    }
+
+  return (fileID);
 }
-grid_t;
 
 
-void grid_init(grid_t *gridptr);
-void grid_free(grid_t *gridptr);
+int cdf4Open(const char *filename, const char *mode, int *filetype)
+{
+  int fileID = -1;
+  int open_file = FALSE;
 
-int gridSize(void);
+  if ( CDF_Debug )
+    Message("Open %s with mode %c", filename, *mode);
 
-const double *gridInqXvalsPtr(int gridID);
-const double *gridInqYvalsPtr(int gridID);
+#if  defined  (HAVE_NETCDF4)
+  open_file = TRUE;
+#endif
 
-const double *gridInqXboundsPtr(int gridID);
-const double *gridInqYboundsPtr(int gridID);
-const double *gridInqAreaPtr(int gridID);
+  if ( open_file )
+    {
+      fileID = cdfOpenFile(filename, mode, filetype);
 
-int gridCompare(int gridID, const grid_t *grid);
-int gridGenerate(const grid_t *grid);
+      if ( CDF_Debug )
+	Message("File %s opened with id %d", filename, fileID);
+    }
+  else
+    {
+      fileID = CDI_ELIBNAVAIL;
+    }
 
-void gridGetIndexList( int, int * );
+  return (fileID);
+}
 
-void
-gridUnpack(char * unpackBuffer, int unpackBufferSize,
-           int * unpackBufferPos, int originNamespace, void *context,
-           int force_id);
 
+void cdfCloseFile(int fileID)
+{
+#if  defined  (HAVE_LIBNETCDF)
+  cdf_close(fileID);
 #endif
+}
+
+void cdfClose(int fileID)
+{
+  cdfCloseFile(fileID);
+}
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -4471,58 +3243,80 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
  * require-trailing-newline: t
  * End:
  */
-#ifndef _ZAXIS_H
-#define _ZAXIS_H
-
-int zaxisSize(void);
-
-void
-zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
-            int * unpackBufferPos, int originNamespace, void *context,
-            int force_id);
-
-#endif
-#ifndef _VARSCAN_H
-#define _VARSCAN_H
+#ifndef NAMESPACE_H
+#define NAMESPACE_H
 
-#ifndef _GRID_H
-#  include "grid.h"
+#ifdef HAVE_CONFIG_H
 #endif
 
-#include "cdi.h"
-
-void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int level_sf, int level_unit, int prec,
-		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
-		  const char *name, const char *stdname, const char *longname, const char *units);
 
-void varDefVCT(size_t vctsize, double *vctptr);
-void varDefZAxisReference(int nlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]);
+typedef enum {
+  STAGE_DEFINITION = 0,
+  STAGE_TIMELOOP   = 1,
+  STAGE_CLEANUP    = 2,
+  STAGE_UNUSED     = 3,
+} statusCode;
 
-int  varDefGrid(int vlistID, const grid_t *grid, int mode);
-int  varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
-		 double *levels1, double *levels2, int vctsize, double *vct, char *name,
-		 char *longname, char *units, int prec, int mode, int ltype);
+typedef struct {
+  int idx;
+  int nsp;
+} namespaceTuple_t;
 
-void varDefMissval(int varID, double missval);
-void varDefCompType(int varID, int comptype);
-void varDefInst(int varID, int instID);
-int  varInqInst(int varID);
-void varDefModel(int varID, int modelID);
-int  varInqModel(int varID);
-void varDefTable(int varID, int tableID);
-int  varInqTable(int varID);
-void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
+enum namespaceSwitch
+{
+  NSSWITCH_NO_SUCH_SWITCH = -1,
+  NSSWITCH_ABORT,
+  NSSWITCH_WARNING,
+  NSSWITCH_SERIALIZE_GET_SIZE,
+  NSSWITCH_SERIALIZE_PACK,
+  NSSWITCH_SERIALIZE_UNPACK,
+  NSSWITCH_FILE_OPEN,
+  NSSWITCH_FILE_WRITE,
+  NSSWITCH_FILE_CLOSE,
+  NSSWITCH_STREAM_OPEN_BACKEND,
+  NSSWITCH_STREAM_DEF_VLIST_,
+  NSSWITCH_STREAM_WRITE_VAR_,
+  NSSWITCH_STREAM_WRITE_VAR_CHUNK_,
+  NSSWITCH_STREAM_WRITE_VAR_PART_,
+  NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_,
+  NSSWITCH_STREAM_CLOSE_BACKEND,
+  NSSWITCH_STREAM_DEF_TIMESTEP_,
+  NSSWITCH_STREAM_SYNC,
+#ifdef HAVE_LIBNETCDF
+  NSSWITCH_NC__CREATE,
+  NSSWITCH_CDF_DEF_VAR,
+  NSSWITCH_CDF_DEF_TIMESTEP,
+  NSSWITCH_CDF_STREAM_SETUP,
+#endif
+  NUM_NAMESPACE_SWITCH,
+};
 
-void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess);
-void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate);
+union namespaceSwitchValue
+{
+  void *data;
+  void (*func)();
+};
 
+#define NSSW_FUNC(p) ((union namespaceSwitchValue){ .func = (void (*)())(p) })
+#define NSSW_DATA(p) ((union namespaceSwitchValue){ .data = (void *)(p) })
 
-void varDefOptGribInt(int varID, long lval, const char *keyword);
-void varDefOptGribDbl(int varID, double dval, const char *keyword);
-int varOptGribNentries(int varID);
+int              namespaceNew();
+void             namespaceDelete(int namespaceID);
+void             namespaceCleanup      ( void );
+int              namespaceGetNumber    ( void );
+void namespaceSetActive(int namespaceID);
+int              namespaceGetActive    ( void );
+int              namespaceIdxEncode    ( namespaceTuple_t );
+int              namespaceIdxEncode2   ( int, int );
+namespaceTuple_t namespaceResHDecode   ( int );
+int              namespaceAdaptKey     ( int originResH, int originNamespace);
+int              namespaceAdaptKey2    ( int );
+void             namespaceDefResStatus ( statusCode );
+statusCode       namespaceInqResStatus ( void );
+void namespaceSwitchSet(enum namespaceSwitch sw,
+                        union namespaceSwitchValue value);
+union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw);
 
-int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, char *longname, char *units, int ltype);
 
 #endif
 /*
@@ -4534,1397 +3328,1044 @@ int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const do
  * require-trailing-newline: t
  * End:
  */
-#ifndef _BINARY_H
-#define _BINARY_H
+#if defined (HAVE_CONFIG_H)
+#endif
 
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
 
-#ifndef _DTYPES_H
-#include "dtypes.h"
+
+extern int CDF_Debug;
+
+#if  defined  (HAVE_LIBNETCDF)
+/*
+#if ! defined (MIN_BUF_SIZE)
+#  define  MIN_BUF_SIZE  131072L
 #endif
 
+static size_t ChunkSizeMin = MIN_BUF_SIZE;
+*/
+void cdf_create(const char *path, int cmode, int *ncidp)
+{
+  int status;
+  int oldfill;
+  size_t initialsz = 0, chunksizehint = 0;
+  /*
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+  struct stat filestat;
+  char basename[1024];
+  char *pend;
 
-UINT32 get_UINT32(unsigned char *x);
-UINT32 get_SUINT32(unsigned char *x);
-UINT64 get_UINT64(unsigned char *x);
-UINT64 get_SUINT64(unsigned char *x);
+  pend = strrchr(path, '/');
+  if ( pend == 0 )
+    strcpy(basename, "./");
+  else
+    {
+      memcpy(basename, path, pend-path);
+      basename[pend-path] = 0;
+    }
 
+  if ( stat(basename, &filestat) != 0 )
+    SysError(basename);
 
-size_t binReadF77Block(int fileID, int byteswap);
-void   binWriteF77Block(int fileID, int byteswap, size_t blocksize);
+  chunksizehint = (size_t) filestat.st_blksize * 4;
+#endif
 
-int binReadInt32(int fileID, int byteswap, size_t size, INT32 *ptr);
-int binReadInt64(int fileID, int byteswap, size_t size, INT64 *ptr);
+  if ( chunksizehint < ChunkSizeMin ) chunksizehint = ChunkSizeMin;
+  */
+#if defined(__SX__) || defined(ES)
+  chunksizehint = 16777216; /* 16 MB */
+#endif
 
-int binWriteInt32(int fileID, int byteswap, size_t size, INT32 *ptr);
-int binWriteInt64(int fileID, int byteswap, size_t size, INT64 *ptr);
+  if ( cdiNcChunksizehint != CDI_UNDEFID )
+    chunksizehint = (size_t)cdiNcChunksizehint;
 
-int binReadFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
-int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
+  cdi_nc__create_funcp my_nc__create =
+    (cdi_nc__create_funcp)namespaceSwitchGet(NSSWITCH_NC__CREATE).func;
+  status = my_nc__create(path, cmode, initialsz, &chunksizehint, ncidp);
 
-int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
-int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  mode = %d  file = %s", *ncidp, cmode, path);
 
-#endif  /* _BINARY_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("chunksizehint %d", chunksizehint);
 
-void swap4byte(void *ptr, size_t size);
-void swap8byte(void *ptr, size_t size);
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _SERVICE_H
-#define _SERVICE_H
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 
+  status = nc_set_fill(*ncidp, NC_NOFILL, &oldfill);
 
-typedef struct {
-  int    checked;
-  int    byteswap;
-  int    header[8];
-  int    hprec;      /* header precision */
-  int    dprec;      /* data   precision */
-  size_t datasize;
-  size_t buffersize;
-  void  *buffer;
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 }
-srvrec_t;
 
 
-const char *srvLibraryVersion(void);
+int cdf_open(const char *path, int omode, int *ncidp)
+{
+  int status = 0;
+  int dapfile = FALSE;
+  struct stat filestat;
+  size_t chunksizehint = 0;
 
-void srvDebug(int debug);
+#if  defined  (HAVE_LIBNC_DAP)
+  if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = TRUE;
+#endif
 
-int  srvCheckFiletype(int fileID, int *swap);
+  if ( dapfile )
+    {
+      status = nc_open(path, omode, ncidp);
+    }
+  else
+    {
+      if ( stat(path, &filestat) != 0 ) SysError(path);
 
-srvrec_t *srvNew(void);
-void srvDelete(srvrec_t *srvp);
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+      chunksizehint = (size_t) filestat.st_blksize * 4;
+#endif
+      /*
+      if ( chunksizehint < ChunkSizeMin ) chunksizehint = ChunkSizeMin;
+      */
+      if ( cdiNcChunksizehint != CDI_UNDEFID )
+        chunksizehint = (size_t)cdiNcChunksizehint;
 
-int  srvRead(int fileID, srvrec_t *srvp);
-void srvWrite(int fileID, srvrec_t *srvp);
+      /* FIXME: parallel part missing */
+      status = nc__open(path, omode, &chunksizehint, ncidp);
 
-int  srvInqHeader(srvrec_t *srvp, int *header);
-int  srvInqDataSP(srvrec_t *srvp, float *data);
-int  srvInqDataDP(srvrec_t *srvp, double *data);
+      if ( CDF_Debug ) Message("chunksizehint %d", chunksizehint);
+    }
 
-int  srvDefHeader(srvrec_t *srvp, const int *header);
-int  srvDefDataSP(srvrec_t *srvp, const float *data);
-int  srvDefDataDP(srvrec_t *srvp, const double *data);
+  if ( CDF_Debug )
+    Message("ncid = %d  mode = %d  file = %s", *ncidp, omode, path);
 
+  if ( CDF_Debug && status != NC_NOERR ) Message("%s", nc_strerror(status));
 
-#endif  /* _SERVICE_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_SRV_H
-#define _STREAM_SRV_H
+  return (status);
+}
 
-#ifndef _SERVICE_H
-#  include "service.h"
-#endif
 
-int    srvInqContents(stream_t *streamptr);
-int    srvInqTimestep(stream_t *streamptr, int tsID);
+void cdf_close(int ncid)
+{
+  int status;
 
-int    srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void   srvDefRecord(stream_t *streamptr);
-void   srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void   srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void   srvWriteRecord(stream_t *streamptr, const double *data);
+  status = nc_close(ncid);
 
-void   srvReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
-void   srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void   srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
-void   srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
-#endif  /* _STREAM_SRV_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_EXT_H
-#define _STREAM_EXT_H
+void cdf_redef(int ncid)
+{
+  int status;
 
-#ifndef _EXTRA_H
-#  include "extra.h"
-#endif
+  status = nc_redef(ncid);
 
-int    extInqContents(stream_t *streamptr);
-int    extInqTimestep(stream_t *streamptr, int tsID);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-int    extInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void   extDefRecord(stream_t *streamptr);
-void   extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void   extReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void   extWriteRecord(stream_t *streamptr, const double *data);
 
-void   extReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
-void   extWriteVarDP(stream_t *streamptr, int varID, const double *data);
+void cdf_enddef(int ncid)
+{
+  int status;
 
-void   extReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
-void   extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+  status = nc_enddef(ncid);
 
-#endif  /* _STREAM_EXT_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _STREAM_IEG_H
-#define _STREAM_IEG_H
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-#ifndef _IEG_H
-#  include "ieg.h"
-#endif
 
-int    iegInqContents(stream_t *streamptr);
-int    iegInqTimestep(stream_t *streamptr, int tsID);
+void cdf__enddef(const int ncid, const size_t hdr_pad)
+{
+  int status;
+  const size_t v_align   = 4UL; /* [B] Alignment of beginning of data section for fixed variables */
+  const size_t v_minfree = 0UL; /* [B] Pad at end of data section for fixed size variables */
+  const size_t r_align   = 4UL; /* [B] Alignment of beginning of data section for record variables */
 
-int    iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
-void   iegDefRecord(stream_t *streamptr);
-void   iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
-void   iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
-void   iegWriteRecord(stream_t *streamptr, const double *data);
+  /* nc_enddef(ncid) is equivalent to nc__enddef(ncid, 0, 4, 0, 4) */
+  status = nc__enddef(ncid, hdr_pad, v_align, v_minfree, r_align);
 
-void   iegReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
-void   iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void   iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
-void   iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
-#endif  /* _STREAM_IEG_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _CDF_INT_H
-#define _CDF_INT_H
+void cdf_sync(int ncid)
+{
+  int status;
 
-#if  defined  (HAVE_LIBNETCDF)
+  status = nc_sync(ncid);
 
-#include <stdlib.h>
-#include "netcdf.h"
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void cdf_create (const char *path, int cmode, int *idp);
-int  cdf_open   (const char *path, int omode, int *idp);
-void cdf_close  (int ncid);
 
-void cdf_redef(int ncid);
-void cdf_enddef(int ncid);
-void cdf__enddef(const int ncid, const size_t hdr_pad);
-void cdf_sync(int ncid);
+void cdf_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int *unlimdimidp)
+{
+  int status;
 
-void cdf_inq (int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int *unlimdimidp);
+  status = nc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp);
 
-void cdf_def_dim (int ncid, const char *name, size_t len, int *idp);
-void cdf_inq_dimid (int ncid, const char *name, int *dimidp);
-void cdf_inq_dim (int ncid, int dimid, char *name, size_t * lengthp);
-void cdf_inq_dimname (int ncid, int dimid, char *name);
-void cdf_inq_dimlen (int ncid, int dimid, size_t * lengthp);
-void cdf_def_var (int ncid, const char *name, nc_type xtype, int ndims, const int dimids[], int *varidp);
-void cdf_def_var_serial(int ncid, const char *name, nc_type xtype, int ndims, const int dimids[], int *varidp);
-void cdf_inq_varid(int ncid, const char *name, int *varidp);
-void cdf_inq_nvars(int ncid, int *nvarsp);
-void cdf_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int dimids[], int *nattsp);
-void cdf_inq_varname (int ncid, int varid, char *name);
-void cdf_inq_vartype (int ncid, int varid, nc_type *xtypep);
-void cdf_inq_varndims (int ncid, int varid, int *ndimsp);
-void cdf_inq_vardimid (int ncid, int varid, int dimids[]);
-void cdf_inq_varnatts (int ncid, int varid, int *nattsp);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d ndims = %d nvars = %d ngatts = %d unlimid = %d",
+	    ncid, *ndimsp, *nvarsp, *ngattsp, *unlimdimidp);
 
-void cdf_copy_att (int ncid_in, int varid_in, const char *name, int ncid_out, int varid_out);
-void cdf_put_var_text   (int ncid, int varid, const char *tp);
-void cdf_put_var_uchar  (int ncid, int varid, const unsigned char *up);
-void cdf_put_var_schar  (int ncid, int varid, const signed char *cp);
-void cdf_put_var_short  (int ncid, int varid, const short *sp);
-void cdf_put_var_int    (int ncid, int varid, const int *ip);
-void cdf_put_var_long   (int ncid, int varid, const long *lp);
-void cdf_put_var_float  (int ncid, int varid, const float *fp);
-void cdf_put_var_double (int ncid, int varid, const double *dp);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void cdf_get_var_text   (int ncid, int varid, char *tp);
-void cdf_get_var_uchar  (int ncid, int varid, unsigned char *up);
-void cdf_get_var_schar  (int ncid, int varid, signed char *cp);
-void cdf_get_var_short  (int ncid, int varid, short *sp);
-void cdf_get_var_int    (int ncid, int varid, int *ip);
-void cdf_get_var_long   (int ncid, int varid, long *lp);
-void cdf_get_var_float  (int ncid, int varid, float *fp);
-void cdf_get_var_double (int ncid, int varid, double *dp);
 
-void cdf_get_var1_text(int ncid, int varid, const size_t index[], char *tp);
+void cdf_def_dim(int ncid, const char *name, size_t len, int *dimidp)
+{
+  int status;
 
-void cdf_get_var1_double(int ncid, int varid, const size_t index[], double *dp);
-void cdf_put_var1_double(int ncid, int varid, const size_t index[], const double *dp);
+  status = nc_def_dim(ncid, name, len, dimidp);
 
-void cdf_get_vara_uchar(int ncid, int varid, const size_t start[], const size_t count[], unsigned char *tp);
-void cdf_get_vara_text(int ncid, int varid, const size_t start[], const size_t count[], char *tp);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  name = %s  len = %d", ncid, name, len);
 
-void cdf_get_vara_double(int ncid, int varid, const size_t start[], const size_t count[], double *dp);
-void cdf_put_vara_double(int ncid, int varid, const size_t start[], const size_t count[], const double *dp);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void cdf_get_vara_float(int ncid, int varid, const size_t start[], const size_t count[], float *fp);
-void cdf_put_vara_float(int ncid, int varid, const size_t start[], const size_t count[], const float *fp);
 
-void cdf_put_att_text(int ncid, int varid, const char *name, size_t len, const char *tp);
-void cdf_put_att_int(int ncid, int varid, const char *name, nc_type xtype, size_t len, const int *ip);
-void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype, size_t len, const double *dp);
+void cdf_inq_dimid(int ncid, const char *name, int *dimidp)
+{
+  int status;
 
-void cdf_get_att_string(int ncid, int varid, const char *name, char **tp);
-void cdf_get_att_text  (int ncid, int varid, const char *name, char *tp);
-void cdf_get_att_int   (int ncid, int varid, const char *name, int *ip);
-void cdf_get_att_double(int ncid, int varid, const char *name, double *dp);
+  status = nc_inq_dimid(ncid, name, dimidp);
 
-void cdf_inq_att    (int ncid, int varid, const char *name, nc_type * xtypep, size_t * lenp);
-void cdf_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep);
-void cdf_inq_attlen (int ncid, int varid, const char *name, size_t *lenp);
-void cdf_inq_attname(int ncid, int varid, int attnum, char *name);
-void cdf_inq_attid  (int ncid, int varid, const char *name, int *attnump);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  name = %s  dimid= %d", ncid, name, *dimidp);
 
-typedef int (*cdi_nc__create_funcp)(const char *path, int cmode,
-                                    size_t initialsz, size_t *chunksizehintp,
-                                    int *ncidp);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
-                                      nc_type xtype, int ndims,
-                                      const int dimids[], int *varidp);
 
-#endif
+void cdf_inq_dim(int ncid, int dimid, char *name, size_t * lengthp)
+{
+  int status;
 
-#endif  /* _CDF_INT_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _CDF_H
-#define _CDF_H
+  status = nc_inq_dim(ncid, dimid, name, lengthp);
 
-void cdfDebug(int debug);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  dimid = %d  length = %d name = %s", ncid, dimid, *lengthp, name);
 
-const char *cdfLibraryVersion(void);
-const char *hdfLibraryVersion(void);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-int  cdfOpen(const char *filename, const char *mode);
-int  cdfOpen64(const char *filename, const char *mode);
-int  cdf4Open(const char *filename, const char *mode, int *filetype);
-void cdfClose(int fileID);
 
-#endif  /* _CDF_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _VLIST_H
-#define _VLIST_H
+void cdf_inq_dimname(int ncid, int dimid, char *name)
+{
+  int status;
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+  status = nc_inq_dimname(ncid, dimid, name);
 
-#include <stddef.h>  /* size_t */
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  dimid = %d  name = %s", ncid, dimid, name);
 
-#ifndef _CDI_LIMITS_H
-#  include "cdi_limits.h"
-#endif
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-#define VALIDMISS 1.e+303
 
-/*
- * CDI attribute
- */
-typedef struct {
-  size_t    xsz;	  /* amount of space at xvalue                      */
-  size_t    namesz;       /* size of name                                   */
-  char     *name;         /* attribute name                                 */
-  int       indtype;	  /* internal data type of xvalue (INT, FLT or TXT) */
-  int       exdtype;      /* external data type                             */
-                          /* indtype    exdtype                             */
-                          /* TXT        TXT                                 */
-                          /* INT        INT16, INT32                        */
-                          /* FLT        FLT32, FLT64                        */
-  size_t    nelems;    	  /* number of elements                             */
-  void     *xvalue;       /* the actual data                                */
-} cdi_att_t;
+void cdf_inq_dimlen(int ncid, int dimid, size_t * lengthp)
+{
+  int status;
 
+  status = nc_inq_dimlen(ncid, dimid, lengthp);
 
-typedef struct {
-  size_t     nalloc;		/* number allocated >= nelems */
-  size_t     nelems;		/* length of the array */
-  cdi_att_t  value[MAX_ATTRIBUTES];
-} cdi_atts_t;
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d dimid = %d length = %d", ncid, dimid, *lengthp);
 
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-typedef struct
+
+void cdf_def_var(int ncid, const char *name, nc_type xtype, int ndims,
+                 const int dimids[], int *varidp)
 {
-  int      flag;
-  int      index;
-  int      mlevelID;
-  int      flevelID;
+  cdi_cdf_def_var_funcp my_cdf_def_var
+    = (cdi_cdf_def_var_funcp)namespaceSwitchGet(NSSWITCH_CDF_DEF_VAR).func;
+  my_cdf_def_var(ncid, name, xtype, ndims, dimids, varidp);
 }
-levinfo_t;
 
-#define DEFAULT_LEVINFO(levID) \
-  (levinfo_t){ 0, -1, levID, levID}
-/*
-#define DEFAULT_LEVINFO(levID) \
-  (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
-*/
-typedef struct
+void
+cdf_def_var_serial(int ncid, const char *name, nc_type xtype, int ndims,
+                   const int dimids[], int *varidp)
 {
-  int ens_index;
-  int ens_count;
-  int forecast_init_type;
-}
-ensinfo_t;
+  int status = nc_def_var(ncid, name, xtype, ndims, dimids, varidp);
 
-/* ---------------------------------- */
-/* Local change: 2013-01-28, FP (DWD) */
-/* ---------------------------------- */
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  name = %s  xtype = %d  ndims = %d  varid = %d",
+	    ncid, name, xtype, ndims, *varidp);
 
-/* Length of optional keyword/value pair list */
-#define MAX_OPT_GRIB_ENTRIES 50
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
 
-typedef struct
+
+void cdf_inq_varid(int ncid, const char *name, int *varidp)
 {
-  int         flag;
-  int         isUsed;
-  int         mvarID;
-  int         fvarID;
-  int         param;
-  int         gridID;
-  int         zaxisID;
-  int         tsteptype; /* TSTEP_* */
-  int         datatype;  /* DATATYPE_PACKX for GRIB data, else DATATYPE_FLT32 or DATATYPE_FLT64 */
-  int         instID;
-  int         modelID;
-  int         tableID;
-  int         timave;
-  int         timaccu;
-  int         typeOfGeneratingProcess;
-  int         productDefinitionTemplate;
-  int         chunktype;
-  int         xyz;
-  int         missvalused; /* TRUE if missval is defined */
-  int         lvalidrange;
-  char       *name;
-  char       *longname;
-  char       *stdname;
-  char       *units;
-  char       *extra;
-  double      missval;
-  double      scalefactor;
-  double      addoffset;
-  double      validrange[2];
-  levinfo_t  *levinfo;
-  int         comptype;     // compression type
-  int         complevel;    // compression level
-  ensinfo_t  *ensdata;      /* Ensemble information */
-  cdi_atts_t  atts;
-  int         iorank;
-#if  defined  (HAVE_LIBGRIB_API)
-  /* ---------------------------------- */
-  /* Local change: 2013-01-28, FP (DWD) */
-  /* ---------------------------------- */
+  int status;
 
-  /* (Optional) list of keyword/double value pairs */
-  int    opt_grib_dbl_nentries;
-  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
-  int    opt_grib_dbl_update[MAX_OPT_GRIB_ENTRIES];
-  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
-  /* (Optional) list of keyword/integer value pairs */
-  int    opt_grib_int_nentries;
-  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
-  int    opt_grib_int_update[MAX_OPT_GRIB_ENTRIES];
-  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
-#endif
+  status = nc_inq_varid(ncid, name, varidp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  name = %s  varid = %d ", ncid, name, *varidp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
-var_t;
 
 
-typedef struct
+void cdf_inq_nvars(int ncid, int *nvarsp)
 {
-  int         locked;
-  int         self;
-  int         nvars;        /* number of variables                */
-  int         ngrids;
-  int         nzaxis;
-  long        ntsteps;
-  int         taxisID;
-  int         tableID;
-  int         instID;
-  int         modelID;
-  int         varsAllocated;
-  int         gridIDs[MAX_GRIDS_PS];
-  int         zaxisIDs[MAX_ZAXES_PS];
-  var_t      *vars;
-  cdi_atts_t  atts;
-}
-vlist_t;
+  int status;
 
+  status = nc_inq_nvars(ncid, nvarsp);
 
-vlist_t *vlist_to_pointer(int vlistID);
-const char *vlistInqVarNamePtr(int vlistID, int varID);
-const char *vlistInqVarLongnamePtr(int vlistID, int varID);
-const char *vlistInqVarStdnamePtr(int vlistID, int varID);
-const char *vlistInqVarUnitsPtr(int vlistID, int varID);
-void     vlistDestroyVarName(int vlistID, int varID);
-void     vlistDestroyVarLongname(int vlistID, int varID);
-void     vlistDestroyVarUnits(int vlistID, int varID);
-void     vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
-int      vlistInqVarMissvalUsed(int vlistID, int varID);
-int      vlistHasTime(int vlistID);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d  nvars = %d", ncid, *nvarsp);
 
-int      vlistDelAtts(int vlistID, int varID);
-int      vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void     vlistUnpack(char * buffer, int bufferSize, int * pos,
-                     int originNamespace, void *context, int force_id);
 
-/*      vlistDefVarValidrange: Define the valid range of a Variable */
-void    vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
+void cdf_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp,
+		 int dimids[], int *nattsp)
+{
+  int status;
 
-/*      vlistInqVarValidrange: Get the valid range of a Variable */
-int     vlistInqVarValidrange(int vlistID, int varID, double *validrange);
+  status = nc_inq_var(ncid, varid, name, xtypep, ndimsp, dimids, nattsp);
 
-void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3]);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d ndims = %d xtype = %d natts = %d name = %s",
+	    ncid, varid, *ndimsp, *xtypep, *nattsp, name);
 
-int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void vlist_lock(int vlistID);
-void vlist_unlock(int vlistID);
 
-static inline void
-vlistAdd2GridIDs(vlist_t *vlistptr, int gridID)
+void cdf_inq_varname(int ncid, int varid, char *name)
 {
-  int index, ngrids = vlistptr->ngrids;
-  for ( index = 0; index < ngrids; index++ )
-    if (vlistptr->gridIDs[index] == gridID ) break;
-  if ( index == ngrids )
-    {
-      if (ngrids >= MAX_GRIDS_PS)
-        Error("Internal limit exceeded: more than %d grids.", MAX_GRIDS_PS);
-      ++(vlistptr->ngrids);
-      vlistptr->gridIDs[ngrids] = gridID;
-    }
+  int status;
+
+  status = nc_inq_varname(ncid, varid, name);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static inline void
-vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
+
+void cdf_inq_vartype(int ncid, int varid, nc_type *xtypep)
 {
-  int index, nzaxis = vlistptr->nzaxis;
-  for ( index = 0; index < nzaxis; index++ )
-    if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
+  int status;
 
-  if ( index == nzaxis )
-    {
-      if ( nzaxis >= MAX_ZAXES_PS )
-	Error("Internal limit exceeded: more than %d zaxis.", MAX_ZAXES_PS);
-      vlistptr->zaxisIDs[nzaxis] = zaxisID;
-      vlistptr->nzaxis++;
-    }
+  status = nc_inq_vartype(ncid, varid, xtypep);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d xtype = %s", ncid, varid, *xtypep);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
-#if  defined  (HAVE_LIBGRIB_API)
-extern int   cdiNAdditionalGRIBKeys;
-extern char* cdiAdditionalGRIBKeys[];
-#endif
+void cdf_inq_varndims(int ncid, int varid, int *ndimsp)
+{
+  int status;
 
-extern
-#ifndef __cplusplus
-const
-#endif
-resOps vlistOps;
+  status = nc_inq_varndims(ncid, varid, ndimsp);
 
-#endif  /* _VLIST_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef VLIST_VAR_H
-#define VLIST_VAR_H
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-#ifndef _VLIST_H
-#include "vlist.h"
-#endif
 
-int  vlistVarGetPackSize(vlist_t *p, int varID, void *context);
-void vlistVarPack(vlist_t *p, int varID,
-                  char * buffer, int bufferSize, int * pos, void *context);
-void vlistVarUnpack(int vlistID,
-                    char * buf, int size, int *position, int, void *context);
-int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB);
-void vlistDefVarIOrank    ( int, int, int );
-int  vlistInqVarIOrank    ( int, int );
+void cdf_inq_vardimid(int ncid, int varid, int dimids[])
+{
+  int status;
 
-void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
+  status = nc_inq_vardimid(ncid, varid, dimids);
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef VLIST_ATT_H
-#define VLIST_ATT_H
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-int
-vlistAttsGetSize(vlist_t *p, int varID, void *context);
 
-void
-vlistAttsPack(vlist_t *p, int varID,
-              void * buf, int size, int *position, void *context);
+void cdf_inq_varnatts(int ncid, int varid, int *nattsp)
+{
+  int status;
 
-void
-vlistAttsUnpack(int vlistID, int varID,
-                void * buf, int size, int *position, void *context);
+  status = nc_inq_varnatts(ncid, varid, nattsp);
 
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d nattsp = %d", ncid, varid, *nattsp);
 
-#endif
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef MODEL_H
-#define MODEL_H
 
-int
-modelUnpack(void *buf, int size, int *position,
-            int originNamespace, void *context, int force_id);
+void cdf_put_var_text(int ncid, int varid, const char *tp)
+{
+  int status;
 
-void modelDefaultEntries(void);
+  status = nc_put_var_text(ncid, varid, tp);
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef INSTITUTION_H
-#define INSTITUTION_H
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %s", ncid, varid, tp);
 
-int
-instituteUnpack(void *buf, int size, int *position, int originNamespace,
-                void *context, int force_id);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void instituteDefaultEntries(void);
 
-#endif
+void cdf_put_var_short(int ncid, int varid, const short *sp)
+{
+  int status;
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef RESOURCE_UNPACK_H
-#define RESOURCE_UNPACK_H
+  status = nc_put_var_short(ncid, varid, sp);
 
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %hd", ncid, varid, *sp);
 
-enum
-{ GRID      = 1,
-  ZAXIS     = 2,
-  TAXIS     = 3,
-  INSTITUTE = 4,
-  MODEL     = 5,
-  STREAM    = 6,
-  VLIST     = 7,
-  RESH_DELETE,
-  START     = 55555555,
-  END       = 99999999
-};
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
-                         void *context);
 
-#endif
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
+void cdf_put_var_int(int ncid, int varid, const int *ip)
+{
+  int status;
 
-#ifndef SERIALIZE_H
-#define SERIALIZE_H
+  status = nc_put_var_int(ncid, varid, ip);
 
-#include <string.h>
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %d", ncid, varid, *ip);
 
-#include "cdi.h"
-#include "cdi_cksum.h"
-#include "error.h"
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-/*
- * Generic interfaces for (de-)marshalling
- */
-int serializeGetSize(int count, int datatype, void *context);
-void serializePack(const void *data, int count, int datatype,
-                   void *buf, int buf_size, int *position, void *context);
-void serializeUnpack(const void *buf, int buf_size, int *position,
-                     void *data, int count, int datatype, void *context);
 
-/*
- * (de-)marshalling function for common data structures
- */
-static inline int
-serializeStrTabGetPackSize(const char **strTab, int numStr,
-                           void *context)
+void cdf_put_var_long(int ncid, int varid, const long *lp)
 {
-  xassert(numStr >= 0);
-  int packBuffSize = 0;
-  for (size_t i = 0; i < (size_t)numStr; ++i)
-  {
-    size_t len = strlen(strTab[i]);
-    packBuffSize +=
-      serializeGetSize(1, DATATYPE_INT, context)
-      + serializeGetSize((int)len, DATATYPE_TXT, context);
-  }
-  packBuffSize +=
-    serializeGetSize(1, DATATYPE_UINT32, context);
-  return packBuffSize;
+  int status;
+
+  status = nc_put_var_long(ncid, varid, lp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %ld", ncid, varid, *lp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static inline void
-serializeStrTabPack(const char **strTab, int numStr,
-                    void *buf, int buf_size, int *position, void *context)
+
+void cdf_put_var_float(int ncid, int varid, const float *fp)
 {
-  uint32_t d = 0;
-  xassert(numStr >= 0);
-  for (size_t i = 0; i < (size_t)numStr; ++i)
-  {
-    size_t len = strlen(strTab[i]);
-    serializePack(&(int){(int)len}, 1, DATATYPE_INT,
-                  buf, buf_size, position, context);
-    serializePack(strTab[i], (int)len, DATATYPE_TXT,
-                  buf, buf_size, position, context);
-    d ^= cdiCheckSum(DATATYPE_TXT, (int)len, strTab[i]);
-  }
-  serializePack(&d, 1, DATATYPE_UINT32,
-                buf, buf_size, position, context);
+  int status;
+
+  status = nc_put_var_float(ncid, varid, fp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %f", ncid, varid, *fp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static inline void
-serializeStrTabUnpack(const void *buf, int buf_size, int *position,
-                      char **strTab, int numStr, void *context)
+
+void cdf_put_vara_double(int ncid, int varid, const size_t start[],
+                         const size_t count[], const double *dp)
 {
-  uint32_t d, d2 = 0;
-  xassert(numStr >= 0);
-  for (size_t i = 0; i < (size_t)numStr; ++i)
+  int status;
+
+  status = nc_put_vara_double(ncid, varid, start, count, dp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+
+  if ( status != NC_NOERR )
     {
-      int len;
-      serializeUnpack(buf, buf_size, position,
-                      &len, 1, DATATYPE_INT, context);
-      serializeUnpack(buf, buf_size, position,
-                      strTab[i], len, DATATYPE_TXT, context);
-      strTab[i][len] = '\0';
-      d2 ^= cdiCheckSum(DATATYPE_TXT, (size_t)len, strTab[i]);
+      char name[256];
+      nc_inq_varname(ncid, varid, name);
+      Message("varname = %s", name);
     }
-  serializeUnpack(buf, buf_size, position,
-                  &d, 1, DATATYPE_UINT32, context);
-  xassert(d == d2);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-/*
- * Interfaces for marshalling within a single memory domain
- */
-int serializeGetSizeInCore(int count, int datatype, void *context);
-void serializePackInCore(const void *data, int count, int datatype,
-                          void *buf, int buf_size, int *position, void *context);
-void serializeUnpackInCore(const void *buf, int buf_size, int *position,
-                           void *data, int count, int datatype, void *context);
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef STREAM_FCOMMON_H
-#define STREAM_FCOMMON_H
+void  cdf_put_vara_float(int ncid, int varid, const size_t start[],
+                         const size_t count[], const float *fp)
+{
+  int status;
 
-#include "cdi_int.h"
+  status = nc_put_vara_float(ncid, varid, start, count, fp);
 
-enum {
-  SINGLE_PRECISION = 4,
-  DOUBLE_PRECISION = 8,
-};
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *fp);
 
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
-                       const char *container_name);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if  defined  (HAVE_CONFIG_H)
-#endif
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <errno.h>
+void  cdf_get_vara_int(int ncid, int varid, const size_t start[],
+                       const size_t count[], int *dp)
+{
+  int status;
 
+  status = nc_get_vara_int(ncid, varid, start, count, dp);
 
-#if ! defined (HAVE_CONFIG_H)
-#if ! defined (HAVE_MALLOC_H)
-#  if defined (SX)
-#    define  HAVE_MALLOC_H
-#  endif
-#endif
-#endif
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-#if  defined  (HAVE_MALLOC_H)
-#    include <malloc.h>
-#endif
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
 
-#define  MALLOC_FUNC   0
-#define  CALLOC_FUNC   1
-#define  REALLOC_FUNC  2
-#define  FREE_FUNC     3
+void  cdf_get_vara_double(int ncid, int varid, const size_t start[],
+                          const size_t count[], double *dp)
+{
+  int status;
 
-#undef   UNDEFID
-#define  UNDEFID  -1
+  status = nc_get_vara_double(ncid, varid, start, count, dp);
 
-#define  MAXNAME  32   /* Min = 8, for  "unknown" ! */
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-int dmemory_ExitOnError = 0;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-typedef struct
+
+void  cdf_get_vara_float(int ncid, int varid, const size_t start[],
+                         const size_t count[], float *fp)
 {
-  void     *ptr;
-  int       item;
-  size_t    size;
-  size_t    nobj;
-  int       mtype;
-  int       line;
-  char      file[MAXNAME];
-  char      caller[MAXNAME];
-}
-MemTable_t;
+  int status;
 
-static MemTable_t *memTable;
-static size_t  memTableSize  = 0;
-static long    memAccess     = 0;
+  status = nc_get_vara_float(ncid, varid, start, count, fp);
 
-static size_t  MemObjs       = 0;
-static size_t  MaxMemObjs    = 0;
-static size_t  MemUsed       = 0;
-static size_t  MaxMemUsed    = 0;
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-static int     MEM_Debug     = 0;   /* If set to 1, debugging */
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-void memDebug(int debug)
+
+void  cdf_get_vara_text(int ncid, int varid, const size_t start[],
+			const size_t count[], char *tp)
 {
-  MEM_Debug = debug;
+  int status;
+
+  status = nc_get_vara_text(ncid, varid, start, count, tp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memInternalProblem(const char *caller, const char *fmt, ...)
+
+void  cdf_get_vara_uchar(int ncid, int varid, const size_t start[], const size_t count[], unsigned char *tp)
 {
-  va_list args;
+  int status;
 
-  va_start(args, fmt);
+  status = nc_get_vara_uchar(ncid, varid, start, count, tp);
 
-  printf("\n");
-   fprintf(stderr, "Internal problem (%s) : ", caller);
-  vfprintf(stderr, fmt, args);
-   fprintf(stderr, "\n");
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-  va_end(args);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-  exit(EXIT_FAILURE);
+
+void cdf_put_var_double(int ncid, int varid, const double *dp)
+{
+  int status;
+
+  status = nc_put_var_double(ncid, varid, dp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memError(const char *caller, const char *file, int line, size_t size)
+
+void cdf_get_var1_text(int ncid, int varid, const size_t index[], char *tp)
 {
-  printf("\n");
-  fprintf(stderr, "Error (%s) : Allocation of %zu bytes failed. [ line %d file %s ]\n",
-	  caller, size, line, file);
+  int status;
 
-  if ( errno ) perror("System error message ");
+  status = nc_get_var1_text(ncid, varid, index, tp);
 
-  exit(EXIT_FAILURE);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memListPrintEntry(int mtype, int item, size_t size, void *ptr,
-		       const char *caller, const char *file, int line)
+
+void cdf_get_var1_double(int ncid, int varid, const size_t index[], double *dp)
 {
-  switch (mtype)
-    {
-    case MALLOC_FUNC:
-      fprintf(stderr, "[%-7s ", "Malloc");
-      break;
-    case CALLOC_FUNC:
-      fprintf(stderr, "[%-7s ", "Calloc");
-      break;
-    case REALLOC_FUNC:
-      fprintf(stderr, "[%-7s ", "Realloc");
-      break;
-    case FREE_FUNC:
-      fprintf(stderr, "[%-7s ", "Free");
-      break;
-    }
+  int status;
 
-   fprintf(stderr, "memory item %3d ", item);
-   fprintf(stderr, "(%6zu byte) ", size);
-   fprintf(stderr, "at %p", ptr);
-   if ( file != NULL )
-     {
-       fprintf(stderr, " line %4d", line);
-       fprintf(stderr, " file %s", file);
-     }
-   if ( caller != NULL )
-     fprintf(stderr, " (%s)", caller);
-   fprintf(stderr, "]\n");
+  status = nc_get_var1_double(ncid, varid, index, dp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memListPrintTable(void)
+
+void cdf_put_var1_double(int ncid, int varid, const size_t index[], const double *dp)
 {
-  int item, item1, item2 = 0;
+  int status;
 
-  if ( MemObjs ) fprintf(stderr, "\nMemory table:\n");
+  status = nc_put_var1_double(ncid, varid, index, dp);
 
-  /* find maximum item */
-  for (size_t memID = 0; memID < memTableSize; memID++)
-    if ( memTable[memID].item != UNDEFID )
-      if ( memTable[memID].item > item2 ) item2 = memTable[memID].item;
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d val = %f", ncid, varid, *dp);
 
-  /* find minimum item */
-  item1 = item2;
-  for (size_t memID = 0; memID < memTableSize; memID++)
-    if ( memTable[memID].item != UNDEFID )
-      if ( memTable[memID].item < item1 ) item1 = memTable[memID].item;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-  for ( item = item1; item <= item2; item++ )
-    for (size_t memID = 0; memID < memTableSize; memID++)
-      {
-	if ( memTable[memID].item == item )
-	  memListPrintEntry(memTable[memID].mtype, memTable[memID].item,
-			    memTable[memID].size*memTable[memID].nobj,
-			    memTable[memID].ptr, memTable[memID].caller,
-			    memTable[memID].file, memTable[memID].line);
-      }
 
-  if ( MemObjs )
-    {
-      fprintf(stderr, "  Memory access             : %6u\n", (unsigned) memAccess);
-      fprintf(stderr, "  Maximum objects           : %6zu\n", memTableSize);
-      fprintf(stderr, "  Objects used              : %6u\n", (unsigned) MaxMemObjs);
-      fprintf(stderr, "  Objects in use            : %6u\n", (unsigned) MemObjs);
-      fprintf(stderr, "  Memory allocated          : ");
-      if (MemUsed > 1024*1024*1024)
-	fprintf(stderr, " %5d GB\n",   (int) (MemUsed/(1024*1024*1024)));
-      else if (MemUsed > 1024*1024)
-	fprintf(stderr, " %5d MB\n",   (int) (MemUsed/(1024*1024)));
-      else if (MemUsed > 1024)
-	fprintf(stderr, " %5d KB\n",   (int) (MemUsed/(1024)));
-      else
-	fprintf(stderr, " %5d Byte\n", (int)  MemUsed);
-    }
+void cdf_get_var_text(int ncid, int varid, char *tp)
+{
+  int status;
 
-  if ( MaxMemUsed )
-    {
-      fprintf(stderr, "  Maximum memory allocated  : ");
-      if (MaxMemUsed > 1024*1024*1024)
-	fprintf(stderr, " %5d GB\n",   (int) (MaxMemUsed/(1024*1024*1024)));
-      else if (MaxMemUsed > 1024*1024)
-	fprintf(stderr, " %5d MB\n",   (int) (MaxMemUsed/(1024*1024)));
-      else if (MaxMemUsed > 1024)
-	fprintf(stderr, " %5d KB\n",   (int) (MaxMemUsed/(1024)));
-      else
-	fprintf(stderr, " %5d Byte\n", (int)  MaxMemUsed);
-    }
+  status = nc_get_var_text(ncid, varid, tp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memGetDebugLevel(void)
+
+void cdf_get_var_short(int ncid, int varid, short *sp)
 {
-  char *debugLevel;
+  int status;
 
-  debugLevel = getenv("MEMORY_DEBUG");
+  status = nc_get_var_short(ncid, varid, sp);
 
-  if ( debugLevel )
-    {
-      if ( isdigit((int) debugLevel[0]) )
-	MEM_Debug = atoi(debugLevel);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-      if ( MEM_Debug )
-	atexit(memListPrintTable);
-    }
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memInit(void)
+
+void cdf_get_var_int(int ncid, int varid, int *ip)
 {
-  static int initDebugLevel = 0;
+  int status;
 
-  if ( ! initDebugLevel )
-    {
-      memGetDebugLevel();
-      initDebugLevel = 1;
-    }
+  status = nc_get_var_int(ncid, varid, ip);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-int memListDeleteEntry(void *ptr, size_t *size)
+
+void cdf_get_var_long(int ncid, int varid, long *lp)
 {
-  int item = UNDEFID;
-  size_t memID;
+  int status;
 
-  for (memID = 0; memID < memTableSize; memID++ )
-    {
-      if ( memTable[memID].item == UNDEFID ) continue;
-      if ( memTable[memID].ptr == ptr ) break;
-    }
+  status = nc_get_var_long(ncid, varid, lp);
 
-  if ( memID != memTableSize )
-    {
-      MemObjs--;
-      MemUsed -= memTable[memID].size * memTable[memID].nobj;
-      *size = memTable[memID].size * memTable[memID].nobj;
-       item = memTable[memID].item;
-       memTable[memID].item   = UNDEFID;
-    }
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-  return (item);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-void memTableInitEntry(size_t memID)
+
+void cdf_get_var_float(int ncid, int varid, float *fp)
 {
-  if ( memID >= memTableSize )
-    memInternalProblem(__func__, "memID %d undefined!", memID);
+  int status;
 
-  memTable[memID].ptr    = NULL;
-  memTable[memID].item   = UNDEFID;
-  memTable[memID].size   = 0;
-  memTable[memID].nobj   = 0;
-  memTable[memID].mtype  = UNDEFID;
-  memTable[memID].line   = UNDEFID;
+  status = nc_get_var_float(ncid, varid, fp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
-		    const char *caller, const char *file, int line)
+
+void cdf_get_var_double(int ncid, int varid, double *dp)
 {
-  static int item = 0;
-  size_t memSize = 0;
-  size_t memID = 0;
+  int status;
 
-  /*
-    Look for a free slot in memTable.
-    (Create the table the first time through).
-  */
-  if ( memTableSize == 0 )
-    {
-      memTableSize = 8;
-      memSize  = memTableSize * sizeof(MemTable_t);
-      memTable = (MemTable_t *) malloc(memSize);
-      if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
+  status = nc_get_var_double(ncid, varid, dp);
 
-      for(size_t i = 0; i < memTableSize; i++)
-	memTableInitEntry(i);
-    }
-  else
-    {
-      while( memID < memTableSize )
-	{
-	  if ( memTable[memID].item == UNDEFID ) break;
-	  memID++;
-	}
-    }
-  /*
-    If the table overflows, double its size.
-  */
-  if ( memID == memTableSize )
-    {
-      memTableSize = 2*memTableSize;
-      memSize  = memTableSize*sizeof(MemTable_t);
-      memTable = (MemTable_t*) realloc(memTable, memSize);
-      if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d val[0] = %f", ncid, varid, *dp);
 
-      for (size_t i = memID; i < memTableSize; i++)
-	memTableInitEntry(i);
-    }
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-  memTable[memID].item  = item;
-  memTable[memID].ptr   = ptr;
-  memTable[memID].size  = size;
-  memTable[memID].nobj  = nobj;
-  memTable[memID].mtype = mtype;
-  memTable[memID].line  = line;
 
-  if ( file )
-    {
-      size_t len = strlen(file);
-      if ( len > MAXNAME-1 ) len = MAXNAME-1;
+void cdf_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out,
+		  int varid_out)
+{
+  int status;
 
-      (void) memcpy(memTable[memID].file, file, len);
-      memTable[memID].file[len] = '\0';
-    }
-  else
-    {
-      (void) strcpy(memTable[memID].file, "unknown");
-    }
+  status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out);
 
-  if ( caller )
-    {
-      size_t len = strlen(caller);
-      if ( len > MAXNAME-1 ) len = MAXNAME-1;
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %s %d %d", ncid_in, varid_out, name, ncid_out, varid_out);
 
-      (void) memcpy(memTable[memID].caller, caller, len);
-      memTable[memID].caller[len] = '\0';
-    }
-  else
-    {
-      (void) strcpy(memTable[memID].caller, "unknown");
-    }
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-  MaxMemObjs++;
-  MemObjs++;
-  MemUsed += size*nobj;
-  if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
 
-  return (item++);
+void cdf_put_att_text(int ncid, int varid, const char *name, size_t len,
+		      const char *tp)
+{
+  int status;
+
+  status = nc_put_att_text(ncid, varid, name, len, tp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d att = %s text = %.*s", ncid, varid, name, (int)len, tp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-static
-int memListChangeEntry(void *ptrold, void *ptr, size_t size,
-		       const char *caller, const char *file, int line)
+
+void cdf_put_att_int(int ncid, int varid, const char *name, nc_type xtype,
+		     size_t len, const int *ip)
 {
-  int item = UNDEFID;
-  size_t memID = 0;
-  size_t sizeold;
+  int status;
 
-  while( memID < memTableSize )
-    {
-      if ( memTable[memID].item != UNDEFID )
-	if ( memTable[memID].ptr == ptrold ) break;
-      memID++;
-    }
+  status = nc_put_att_int(ncid, varid, name, xtype, len, ip);
 
-  if ( memID == memTableSize )
-    {
-      if ( ptrold != NULL )
-	memInternalProblem(__func__, "Item at %p not found.", ptrold);
-    }
-  else
-    {
-      item = memTable[memID].item;
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d att = %s val = %d", ncid, varid, name, *ip);
 
-      sizeold = memTable[memID].size*memTable[memID].nobj;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-      memTable[memID].ptr   = ptr;
-      memTable[memID].size  = size;
-      memTable[memID].nobj  = 1;
-      memTable[memID].mtype = REALLOC_FUNC;
-      memTable[memID].line  = line;
 
-      if ( file )
-	{
-	  size_t len = strlen(file);
-	  if ( len > MAXNAME-1 ) len = MAXNAME-1;
+void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype,
+			size_t len, const double *dp)
+{
+  int status;
+
+  status = nc_put_att_double(ncid, varid, name, xtype, len, dp);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("%d %d %f", ncid, varid, *dp);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-	  (void) memcpy(memTable[memID].file, file, len);
-	  memTable[memID].file[len] = '\0';
-	}
-      else
-	{
-	  (void) strcpy(memTable[memID].file, "unknown");
-	}
 
-      if ( caller )
-	{
-	  size_t len = strlen(caller);
-	  if ( len > MAXNAME-1 ) len = MAXNAME-1;
+void cdf_get_att_text(int ncid, int varid, const char *name, char *tp)
+{
+  int status;
 
-	  (void) memcpy(memTable[memID].caller, caller, len);
-	  memTable[memID].caller[len] = '\0';
-	}
-      else
-	{
-	  (void) strcpy(memTable[memID].caller, "unknown");
-	}
+  status = nc_get_att_text(ncid, varid, name, tp);
 
-      MemUsed -= sizeold;
-      MemUsed += size;
-      if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
-    }
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
 
-  return (item);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-
-void *Calloc(const char *caller, const char *file, int line, size_t nobjs, size_t size)
+void cdf_get_att_string(int ncid, int varid, const char *name, char **tp)
 {
-  void *ptr = NULL;
-  int item = UNDEFID;
+#if  defined  (HAVE_NETCDF4)
+  int status;
 
-  memInit();
+  status = nc_get_att_string(ncid, varid, name, tp);
 
-  if ( nobjs*size > 0 )
-    {
-      ptr = calloc(nobjs, size);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
 
-      if ( MEM_Debug )
-	{
-	  memAccess++;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+#endif
+}
 
-	  if ( ptr ) item = memListNewEntry(CALLOC_FUNC, ptr, size, nobjs, caller, file, line);
 
-	  memListPrintEntry(CALLOC_FUNC, item, size*nobjs, ptr, caller, file, line);
-	}
+void cdf_get_att_int(int ncid, int varid, const char *name, int *ip)
+{
+  int status;
 
-      if ( ptr == NULL && dmemory_ExitOnError )
-	memError(caller, file, line, size*nobjs);
-    }
-  else
-    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
+  status = nc_get_att_int(ncid, varid, name, ip);
 
-  return(ptr);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d att = %s val = %d", ncid, varid, name, *ip);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
-void *Malloc(const char *caller, const char *file, int line, size_t size)
+void cdf_get_att_double(int ncid, int varid, const char *name, double *dp)
 {
-  void *ptr = NULL;
-  int item = UNDEFID;
+  int status;
 
-  memInit();
+  status = nc_get_att_double(ncid, varid, name, dp);
 
-  if ( size > 0 )
-    {
-      ptr = malloc(size);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d att = %s val = %.9g",
+	    ncid, varid, name, *dp);
 
-      if ( MEM_Debug )
-	{
-	  memAccess++;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-	  if ( ptr ) item = memListNewEntry(MALLOC_FUNC, ptr, size, 1, caller, file, line);
 
-	  memListPrintEntry(MALLOC_FUNC, item, size, ptr, caller, file, line);
-	}
+void cdf_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
+		 size_t *lenp)
+{
+  int status;
 
-      if ( ptr == NULL && dmemory_ExitOnError )
-	memError(caller, file, line, size);
-    }
-  else
-    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
+  status = nc_inq_att(ncid, varid, name, xtypep, lenp);
 
-  return (ptr);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
-void *Realloc(const char *caller, const char *file, int line, void *ptrold, size_t size)
+void cdf_inq_atttype(int ncid, int varid, const char *name, nc_type * xtypep)
 {
-  void *ptr = NULL;
-  int item = UNDEFID;
+  int status;
 
-  memInit();
+  status = nc_inq_atttype(ncid, varid, name, xtypep);
 
-  if ( size > 0 )
-    {
-      ptr = realloc(ptrold, size);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
 
-      if ( MEM_Debug )
-	{
-	  memAccess++;
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+}
 
-	  if ( ptr )
-	    {
-	      item = memListChangeEntry(ptrold, ptr, size, caller, file, line);
 
-	      if ( item == UNDEFID ) item = memListNewEntry(REALLOC_FUNC, ptr, size, 1, caller, file, line);
-	    }
+void cdf_inq_attlen(int ncid, int varid, const char *name, size_t * lenp)
+{
+  int status;
 
-	  memListPrintEntry(REALLOC_FUNC, item, size, ptr, caller, file, line);
-	}
+  status = nc_inq_attlen(ncid, varid, name, lenp);
 
-      if ( ptr == NULL && dmemory_ExitOnError )
-	memError(caller, file, line, size);
-    }
-  else
-    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d name = %s len = %d", ncid, varid, name, *lenp);
 
-  return (ptr);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
-void Free(const char *caller, const char *file, int line, void *ptr)
+void cdf_inq_attname(int ncid, int varid, int attnum, char *name)
 {
-  int item;
-  size_t size;
+  int status;
 
-  memInit();
+  status = nc_inq_attname(ncid, varid, attnum, name);
 
-  if ( MEM_Debug )
-    {
-      if ( (item = memListDeleteEntry(ptr, &size)) >= 0 )
-	{
-	  memListPrintEntry(FREE_FUNC, item, size, ptr, caller, file, line);
-	}
-      else
-	{
-	  if ( ptr )
-	    fprintf(stderr, "%s info: memory entry at %p not found. [line %4d file %s (%s)]\n",
-		    __func__, ptr, line, file, caller);
-	}
-    }
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d attnum = %d name = %s", ncid, varid, attnum, name);
 
-  free(ptr);
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-void *cdiXmalloc(size_t size, const char *filename, const char *functionname,
-                 int line)
+
+void cdf_inq_attid(int ncid, int varid, const char *name, int *attnump)
 {
-  void *value = malloc(size);
-  if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "malloc failed: %s",
-             strerror(errno));
-  return value;
+  int status;
+
+  status = nc_inq_attid(ncid, varid, name, attnump);
+
+  if ( CDF_Debug || status != NC_NOERR )
+    Message("ncid = %d varid = %d", ncid, varid);
+
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
-void *cdiXcalloc(size_t nmemb, size_t size, const char *filename,
-                 const char *functionname, int line)
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef CDI_CKSUM_H_
+#define CDI_CKSUM_H_
+
+#include <inttypes.h>
+
+uint32_t cdiCheckSum(int type, int count, const void *data);
+
+#endif
+#ifdef HAVE_CONFIG_H
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
+
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size);
+
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size);
+
+uint32_t
+memcrc(const unsigned char *b, size_t n);
+
+#ifdef HAVE_CONFIG_H
+#endif
+
+#ifndef SERIALIZE_H
+#define SERIALIZE_H
+
+#include <string.h>
+
+#ifndef  CDI_CKSUM_H_
+#endif
+#ifndef  _ERROR_H
+#endif
+
+/*
+ * Generic interfaces for (de-)marshalling
+ */
+int serializeGetSize(int count, int datatype, void *context);
+void serializePack(const void *data, int count, int datatype,
+                   void *buf, int buf_size, int *position, void *context);
+void serializeUnpack(const void *buf, int buf_size, int *position,
+                     void *data, int count, int datatype, void *context);
+
+/*
+ * (de-)marshalling function for common data structures
+ */
+static inline int
+serializeStrTabGetPackSize(const char **strTab, int numStr,
+                           void *context)
 {
-  void *value = calloc(nmemb, size);
-  if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "calloc failed: %s",
-             strerror(errno) );
-  return value;
+  xassert(numStr >= 0);
+  int packBuffSize = 0;
+  for (size_t i = 0; i < (size_t)numStr; ++i)
+  {
+    size_t len = strlen(strTab[i]);
+    packBuffSize +=
+      serializeGetSize(1, DATATYPE_INT, context)
+      + serializeGetSize((int)len, DATATYPE_TXT, context);
+  }
+  packBuffSize +=
+    serializeGetSize(1, DATATYPE_UINT32, context);
+  return packBuffSize;
 }
 
-void *cdiXrealloc(void *p, size_t size, const char *functionname,
-                  const char *filename, int line)
+static inline void
+serializeStrTabPack(const char **strTab, int numStr,
+                    void *buf, int buf_size, int *position, void *context)
 {
-  void *value = realloc(p, size);
-  if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "realloc failed: %s",
-             strerror(errno));
-  return value;
+  uint32_t d = 0;
+  xassert(numStr >= 0);
+  for (size_t i = 0; i < (size_t)numStr; ++i)
+  {
+    size_t len = strlen(strTab[i]);
+    serializePack(&(int){(int)len}, 1, DATATYPE_INT,
+                  buf, buf_size, position, context);
+    serializePack(strTab[i], (int)len, DATATYPE_TXT,
+                  buf, buf_size, position, context);
+    d ^= cdiCheckSum(DATATYPE_TXT, (int)len, strTab[i]);
+  }
+  serializePack(&d, 1, DATATYPE_UINT32,
+                buf, buf_size, position, context);
 }
 
-size_t memTotal(void)
+static inline void
+serializeStrTabUnpack(const void *buf, int buf_size, int *position,
+                      char **strTab, int numStr, void *context)
 {
-  size_t memtotal = 0;
-#if  defined  (HAVE_MALLINFO)
-  struct mallinfo meminfo = mallinfo();
-  if ( MEM_Debug )
+  uint32_t d, d2 = 0;
+  xassert(numStr >= 0);
+  for (size_t i = 0; i < (size_t)numStr; ++i)
     {
-      fprintf(stderr, "arena      %8zu (non-mmapped space allocated from system)\n", (size_t)meminfo.arena);
-      fprintf(stderr, "ordblks    %8zu (number of free chunks)\n", (size_t)meminfo.ordblks);
-      fprintf(stderr, "smblks     %8zu (number of fastbin blocks)\n", (size_t) meminfo.smblks);
-      fprintf(stderr, "hblks      %8zu (number of mmapped regions)\n", (size_t) meminfo.hblks);
-      fprintf(stderr, "hblkhd     %8zu (space in mmapped regions)\n", (size_t) meminfo.hblkhd);
-      fprintf(stderr, "usmblks    %8zu (maximum total allocated space)\n", (size_t) meminfo.usmblks);
-      fprintf(stderr, "fsmblks    %8zu (maximum total allocated space)\n", (size_t) meminfo.fsmblks);
-      fprintf(stderr, "uordblks   %8zu (total allocated space)\n", (size_t) meminfo.uordblks);
-      fprintf(stderr, "fordblks   %8zu (total free space)\n", (size_t) meminfo.fordblks);
-      fprintf(stderr, "Memory in use:   %8zu bytes\n", (size_t) meminfo.usmblks + (size_t)meminfo.uordblks);
-      fprintf(stderr, "Total heap size: %8zu bytes\n", (size_t) meminfo.arena);
-
-      /* malloc_stats(); */
+      int len;
+      serializeUnpack(buf, buf_size, position,
+                      &len, 1, DATATYPE_INT, context);
+      serializeUnpack(buf, buf_size, position,
+                      strTab[i], len, DATATYPE_TXT, context);
+      strTab[i][len] = '\0';
+      d2 ^= cdiCheckSum(DATATYPE_TXT, (size_t)len, strTab[i]);
     }
-  memtotal = (size_t)meminfo.arena;
+  serializeUnpack(buf, buf_size, position,
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(d == d2);
+}
+
+/*
+ * Interfaces for marshalling within a single memory domain
+ */
+int serializeGetSizeInCore(int count, int datatype, void *context);
+void serializePackInCore(const void *data, int count, int datatype,
+                          void *buf, int buf_size, int *position, void *context);
+void serializeUnpackInCore(const void *buf, int buf_size, int *position,
+                           void *data, int count, int datatype, void *context);
+
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
 #endif
 
-  return (memtotal);
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+
+uint32_t cdiCheckSum(int type, int count, const void *buffer)
+{
+  uint32_t s = 0U;
+  xassert(count >= 0);
+  size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
+  memcrc_r_eswap(&s, (const unsigned char *)buffer, (size_t)count, elemSize);
+  s = memcrc_finish(&s, (off_t)(elemSize * (size_t)count));
+  return s;
 }
+#if defined (HAVE_CONFIG_H)
+#endif
 
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
 
-void memExitOnError(void)
+const char *cdiStringError(int cdiErrno)
 {
-  dmemory_ExitOnError = 1;
+  static const char UnknownError[] = "Unknown Error";
+  static const char _EUFTYPE[]     = "Unsupported file type";
+  static const char _ELIBNAVAIL[]  = "Unsupported file type (library support not compiled in)";
+  static const char _EUFSTRUCT[]   = "Unsupported file structure";
+  static const char _EUNC4[]       = "Unsupported netCDF4 structure";
+  static const char _ELIMIT[]      = "Internal limits exceeded";
+
+  switch (cdiErrno) {
+  case CDI_ESYSTEM:
+    {
+      char *cp = (char *) strerror(errno);
+      if ( cp == NULL ) break;
+      return cp;
+    }
+  case CDI_EUFTYPE:    return _EUFTYPE;
+  case CDI_ELIBNAVAIL: return _ELIBNAVAIL;
+  case CDI_EUFSTRUCT:  return _EUFSTRUCT;
+  case CDI_EUNC4:      return _EUNC4;
+  case CDI_ELIMIT:     return _ELIMIT;
+  }
+
+  return UnknownError;
 }
 /*
  * Local Variables:
@@ -5938,7 +4379,11 @@ void memExitOnError(void)
 #ifndef _DMEMORY_H
 #define _DMEMORY_H
 
+//Ensure that all standard headers that may declare malloc() and friends are already included so that our macros won't clobber their definitions.
 #include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+    #include <malloc.h>
+#endif
 
 /*
  * if DEBUG_MEMORY is defined setenv MEMORY_DEBUG to debug memory
@@ -5998,190 +4443,130 @@ void *cdiXrealloc(void *, size_t, const char *, const char *, int);
  * require-trailing-newline: t
  * End:
  */
-#ifdef HAVE_CONFIG_H
-#endif
+#ifndef _GRIBAPI_H
+#define _GRIBAPI_H
 
-#include <inttypes.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef WORDS_BIGENDIAN
-#include <limits.h>
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#ifndef  _ERROR_H
+#endif
 #endif
 
+#ifndef  _CDI_INT_H
+#endif
 
-static const uint32_t crctab[] = {
-  0x00000000,
-  0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
-  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
-  0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
-  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
-  0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
-  0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
-  0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
-  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
-  0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
-  0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
-  0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
-  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
-  0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
-  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
-  0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
-  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
-  0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
-  0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
-  0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
-  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
-  0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
-  0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
-  0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
-  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
-  0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
-  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
-  0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
-  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
-  0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
-  0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
-  0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
-  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
-  0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
-  0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
-  0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
-  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
-  0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
-  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
-  0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
-  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
-  0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
-  0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
-  0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
-  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
-  0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
-  0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
-  0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
-  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
-  0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
-  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
-  0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
-};
-
-
-uint32_t
-memcrc(const unsigned char *b, size_t n)
-{
-/*  Input arguments:
- *  const char*   b == byte sequence to checksum
- *  size_t        n == length of sequence
- */
-
-
-  uint32_t s = 0;
-
-  memcrc_r(&s, b, n);
+#define  GRIBAPI_MISSVAL  -9.E33
 
-  /* Extend with the length of the string. */
-  while (n != 0) {
-    register uint32_t c = n & 0377;
-    n >>= 8;
-    s = (s << 8) ^ crctab[(s >> 24) ^ c];
-  }
+/* GRIB2 Level Types */
+#define  GRIB2_LTYPE_SURFACE               1
+#define  GRIB2_LTYPE_CLOUD_BASE            2
+#define  GRIB2_LTYPE_CLOUD_TOP             3
+#define  GRIB2_LTYPE_ISOTHERM0             4
+#define  GRIB2_LTYPE_TOA                   8
+#define  GRIB2_LTYPE_SEA_BOTTOM            9
+#define  GRIB2_LTYPE_ATMOSPHERE           10
+#define  GRIB2_LTYPE_ISOBARIC            100
+#define  GRIB2_LTYPE_MEANSEA             101
+#define  GRIB2_LTYPE_ALTITUDE            102
+#define  GRIB2_LTYPE_HEIGHT              103
+#define  GRIB2_LTYPE_SIGMA               104
+#define  GRIB2_LTYPE_HYBRID              105
+#define  GRIB2_LTYPE_LANDDEPTH           106
+#define  GRIB2_LTYPE_ISENTROPIC          107
+#define  GRIB2_LTYPE_SNOW                114
+#define  GRIB2_LTYPE_REFERENCE           150
+#define  GRIB2_LTYPE_SEADEPTH            160  /* Depth Below Sea Level                                 */
+#define  GRIB2_LTYPE_LAKE_BOTTOM         162  /* Lake or River Bottom                                  */
+#define  GRIB2_LTYPE_SEDIMENT_BOTTOM     163  /* Bottom Of Sediment Layer                              */
+#define  GRIB2_LTYPE_SEDIMENT_BOTTOM_TA  164  /* Bottom Of Thermally Active Sediment Layer             */
+#define  GRIB2_LTYPE_SEDIMENT_BOTTOM_TW  165  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
+#define  GRIB2_LTYPE_MIX_LAYER           166  /* Mixing Layer                                          */
 
+/* GRIB2 Data representation type (Grid Type) */
+#define  GRIB2_GTYPE_LATLON                0  /*  latitude/longitude                                   */
+#define  GRIB2_GTYPE_LATLON_ROT            1  /*  rotated latitude/longitude                           */
+#define  GRIB2_GTYPE_LATLON_STR            2  /*  stretched latitude/longitude                         */
+#define  GRIB2_GTYPE_LATLON_ROTSTR         3  /*  rotated and stretched latitude/longitude             */
+#define  GRIB2_GTYPE_GAUSSIAN             40  /*  gaussian grid                                        */
+#define  GRIB2_GTYPE_GAUSSIAN_ROT         41  /*  rotated gaussian grid                                */
+#define  GRIB2_GTYPE_GAUSSIAN_STR         42  /*  stretched gaussian grid                              */
+#define  GRIB2_GTYPE_GAUSSIAN_ROTSTR      43  /*  rotated and stretched gaussian grid                  */
+#define  GRIB2_GTYPE_LCC                  30  /*  Lambert conformal                                    */
+#define  GRIB2_GTYPE_SPECTRAL             50  /*  spherical harmonics                                  */
+#define  GRIB2_GTYPE_GME                 100  /*  hexagonal GME grid                                   */
+#define  GRIB2_GTYPE_UNSTRUCTURED        101  /*  General Unstructured Grid                            */
 
-  return ~s;
-}
+const char *gribapiLibraryVersionString(void);
+void gribContainersNew(stream_t * streamptr);
+void gribContainersDelete(stream_t * streamptr);
 
-void
-memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
+#ifdef HAVE_LIBGRIB_API
+static inline void *gribHandleNew(int editionNumber)
 {
-/*  Input arguments:
- *  const char*   b == byte sequence to checksum
- *  size_t        n == length of sequence
- */
+  void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
 
+  if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
 
-  register uint32_t c, s = *state;
-  register size_t n = block_len;
-  register const unsigned char *b = block;
+  return gh;
+}
 
-  for (; n > 0; --n) {
-    c = (uint32_t)(*b++);
-    s = (s << 8) ^ crctab[(s >> 24) ^ c];
-  }
+static inline void gribHandleDelete(void *gh)
+{
+  grib_handle_delete(gh);
+}
+#else
+#define gribHandleNew(editionNumber) (NULL)
+#define gribHandleDelete(gh)
+#endif
 
-  *state = s;
+typedef struct {
+  int init;
+  void *gribHandle;
 }
+gribContainer_t;
 
-#define SWAP_CSUM(BITWIDTH,BYTEWIDTH,NACC)                              \
-  do {                                                                  \
-    register const uint##BITWIDTH##_t *b = (uint##BITWIDTH##_t *)elems; \
-    for (size_t i = 0; i < num_elems; ++i) {                            \
-      for(size_t aofs = NACC; aofs > 0; --aofs) {                       \
-        uint##BITWIDTH##_t accum = b[i + aofs - 1];                     \
-        for (size_t j = 0; j < BYTEWIDTH; ++j) {                        \
-          uint32_t c = (uint32_t)(accum & UCHAR_MAX);                   \
-          s = (s << 8) ^ crctab[(s >> 24) ^ c];                         \
-          accum >>= 8;                                                  \
-        }                                                               \
-      }                                                                 \
-    }                                                                   \
-  } while (0)
+#endif  /* _GRIBAPI_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_CDF_H
+#define _STREAM_CDF_H
 
+void   cdfDefVars(stream_t *streamptr);
+void   cdfDefTimestep(stream_t *streamptr, int tsID);
+int    cdfInqTimestep(stream_t *streamptr, int tsID);
+int    cdfInqContents(stream_t *streamptr);
+void   cdfDefHistory(stream_t *streamptr, int size, const char *history);
+int    cdfInqHistorySize(stream_t *streamptr);
+void   cdfInqHistoryString(stream_t *streamptr, char *history);
 
+void   cdfEndDef(stream_t * streamptr);
+void   cdfDefRecord(stream_t * streamptr);
 
-/**
- *  Does endian-swapping prior to checksumming in case platform is big-endian
- *
- *  @param elems points to first first element with alignment elem_size
- *  @param num_elems number of elements to process
- *  @param elem_size size of each element in bytes
- */
-void
-memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
-               size_t elem_size)
-{
-#ifdef WORDS_BIGENDIAN
-  register uint32_t s = *state;
+void   cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
 
-  switch (elem_size)
-  {
-  case 1:
-    memcrc_r(state, elems, num_elems * elem_size);
-    return;
-  case 2:
-    SWAP_CSUM(16,2,1);
-    break;
-  case 4:
-    SWAP_CSUM(32,4,1);
-    break;
-  case 8:
-    SWAP_CSUM(64,8,1);
-    break;
-  case 16:
-    SWAP_CSUM(64,8,2);
-    break;
-  }
-  *state = s;
-#else
-  memcrc_r(state, elems, num_elems * elem_size);
-#endif
-}
+void   cdfReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
 
+void   cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss);
+void   cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss);
 
-uint32_t
-memcrc_finish(uint32_t *state, off_t total_size)
-{
-  register uint32_t c, s = *state;
-  register uint64_t n = (uint64_t)total_size;
+void   cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
 
-  /* Extend with the length of the string. */
-  while (n != 0) {
-    c = n & 0377;
-    n >>= 8;
-    s = (s << 8) ^ crctab[(s >> 24) ^ c];
-  }
+void   cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+void   cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss);
+void   cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
-  return ~s;
-}
+void   cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
+                           const int rect[][2], const void *data, int nmiss);
 
+#endif
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -6191,23878 +4576,27833 @@ memcrc_finish(uint32_t *state, off_t total_size)
  * require-trailing-newline: t
  * End:
  */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#ifndef _CGRIBEX_H
+#define _CGRIBEX_H
 
-#include <inttypes.h>
+#include <stdio.h>
 #include <sys/types.h>
-#include <stdlib.h>
 
+#define  GRIB_MISSVAL  -9.E33
 
-uint32_t cdiCheckSum(int type, int count, const void *buffer)
-{
-  uint32_t s = 0U;
-  xassert(count >= 0);
-  size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
-  memcrc_r_eswap(&s, (const unsigned char *)buffer, (size_t)count, elemSize);
-  s = memcrc_finish(&s, (off_t)(elemSize * (size_t)count));
-  return s;
-}
-#if defined (HAVE_CONFIG_H)
-#endif
+/* GRIB1 Level Types */
+#define  GRIB1_LTYPE_SURFACE               1
+#define  GRIB1_LTYPE_CLOUD_BASE            2
+#define  GRIB1_LTYPE_CLOUD_TOP             3
+#define  GRIB1_LTYPE_ISOTHERM0             4
+#define  GRIB1_LTYPE_TOA                   8
+#define  GRIB1_LTYPE_SEA_BOTTOM            9
+#define  GRIB1_LTYPE_ATMOSPHERE           10
+#define  GRIB1_LTYPE_99                   99
+#define  GRIB1_LTYPE_ISOBARIC            100
+#define  GRIB1_LTYPE_MEANSEA             102
+#define  GRIB1_LTYPE_ALTITUDE            103
+#define  GRIB1_LTYPE_HEIGHT              105
+#define  GRIB1_LTYPE_SIGMA               107
+#define  GRIB1_LTYPE_SIGMA_LAYER         108
+#define  GRIB1_LTYPE_HYBRID              109
+#define  GRIB1_LTYPE_HYBRID_LAYER        110
+#define  GRIB1_LTYPE_LANDDEPTH           111
+#define  GRIB1_LTYPE_LANDDEPTH_LAYER     112
+#define  GRIB1_LTYPE_ISENTROPIC          113
+#define  GRIB1_LTYPE_SEADEPTH            160  /* Depth Below Sea Level                                 */
+#define  GRIB1_LTYPE_LAKE_BOTTOM         162  /* Lake or River Bottom                                  */
+#define  GRIB1_LTYPE_SEDIMENT_BOTTOM     163  /* Bottom Of Sediment Layer                              */
+#define  GRIB1_LTYPE_SEDIMENT_BOTTOM_TA  164  /* Bottom Of Thermally Active Sediment Layer             */
+#define  GRIB1_LTYPE_SEDIMENT_BOTTOM_TW  165  /* Bottom Of Sediment Layer Penetrated By Thermal Wave   */
+#define  GRIB1_LTYPE_MIX_LAYER           166  /* Mixing Layer                                          */
+#define  GRIB1_LTYPE_99_MARGIN          1000
 
-#include <stddef.h>
-#include <string.h>
+/* GRIB1 Data representation type (Grid Type) [Table 6] */
+#define  GRIB1_GTYPE_LATLON                0  /*  latitude/longitude                                   */
+#define  GRIB1_GTYPE_LATLON_ROT           10  /*  rotated latitude/longitude                           */
+#define  GRIB1_GTYPE_LATLON_STR           20  /*  stretched latitude/longitude                         */
+#define  GRIB1_GTYPE_LATLON_ROTSTR        30  /*  rotated and stretched latitude/longitude             */
+#define  GRIB1_GTYPE_GAUSSIAN              4  /*  gaussian grid                                        */
+#define  GRIB1_GTYPE_GAUSSIAN_ROT         14  /*  rotated gaussian grid                                */
+#define  GRIB1_GTYPE_GAUSSIAN_STR         24  /*  stretched gaussian grid                              */
+#define  GRIB1_GTYPE_GAUSSIAN_ROTSTR      34  /*  rotated and stretched gaussian grid                  */
+#define  GRIB1_GTYPE_LCC                   3  /*  Lambert conformal                                    */
+#define  GRIB1_GTYPE_SPECTRAL             50  /*  spherical harmonics                                  */
+#define  GRIB1_GTYPE_GME                 192  /*  hexagonal GME grid                                   */
 
+/*
+ *  Macros for the indicator section ( Section 0 )
+ */
+#define  ISEC0_GRIB_Len             (isec0[ 0])  /*  Number of octets in the GRIB message              */
+#define  ISEC0_GRIB_Version         (isec0[ 1])  /*  GRIB edition number                               */
 
 
-extern int cdiDefaultCalendar;
+/*
+ *  Macros for the product definition section ( Section 1 )
+ */
+#define  ISEC1_TABLE4_MINUTE      0
+#define  ISEC1_TABLE4_HOUR        1
+#define  ISEC1_TABLE4_DAY         2
+#define  ISEC1_TABLE4_3HOURS     10
+#define  ISEC1_TABLE4_6HOURS     11
+#define  ISEC1_TABLE4_12HOURS    12
+#define  ISEC1_TABLE4_QUARTER    13
+#define  ISEC1_TABLE4_30MINUTES  14
 
-static int DefaultTimeType = TAXIS_ABSOLUTE;
-static int DefaultTimeUnit = TUNIT_HOUR;
 
+#define  ISEC1_CodeTable            (isec1[ 0])  /*  Version number of code table                 */
+#define  ISEC1_CenterID             (isec1[ 1])  /*  Identification of centre                     */
+#define  ISEC1_ModelID              (isec1[ 2])  /*  Identification of model                      */
+#define  ISEC1_GridDefinition       (isec1[ 3])  /*  Grid definition                              */
+#define  ISEC1_Sec2Or3Flag          (isec1[ 4])  /*  Section 2 or 3 included                      */
+#define  ISEC1_Parameter            (isec1[ 5])  /*  Parameter indicator                          */
+#define  ISEC1_LevelType            (isec1[ 6])  /*  Type of level indicator                      */
+#define  ISEC1_Level1               (isec1[ 7])  /*  Level 1                                      */
+#define  ISEC1_Level2               (isec1[ 8])  /*  Level 2                                      */
+#define  ISEC1_Year                 (isec1[ 9])  /*  Year of century (YY)                         */
+#define  ISEC1_Month                (isec1[10])  /*  Month (MM)                                   */
+#define  ISEC1_Day                  (isec1[11])  /*  Day (DD)                                     */
+#define  ISEC1_Hour                 (isec1[12])  /*  Hour (HH)                                    */
+#define  ISEC1_Minute               (isec1[13])  /*  Minute (MM)                                  */
+#define  ISEC1_TimeUnit             (isec1[14])  /*  Time unit indicator                          */
+#define  ISEC1_TimePeriod1          (isec1[15])  /*  P1 Time period                               */
+#define  ISEC1_TimePeriod2          (isec1[16])  /*  P2 Time period                               */
+#define  ISEC1_TimeRange            (isec1[17])  /*  Time range indicator                         */
+#define  ISEC1_AvgNum               (isec1[18])  /*  Number of products included in an average    */
+#define  ISEC1_AvgMiss              (isec1[19])  /*  Number of products missing from an average   */
+#define  ISEC1_Century              (isec1[20])  /*  Century                                      */
+#define  ISEC1_SubCenterID          (isec1[21])  /*  Subcenter identifier                         */
+#define  ISEC1_DecScaleFactor       (isec1[22])  /*  Decimal scale factor                         */
+#define  ISEC1_LocalFLag            (isec1[23])  /*  Flag field to indicate local use in isec1    */
 
-char *Timeunits[] = {
-  "undefined",
-  "seconds",
-  "minutes",
-  "quarters",
-  "30minutes",
-  "hours",
-  "3hours",
-  "6hours",
-  "12hours",
-  "days",
-  "months",
-  "years",
-};
+#define  ISEC1_ECMWF_LocalExtension (isec1[36])
+#define  ISEC1_ECMWF_Class          (isec1[37])
 
 
-static int    taxisCompareP    ( void * taxisptr1, void * taxisptr2 );
-static void   taxisDestroyP    ( void * taxisptr );
-static void   taxisPrintKernel(taxis_t *taxisptr, FILE * fp);
-static int    taxisGetPackSize ( void * taxisptr, void *context );
-static void   taxisPack        ( void * taxisptr, void *buf, int size,
-				 int *position, void *context );
-static int    taxisTxCode      ( void );
+/*
+ *  Macros for the grid definition section ( Section 2 )
+ */
+#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
 
-const resOps taxisOps = {
-  taxisCompareP,
-  taxisDestroyP,
-  (void (*)(void *, FILE *))taxisPrintKernel,
-  taxisGetPackSize,
-  taxisPack,
-  taxisTxCode
-};
+/* Triangular grids */
 
-#define container_of(ptr, type, member) \
-  ((type *)((unsigned char *)ptr - offsetof(type,member)))
+#define  ISEC2_GME_NI2              (isec2[ 1])  /*  Number of factor 2 in factorisation of Ni    */
+#define  ISEC2_GME_NI3              (isec2[ 2])  /*  Number of factor 3 in factorisation of Ni    */
+#define  ISEC2_GME_ND               (isec2[ 3])  /*  Nubmer of diamonds                           */
+#define  ISEC2_GME_NI               (isec2[ 4])  /*  Number of tri. subdiv. of the icosahedron    */
+#define  ISEC2_GME_AFlag            (isec2[ 5])  /*  Flag for orientation of diamonds (Table A)   */
+#define  ISEC2_GME_LatPP            (isec2[ 6])  /*  Latitude of pole point                       */
+#define  ISEC2_GME_LonPP            (isec2[ 7])  /*  Longitude of pole point                      */
+#define  ISEC2_GME_LonMPL           (isec2[ 8])  /*  Longitude of the first diamond               */
+#define  ISEC2_GME_BFlag            (isec2[ 9])  /*  Flag for storage sequence (Table B)          */
 
-struct refcount_string
-{
-  int ref_count;
-  char string[];
-};
+/* Spherical harmonic coeficients */
 
-static char *
-new_refcount_string(size_t len)
-{
-  struct refcount_string *container
-    = xmalloc(sizeof (*container) + len + 1);
-  container->ref_count = 1;
-  return container->string;
-}
+#define  ISEC2_PentaJ               (isec2[ 1])  /*  J pentagonal resolution parameter            */
+#define  ISEC2_PentaK               (isec2[ 2])  /*  K pentagonal resolution parameter            */
+#define  ISEC2_PentaM               (isec2[ 3])  /*  M pentagonal resolution parameter            */
+#define  ISEC2_RepType              (isec2[ 4])  /*  Representation type                          */
+#define  ISEC2_RepMode              (isec2[ 5])  /*  Representation mode                          */
 
-static void
-delete_refcount_string(void *p)
-{
-  if (p)
-    {
-      struct refcount_string *container
-        = container_of(p, struct refcount_string, string);
-      if (!--(container->ref_count))
-        free(container);
-    }
-}
+/* Gaussian grids */
 
-static char *
-dup_refcount_string(char *p)
-{
-  if (p)
-    {
-      struct refcount_string *container
-        = container_of(p, struct refcount_string, string);
-      ++(container->ref_count);
-    }
-  return p;
-}
+#define  ISEC2_NumLon               (isec2[ 1])  /*  Number of points along a parallel (Ni)       */
+#define  ISEC2_NumLat               (isec2[ 2])  /*  Number of points along a meridian (Nj)       */
+#define  ISEC2_FirstLat             (isec2[ 3])  /*  Latitude of the first grid point             */
+#define  ISEC2_FirstLon             (isec2[ 4])  /*  Longitude of the first grid point            */
+#define  ISEC2_ResFlag              (isec2[ 5])  /*  Resolution flag: 128 regular grid            */
+#define  ISEC2_LastLat              (isec2[ 6])  /*  Latitude of the last grid point              */
+#define  ISEC2_LastLon              (isec2[ 7])  /*  Longitude of the last grid point             */
+#define  ISEC2_LonIncr              (isec2[ 8])  /*  i direction increment                        */
+#define  ISEC2_LatIncr              (isec2[ 9])  /*  j direction increment                        */
+#define  ISEC2_NumPar               (isec2[ 9])  /*  Number of parallels between a pole and the E.*/
+#define  ISEC2_ScanFlag             (isec2[10])  /*  Scanning mode flags                          */
+#define  ISEC2_NumVCP               (isec2[11])  /*  Number of vertical coordinate parameters     */
 
+/* Lambert */
+#define  ISEC2_Lambert_Lov          (isec2[ 6])  /*  Orientation of the grid                      */
+#define  ISEC2_Lambert_dx           (isec2[ 8])  /*  X-direction grid length                      */
+#define  ISEC2_Lambert_dy           (isec2[ 9])  /*  Y-direction grid length                      */
+#define  ISEC2_Lambert_ProjFlag     (isec2[12])  /*  Projection centre flag                       */
+#define  ISEC2_Lambert_LatS1        (isec2[13])  /*  First lat at which the secant cone cuts the sphere */
+#define  ISEC2_Lambert_LatS2        (isec2[14])  /*  Second lat at which the secant cone cuts the sphere */
+#define  ISEC2_Lambert_LatSP        (isec2[19])  /*  Latitude of the southern pole                */
+#define  ISEC2_Lambert_LonSP        (isec2[20])  /*  Longitude of the southern pole               */
 
-#undef container_of
 
-static int  TAXIS_Debug = 0;   /* If set to 1, debugging */
+#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
 
+#define  ISEC2_RowLonPtr            (&isec2[22])
+#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
 
-char *tunitNamePtr(int unitID)
-{
-  char *name;
-  int size = sizeof(Timeunits)/sizeof(char *);
+/* */
 
-  if ( unitID > 0 && unitID < size )
-    name = Timeunits[unitID];
-  else
-    name = Timeunits[0];
+#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
+#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
 
-  return (name);
-}
+#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
+#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
 
-#if 0
-static
-void taxis_defaults(void)
-{
-  char *timeunit;
+/*
+ *  Macros for the bit map section ( Section 3 )
+ */
+#define  ISEC3_PredefBitmap         (isec3[ 0])  /* Predefined bitmap                             */
+#define  ISEC3_MissVal              (isec3[ 1])  /* Missing data value for integers               */
+#define  FSEC3_MissVal              (fsec3[ 1])  /* Missing data value for floats                 */
 
-  timeunit = getenv("TIMEUNIT");
-  if ( timeunit )
-    {
-      if ( strcmp(timeunit, "minutes") == 0 )
-	DefaultTimeUnit = TUNIT_MINUTE;
-      else if ( strcmp(timeunit, "hours") == 0 )
-	DefaultTimeUnit = TUNIT_HOUR;
-      else if ( strcmp(timeunit, "3hours") == 0 )
-	DefaultTimeUnit = TUNIT_3HOURS;
-      else if ( strcmp(timeunit, "6hours") == 0 )
-	DefaultTimeUnit = TUNIT_6HOURS;
-      else if ( strcmp(timeunit, "12hours") == 0 )
-	DefaultTimeUnit = TUNIT_12HOURS;
-      else if ( strcmp(timeunit, "days") == 0 )
-	DefaultTimeUnit = TUNIT_DAY;
-      else if ( strcmp(timeunit, "months") == 0 )
-	DefaultTimeUnit = TUNIT_MONTH;
-      else if ( strcmp(timeunit, "years") == 0 )
-	DefaultTimeUnit = TUNIT_YEAR;
-      else
-	Warning("Unsupported TIMEUNIT %s!", timeunit);
-    }
-}
-#endif
+/*
+ *  Macros for the binary data section ( Section 4 )
+ */
+#define  ISEC4_NumValues            (isec4[ 0])  /* Number of data values for encode/decode       */
+#define  ISEC4_NumBits              (isec4[ 1])  /* Number of bits used for each encoded value    */
+#define  ISEC4_NumNonMissValues     (isec4[20])  /* Number of non-missing values                  */
 
-static
-void taxisDefaultValue(taxis_t* taxisptr)
-{
-  taxisptr->self        = CDI_UNDEFID;
-  taxisptr->used        = FALSE;
-  taxisptr->type        = DefaultTimeType;
-  taxisptr->vdate       = 0;
-  taxisptr->vtime       = 0;
-  taxisptr->rdate       = CDI_UNDEFID;
-  taxisptr->rtime       = 0;
-  taxisptr->fdate       = CDI_UNDEFID;
-  taxisptr->ftime       = 0;
-  taxisptr->calendar    = cdiDefaultCalendar;
-  taxisptr->unit        = DefaultTimeUnit;
-  taxisptr->numavg      = 0;
-  taxisptr->climatology = FALSE;
-  taxisptr->has_bounds  = FALSE;
-  taxisptr->vdate_lb    = 0;
-  taxisptr->vtime_lb    = 0;
-  taxisptr->vdate_ub    = 0;
-  taxisptr->vtime_ub    = 0;
-  taxisptr->fc_unit     = DefaultTimeUnit;
-  taxisptr->fc_period   = 0;
-  taxisptr->name        = NULL;
-  taxisptr->longname    = NULL;
-}
 
-static taxis_t *
-taxisNewEntry(cdiResH resH)
-{
-  taxis_t *taxisptr = (taxis_t*) xmalloc(sizeof(taxis_t));
 
-  taxisDefaultValue(taxisptr);
-  if (resH == CDI_UNDEFID)
-    taxisptr->self = reshPut(taxisptr, &taxisOps);
-  else
-    {
-      taxisptr->self = resH;
-      reshReplace(resH, taxisptr, &taxisOps);
-    }
 
-  return (taxisptr);
-}
+void  gribFixZSE(int flag);     /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
+void  gribSetConst(int flag);   /* 1: Don't pack constant fields on regular grids */
+void  gribSetDebug(int debug);  /* 1: Debugging */
+void  gribSetRound(int round);
+void  gribSetRefDP(double refval);
+void  gribSetRefSP(float  refval);
+void  gribSetValueCheck(int vcheck);
+
+
+void  gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+               float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+               int kleng, int *kword, char *hoper, int *kret);
+
+void  gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+               double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+               int kleng, int *kword, char *hoper, int *kret);
+
+
+const char *cgribexLibraryVersion(void);
+
+void  gribDebug(int debug);
+void  gribSetCalendar(int calendar);
+
+void  gribDateTime(int *isec1, int *date, int *time);
+int   gribRefDate(int *isec1);
+int   gribRefTime(int *isec1);
+int   gribTimeIsFC(int *isec1);
+
+void  gribPrintSec0(int *isec0);
+void  gribPrintSec1(int *isec0, int *isec1);
+void  gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
+void  gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2);
+void  gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
+void  gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3);
+void  gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
+void  gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4);
+void  gribPrintSec4Wave(int *isec4);
+
+void  gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
+
+int   gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize);
+
+int   gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int   gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int   gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+
+int   gribOpen(const char *filename, const char *mode);
+void  gribClose(int fileID);
+
+int   gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
+int   gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
+off_t gribGetPos(int fileID);
+int   gribGetSize(int fileID);
+int   gribCheckSeek(int fileID, long *offset, int *version);
+int   gribFileSeek(int fileID, long *offset);
+int   gribReadSize(int fileID);
+int   gribVersion(unsigned char *buffer, size_t buffersize);
+
+int   grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
+
+double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
+
+#endif  /* _CGRIBEX_H */ 
+
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_LIBNETCDF
+#endif
 
-static
-void taxisInit (void)
-{
-  static int taxisInitialized = 0;
-  char *env;
+#if  defined  (HAVE_LIBCGRIBEX)
+#endif
 
-  if ( taxisInitialized ) return;
+extern int cdiPioSerialOpenFileMap(int streamID);
 
-  taxisInitialized = 1;
+int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
 
-  env = getenv("TAXIS_DEBUG");
-  if ( env ) TAXIS_Debug = atoi(env);
-}
+int cdiDefaultInstID   = CDI_UNDEFID;
+int cdiDefaultModelID  = CDI_UNDEFID;
+int cdiDefaultTableID  = CDI_UNDEFID;
+//int cdiNcMissingValue  = CDI_UNDEFID;
+int cdiNcChunksizehint = CDI_UNDEFID;
+int cdiChunkType       = CHUNK_GRID;
+int cdiSplitLtype105   = CDI_UNDEFID;
 
-#if 0
-static
-void taxis_copy(taxis_t *taxisptr2, taxis_t *taxisptr1)
-{
-  int taxisID2 = taxisptr2->self;
-  memcpy(taxisptr2, taxisptr1, sizeof(taxis_t));
-  taxisptr2->self = taxisID2;
-}
-#endif
+int cdiIgnoreAttCoordinates = FALSE;
+int cdiIgnoreValidRange     = FALSE;
+int cdiSkipRecords          = 0;
+int cdiInventoryMode        = 1;
+size_t CDI_netcdf_hdr_pad   = 0UL;
 
-/*
- at Function  taxisCreate
- at Title     Create a Time axis
+char *cdiPartabPath   = NULL;
+int   cdiPartabIntern = 1;
 
- at Prototype int taxisCreate(int taxistype)
- at Parameter
-    @Item  taxistype  The type of the Time axis, one of the set of predefined CDI time axis types.
-                      The valid CDI time axis types are @func{TAXIS_ABSOLUTE} and @func{TAXIS_RELATIVE}.
+double cdiDefaultMissval = -9.E33;
 
- at Description
-The function @func{taxisCreate} creates a Time axis.
+const char Filetypes[][9] = {
+  "UNKNOWN",
+  "GRIB",
+  "GRIB2",
+  "netCDF",
+  "netCDF2",
+  "netCDF4",
+  "netCDF4c",
+  "SERVICE",
+  "EXTRA",
+  "IEG",
+  "HDF5",
+};
 
- at Result
- at func{taxisCreate} returns an identifier to the Time axis.
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
 
- at Example
-Here is an example using @func{taxisCreate} to create a relative T-axis
-with a standard calendar.
 
- at Source
-   ...
-int taxisID;
-   ...
-taxisID = taxisCreate(TAXIS_RELATIVE);
-taxisDefCalendar(taxisID, CALENDAR_STANDARD);
-taxisDefRdate(taxisID, 19850101);
-taxisDefRtime(taxisID, 120000);
-   ...
- at EndSource
- at EndFunction
-*/
-int taxisCreate(int taxistype)
+int CDI_Debug   = 0;    /* If set to 1, debugging           */
+
+int cdiGribApiDebug     = 0;
+int cdiDefaultLeveltype = -1;
+int cdiDataUnreduced = 0;
+int cdiSortName = 0;
+int cdiHaveMissval = 0;
+
+
+static long cdiGetenvInt(char *envName)
 {
-  if ( CDI_Debug )
-    Message("taxistype: %d", taxistype);
+  char *envString;
+  long envValue = -1;
+  long fact = 1;
 
-  taxisInit ();
+  envString = getenv(envName);
 
-  taxis_t *taxisptr = taxisNewEntry(CDI_UNDEFID);
-  taxisptr->type = taxistype;
+  if ( envString )
+    {
+      int loop, len;
 
-  int taxisID = taxisptr->self;
+      len = (int) strlen(envString);
+      for ( loop = 0; loop < len; loop++ )
+	{
+	  if ( ! isdigit((int) envString[loop]) )
+	    {
+	      switch ( tolower((int) envString[loop]) )
+		{
+		case 'k':  fact = 1024;        break;
+		case 'm':  fact = 1048576;     break;
+		case 'g':  fact = 1073741824;  break;
+		default:
+		  fact = 0;
+		  Message("Invalid number string in %s: %s", envName, envString);
+		  Warning("%s must comprise only digits [0-9].",envName);
+		  break;
+		}
+	      break;
+	    }
+	}
 
-  if ( CDI_Debug )
-    Message("taxisID: %d", taxisID);
+      if ( fact ) envValue = fact*atol(envString);
 
-  return (taxisID);
+      if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
+    }
+
+  return (envValue);
 }
 
-void taxisDestroyKernel(taxis_t *taxisptr)
+static void
+cdiPrintDefaults(void)
 {
-  int id = taxisptr->self;
-  delete_refcount_string(taxisptr->name);
-  delete_refcount_string(taxisptr->longname);
-  if (id != CDI_UNDEFID)
-    reshRemove(id, &taxisOps);
+  fprintf(stderr, "default instID     :  %d\n"
+          "default modelID    :  %d\n"
+          "default tableID    :  %d\n"
+          "default missval    :  %g\n", cdiDefaultInstID,
+          cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
 }
 
-/*
- at Function  taxisDestroy
- at Title     Destroy a Time axis
-
- at Prototype void taxisDestroy(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @func{taxisCreate}
-
- at EndFunction
-*/
-void taxisDestroy(int taxisID)
+void cdiPrintVersion(void)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  taxisDestroyKernel(taxisptr);
-  free(taxisptr);
+  fprintf(stderr, "     CDI library version : %s\n", cdiLibraryVersion());
+#if  defined  (HAVE_LIBCGRIBEX)
+  fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
+#endif
+#if  defined  (HAVE_LIBGRIB_API)
+  fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+  fprintf(stderr, "  netCDF library version : %s\n", cdfLibraryVersion());
+#endif
+#if  defined  (HAVE_LIBHDF5)
+  fprintf(stderr, "    HDF5 library version : %s\n", hdfLibraryVersion());
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+  fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+  fprintf(stderr, "   EXTRA library version : %s\n", extLibraryVersion());
+#endif
+#if  defined  (HAVE_LIBIEG)
+  fprintf(stderr, "     IEG library version : %s\n", iegLibraryVersion());
+#endif
+  fprintf(stderr, "    FILE library version : %s\n", fileLibraryVersion());
 }
 
-
-void taxisDestroyP( void * taxisptr )
+void cdiDebug(int level)
 {
-  taxisDestroyKernel((taxis_t *)taxisptr);
-  free(taxisptr);
-}
+  if ( level == 1 || (level &  2) ) CDI_Debug = 1;
 
+  if ( CDI_Debug ) Message("debug level %d", level);
 
-int taxisDuplicate(int taxisID1)
-{
-  taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps);
-  taxis_t *taxisptr2 = taxisNewEntry(CDI_UNDEFID);
+  if ( level == 1 || (level &  4) ) memDebug(1);
 
-  int taxisID2 = taxisptr2->self;
+  if ( level == 1 || (level &  8) ) fileDebug(1);
 
-  if ( CDI_Debug )
-    Message("taxisID2: %d", taxisID2);
+  if ( level == 1 || (level & 16) )
+    {
+#if  defined  (HAVE_LIBCGRIBEX)
+      gribSetDebug(1);
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+      cdfDebug(1);
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+      srvDebug(1);
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+      extDebug(1);
+#endif
+#if  defined  (HAVE_LIBIEG)
+      iegDebug(1);
+#endif
+    }
 
-  ptaxisCopy(taxisptr2, taxisptr1);
-  return (taxisID2);
+  if ( CDI_Debug )
+    {
+      cdiPrintDefaults();
+      cdiPrintDatatypes();
+    }
 }
 
 
-void taxisDefType(int taxisID, int type)
+int cdiHaveFiletype(int filetype)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  int status = 0;
 
-  if (taxisptr->type != type)
+  switch (filetype)
     {
-      taxisptr->type = type;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB)
+#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
+    case FILETYPE_GRB:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB_API)
+    case FILETYPE_GRB2: { status = 1; break; }
+#endif
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:   { status = 1; break; }
+#if  defined  (HAVE_NETCDF2)
+    case FILETYPE_NC2:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_NETCDF4)
+    case FILETYPE_NC4:  { status = 1; break; }
+    case FILETYPE_NC4C: { status = 1; break; }
+#endif
+#endif
+    default: { status = 0; break; }
     }
-}
 
-/*
- at Function  taxisDefVdate
- at Title     Define the verification date
-
- at Prototype void taxisDefVdate(int taxisID, int vdate)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  vdate    Verification date (YYYYMMDD)
+  return (status);
+}
 
- at Description
-The function @func{taxisDefVdate} defines the verification date of a Time axis.
+void cdiDefTableID(int tableID)
+{
+  cdiDefaultTableID = tableID;
+  int modelID = cdiDefaultModelID = tableInqModel(tableID);
+  cdiDefaultInstID = modelInqInstitut(modelID);
+}
 
- at EndFunction
-*/
-void taxisDefVdate(int taxisID, int vdate)
+static
+void cdiSetChunk(const char *chunkAlgo)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  //char *pch;
+  //size_t len = strlen(chunkAlgo);
+  int algo = -1;
 
-  if (taxisptr->vdate != vdate)
+  if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CHUNK_AUTO;
+  else if ( strcmp("grid",  chunkAlgo)   == 0 ) algo = CHUNK_GRID;
+  else if ( strcmp("lines", chunkAlgo)   == 0 ) algo = CHUNK_LINES;
+  /*
+  else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
     {
-      taxisptr->vdate = vdate;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+      int ix, iy;
+      ix = atoi(chunkAlgo);
+      iy = atoi(pch+1);
+      if ( ix > 0 && iy > 0 )
+        {
+          cdiChunkX = ix;
+          cdiChunkY = iy;
+          algo = CHUNK_USER;
+        }
+      else
+        Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
     }
-}
-
-/*
- at Function  taxisDefVtime
- at Title     Define the verification time
+  */
+  else
+    Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
 
- at Prototype void taxisDefVtime(int taxisID, int vtime)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  vtime    Verification time (hhmmss)
+  if ( algo != -1 )
+    {
+      cdiChunkType = algo;
+      if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
+    }
+}
 
- at Description
-The function @func{taxisDefVtime} defines the verification time of a Time axis.
 
- at EndFunction
-*/
-void taxisDefVtime(int taxisID, int vtime)
+void cdiInitialize(void)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  static int Init_CDI = FALSE;
+  char *envString;
+  long value;
 
-  if (taxisptr->vtime != vtime)
+  if ( ! Init_CDI )
     {
-      taxisptr->vtime = vtime;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+      Init_CDI = TRUE;
 
-/*
- at Function  taxisDefRdate
- at Title     Define the reference date
+#if  defined  (HAVE_LIBCGRIBEX)
+      gribFixZSE(1);   // 1: Fix ZeroShiftError of simple packed spherical harmonics
+      gribSetConst(1); // 1: Don't pack constant fields on regular grids
+#endif
 
- at Prototype void taxisDefRdate(int taxisID, int rdate)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  rdate    Reference date (YYYYMMDD)
+      value = cdiGetenvInt("CDI_DEBUG");
+      if ( value >= 0 ) CDI_Debug = (int) value;
 
- at Description
-The function @func{taxisDefRdate} defines the reference date of a Time axis.
+      value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
+      if ( value >= 0 ) cdiGribApiDebug = (int) value;
 
- at EndFunction
-*/
-void taxisDefRdate(int taxisID, int rdate)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+      value = cdiGetenvInt("CDI_REGULARGRID");
+      if ( value >= 0 ) cdiDataUnreduced = (int) value;
 
-  if (taxisptr->rdate != rdate)
-    {
-      taxisptr->rdate = rdate;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+      value = cdiGetenvInt("CDI_SORTNAME");
+      if ( value >= 0 ) cdiSortName = (int) value;
 
-/*
- at Function  taxisDefRtime
- at Title     Define the reference time
+      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
+      if ( value >= 0 ) cdiHaveMissval = (int) value;
 
- at Prototype void taxisDefRtime(int taxisID, int rtime)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  rtime    Reference time (hhmmss)
+      value = cdiGetenvInt("CDI_LEVELTYPE");
+      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
 
- at Description
-The function @func{taxisDefRtime} defines the reference time of a Time axis.
+      value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
+      if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
 
- at EndFunction
-*/
-void taxisDefRtime(int taxisID, int rtime)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+      envString = getenv("CDI_MISSVAL");
+      if ( envString ) cdiDefaultMissval = atof(envString);
+      /*
+      envString = getenv("NC_MISSING_VALUE");
+      if ( envString ) cdiNcMissingValue = atoi(envString);
+      */
+      envString = getenv("NC_CHUNKSIZEHINT");
+      if ( envString ) cdiNcChunksizehint = atoi(envString);
 
-  if (taxisptr->rtime != rtime)
-    {
-      taxisptr->rtime = rtime;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+      envString = getenv("CDI_CHUNK_ALGO");
+      if ( envString ) cdiSetChunk(envString);
 
-/*
- at Function  taxisDefFdate
- at Title     Define the forecast reference date
+      envString = getenv("SPLIT_LTYPE_105");
+      if ( envString ) cdiSplitLtype105 = atoi(envString);
 
- at Prototype void taxisDefFdate(int taxisID, int fdate)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  fdate    Forecast reference date (YYYYMMDD)
+      envString = getenv("IGNORE_ATT_COORDINATES");
+      if ( envString ) cdiIgnoreAttCoordinates = atoi(envString);
 
- at Description
-The function @func{taxisDefFdate} defines the forecast reference date of a Time axis.
+      envString = getenv("IGNORE_VALID_RANGE");
+      if ( envString ) cdiIgnoreValidRange = atoi(envString);
 
- at EndFunction
-*/
-void taxisDefFdate(int taxisID, int fdate)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+      envString = getenv("CDI_SKIP_RECORDS");
+      if ( envString )
+	{
+	  cdiSkipRecords = atoi(envString);
+	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
+	}
 
-  if (taxisptr->fdate != fdate)
-    {
-      taxisptr->fdate = fdate;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+      envString = getenv("CDI_INVENTORY_MODE");
+      if ( envString )
+	{
+	  if ( strncmp(envString, "time", 4) == 0 )
+	    {
+	      cdiInventoryMode = 2;
+	      if ( CDI_Debug )
+		Message("Inventory mode was set to timestep!");
+	    }
+	}
+
+      envString = getenv("CDI_CALENDAR");
+      if ( envString )
+	{
+	  if      ( strncmp(envString, "standard", 8) == 0 )
+	    cdiDefaultCalendar = CALENDAR_STANDARD;
+	  else if ( strncmp(envString, "proleptic", 9) == 0 )
+	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
+	  else if ( strncmp(envString, "360days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_360DAYS;
+	  else if ( strncmp(envString, "365days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_365DAYS;
+	  else if ( strncmp(envString, "366days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_366DAYS;
+	  else if ( strncmp(envString, "none", 4) == 0 )
+	    cdiDefaultCalendar = CALENDAR_NONE;
+
+	  if ( CDI_Debug )
+	    Message("Default calendar set to %s!", envString);
+	}
+#if  defined  (HAVE_LIBCGRIBEX)
+      gribSetCalendar(cdiDefaultCalendar);
+#endif
+
+      envString = getenv("PARTAB_INTERN");
+      if ( envString ) cdiPartabIntern = atoi(envString);
+
+      envString = getenv("PARTAB_PATH");
+      if ( envString ) cdiPartabPath = strdup(envString);
     }
 }
 
-/*
- at Function  taxisDefFtime
- at Title     Define the forecast reference time
 
- at Prototype void taxisDefFtime(int taxisID, int ftime)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  ftime    Forecast reference time (hhmmss)
+const char *strfiletype(int filetype)
+{
+  const char *name;
+  int size = (int) (sizeof(Filetypes)/sizeof(char *));
+
+  if ( filetype > 0 && filetype < size )
+    name = Filetypes[filetype];
+  else
+    name = Filetypes[0];
+
+  return (name);
+}
+
+
+void cdiDefGlobal(const char *string, int val)
+{
+  if      ( strcmp(string, "REGULARGRID")      == 0 ) cdiDataUnreduced = val;
+  else if ( strcmp(string, "GRIBAPI_DEBUG")    == 0 ) cdiGribApiDebug = val;
+  else if ( strcmp(string, "SORTNAME")         == 0 ) cdiSortName = val;
+  else if ( strcmp(string, "HAVE_MISSVAL")     == 0 ) cdiHaveMissval = val;
+  else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
+  else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
+  else Warning("Unsupported global key: %s", string);
+}
 
- at Description
-The function @func{taxisDefFtime} defines the forecast reference time of a Time axis.
 
- at EndFunction
-*/
-void taxisDefFtime(int taxisID, int ftime)
+void cdiDefMissval(double missval)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  cdiInitialize();
 
-  if (taxisptr->ftime != ftime)
-    {
-      taxisptr->ftime = ftime;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  cdiDefaultMissval = missval;
 }
 
-/*
- at Function  taxisDefCalendar
- at Title     Define the calendar
 
- at Prototype void taxisDefCalendar(int taxisID, int calendar)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
-    @Item  calendar The type of the calendar, one of the set of predefined CDI calendar types.
-                    The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEPTIC},
-                    @func{CALENDAR_360DAYS}, @func{CALENDAR_365DAYS} and @func{CALENDAR_366DAYS}.
+double cdiInqMissval(void)
+{
+  cdiInitialize();
 
- at Description
-The function @func{taxisDefCalendar} defines the calendar of a Time axis.
+  return (cdiDefaultMissval);
+}
 
- at EndFunction
-*/
-void taxisDefCalendar(int taxisID, int calendar)
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#include <stdio.h>
+
+void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  unsigned uparam = (unsigned)param;
+  unsigned upnum;
 
-  if (taxisptr->calendar != calendar)
-    {
-      taxisptr->calendar = calendar;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  *pdis = 0xff   & uparam;
+  *pcat = 0xff   & uparam >> 8;
+  upnum = 0xffff & uparam >> 16;
+  if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
+  *pnum = (int)upnum;
 }
 
 
-void taxisDefTunit(int taxisID, int unit)
+int cdiEncodeParam(int pnum, int pcat, int pdis)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  unsigned uparam, upnum;
 
-  if (taxisptr->unit != unit)
-    {
-      taxisptr->unit = unit;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  if ( pcat < 0 || pcat > 255 ) pcat = 255;
+  if ( pdis < 0 || pdis > 255 ) pdis = 255;
+
+  upnum = (unsigned)pnum;
+  if ( pnum < 0 ) upnum = (unsigned)(0x8000 - pnum);
+
+  uparam = upnum << 16 | (unsigned)(pcat << 8) | (unsigned)pdis;
+
+  return ((int)uparam);
 }
 
 
-void taxisDefForecastTunit(int taxisID, int unit)
+void cdiDecodeDate(int date, int *year, int *month, int *day)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  int idate;
 
-  if (taxisptr->fc_unit != unit)
-    {
-      taxisptr->fc_unit = unit;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  *year  =  date / 10000;
+  idate  = date - *year*10000;
+  if ( idate < 0 ) idate = -idate;
+  *month = idate / 100;
+  *day   = idate - *month*100;
 }
 
 
-void taxisDefForecastPeriod(int taxisID, double fc_period)
+int cdiEncodeDate(int year, int month, int day)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  int date;
+  int iyear;
 
-  if (taxisptr->fc_period != fc_period)
-    {
-      taxisptr->fc_period = fc_period;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  iyear = year;
+  if ( iyear < 0 ) iyear = -iyear;
+  date = iyear*10000 + month*100 + day;
+  if ( year < 0 ) date = -date;
+
+  return (date);
 }
 
 
-void taxisDefNumavg(int taxisID, int numavg)
+void cdiDecodeTime(int time, int *hour, int *minute, int *second)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  int itime;
 
-  if (taxisptr->numavg != numavg)
-    {
-      taxisptr->numavg = numavg;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  *hour   = time / 10000;
+  itime   = time - *hour*10000;
+  *minute = itime / 100;
+  *second = itime - *minute*100;
 }
 
-/*
-The type of the time axis, one of the set of predefined CDI time types.
-The valid CDI time types are TAXIS_ABSOLUTE and TAXIS_RELATIVE.
-*/
-int taxisInqType(int taxisID)
+
+int cdiEncodeTime(int hour, int minute, int second)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  int time;
 
-  return (taxisptr->type);
+  time = hour*10000 + minute*100 + second;
+
+  return (time);
 }
 
 
-int taxisHasBounds(int taxisID)
+void cdiParamToString(int param, char *paramstr, int maxlen)
 {
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  int dis, cat, num;
+  int len;
 
-  return (taxisptr->has_bounds);
+  cdiDecodeParam(param, &num, &cat, &dis);
+
+  if ( dis == 255 && (cat == 255 || cat == 0 ) )
+    len = sprintf(paramstr, "%d", num);
+  else  if ( dis == 255 )
+    len = sprintf(paramstr, "%d.%d", num, cat);
+  else
+    len = sprintf(paramstr, "%d.%d.%d", num, cat, dis);
+
+  if ( len > ( maxlen-1) )
+    fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
 }
 
 
-void taxisDeleteBounds(int taxisID)
+char *cdiUnitNamePtr(int cdi_unit)
 {
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  char *cdiUnits[] = {
+    /*  0 */  "undefined",
+    /*  1 */  "Pa",
+    /*  2 */  "hPa",
+    /*  3 */  "mm",
+    /*  4 */  "cm",
+    /*  5 */  "dm",
+    /*  6 */  "m",
+  };
+  char *name;
+  int size = (int) (sizeof(cdiUnits)/sizeof(char *));
 
-  if (taxisptr->has_bounds != FALSE)
-    {
-      taxisptr->has_bounds = FALSE;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+  if ( cdi_unit > 0 && cdi_unit < size )
+    name = cdiUnits[cdi_unit];
+  else
+    name = NULL;
+
+  return (name);
 }
 
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _CALENDAR_H
+#define _CALENDAR_H
 
-void taxisCopyTimestep(int taxisID2, int taxisID1)
-{
-  taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps),
-    *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
+void encode_caldaysec(int calendar, int year, int month, int day, int hour, int minute, int second,
+		      int *julday, int *secofday);
+void decode_caldaysec(int calendar, int julday, int secofday, 
+		      int *year, int *month, int *day, int *hour, int *minute, int *second);
 
-  reshLock();
+#endif  /* _CALENDAR_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
 
-  taxisptr2->rdate = taxisptr1->rdate;
-  taxisptr2->rtime = taxisptr1->rtime;
+/* Automatically generated by m214003 at 2015-04-22, do not edit */
 
-  taxisptr2->vdate = taxisptr1->vdate;
-  taxisptr2->vtime = taxisptr1->vtime;
+/* CGRIBEXLIB_VERSION="1.7.2" */
 
-  if ( taxisptr2->has_bounds )
-    {
-      taxisptr2->vdate_lb = taxisptr1->vdate_lb;
-      taxisptr2->vtime_lb = taxisptr1->vtime_lb;
-      taxisptr2->vdate_ub = taxisptr1->vdate_ub;
-      taxisptr2->vtime_ub = taxisptr1->vtime_ub;
-    }
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic push
+#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic warning "-Wstrict-overflow"
+#endif
 
-  taxisptr2->fdate = taxisptr1->fdate;
-  taxisptr2->ftime = taxisptr1->ftime;
+#ifdef _ARCH_PWR6
+#pragma options nostrict
+#endif
 
-  taxisptr2->fc_unit   = taxisptr1->fc_unit;
-  taxisptr2->fc_period = taxisptr1->fc_period;
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  reshSetStatus(taxisID2, &taxisOps, RESH_DESYNC_IN_USE);
-  reshUnlock();
-}
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <inttypes.h>
 
-/*
- at Function  taxisInqVdate
- at Title     Get the verification date
 
- at Prototype int taxisInqVdate(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
- at Description
-The function @func{taxisInqVdate} returns the verification date of a Time axis.
+#ifndef _TEMPLATES_H
+#define _TEMPLATES_H
 
- at Result
- at func{taxisInqVdate} returns the verification date.
+#define CAT(X,Y)      X##_##Y
+#define TEMPLATE(X,Y) CAT(X,Y)
 
- at EndFunction
-*/
-int taxisInqVdate(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+#endif 
+#ifndef _GRIB_INT_H
+#define _GRIB_INT_H
 
-  return (taxisptr->vdate);
-}
+#if defined (HAVE_CONFIG_H)
+#endif
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
 
-void taxisInqVdateBounds(int taxisID, int *vdate_lb, int *vdate_ub)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  *vdate_lb = taxisptr->vdate_lb;
-  *vdate_ub = taxisptr->vdate_ub;
-}
+#if ! defined   (_CGRIBEX_H)
+#endif
+#if ! defined   (_ERROR_H)
+#endif
+#if ! defined   (_DTYPES_H)
+#endif
 
+#if ! defined   (FALSE)
+#  define  FALSE  0
+#endif
 
-void taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+#if ! defined   (TRUE)
+#  define  TRUE  1
+#endif
 
-  if (taxisptr->vdate_lb != vdate_lb
-      || taxisptr->vdate_ub != vdate_ub
-      || taxisptr->has_bounds != TRUE)
-    {
-      taxisptr->vdate_lb = vdate_lb;
-      taxisptr->vdate_ub = vdate_ub;
-      taxisptr->has_bounds = TRUE;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+#if ! defined   (UCHAR)
+#  define  UCHAR  unsigned char
+#endif
 
-/*
- at Function  taxisInqVtime
- at Title     Get the verification time
 
- at Prototype int taxisInqVtime(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+#if defined (CRAY) || defined (SX) || defined (__uxpch__)
+#  define VECTORCODE
+#endif
 
- at Description
-The function @func{taxisInqVtime} returns the verification time of a Time axis.
 
- at Result
- at func{taxisInqVtime} returns the verification time.
+#if defined (VECTORCODE)
+#if  defined  (INT32)
+#  define  GRIBPACK     unsigned INT32
+#  define  PACK_GRIB    packInt32
+#  define  UNPACK_GRIB  unpackInt32
+#else
+#  define  GRIBPACK     unsigned INT64
+#  define  PACK_GRIB    packInt64
+#  define  UNPACK_GRIB  unpackInt64
+#endif
+#else
+#  define  GRIBPACK     unsigned char
+#endif
 
- at EndFunction
-*/
-int taxisInqVtime(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+#define  U_BYTEORDER     static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
+#define  IS_BIGENDIAN()  (u_byteorder.c[sizeof(long) - 1])
 
-  return (taxisptr->vtime);
-}
+#if defined (__xlC__) /* performance problems on IBM */
+#ifndef DBL_IS_NAN
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#else
+#ifndef DBL_IS_NAN
+#if  defined  (HAVE_DECL_ISNAN)
+#  define DBL_IS_NAN(x)     (isnan(x))
+#elif  defined  (FP_NAN)
+#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
+#else
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#endif
+#endif
 
+#ifndef DBL_IS_EQUAL
+/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
+#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
+#endif
 
-void taxisInqVtimeBounds(int taxisID, int *vtime_lb, int *vtime_ub)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+#ifndef IS_EQUAL
+#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
+#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
+#endif
 
-  *vtime_lb = taxisptr->vtime_lb;
-  *vtime_ub = taxisptr->vtime_ub;
-}
+/* dummy use of unused parameters to silence compiler warnings */
+#define  UNUSED(x) (void)x
 
+#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (---> 8388607)  */
 
-void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+#define  POW_2_M24  0.000000059604644775390625  /*  pow(2.0, -24.0) */
 
-  if (taxisptr->vtime_lb != vtime_lb
-      || taxisptr->vtime_ub != vtime_ub
-      || taxisptr->has_bounds != TRUE)
-    {
-      taxisptr->vtime_lb = vtime_lb;
-      taxisptr->vtime_ub = vtime_ub;
-      taxisptr->has_bounds = TRUE;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+double intpow2(int x);
 
-/*
- at Function  taxisInqRdate
- at Title     Get the reference date
+int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
+int correct_bdslen(int bdslen, long recsize, long gribpos);
 
- at Prototype int taxisInqRdate(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+/* CDI converter routines */
 
- at Description
-The function @func{taxisInqRdate} returns the reference date of a Time axis.
+/* param format:  DDDCCCNNN */
 
- at Result
- at func{taxisInqRdate} returns the reference date.
+void    cdiDecodeParam(int param, int *dis, int *cat, int *num);
+int     cdiEncodeParam(int dis, int cat, int num);
 
- at EndFunction
-*/
-int taxisInqRdate(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+/* date format:  YYYYMMDD */
+/* time format:  hhmmss   */
 
-  if ( taxisptr->rdate == -1 )
-    {
-      taxisptr->rdate = taxisptr->vdate;
-      taxisptr->rtime = taxisptr->vtime;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+void    cdiDecodeDate(int date, int *year, int *month, int *day);
+int     cdiEncodeDate(int year, int month, int day);
 
-  return (taxisptr->rdate);
-}
+void    cdiDecodeTime(int time, int *hour, int *minute, int *second);
+int     cdiEncodeTime(int hour, int minute, int second);
 
-/*
- at Function  taxisInqRtime
- at Title     Get the reference time
+/* CALENDAR types */
 
- at Prototype int taxisInqRtime(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+#define  CALENDAR_STANDARD        0  /* don't change this value (used also in cgribexlib)! */
+#define  CALENDAR_PROLEPTIC       1
+#define  CALENDAR_360DAYS         2
+#define  CALENDAR_365DAYS         3
+#define  CALENDAR_366DAYS         4
+#define  CALENDAR_NONE            5
 
- at Description
-The function @func{taxisInqRtime} returns the reference time of a Time axis.
+extern FILE *grprsm;
 
- at Result
- at func{taxisInqRtime} returns the reference time.
+extern int  CGRIBEX_Debug;
 
- at EndFunction
-*/
-int taxisInqRtime(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+void   gprintf(const char *caller, const char *fmt, ...);
 
-  if ( taxisptr->rdate == -1 )
-    {
-      taxisptr->rdate = taxisptr->vdate;
-      taxisptr->rtime = taxisptr->vtime;
-      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
-    }
+void   grsdef(void);
 
-  return (taxisptr->rtime);
-}
+void   prtbin(int kin, int knbit, int *kout, int *kerr);
+void   confp3(double pval, int *kexp, int *kmant, int kbits, int kround);
+double decfp2(int kexp, int kmant);
+void   ref2ibm(double *pref, int kbits);
 
-/*
- at Function  taxisInqFdate
- at Title     Get the forecast reference date
+void   scale_complex_double(double *fpdata, int pcStart, int pcScale, int trunc, int inv);
+void   scale_complex_float(float *fpdata, int pcStart, int pcScale, int trunc, int inv);
+void   scatter_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
+void   scatter_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
+void   gather_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
+void   gather_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
 
- at Prototype int taxisInqFdate(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+void   scm0_double(double *pdl, double *pdr, double *pfl, double *pfr, int klg);
+int    qu2reg2(double *pfield, int *kpoint, int klat, int klon,
+	       double *ztemp, double msval, int *kret);
+int    qu2reg3_double(double *pfield, int *kpoint, int klat, int klon,
+		      double msval, int *kret, int omisng, int operio, int oveggy);
+int    qu2reg3_float(float *pfield, int *kpoint, int klat, int klon,
+		     float msval, int *kret, int omisng, int operio, int oveggy);
 
- at Description
-The function @func{taxisInqFdate} returns the forecast reference date of a Time axis.
+#if  defined  (INT32)
+long   packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc);
+#endif
+long   packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc);
+#if  defined  (INT32)
+long   unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc);
+#endif
+long   unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc);
 
- at Result
- at func{taxisInqFdate} returns the forecast reference date.
+void  grib_encode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+			 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+			 int kleng, int *kword, int efunc, int *kret);
+void  grib_encode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+			float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+			int kleng, int *kword, int efunc, int *kret);
 
- at EndFunction
-*/
-int taxisInqFdate(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+void  grib_decode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+			 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+			 int kleng, int *kword, int dfunc, int *kret);
+void  grib_decode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+			float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+			int kleng, int *kword, int dfunc, int *kret);
+
+
+int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
+		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
+int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
+		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
+		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
 
-  if ( taxisptr->fdate == -1 )
-    {
-      taxisptr->fdate = taxisptr->vdate;
-      taxisptr->ftime = taxisptr->vtime;
-    }
+#endif  /* _GRIB_INT_H */
+#ifndef _GRIBDECODE_H
+#define _GRIBDECODE_H
 
-  return (taxisptr->fdate);
-}
+#define  UNDEFINED          9.999e20
 
-/*
- at Function  taxisInqFtime
- at Title     Get the forecast reference time
 
- at Prototype int taxisInqFtime(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+#define  GET_INT3(a,b,c)    ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
+#define  GET_INT2(a,b)      ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 8) + b))
+#define  GET_INT1(a)        ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (a&127))
 
- at Description
-The function @func{taxisInqFtime} returns the forecast reference time of a Time axis.
+/* this requires a 32-bit default integer machine */
+#define  GET_UINT4(a,b,c,d) ((int) ((a << 24) + (b << 16) + (c << 8) + (d)))
+#define  GET_UINT3(a,b,c)   ((int) ((a << 16) + (b << 8)  + (c)))
+#define  GET_UINT2(a,b)     ((int) ((a << 8)  + (b)))
+#define  GET_UINT1(a)       ((int)  (a))
 
- at Result
- at func{taxisInqFtime} returns the forecast reference time.
+#define  BUDG_START(s)      (s[0]=='B' && s[1]=='U' && s[2]=='D' && s[3]=='G')
+#define  TIDE_START(s)      (s[0]=='T' && s[1]=='I' && s[2]=='D' && s[3]=='E')
+#define  GRIB_START(s)      (s[0]=='G' && s[1]=='R' && s[2]=='I' && s[3]=='B')
+#define  GRIB_FIN(s)        (s[0]=='7' && s[1]=='7' && s[2]=='7' && s[3]=='7')
 
- at EndFunction
-*/
-int taxisInqFtime(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+/* GRIB1 Section 0: Indicator Section (IS) */
 
-  if ( taxisptr->fdate == -1 )
-    {
-      taxisptr->fdate = taxisptr->vdate;
-      taxisptr->ftime = taxisptr->vtime;
-    }
+#define  GRIB1_SECLEN(s)     GET_INT3(s[ 4], s[ 5], s[ 6])
+#define  GRIB_EDITION(s)     GET_UINT1(s[ 7])
 
-  return (taxisptr->ftime);
-}
+/* GRIB1 Section 1: Product Definition Section (PDS) */
 
-/*
- at Function  taxisInqCalendar
- at Title     Get the calendar
+#define  PDS_Len             GET_UINT3(pds[ 0], pds[ 1], pds[ 2])
+#define  PDS_CodeTable       GET_UINT1(pds[ 3])
+#define  PDS_CenterID        GET_UINT1(pds[ 4])
+#define  PDS_ModelID         GET_UINT1(pds[ 5])
+#define  PDS_GridDefinition  GET_UINT1(pds[ 6])
+#define  PDS_Sec2Or3Flag     GET_UINT1(pds[ 7])
+#define  PDS_HAS_GDS         ((pds[7] & 128) != 0)
+#define  PDS_HAS_BMS         ((pds[7] &  64) != 0)
+#define  PDS_Parameter       GET_UINT1(pds[ 8])
+#define  PDS_LevelType       GET_UINT1(pds[ 9])
+#define  PDS_Level1          (pds[10])
+#define  PDS_Level2	     (pds[11])
+#define  PDS_Level	     GET_UINT2(pds[10], pds[11])
+#define  PDS_Year            GET_INT1(pds[12])
+#define  PDS_Month           GET_UINT1(pds[13])
+#define  PDS_Day             GET_UINT1(pds[14])
+#define  PDS_Hour            GET_UINT1(pds[15])
+#define  PDS_Minute          GET_UINT1(pds[16])
+#define  PDS_Date            (PDS_Year*10000+PDS_Month*100+PDS_Day)
+#define  PDS_Time            (PDS_Hour*100+PDS_Minute)
+#define  PDS_TimeUnit        GET_UINT1(pds[17])
+#define  PDS_TimePeriod1     GET_UINT1(pds[18])
+#define  PDS_TimePeriod2     GET_UINT1(pds[19])
+#define  PDS_TimeRange       GET_UINT1(pds[20])
+#define  PDS_AvgNum          GET_UINT2(pds[21], pds[22])
+#define  PDS_AvgMiss         GET_UINT1(pds[23])
+#define  PDS_Century         GET_UINT1(pds[24])
+#define  PDS_Subcenter       GET_UINT1(pds[25])
+#define  PDS_DecimalScale    GET_INT2(pds[26],pds[27])
 
- at Prototype int taxisInqCalendar(int taxisID)
- at Parameter
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
- at Description
-The function @func{taxisInqCalendar} returns the calendar of a Time axis.
+/* GRIB1 Section 2: Grid Description Section (GDS) */
 
- at Result
- at func{taxisInqCalendar} returns the type of the calendar,
-one of the set of predefined CDI calendar types.
-The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEPTIC},
- at func{CALENDAR_360DAYS}, @func{CALENDAR_365DAYS} and @func{CALENDAR_366DAYS}.
+#define  GDS_Len             ((gds) == NULL ? 0 : GET_UINT3(gds[ 0], gds[ 1], gds[ 2]))
+#define  GDS_NV              GET_UINT1(gds[ 3])
+#define  GDS_PVPL            GET_UINT1(gds[ 4])
+#define  GDS_PV	             ((gds[3] ==    0) ? -1 : (int) gds[4] - 1)
+#define  GDS_PL	             ((gds[4] == 0xFF) ? -1 : (int) gds[3] * 4 + (int) gds[4] - 1)
+#define  GDS_GridType        GET_UINT1(gds[ 5])
 
- at EndFunction
-*/
-int taxisInqCalendar(int taxisID)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  return (taxisptr->calendar);
-}
+/* GRIB1 Triangular grid of DWD */
+#define  GDS_GME_NI2         GET_UINT2(gds[ 6], gds[ 7])
+#define  GDS_GME_NI3         GET_UINT2(gds[ 8], gds[ 9])
+#define  GDS_GME_ND          GET_UINT3(gds[10], gds[11], gds[12])
+#define  GDS_GME_NI          GET_UINT3(gds[13], gds[14], gds[15])
+#define  GDS_GME_AFlag       GET_UINT1(gds[16])
+#define  GDS_GME_LatPP       GET_INT3(gds[17], gds[18], gds[19])
+#define  GDS_GME_LonPP       GET_INT3(gds[20], gds[21], gds[22])
+#define  GDS_GME_LonMPL      GET_INT3(gds[23], gds[24], gds[25])
+#define  GDS_GME_BFlag       GET_UINT1(gds[27])
 
+/* GRIB1 Spectral */
+#define  GDS_PentaJ          GET_UINT2(gds[ 6], gds[ 7])
+#define  GDS_PentaK          GET_UINT2(gds[ 8], gds[ 9])
+#define  GDS_PentaM          GET_UINT2(gds[10], gds[11])
+#define  GDS_RepType         GET_UINT1(gds[12])
+#define  GDS_RepMode         GET_UINT1(gds[13])
 
-int taxisInqTunit(int taxisID)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+/* GRIB1 Regular grid */
+#define  GDS_NumLon          GET_UINT2(gds[ 6], gds[ 7])
+#define  GDS_NumLat          GET_UINT2(gds[ 8], gds[ 9])
+#define  GDS_FirstLat        GET_INT3(gds[10], gds[11], gds[12])
+#define  GDS_FirstLon        GET_INT3(gds[13], gds[14], gds[15])
+#define  GDS_ResFlag         GET_UINT1(gds[16])
+#define  GDS_LastLat         GET_INT3(gds[17], gds[18], gds[19])
+#define  GDS_LastLon         GET_INT3(gds[20], gds[21], gds[22])
+#define  GDS_LonIncr         GET_UINT2(gds[23], gds[24])
+#define  GDS_LatIncr         GET_UINT2(gds[25], gds[26])
+#define  GDS_NumPar          GET_UINT2(gds[25], gds[26])
+#define  GDS_ScanFlag        GET_UINT1(gds[27])
+#define  GDS_LatSP           GET_INT3(gds[32], gds[33], gds[34])
+#define  GDS_LonSP           GET_INT3(gds[35], gds[36], gds[37])
+#define  GDS_RotAngle        GET_Real(&(gds[38]))
 
-  return (taxisptr->unit);
-}
+/* GRIB1 Lambert */
+#define  GDS_Lambert_Lov     GET_INT3(gds[17], gds[18], gds[19])
+#define  GDS_Lambert_dx	     GET_INT3(gds[20], gds[21], gds[22])
+#define  GDS_Lambert_dy	     GET_INT3(gds[23], gds[24], gds[25])
+#define  GDS_Lambert_ProjFlag GET_UINT1(gds[26])
+#define  GDS_Lambert_LatS1   GET_INT3(gds[28], gds[29], gds[30])
+#define  GDS_Lambert_LatS2   GET_INT3(gds[31], gds[32], gds[33])
+#define  GDS_Lambert_LatSP   GET_INT3(gds[34], gds[35], gds[36])
+#define  GDS_Lambert_LonSP   GET_INT3(gds[37], gds[37], gds[37])
 
+/* GRIB1 Section 3: Bit Map Section (BMS) */
 
-int taxisInqForecastTunit(int taxisID)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+#define  BMS_Len	     ((bms) == NULL ? 0 : (int) (bms[0]<<16)+(bms[1]<<8)+bms[2])
+#define  BMS_UnusedBits      (bms[3])
+#define  BMS_Numeric         
+#define  BMS_Bitmap	     ((bms) == NULL ? NULL : (bms)+6)
+#define  BMS_BitmapSize      (((((bms[0]<<16)+(bms[1]<<8)+bms[2]) - 6)<<3) - bms[3])
 
-  return (taxisptr->fc_unit);
-}
+/* GRIB1 Section 4: Binary Data Section (BDS) */
 
+#define  BDS_Len	    ((int) ((bds[0]<<16)+(bds[1]<<8)+bds[2]))
+#define  BDS_Flag	    (bds[3])
+#define  BDS_BinScale       GET_INT2(bds[ 4], bds[ 5])
+#define  BDS_RefValue       decfp2((int)bds[ 6], GET_UINT3(bds[ 7], bds[ 8], bds[ 9]))
+#define  BDS_NumBits        ((int) bds[10])
+#define  BDS_RealCoef       decfp2((int)bds[zoff+11], GET_UINT3(bds[zoff+12], bds[zoff+13], bds[zoff+14]))
+#define  BDS_PackData       ((int) ((bds[zoff+11]<<8) + bds[zoff+12]))
+#define  BDS_Power          GET_INT2(bds[zoff+13], bds[zoff+14])
+#define  BDS_Z              (bds[13])
 
-double taxisInqForecastPeriod(int taxisID)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+/* GRIB1 Section 5: End Section (ES) */
 
-  return (taxisptr->fc_period);
-}
+/* GRIB2 */
 
+#define  GRIB2_SECLEN(section)   (GET_UINT4(section[0], section[1], section[2], section[3]))
+#define  GRIB2_SECNUM(section)   (GET_UINT1(section[4]))
 
-int taxisInqNumavg(int taxisID)
-{
-  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+#endif  /* _GRIBDECODE_H */
+#ifndef _GRIB_ENCODE_H
+#define _GRIB_ENCODE_H
 
-  return (taxisptr->numavg);
+
+#define PutnZero(n) \
+{ \
+  int i; \
+  for ( i = z; i < z+n; i++ ) lGrib[i] = 0; \
+  z += n; \
 }
 
+#define Put1Byte(Value)  (lGrib[z++] = (Value))
+#define Put2Byte(Value) ((lGrib[z++] = (Value) >>  8), \
+                         (lGrib[z++] = (Value)))
+#define Put3Byte(Value) ((lGrib[z++] = (Value) >> 16), \
+                         (lGrib[z++] = (Value) >>  8), \
+                         (lGrib[z++] = (Value)))
+#define Put4Byte(Value) ((lGrib[z++] = (Value) >> 24), \
+                         (lGrib[z++] = (Value) >> 16), \
+                         (lGrib[z++] = (Value) >>  8), \
+                         (lGrib[z++] = (Value)))
 
-taxis_t *taxisPtr(int taxisID)
-{
-  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+#define Put1Int(Value)  {ival = Value; if ( ival < 0 ) ival =     0x80 - ival; Put1Byte(ival);}
+#define Put2Int(Value)  {ival = Value; if ( ival < 0 ) ival =   0x8000 - ival; Put2Byte(ival);}
+#define Put3Int(Value)  {ival = Value; if ( ival < 0 ) ival = 0x800000 - ival; Put3Byte(ival);}
 
-  return (taxisptr);
+#define Put1Real(Value)          \
+{                                \
+  confp3(Value, &exponent, &mantissa, BitsPerInt, 1); \
+  Put1Byte(exponent);            \
+  Put3Byte(mantissa);            \
 }
 
-void
-ptaxisDefName(taxis_t *taxisptr, const char *name)
-{
-  if (name)
-    {
-      size_t len = strlen(name);
-      delete_refcount_string(taxisptr->name);
-      char *taxisname = taxisptr->name = new_refcount_string(len);
-      strcpy(taxisname, name);
-    }
-}
+#endif  /* _GRIB_ENCODE_H */
+#include <stdio.h>
+#include <math.h>
 
-void
-ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
-{
-  if (longname)
-    {
-      size_t len = strlen(longname);
-      delete_refcount_string(taxisptr->longname);
-      char *taxislongname = taxisptr->longname = new_refcount_string(len);
-      strcpy(taxislongname, longname);
-    }
-}
 
-void cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
-{
-  static int lwarn = TRUE;
+const double _pow2tab[158] = {
+ /* pow(2.0,  0.0) */  1.0,
+ /* pow(2.0,  1.0) */  2.0,
+ /* pow(2.0,  2.0) */  4.0,
+ /* pow(2.0,  3.0) */  8.0,
+ /* pow(2.0,  4.0) */  16.0,
+ /* pow(2.0,  5.0) */  32.0,
+ /* pow(2.0,  6.0) */  64.0,
+ /* pow(2.0,  7.0) */  128.0,
+ /* pow(2.0,  8.0) */  256.0,
+ /* pow(2.0,  9.0) */  512.0,
+ /* pow(2.0, 10.0) */  1024.0,
+ /* pow(2.0, 11.0) */  2048.0,
+ /* pow(2.0, 12.0) */  4096.0,
+ /* pow(2.0, 13.0) */  8192.0,
+ /* pow(2.0, 14.0) */  16384.0,
+ /* pow(2.0, 15.0) */  32768.0,
+ /* pow(2.0, 16.0) */  65536.0,
+ /* pow(2.0, 17.0) */  131072.0,
+ /* pow(2.0, 18.0) */  262144.0,
+ /* pow(2.0, 19.0) */  524288.0,
+ /* pow(2.0, 20.0) */  1048576.0,
+ /* pow(2.0, 21.0) */  2097152.0,
+ /* pow(2.0, 22.0) */  4194304.0,
+ /* pow(2.0, 23.0) */  8388608.0,
+ /* pow(2.0, 24.0) */  16777216.0,
+ /* pow(2.0, 25.0) */  33554432.0,
+ /* pow(2.0, 26.0) */  67108864.0,
+ /* pow(2.0, 27.0) */  134217728.0,
+ /* pow(2.0, 28.0) */  268435456.0,
+ /* pow(2.0, 29.0) */  536870912.0,
+ /* pow(2.0, 30.0) */  1073741824.0,
+ /* pow(2.0, 31.0) */  2147483648.0,
+ /* pow(2.0, 32.0) */  4294967296.0,
+ /* pow(2.0, 33.0) */  8589934592.0,
+ /* pow(2.0, 34.0) */  17179869184.0,
+ /* pow(2.0, 35.0) */  34359738368.0,
+ /* pow(2.0, 36.0) */  68719476736.0,
+ /* pow(2.0, 37.0) */  137438953472.0,
+ /* pow(2.0, 38.0) */  274877906944.0,
+ /* pow(2.0, 39.0) */  549755813888.0,
+ /* pow(2.0, 40.0) */  1099511627776.0,
+ /* pow(2.0, 41.0) */  2199023255552.0,
+ /* pow(2.0, 42.0) */  4398046511104.0,
+ /* pow(2.0, 43.0) */  8796093022208.0,
+ /* pow(2.0, 44.0) */  17592186044416.0,
+ /* pow(2.0, 45.0) */  35184372088832.0,
+ /* pow(2.0, 46.0) */  70368744177664.0,
+ /* pow(2.0, 47.0) */  140737488355328.0,
+ /* pow(2.0, 48.0) */  281474976710656.0,
+ /* pow(2.0, 49.0) */  562949953421312.0,
+ /* pow(2.0, 50.0) */  1125899906842624.0,
+ /* pow(2.0, 51.0) */  2251799813685248.0,
+ /* pow(2.0, 52.0) */  4503599627370496.0,
+ /* pow(2.0, 53.0) */  9007199254740992.0,
+ /* pow(2.0, 54.0) */  18014398509481984.0,
+ /* pow(2.0, 55.0) */  36028797018963968.0,
+ /* pow(2.0, 56.0) */  72057594037927936.0,
+ /* pow(2.0, 57.0) */  144115188075855872.0,
+ /* pow(2.0, 58.0) */  288230376151711744.0,
+ /* pow(2.0, 59.0) */  576460752303423488.0,
+ /* pow(2.0, 60.0) */  1152921504606846976.0,
+ /* pow(2.0, 61.0) */  2305843009213693952.0,
+ /* pow(2.0, 62.0) */  4611686018427387904.0,
+ /* pow(2.0, 63.0) */  9223372036854775808.0,
+ /* pow(2.0, 64.0) */  18446744073709551616.0,
+ /* pow(2.0, 65.0) */  36893488147419103232.0,
+ /* pow(2.0, 66.0) */  73786976294838206464.0,
+ /* pow(2.0, 67.0) */  147573952589676412928.0,
+ /* pow(2.0, 68.0) */  295147905179352825856.0,
+ /* pow(2.0, 69.0) */  590295810358705651712.0,
+ /* pow(2.0, 70.0) */  1180591620717411303424.0,
+ /* pow(2.0, 71.0) */  2361183241434822606848.0,
+ /* pow(2.0, 72.0) */  4722366482869645213696.0,
+ /* pow(2.0, 73.0) */  9444732965739290427392.0,
+ /* pow(2.0, 74.0) */  18889465931478580854784.0,
+ /* pow(2.0, 75.0) */  37778931862957161709568.0,
+ /* pow(2.0, 76.0) */  75557863725914323419136.0,
+ /* pow(2.0, 77.0) */  151115727451828646838272.0,
+ /* pow(2.0, 78.0) */  302231454903657293676544.0,
+ /* pow(2.0, 79.0) */  604462909807314587353088.0,
+ /* pow(2.0, 80.0) */  1208925819614629174706176.0,
+ /* pow(2.0, 81.0) */  2417851639229258349412352.0,
+ /* pow(2.0, 82.0) */  4835703278458516698824704.0,
+ /* pow(2.0, 83.0) */  9671406556917033397649408.0,
+ /* pow(2.0, 84.0) */  19342813113834066795298816.0,
+ /* pow(2.0, 85.0) */  38685626227668133590597632.0,
+ /* pow(2.0, 86.0) */  77371252455336267181195264.0,
+ /* pow(2.0, 87.0) */  154742504910672534362390528.0,
+ /* pow(2.0, 88.0) */  309485009821345068724781056.0,
+ /* pow(2.0, 89.0) */  618970019642690137449562112.0,
+ /* pow(2.0, 90.0) */  1237940039285380274899124224.0,
+ /* pow(2.0, 91.0) */  2475880078570760549798248448.0,
+ /* pow(2.0, 92.0) */  4951760157141521099596496896.0,
+ /* pow(2.0, 93.0) */  9903520314283042199192993792.0,
+ /* pow(2.0, 94.0) */  19807040628566084398385987584.0,
+ /* pow(2.0, 95.0) */  39614081257132168796771975168.0,
+ /* pow(2.0, 96.0) */  79228162514264337593543950336.0,
+ /* pow(2.0, 97.0) */  158456325028528675187087900672.0,
+ /* pow(2.0, 98.0) */  316912650057057350374175801344.0,
+ /* pow(2.0, 99.0) */  633825300114114700748351602688.0,
+ /* pow(2.0, 100.0) */  1267650600228229401496703205376.0,
+ /* pow(2.0, 101.0) */  2535301200456458802993406410752.0,
+ /* pow(2.0, 102.0) */  5070602400912917605986812821504.0,
+ /* pow(2.0, 103.0) */  10141204801825835211973625643008.0,
+ /* pow(2.0, 104.0) */  20282409603651670423947251286016.0,
+ /* pow(2.0, 105.0) */  40564819207303340847894502572032.0,
+ /* pow(2.0, 106.0) */  81129638414606681695789005144064.0,
+ /* pow(2.0, 107.0) */  162259276829213363391578010288128.0,
+ /* pow(2.0, 108.0) */  324518553658426726783156020576256.0,
+ /* pow(2.0, 109.0) */  649037107316853453566312041152512.0,
+ /* pow(2.0, 110.0) */  1298074214633706907132624082305024.0,
+ /* pow(2.0, 111.0) */  2596148429267413814265248164610048.0,
+ /* pow(2.0, 112.0) */  5192296858534827628530496329220096.0,
+ /* pow(2.0, 113.0) */  10384593717069655257060992658440192.0,
+ /* pow(2.0, 114.0) */  20769187434139310514121985316880384.0,
+ /* pow(2.0, 115.0) */  41538374868278621028243970633760768.0,
+ /* pow(2.0, 116.0) */  83076749736557242056487941267521536.0,
+ /* pow(2.0, 117.0) */  166153499473114484112975882535043072.0,
+ /* pow(2.0, 118.0) */  332306998946228968225951765070086144.0,
+ /* pow(2.0, 119.0) */  664613997892457936451903530140172288.0,
+ /* pow(2.0, 120.0) */  1329227995784915872903807060280344576.0,
+ /* pow(2.0, 121.0) */  2658455991569831745807614120560689152.0,
+ /* pow(2.0, 122.0) */  5316911983139663491615228241121378304.0,
+ /* pow(2.0, 123.0) */  10633823966279326983230456482242756608.0,
+ /* pow(2.0, 124.0) */  21267647932558653966460912964485513216.0,
+ /* pow(2.0, 125.0) */  42535295865117307932921825928971026432.0,
+ /* pow(2.0, 126.0) */  85070591730234615865843651857942052864.0,
+ /* pow(2.0, 127.0) */  170141183460469231731687303715884105728.0,
+ /* pow(2.0, 128.0) */  340282366920938463463374607431768211456.0,
+ /* pow(2.0, 129.0) */  680564733841876926926749214863536422912.0,
+ /* pow(2.0, 130.0) */  1361129467683753853853498429727072845824.0,
+ /* pow(2.0, 131.0) */  2722258935367507707706996859454145691648.0,
+ /* pow(2.0, 132.0) */  5444517870735015415413993718908291383296.0,
+ /* pow(2.0, 133.0) */  10889035741470030830827987437816582766592.0,
+ /* pow(2.0, 134.0) */  21778071482940061661655974875633165533184.0,
+ /* pow(2.0, 135.0) */  43556142965880123323311949751266331066368.0,
+ /* pow(2.0, 136.0) */  87112285931760246646623899502532662132736.0,
+ /* pow(2.0, 137.0) */  174224571863520493293247799005065324265472.0,
+ /* pow(2.0, 138.0) */  348449143727040986586495598010130648530944.0,
+ /* pow(2.0, 139.0) */  696898287454081973172991196020261297061888.0,
+ /* pow(2.0, 140.0) */  1393796574908163946345982392040522594123776.0,
+ /* pow(2.0, 141.0) */  2787593149816327892691964784081045188247552.0,
+ /* pow(2.0, 142.0) */  5575186299632655785383929568162090376495104.0,
+ /* pow(2.0, 143.0) */  11150372599265311570767859136324180752990208.0,
+ /* pow(2.0, 144.0) */  22300745198530623141535718272648361505980416.0,
+ /* pow(2.0, 145.0) */  44601490397061246283071436545296723011960832.0,
+ /* pow(2.0, 146.0) */  89202980794122492566142873090593446023921664.0,
+ /* pow(2.0, 147.0) */  178405961588244985132285746181186892047843328.0,
+ /* pow(2.0, 148.0) */  356811923176489970264571492362373784095686656.0,
+ /* pow(2.0, 149.0) */  713623846352979940529142984724747568191373312.0,
+ /* pow(2.0, 150.0) */  1427247692705959881058285969449495136382746624.0,
+ /* pow(2.0, 151.0) */  2854495385411919762116571938898990272765493248.0,
+ /* pow(2.0, 152.0) */  5708990770823839524233143877797980545530986496.0,
+ /* pow(2.0, 153.0) */  11417981541647679048466287755595961091061972992.0,
+ /* pow(2.0, 154.0) */  22835963083295358096932575511191922182123945984.0,
+ /* pow(2.0, 155.0) */  45671926166590716193865151022383844364247891968.0,
+ /* pow(2.0, 156.0) */  91343852333181432387730302044767688728495783936.0,
+ /* pow(2.0, 157.0) */  182687704666362864775460604089535377456991567872.0,
+};
 
-  if ( timeunit == TUNIT_MINUTE )
-    {
-      timevalue *= 60;
-      timeunit = TUNIT_SECOND;
-    }
-  else if ( timeunit == TUNIT_HOUR )
-    {
-      timevalue /= 24;
-      timeunit = TUNIT_DAY;
-    }
 
-  if ( timeunit == TUNIT_SECOND )
-    {
-      *days = (int) (timevalue/86400);
-      *secs = (int) (timevalue - *days*86400.);
-      if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
-      /*
-      {
-	double cval = *days*86400. + *secs;
-	if ( cval != timevalue )
-	  printf("TUNIT_SECOND error: %g %g %d %d\n", timevalue, cval, *days, *secs);
-      }
-      */
-    }
-  else if ( timeunit == TUNIT_DAY )
-    {
-      *days = (int) timevalue;
-      *secs = (int) ((timevalue - *days)*86400 + 0.5);
-      if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
-      /*
-      {
-	double cval = *days + *secs/86400.;
-	if ( cval != timevalue )
-	  printf("TUNIT_DAY error: %g %g %d %d\n", timevalue, cval, *days, *secs);
-      }
-      */
-    }
-  else
-    {
-      if ( lwarn )
-	{
-	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = FALSE;
-	}
-    }
-}
+const double _pow16tab[71] = {
+ /* pow(16.0,  0.0) */  1.0,
+ /* pow(16.0,  1.0) */  16.0,
+ /* pow(16.0,  2.0) */  256.0,
+ /* pow(16.0,  3.0) */  4096.0,
+ /* pow(16.0,  4.0) */  65536.0,
+ /* pow(16.0,  5.0) */  1048576.0,
+ /* pow(16.0,  6.0) */  16777216.0,
+ /* pow(16.0,  7.0) */  268435456.0,
+ /* pow(16.0,  8.0) */  4294967296.0,
+ /* pow(16.0,  9.0) */  68719476736.0,
+ /* pow(16.0, 10.0) */  1099511627776.0,
+ /* pow(16.0, 11.0) */  17592186044416.0,
+ /* pow(16.0, 12.0) */  281474976710656.0,
+ /* pow(16.0, 13.0) */  4503599627370496.0,
+ /* pow(16.0, 14.0) */  72057594037927936.0,
+ /* pow(16.0, 15.0) */  1152921504606846976.0,
+ /* pow(16.0, 16.0) */  18446744073709551616.0,
+ /* pow(16.0, 17.0) */  295147905179352825856.0,
+ /* pow(16.0, 18.0) */  4722366482869645213696.0,
+ /* pow(16.0, 19.0) */  75557863725914323419136.0,
+ /* pow(16.0, 20.0) */  1208925819614629174706176.0,
+ /* pow(16.0, 21.0) */  19342813113834066795298816.0,
+ /* pow(16.0, 22.0) */  309485009821345068724781056.0,
+ /* pow(16.0, 23.0) */  4951760157141521099596496896.0,
+ /* pow(16.0, 24.0) */  79228162514264337593543950336.0,
+ /* pow(16.0, 25.0) */  1267650600228229401496703205376.0,
+ /* pow(16.0, 26.0) */  20282409603651670423947251286016.0,
+ /* pow(16.0, 27.0) */  324518553658426726783156020576256.0,
+ /* pow(16.0, 28.0) */  5192296858534827628530496329220096.0,
+ /* pow(16.0, 29.0) */  83076749736557242056487941267521536.0,
+ /* pow(16.0, 30.0) */  1329227995784915872903807060280344576.0,
+ /* pow(16.0, 31.0) */  21267647932558653966460912964485513216.0,
+ /* pow(16.0, 32.0) */  340282366920938463463374607431768211456.0,
+ /* pow(16.0, 33.0) */  5444517870735015415413993718908291383296.0,
+ /* pow(16.0, 34.0) */  87112285931760246646623899502532662132736.0,
+ /* pow(16.0, 35.0) */  1393796574908163946345982392040522594123776.0,
+ /* pow(16.0, 36.0) */  22300745198530623141535718272648361505980416.0,
+ /* pow(16.0, 37.0) */  356811923176489970264571492362373784095686656.0,
+ /* pow(16.0, 38.0) */  5708990770823839524233143877797980545530986496.0,
+ /* pow(16.0, 39.0) */  91343852333181432387730302044767688728495783936.0,
+ /* pow(16.0, 40.0) */  1461501637330902918203684832716283019655932542976.0,
+ /* pow(16.0, 41.0) */  23384026197294446691258957323460528314494920687616.0,
+ /* pow(16.0, 42.0) */  374144419156711147060143317175368453031918731001856.0,
+ /* pow(16.0, 43.0) */  5986310706507378352962293074805895248510699696029696.0,
+ /* pow(16.0, 44.0) */  95780971304118053647396689196894323976171195136475136.0,
+ /* pow(16.0, 45.0) */  1532495540865888858358347027150309183618739122183602176.0,
+ /* pow(16.0, 46.0) */  24519928653854221733733552434404946937899825954937634816.0,
+ /* pow(16.0, 47.0) */  392318858461667547739736838950479151006397215279002157056.0,
+ /* pow(16.0, 48.0) */  6277101735386680763835789423207666416102355444464034512896.0,
+ /* pow(16.0, 49.0) */  100433627766186892221372630771322662657637687111424552206336.0,
+ /* pow(16.0, 50.0) */  1606938044258990275541962092341162602522202993782792835301376.0,
+ /* pow(16.0, 51.0) */  25711008708143844408671393477458601640355247900524685364822016.0,
+ /* pow(16.0, 52.0) */  411376139330301510538742295639337626245683966408394965837152256.0,
+ /* pow(16.0, 53.0) */  6582018229284824168619876730229402019930943462534319453394436096.0,
+ /* pow(16.0, 54.0) */  105312291668557186697918027683670432318895095400549111254310977536.0,
+ /* pow(16.0, 55.0) */  1684996666696914987166688442938726917102321526408785780068975640576.0,
+ /* pow(16.0, 56.0) */  26959946667150639794667015087019630673637144422540572481103610249216.0,
+ /* pow(16.0, 57.0) */  431359146674410236714672241392314090778194310760649159697657763987456.0,
+ /* pow(16.0, 58.0) */  6901746346790563787434755862277025452451108972170386555162524223799296.0,
+ /* pow(16.0, 59.0) */  110427941548649020598956093796432407239217743554726184882600387580788736.0,
+ /* pow(16.0, 60.0) */  1766847064778384329583297500742918515827483896875618958121606201292619776.0,
+ /* pow(16.0, 61.0) */  28269553036454149273332760011886696253239742350009903329945699220681916416.0,
+ /* pow(16.0, 62.0) */  452312848583266388373324160190187140051835877600158453279131187530910662656.0,
+ /* pow(16.0, 63.0) */  7237005577332262213973186563042994240829374041602535252466099000494570602496.0,
+ /* pow(16.0, 64.0) */  115792089237316195423570985008687907853269984665640564039457584007913129639936.0,
+ /* pow(16.0, 65.0) */  1852673427797059126777135760139006525652319754650249024631321344126610074238976.0,
+ /* pow(16.0, 66.0) */  29642774844752946028434172162224104410437116074403984394101141506025761187823616.0,
+ /* pow(16.0, 67.0) */  474284397516047136454946754595585670566993857190463750305618264096412179005177856.0,
+ /* pow(16.0, 68.0) */  7588550360256754183279148073529370729071901715047420004889892225542594864082845696.0,
+ /* pow(16.0, 69.0) */  121416805764108066932466369176469931665150427440758720078238275608681517825325531136.0,
+ /* pow(16.0, 70.0) */  1942668892225729070919461906823518906642406839052139521251812409738904285205208498176.0,
+};
 
-static
-void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
+static int _pow2tab_size = sizeof(_pow2tab)/sizeof(double);
+
+void gen_pow2tab(void)
 {
-  static int lwarn = TRUE;
+  int jloop;
 
-  if ( timeunit == TUNIT_SECOND )
-    {
-      *timevalue = days*86400. + secs;
-    }
-  else if ( timeunit == TUNIT_MINUTE  ||
-	    timeunit == TUNIT_QUARTER ||
-	    timeunit == TUNIT_30MINUTES )
-    {
-      *timevalue = days*1440. + secs/60.;
-    }
-  else if ( timeunit == TUNIT_HOUR   ||
-	    timeunit == TUNIT_3HOURS ||
-	    timeunit == TUNIT_6HOURS ||
-	    timeunit == TUNIT_12HOURS )
-    {
-      *timevalue = days*24. + secs/3600.;
-    }
-  else if ( timeunit == TUNIT_DAY )
-    {
-      *timevalue = days + secs/86400.;
-    }
-  else
-    {
-      if ( lwarn )
-	{
-	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = FALSE;
-	}
-    }
+  for ( jloop = 0; jloop < 158; jloop++ )
+    printf(" /* pow(2.0, %2d.0) */  %.1f,\n", jloop,  pow(2.0, (double) jloop));
 }
 
-int days_per_month(int calendar, int year, int month);
 
-void timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime)
+void gen_pow16tab(void)
 {
-  int year, month, day, hour, minute, second;
-  int rdate, rtime;
-  int timeunit;
-  int calendar;
-  int julday, secofday, days, secs;
-
-  *vdate = 0;
-  *vtime = 0;
-
-  timeunit = (*taxis).unit;
-  calendar = (*taxis).calendar;
-
-  rdate  = (*taxis).rdate;
-  rtime  = (*taxis).rtime;
-
-  if ( rdate == 0 && rtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
-
-  cdiDecodeDate(rdate, &year, &month, &day);
-  cdiDecodeTime(rtime, &hour, &minute, &second);
-
-  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
-    {
-      timeunit = TUNIT_DAY;
-      timevalue *= 30;
-    }
+  double pval;
+  int iexp;
 
-  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
+  for ( iexp = 0; iexp < 71; iexp++ )
     {
-      int nmon, dpm;
-      double fmon;
-
-      if ( timeunit == TUNIT_YEAR ) timevalue *= 12;
-
-      nmon = (int) timevalue;
-      fmon = timevalue - nmon;
-
-      month += nmon;
-
-      while ( month > 12 ) { month -= 12; year++; }
-      while ( month <  1 ) { month += 12; year--; }
-
-      dpm = days_per_month(calendar, year, month);
-      timeunit = TUNIT_DAY;
-      timevalue = fmon*dpm;
+      pval = pow(16.0, (double)(iexp));
+      printf(" /* pow(16.0, %2d.0) */  %.1f,\n", iexp, pval);
     }
-
-  encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
-
-  cdiDecodeTimevalue(timeunit, timevalue, &days, &secs);
-
-  julday_add(days, secs, &julday, &secofday);
-
-  decode_caldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
-
-  *vdate = cdiEncodeDate(year, month, day);
-  *vtime = cdiEncodeTime(hour, minute, second);
 }
 
 
-double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
+double intpow2(int x)
 {
-  int ryear, rmonth;
-  int year, month, day, hour, minute, second;
-  int rdate, rtime;
-  double value = 0;
-  int timeunit;
-  int timeunit0;
-  int calendar;
-  int julday1, secofday1, julday2, secofday2, days, secs;
-
-  timeunit = (*taxis).unit;
-  calendar = (*taxis).calendar;
-
-  rdate = (*taxis).rdate;
-  rtime = (*taxis).rtime;
-  if ( rdate == -1 )
-    {
-      rdate  = (*taxis).vdate;
-      rtime  = (*taxis).vtime;
-    }
+  if ( x < _pow2tab_size )
+    return (_pow2tab[x]);
+  else
+    return (pow(2.0, (double) x));
+}
+/* 
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL minmax_val.c
+ result on bailung (gcc 4.8.2):
+  orig    : fmin: -500000  fmax: 499999  time:   4.82s
+  sse2    : fmin: -500000  fmax: 499999  time:   4.83s
 
-  if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return(value);
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD minmax_val.c
+ result on thunder5 (gcc 4.8.2):
+  orig    : fmin: -500000  fmax: 499999  time:   3.10s
+  simd    : fmin: -500000  fmax: 499999  time:   3.10s # omp simd in gcc 4.9
+  avx     : fmin: -500000  fmax: 499999  time:   2.84s
 
-  cdiDecodeDate(rdate, &ryear, &rmonth, &day);
-  cdiDecodeTime(rtime, &hour, &minute, &second);
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
+ result on thunder5 (icc 14.0.2):
+  orig    : fmin: -500000  fmax: 499999  time:   2.83s
+  simd    : fmin: -500000  fmax: 499999  time:   2.83s
+  avx     : fmin: -500000  fmax: 499999  time:   2.92s
 
-  encode_caldaysec(calendar, ryear, rmonth, day, hour, minute, second, &julday1, &secofday1);
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
+ result on hama (icc 15.0.1):
+ float:
+  minmax_val: fmin: -500000  fmax: 499999  time:   0.60s
+ double:
+  minmax_val: fmin: -500000  fmax: 499999  time:   3.06s
+  orig      : fmin: -500000  fmax: 499999  time:   2.66s
+  simd      : fmin: -500000  fmax: 499999  time:   6.65s
+  avx       : fmin: -500000  fmax: 499999  time:   3.11s
 
-  cdiDecodeDate(vdate, &year, &month, &day);
-  cdiDecodeTime(vtime, &hour, &minute, &second);
+xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_MINMAXVAL minmax_val.c
+ result on blizzard (xlc 12):
+  orig    : fmin: -500000  fmax: 499999  time:   7.26s
+  pwr6u6  : fmin: -500000  fmax: 499999  time:   5.92s
+*/
+#if defined(_ARCH_PWR6)
+#pragma options nostrict
+#endif
 
-  timeunit0 = timeunit;
+#include <stdlib.h>
 
-  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
-    {
-      timeunit = TUNIT_DAY;
-    }
+//#undef _GET_X86_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _ARCH_PWR6
 
-  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
-    {
-      int nmonth, dpm;
+#if defined(_GET_IBM_COUNTER)
+#include <libhpc.h>
+#elif defined(_GET_X86_COUNTER)
+#include <x86intrin.h>
+#elif defined(_GET_MACH_COUNTER)
+#include <mach/mach_time.h>
+#endif
 
-      value = (year-ryear)*12 - rmonth + month;
+#if   defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
+#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 4)
+#define GNUC_PUSH_POP
+#endif
+#endif
 
-      nmonth = (int) value;
-      month -= nmonth;
+#if   defined(__GNUC__) && (__GNUC__ >= 4)
+#elif defined(__ICC)    && (__ICC >= 1100)
+#elif defined(__clang__)
+#else
+#define DISABLE_SIMD
+#endif
 
-      while ( month > 12 ) { month -= 12; year++; }
-      while ( month <  1 ) { month += 12; year--; }
+#if !defined(TEST_MINMAXVAL)
+#define DISABLE_SIMD
+#endif
 
-      dpm = days_per_month(calendar, year, month);
+#if defined(DISABLE_SIMD)
+# if defined(ENABLE_AVX)
+#  define _ENABLE_AVX
+# endif
+# if defined(ENABLE_SSE2)
+#  define _ENABLE_SSE2
+# endif
+#endif
 
-      encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
+#if !defined(DISABLE_SIMD)
+# if defined(__AVX__)
+#  define _ENABLE_AVX
+# endif
+# if defined(__SSE2__)
+#  define _ENABLE_SSE2
+# endif
+#endif
 
-      julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+#include <float.h>
+#include <stdint.h>
+#include <inttypes.h>
 
-      value += (days+secs/86400.)/dpm;
+#if defined(_ENABLE_AVX)
+#include <immintrin.h>
+#elif defined(_ENABLE_SSE2)
+#include <emmintrin.h>
+#endif
 
-      if ( timeunit == TUNIT_YEAR ) value = value/12;
-    }
-  else
-    {
-      encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
-      julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+#if defined(_ENABLE_AVX)
 
-      cdiEncodeTimevalue(days, secs, timeunit, &value);
-    }
+static
+void avx_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
+{
+  double fmin[4], fmax[4];
+  __m256d current_max, current_min, work;
 
-  if ( timeunit0 == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
-    {
-      value /= 30;
-    }
+  // load max and min values into all four slots of the YMM registers
+  current_min = _mm256_set1_pd(*min);
+  current_max = _mm256_set1_pd(*max);
 
-  return (value);
-}
+  // Work input until "buf" reaches 32 byte alignment
+  while ( ((unsigned long)buf) % 32 != 0 && nframes > 0) {
 
+    // Load the next double into the work buffer
+    work = _mm256_set1_pd(*buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf++;
+    nframes--;
+  }
 
-void conv_timeval(double timevalue, int *rvdate, int *rvtime)
-{
-  int vdate = 0, vtime = 0;
-  int hour, minute, second;
-  int daysec;
+  while (nframes >= 16) {
 
-  vdate = (int) timevalue;
-  if ( vdate < 0 )
-    daysec = (int) (-(timevalue - vdate)*86400 + 0.01);
-  else
-    daysec = (int) ( (timevalue - vdate)*86400 + 0.01);
+    (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
 
-  hour   =  daysec / 3600;
-  minute = (daysec - hour*3600)/60;
-  second =  daysec - hour*3600 - minute*60;
-  vtime  = cdiEncodeTime(hour, minute, second);
+    work = _mm256_load_pd(buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf += 4;
 
-  *rvdate = vdate;
-  *rvtime = vtime;
-}
+    work = _mm256_load_pd(buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf += 4;
 
+    (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
 
-void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
-{
-  int vdate = 0, vtime = 0;
-  int hour, minute, second;
-  int year, month, day;
-  static int lwarn = TRUE;
+    work = _mm256_load_pd(buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf += 4;
 
-  if ( timeunit == TUNIT_SECOND )
-    {
-      timevalue /= 86400;
-      conv_timeval(timevalue, &vdate, &vtime);
-    }
-  else if ( timeunit == TUNIT_HOUR )
-    {
-      timevalue /= 24;
-      conv_timeval(timevalue, &vdate, &vtime);
-    }
-  else if ( timeunit == TUNIT_DAY )
-    {
-      conv_timeval(timevalue, &vdate, &vtime);
-    }
-  else if ( timeunit == TUNIT_MONTH )
-    {
-      vdate = (int) timevalue*100;
-      vdate += 1;
-      vtime = 0;
-    }
-  else if ( timeunit == TUNIT_YEAR )
-    {
-      if ( timevalue < -214700 )
-	{
-	  Warning("Year %g out of range, set to -214700", timevalue);
-	  timevalue = -214700;
-	}
-      else if ( timevalue > 214700 )
-	{
-	  Warning("Year %g out of range, set to 214700", timevalue);
-	  timevalue = 214700;
-	}
+    work = _mm256_load_pd(buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf += 4;
+    nframes -= 16;
+  }
 
-      vdate = (int) timevalue*10000;
-      vdate += 101;
-      vtime = 0;
-    }
-  else
-    {
-      if ( lwarn )
-	{
-	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = FALSE;
-	}
-    }
+  // work through aligned buffers
+  while (nframes >= 4) {
+    work = _mm256_load_pd(buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf += 4;
+    nframes -= 4;
+  }
 
-  /* verify date and time */
+  // work through the remainung values
+  while ( nframes > 0) {
+    work = _mm256_set1_pd(*buf);
+    current_min = _mm256_min_pd(current_min, work);
+    current_max = _mm256_max_pd(current_max, work);
+    buf++;
+    nframes--;
+  }
 
-  cdiDecodeDate(vdate, &year, &month, &day);
-  cdiDecodeTime(vtime, &hour, &minute, &second);
+  // find min & max value through shuffle tricks
 
-  if ( month > 17 || day > 31 || hour > 23 || minute > 59 || second > 59 )
-    {
-      if ( (month  > 17 || day > 31) && (year < -9999 || year > 9999) ) year = 1;
-      if ( month  > 17 ) month  = 1;
-      if ( day    > 31 ) day    = 1;
-      if ( hour   > 23 ) hour   = 0;
-      if ( minute > 59 ) minute = 0;
-      if ( second > 59 ) second = 0;
+  work = current_min;
+  work = _mm256_shuffle_pd(work, work, 5);
+  work = _mm256_min_pd (work, current_min);
+  current_min = work;
+  work = _mm256_permute2f128_pd(work, work, 1);
+  work = _mm256_min_pd (work, current_min);
+  _mm256_storeu_pd(fmin, work);
 
-      vdate = cdiEncodeDate(year, month, day);
-      vtime = cdiEncodeTime(hour, minute, second);
+  work = current_max;
+  work = current_max;
+  work = _mm256_shuffle_pd(work, work, 5);
+  work = _mm256_max_pd (work, current_max);
+  current_max = work;
+  work = _mm256_permute2f128_pd(work, work, 1);
+  work = _mm256_max_pd (work, current_max);
+  _mm256_storeu_pd(fmax, work);
 
-      if ( lwarn )
-        {
-          lwarn = FALSE;
-          Warning("Reset wrong date/time to %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d!",
-                  year, month, day, hour, minute, second);
-        }
-    }
+  *min = fmin[0];
+  *max = fmax[0];
 
-  *date = vdate;
-  *time = vtime;
+  return;
 }
 
+#elif defined(_ENABLE_SSE2)
 
-void cdiSetForecastPeriod(double timevalue, taxis_t *taxis)
+static
+void sse2_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
 {
-  int year, month, day, hour, minute, second;
-  int vdate, vtime;
-  int timeunit;
-  int calendar;
-  int julday, secofday, days, secs;
-
-  (*taxis).fc_period = timevalue;
-
-  timeunit = (*taxis).fc_unit;
-  calendar = (*taxis).calendar;
-
-  vdate  = (*taxis).vdate;
-  vtime  = (*taxis).vtime;
-
-  if ( vdate == 0 && vtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
-
-  cdiDecodeDate(vdate, &year, &month, &day);
-  cdiDecodeTime(vtime, &hour, &minute, &second);
-
-  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
-    {
-      timeunit = TUNIT_DAY;
-      timevalue *= 30;
-    }
-
-  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
-    {
-      int nmon, dpm;
-      double fmon;
+  __m128d current_max, current_min, work;
+  
+  // load starting max and min values into all slots of the XMM registers
+  current_min = _mm_set1_pd(*min);
+  current_max = _mm_set1_pd(*max);
+  
+  // work on input until buf reaches 16 byte alignment
+  while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) {
+    
+    // load one double and replicate
+    work = _mm_set1_pd(*buf);    
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);    
+    buf++;
+    nframes--;
+  }
+  
+  while (nframes >= 8) {
+    // use 64 byte prefetch for double octetts
+    // __builtin_prefetch(buf+64,0,0); // for GCC 4.3.2 +
 
-      if ( timeunit == TUNIT_YEAR ) timevalue *= 12;
+    work = _mm_load_pd(buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf += 2;
+    work = _mm_load_pd(buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf += 2;
+    work = _mm_load_pd(buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf += 2;
+    work = _mm_load_pd(buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf += 2;
+    nframes -= 8;
+  }
 
-      nmon = (int) timevalue;
-      fmon = timevalue - nmon;
+  // work through smaller chunks of aligned buffers without prefetching
+  while (nframes >= 2) {
+    work = _mm_load_pd(buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf += 2;
+    nframes -= 2;
+  }
 
-      month -= nmon;
+  // work through the remaining value
+  while ( nframes > 0) {
+    // load the last double and replicate
+    work = _mm_set1_pd(*buf);
+    current_min = _mm_min_pd(current_min, work);
+    current_max = _mm_max_pd(current_max, work);
+    buf++;
+    nframes--;
+  }
 
-      while ( month > 12 ) { month -= 12; year++; }
-      while ( month <  1 ) { month += 12; year--; }
+  // find final min and max value through shuffle tricks
+  work = current_min;
+  work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
+  work = _mm_min_pd (work, current_min);
+  _mm_store_sd(min, work);
+  work = current_max;
+  work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
+  work = _mm_max_pd (work, current_max);
+  _mm_store_sd(max, work);
 
-      dpm = days_per_month(calendar, year, month);
-      timeunit = TUNIT_DAY;
-      timevalue = fmon*dpm;
-    }
+  return;
+}
 
-  encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
+#endif // SIMD
 
-  cdiDecodeTimevalue(timeunit, timevalue, &days, &secs);
+#if defined(_ARCH_PWR6)
+static
+void pwr6_minmax_val_double_unrolled6(const double *restrict data, long idatasize, double *fmin, double *fmax)
+{
+#define __UNROLL_DEPTH_1 6
+  size_t datasize = idatasize;
 
-  julday_add(-days, -secs, &julday, &secofday);
+  // to allow pipelining we have to unroll 
 
-  decode_caldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+  {
+    size_t i, j;
+    size_t residual =  datasize % __UNROLL_DEPTH_1;
+    size_t ofs = datasize - residual;
+    double register dmin[__UNROLL_DEPTH_1];
+    double register dmax[__UNROLL_DEPTH_1];
 
-  (*taxis).fdate = cdiEncodeDate(year, month, day);
-  (*taxis).ftime = cdiEncodeTime(hour, minute, second);
-}
+    for ( j = 0; j < __UNROLL_DEPTH_1; j++) 
+      {
+	dmin[j] = data[0];
+	dmax[j] = data[0];
+      }
+    
+    for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_1 ) 
+      {
+	for (j = 0; j < __UNROLL_DEPTH_1; j++) 
+	  {
+	    dmin[j] = __fsel(dmin[j] - data[i+j], data[i+j], dmin[j]);
+	    dmax[j] = __fsel(data[i+j] - dmax[j], data[i+j], dmax[j]);
+	  }
+      }
 
+    for (j = 0; j < residual; j++) 
+      {
+	dmin[j] = __fsel(dmin[j] - data[ofs+j], data[ofs+j], dmin[j]);
+	dmax[j] = __fsel(data[ofs+j] - dmax[j], data[ofs+j], dmax[j]);
+      }
 
-void cdiDecodeTimeval(double timevalue, taxis_t *taxis, int *date, int *time)
-{
-  if ( taxis->type == TAXIS_ABSOLUTE )
-    splitTimevalue(timevalue, taxis->unit, date, time);
-  else
-    timeval2vtime(timevalue, taxis, date, time);
+    for ( j = 0; j < __UNROLL_DEPTH_1; j++) 
+      {
+	*fmin = __fsel(*fmin - dmin[j], dmin[j], *fmin);
+	*fmax = __fsel(dmax[j] - *fmax, dmax[j], *fmax);
+      }
+  }
+#undef __UNROLL_DEPTH_1
 }
+#endif
 
+#if defined(TEST_MINMAXVAL) && defined(__GNUC__)
+static
+void minmax_val_double_orig(const double *restrict data, long idatasize, double *fmin, double *fmax) __attribute__ ((noinline));
+static
+void minmax_val_double_simd(const double *restrict data, long idatasize, double *fmin, double *fmax) __attribute__ ((noinline));
+#endif
 
-double cdiEncodeTimeval(int date, int time, taxis_t *taxis)
+#if defined(GNUC_PUSH_POP)
+#pragma GCC push_options
+#pragma GCC optimize ("O3", "fast-math")
+#endif
+static
+void minmax_val_double_orig(const double *restrict data, long idatasize, double *fmin, double *fmax)
 {
-  double timevalue;
+  size_t i;
+  size_t datasize = idatasize;
+  double dmin = *fmin, dmax = *fmax;
 
-  if ( taxis->type == TAXIS_ABSOLUTE )
+#if   defined(CRAY)
+#pragma _CRI ivdep
+#elif defined(SX)
+#pragma vdir nodep
+#elif defined(__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+  for ( i = 0; i < datasize; ++i )
     {
-      if ( taxis->unit == TUNIT_YEAR )
-	{
-	  int year, month, day;
-	  cdiDecodeDate(date, &year, &month, &day);
-
-	  timevalue = year;
-	}
-      else if ( taxis->unit == TUNIT_MONTH )
-	{
-	  int year, month, day;
-	  cdiDecodeDate(date, &year, &month, &day);
-	  if ( day == 0 )
-	    timevalue = date/100;
-	  else
-	    timevalue = date/100 + 0.5;
-	}
-      else
-	{
-	  int hour, minute, second;
-	  cdiDecodeTime(time, &hour, &minute, &second);
-	  if ( date < 0 )
-	    timevalue = -(-date + (hour*3600 + minute*60 + second)/86400.);
-	  else
-	    timevalue =    date + (hour*3600 + minute*60 + second)/86400.;
-	}
+      dmin = dmin < data[i] ? dmin : data[i];
+      dmax = dmax > data[i] ? dmax : data[i];
     }
-  else
-    timevalue = vtime2timeval(date, time, taxis);
 
-  return (timevalue);
+  *fmin = dmin;
+  *fmax = dmax;
 }
 
-
-void ptaxisInit(taxis_t *taxisptr)
+static
+void minmax_val_float(const float *restrict data, long idatasize, float *fmin, float *fmax)
 {
-  taxisDefaultValue ( taxisptr );
+  size_t i;
+  size_t datasize = idatasize;
+  float dmin = *fmin, dmax = *fmax;
+
+#if   defined(CRAY)
+#pragma _CRI ivdep
+#elif defined(SX)
+#pragma vdir nodep
+#elif defined(__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+  for ( i = 0; i < datasize; ++i )
+    {
+      dmin = dmin < data[i] ? dmin : data[i];
+      dmax = dmax > data[i] ? dmax : data[i];
+    }
+
+  *fmin = dmin;
+  *fmax = dmax;
 }
+#if defined(GNUC_PUSH_POP)
+#pragma GCC pop_options
+#endif
 
+// TEST
+#if defined(OMP_SIMD)
 
-void ptaxisCopy(taxis_t *dest, taxis_t *source)
+//#pragma omp declare reduction(xmin : double : omp_out = omp_in > omp_out ? omp_out : omp_in) initializer( omp_priv = { 1.e300 })
+//#pragma omp declare reduction(xmax : double : omp_out = omp_in < omp_out ? omp_out : omp_in) initializer( omp_priv = { -1.e300 })
+
+#if defined(GNUC_PUSH_POP)
+#pragma GCC push_options
+#pragma GCC optimize ("O3", "fast-math")
+#endif
+static
+void minmax_val_double_simd(const double *restrict data, long idatasize, double *fmin, double *fmax)
 {
-  reshLock ();
+  size_t i;
+  size_t datasize = idatasize;
+  double dmin = *fmin, dmax = *fmax;
 
-  /* memcpy(dest, source, sizeof(taxis_t)); */
-  dest->used        = source->used;
-  dest->type        = source->type;
-  dest->vdate       = source->vdate;
-  dest->vtime       = source->vtime;
-  dest->rdate       = source->rdate;
-  dest->rtime       = source->rtime;
-  dest->fdate       = source->fdate;
-  dest->ftime       = source->ftime;
-  dest->calendar    = source->calendar;
-  dest->unit        = source->unit;
-  dest->numavg      = source->numavg;
-  dest->climatology = source->climatology;
-  dest->has_bounds  = source->has_bounds;
-  dest->vdate_lb    = source->vdate_lb;
-  dest->vtime_lb    = source->vtime_lb;
-  dest->vdate_ub    = source->vdate_ub;
-  dest->vtime_ub    = source->vtime_ub;
-  dest->fc_unit     = source->fc_unit;
-  dest->fc_period   = source->fc_period;
+#if defined(_OPENMP)
+  //#pragma omp simd reduction(xmin:dmin) reduction(xmax:dmax)
+#pragma omp simd
+#endif
+  for ( i = 0; i < datasize; ++i )
+    {
+      dmin = dmin < data[i] ? dmin : data[i];
+      dmax = dmax > data[i] ? dmax : data[i];
+    }
 
-  dest->climatology = source->climatology;
-  delete_refcount_string(dest->name);
-  delete_refcount_string(dest->longname);
-  dest->name = dup_refcount_string(source->name);
-  dest->longname = dup_refcount_string(source->longname);
-  if (dest->self != CDI_UNDEFID)
-    reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
-  reshUnlock ();
+  *fmin = dmin;
+  *fmax = dmax;
 }
+#if defined(GNUC_PUSH_POP)
+#pragma GCC pop_options
+#endif
+#endif
 
-
-static void
-taxisPrintKernel(taxis_t * taxisptr, FILE * fp)
+static
+void minmax_val_double(const double *restrict data, long idatasize, double *fmin, double *fmax)
 {
-  int vdate_lb, vdate_ub;
-  int vtime_lb, vtime_ub;
+#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER) 
+  uint64_t start_minmax, end_minmax;
+#endif
+  size_t datasize = idatasize;
 
-  taxisInqVdateBounds ( taxisptr->self, &vdate_lb, &vdate_ub);
-  taxisInqVtimeBounds ( taxisptr->self, &vtime_lb, &vtime_ub);
+  if ( idatasize < 1 ) return;
 
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "# taxisID %d\n", taxisptr->self);
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "self        = %d\n", taxisptr->self );
-  fprintf ( fp, "used        = %d\n", taxisptr->used );
-  fprintf ( fp, "type        = %d\n", taxisptr->type );
-  fprintf ( fp, "vdate       = %d\n", taxisptr->vdate );
-  fprintf ( fp, "vtime       = %d\n", taxisptr->vtime );
-  fprintf ( fp, "rdate       = %d\n", taxisptr->rdate );
-  fprintf ( fp, "rtime       = %d\n", taxisptr->rtime );
-  fprintf ( fp, "fdate       = %d\n", taxisptr->fdate );
-  fprintf ( fp, "ftime       = %d\n", taxisptr->ftime );
-  fprintf ( fp, "calendar    = %d\n", taxisptr->calendar );
-  fprintf ( fp, "unit        = %d\n", taxisptr->unit );
-  fprintf ( fp, "numavg      = %d\n", taxisptr->numavg );
-  fprintf ( fp, "climatology = %d\n", taxisptr->climatology );
-  fprintf ( fp, "has_bounds  = %d\n", taxisptr->has_bounds );
-  fprintf ( fp, "vdate_lb    = %d\n", vdate_lb );
-  fprintf ( fp, "vtime_lb    = %d\n", vtime_lb );
-  fprintf ( fp, "vdate_ub    = %d\n", vdate_ub );
-  fprintf ( fp, "vtime_ub    = %d\n", vtime_ub );
-  fprintf ( fp, "fc_unit     = %d\n", taxisptr->fc_unit );
-  fprintf ( fp, "fc_period   = %g\n", taxisptr->fc_period );
-  fprintf ( fp, "\n");
-}
+#if defined(_GET_X86_COUNTER) 
+  start_minmax = _rdtsc();
+#endif
+#if defined(_GET_MACH_COUNTER) 
+  start_minmax = mach_absolute_time();
+#endif
 
-void taxisPrint ( int taxisID )
-{
-  taxis_t * taxisptr;
+#if defined(_ENABLE_AVX)
 
-  taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-  taxisPrintKernel ( taxisptr, stdout );
-}
+  avx_minmax_val_double(data, datasize, fmin, fmax);
 
-static int
-taxisCompareP(void *taxisptr1, void *taxisptr2)
-{
-  taxis_t * t1, * t2;
+#elif defined(_ENABLE_SSE2)
 
-  t1 = ( taxis_t * ) taxisptr1;
-  t2 = ( taxis_t * ) taxisptr2;
+  sse2_minmax_val_double(data, datasize, fmin, fmax);
 
-  xassert ( t1 );
-  xassert ( t2 );
+#else
 
-  return ! ( t1->used        == t2->used        &&
-	     t1->type        == t2->type        &&
-	     t1->vdate       == t2->vdate       &&
-	     t1->vtime       == t2->vtime       &&
-	     t1->rdate       == t2->rdate       &&
-	     t1->rtime       == t2->rtime       &&
-	     t1->fdate       == t2->fdate       &&
-	     t1->ftime       == t2->ftime       &&
-	     t1->calendar    == t2->calendar    &&
-	     t1->unit        == t2->unit        &&
-	     t1->fc_unit     == t2->fc_unit     &&
-	     t1->numavg      == t2->numavg      &&
-	     t1->climatology == t2->climatology &&
-	     t1->has_bounds  == t2->has_bounds  &&
-	     t1->vdate_lb    == t2->vdate_lb    &&
-	     t1->vtime_lb    == t2->vtime_lb    &&
-	     t1->vdate_ub    == t2->vdate_ub    &&
-	     t1->vtime_ub    == t2->vtime_ub );
-}
+#if defined(_ARCH_PWR6)
+#define __UNROLL_DEPTH_1 6
 
+  // to allow pipelining we have to unroll 
 
-static int
-taxisTxCode ( void )
-{
-  return TAXIS;
-}
+#if defined(_GET_IBM_COUNTER)
+  hpmStart(1, "minmax fsel");
+#endif
 
-enum { taxisNint = 21 };
+  pwr6_minmax_val_double_unrolled6(data, datasize, fmin, fmax);
 
-static int
-taxisGetPackSize(void *p, void *context)
-{
-  taxis_t *taxisptr = (taxis_t*) p;
-  int packBufferSize
-    = serializeGetSize(taxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_UINT32, context)
-    + (taxisptr->name ?
-       serializeGetSize((int)strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
-    + (taxisptr->longname ?
-       serializeGetSize((int)strlen(taxisptr->longname), DATATYPE_TXT,
-                        context) : 0);
-  return packBufferSize;
-}
+#if defined(_GET_IBM_COUNTER) 
+  hpmStop(1);
+#endif
 
-int
-taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
-            int originNamespace, void *context, int force_id)
-{
-  taxis_t * taxisP;
-  int intBuffer[taxisNint];
-  uint32_t d;
-  int idx = 0;
+#undef __UNROLL_DEPTH_1
 
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, taxisNint, DATATYPE_INT, context);
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_UINT32, context);
+#else // original loop
 
-  xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
+#if defined(_GET_IBM_COUNTER) 
+  hpmStart(1, "minmax base");
+#endif
 
-  taxisInit();
+  minmax_val_double_orig(data, datasize, fmin, fmax);
 
-  cdiResH targetID = namespaceAdaptKey(intBuffer[idx++], originNamespace);
-  taxisP = taxisNewEntry(force_id?targetID:CDI_UNDEFID);
+#if defined(_GET_IBM_COUNTER) 
+  hpmStop(1);
+#endif
 
-  xassert(!force_id || targetID == taxisP->self);
+#endif // _ARCH_PWR6 && original loop
+#endif // SIMD
 
-  taxisP->used        = intBuffer[idx++];
-  taxisP->type        = intBuffer[idx++];
-  taxisP->vdate       = intBuffer[idx++];
-  taxisP->vtime       = intBuffer[idx++];
-  taxisP->rdate       = intBuffer[idx++];
-  taxisP->rtime       = intBuffer[idx++];
-  taxisP->fdate       = intBuffer[idx++];
-  taxisP->ftime       = intBuffer[idx++];
-  taxisP->calendar    = intBuffer[idx++];
-  taxisP->unit        = intBuffer[idx++];
-  taxisP->fc_unit     = intBuffer[idx++];
-  taxisP->numavg      = intBuffer[idx++];
-  taxisP->climatology = intBuffer[idx++];
-  taxisP->has_bounds  = intBuffer[idx++];
-  taxisP->vdate_lb    = intBuffer[idx++];
-  taxisP->vtime_lb    = intBuffer[idx++];
-  taxisP->vdate_ub    = intBuffer[idx++];
-  taxisP->vtime_ub    = intBuffer[idx++];
+#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
+#if defined(_GET_X86_COUNTER) 
+  end_minmax = _rdtsc();
+#endif
+#if defined(_GET_MACH_COUNTER) 
+  end_minmax = mach_absolute_time();
+#endif
+#if defined(_ENABLE_AVX)
+  printf("AVX minmax cycles:: %" PRIu64 "\n",  end_minmax-start_minmax);
+  fprintf (stderr, "AVX min: %lf max: %lf\n", *fmin, *fmax);
+#elif defined(_ENABLE_SSE2)
+  printf("SSE2 minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+  fprintf (stderr, "SSE2 min: %lf max: %lf\n", *fmin, *fmax);
+#else
+  printf("loop minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+  fprintf (stderr, "loop min: %lf max: %lf\n", *fmin, *fmax);
+#endif
+#endif
 
-  if (intBuffer[idx])
-    {
-      int len = intBuffer[idx];
-      char *name = new_refcount_string((size_t)len);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      name, len, DATATYPE_TXT, context);
-      name[len] = '\0';
-      taxisP->name = name;
-    }
-  idx++;
-  if (intBuffer[idx])
-    {
-      int len = intBuffer[idx];
-      char *longname = new_refcount_string((size_t)len);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      longname, len, DATATYPE_TXT, context);
-      longname[len] = '\0';
-      taxisP->longname = longname;
-    }
+  return;
+}
 
-  return taxisP->self;
+#if defined(TEST_MINMAXVAL)
+
+#include <stdio.h>
+#include <sys/time.h>
+
+static
+double dtime()
+{
+  double tseconds = 0.0;
+  struct timeval mytime;
+  gettimeofday(&mytime, NULL);
+  tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
+  return (tseconds);
 }
 
+#define NRUN 10000
 
-static void
-taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferPos,
-          void *context)
+int main(void)
 {
-  taxis_t *taxisP = (taxis_t *)voidP;
-  int intBuffer[taxisNint];
-  uint32_t d;
-  int idx = 0;
+  long datasize = 1000000;
+  double t_begin, t_end;
 
-  intBuffer[idx++] = taxisP->self;
-  intBuffer[idx++] = taxisP->used;
-  intBuffer[idx++] = taxisP->type;
-  intBuffer[idx++] = taxisP->vdate;
-  intBuffer[idx++] = taxisP->vtime;
-  intBuffer[idx++] = taxisP->rdate;
-  intBuffer[idx++] = taxisP->rtime;
-  intBuffer[idx++] = taxisP->fdate;
-  intBuffer[idx++] = taxisP->ftime;
-  intBuffer[idx++] = taxisP->calendar;
-  intBuffer[idx++] = taxisP->unit;
-  intBuffer[idx++] = taxisP->fc_unit;
-  intBuffer[idx++] = taxisP->numavg;
-  intBuffer[idx++] = taxisP->climatology;
-  intBuffer[idx++] = taxisP->has_bounds;
-  intBuffer[idx++] = taxisP->vdate_lb;
-  intBuffer[idx++] = taxisP->vtime_lb;
-  intBuffer[idx++] = taxisP->vdate_ub;
-  intBuffer[idx++] = taxisP->vtime_ub;
-  intBuffer[idx++] = taxisP->name ? (int)strlen(taxisP->name) : 0;
-  intBuffer[idx++] = taxisP->longname ? (int)strlen(taxisP->longname) : 0;
+#if   defined(_OPENMP)
+  printf("_OPENMP=%d\n", _OPENMP);
+#endif
 
-  serializePack(intBuffer, taxisNint, DATATYPE_INT,
-                packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_UINT32,
-                packBuffer, packBufferSize, packBufferPos, context);
-  if (taxisP->name)
-    serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
-                  packBuffer, packBufferSize, packBufferPos, context);
-  if (taxisP->longname)
-    serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
-                  packBuffer, packBufferSize, packBufferPos, context);
+#if   defined(__ICC)
+  printf("icc\n");
+#elif defined(__clang__)
+  printf("clang\n");
+#elif defined(__GNUC__)
+  printf("gcc\n");
+#endif
 
-}
+  {
+    float fmin, fmax;
+    float *data_sp = (float*) malloc(datasize*sizeof(float));
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <stdio.h>
-#include <stdint.h>
-#include <math.h>		/* for floor() */
+    for ( long i = 0; i < datasize/2; i++ )        data_sp[i] = (float) (i);
+    for ( long i = datasize/2; i < datasize; i++ ) data_sp[i] = (float) (-datasize + i);
 
+    printf("float:\n");
 
-/* convert Julian date into year, months, day */
-void decode_julday(int calendar,
-		   int julday,	/* Julian day number to convert */
-		   int *year,	/* Gregorian year (out)         */
-		   int *mon,	/* Gregorian month (1-12) (out) */
-		   int *day)	/* Gregorian day (1-31) (out)   */
-{
-  int a = julday;
-  double b, c;
-  double d, e, f;
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_sp[0];
+	minmax_val_float(data_sp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("minmax_val: fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+    free(data_sp);
+  }
+
+  {
+    double fmin, fmax;
+    double *data_dp = (double*) malloc(datasize*sizeof(double));
+
+    // for ( long i = datasize-1; i >= 0; i-- ) data[i] = (double) (-datasize/2 + i);
+    for ( long i = 0; i < datasize/2; i++ )        data_dp[i] = (double) (i);
+    for ( long i = datasize/2; i < datasize; i++ ) data_dp[i] = (double) (-datasize + i);
 
-  b = floor((a - 1867216.25)/36524.25);
-  c = a + b - floor(b/4) + 1525;
+    printf("double:\n");
 
-  if ( calendar == CALENDAR_STANDARD )
-    if ( a < 2299161 )
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
       {
-	c = a + 1524;
-      } 
+	fmin = fmax = data_dp[0];
+	minmax_val_double(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("minmax_val: fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
 
-  d = floor((c - 122.1)/365.25);
-  e = floor(365.25*d);
-  f = floor((c - e)/30.6001);
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_dp[0];
+	minmax_val_double_orig(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("orig      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
 
-  *day  = (int)(c - e - floor(30.6001*f));
-  *mon  = (int)(f - 1 - 12*floor(f/14));
-  *year = (int)(d - 4715 - floor((7 + *mon)/10));
+#if defined(OMP_SIMD)
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_dp[0];
+	minmax_val_double_simd(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("simd      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
+
+#if defined(_ENABLE_AVX)
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_dp[0];
+	avx_minmax_val_double(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("avx       : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#elif defined(_ENABLE_SSE2)
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_dp[0];
+	sse2_minmax_val_double(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("sse2      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
+#if defined(_ARCH_PWR6)
+    t_begin = dtime();
+    for ( int i = 0; i < NRUN; ++i )
+      {
+	fmin = fmax = data_dp[0];
+	pwr6_minmax_val_double_unrolled6(data_dp, datasize, &fmin, &fmax);
+      }
+    t_end = dtime();
+    printf("pwr6u6  : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+#endif
+    free(data_dp);
+  }
+
+  return (0);
 }
+#endif // TEST_MINMAXVAL
 
+#undef DISABLE_SIMD
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE2
+#undef GNUC_PUSH_POP
+/* 
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
+ result on hama (gcc 4.8.2):
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 16.0471s
+  sse41   : val1: 1  val2: 1  val3: 2  valn: 66  time: 15.4391s
 
-/* convert year, month, day into Julian calendar day */
-int encode_julday(int calendar, int year, int month, int day)
-{
-  int iy;
-  int im;
-  int ib;
-  int julday;
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
+ result on bailung (gcc 4.7):
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 8.4166s
+  sse41   : val1: 1  val2: 1  val3: 2  valn: 66  time: 7.1522s
 
-  if ( month <= 2 )
-    {
-      iy = year  - 1;
-      im = month + 12;
-    }
-  else
-    {
-      iy = year;
-      im = month;
-    }
+gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
+ result on thunder5 (gcc 4.7):
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 6.21976s
+  avx     : val1: 1  val2: 1  val3: 2  valn: 66  time: 4.54485s
 
+icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_ENCODE encode_array.c
+ result on thunder5 (icc 13.2):
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 14.6279s
+  avx     : val1: 1  val2: 1  val3: 2  valn: 66  time:  4.9776s
 
-  if ( iy < 0 )
-    ib = (int)((iy+1)/400) - (int)((iy+1)/100);
-  else
-    ib = (int)(iy/400) - (int)(iy/100);
+xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_ENCODE encode_array.c
+ result on blizzard (xlc 12):
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 132.25s
+  unrolled: val1: 1  val2: 1  val3: 2  valn: 66  time:  27.202s
+  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 106.627s  // without -qhot
+  unrolled: val1: 1  val2: 1  val3: 2  valn: 66  time:  39.929s  // without -qhot
+*/
+#ifdef _ARCH_PWR6
+#pragma options nostrict
+#endif
 
-  if ( calendar == CALENDAR_STANDARD )
-    {
-      if ( year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15))) )
-	{
-	  /*
-	  ** 15th October 1582 AD or later
-	  */
-	}
-      else
-	{
-	  /*
-	  ** 4th October 1582 AD or earlier
-	  */
-	  ib = -2;
-	}
-    }
+#ifdef TEST_ENCODE
+#include <stdio.h>
+#include <stdlib.h>
+#define  GRIBPACK     unsigned char
+#define  IS_BIGENDIAN()  (u_byteorder.c[sizeof(long) - 1])
+#define  U_BYTEORDER     static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
+#define  Error(x,y)
+#endif
 
-  julday = (int) (floor(365.25*iy) + (int)(30.6001*(im+1)) + ib + 1720996.5 + day + 0.5);
+//#undef _GET_X86_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _ARCH_PWR6
 
-  return (julday);
-}
+#if defined _GET_IBM_COUNTER
+#include <libhpc.h>
+#elif defined _GET_X86_COUNTER
+#include <x86intrin.h>
+#elif defined _GET_MACH_COUNTER
+#include <mach/mach_time.h>
+#endif
 
+#include <stdint.h>
 
-int date_to_julday(int calendar, int date)
-{
-  int julday;
-  int year, month, day;
+#if   defined(__GNUC__) && (__GNUC__ >= 4)
+#elif defined(__ICC)    && (__ICC >= 1100)
+#elif defined(__clang__)
+#else
+#define DISABLE_SIMD
+#endif
 
-  cdiDecodeDate(date, &year, &month, &day);
+//#define DISABLE_SIMD
 
-  julday = encode_julday(calendar, year, month, day);
+#ifdef DISABLE_SIMD
+# ifdef ENABLE_AVX
+#  define _ENABLE_AVX
+# endif
+# ifdef ENABLE_SSE4_1
+#  define _ENABLE_SSE4_1
+# endif
+#endif
 
-  return (julday);
-}
+#ifndef DISABLE_SIMD
+# ifdef __AVX__
+#  define _ENABLE_AVX
+# endif
+# ifdef __SSE4_1__
+#  define _ENABLE_SSE4_1
+# endif
+#endif
+
+#if defined _ENABLE_AVX
+#include <immintrin.h>
+#elif defined _ENABLE_SSE4_1
+#include <smmintrin.h>
+#endif
 
+#if defined _ENABLE_AVX
 
-int julday_to_date(int calendar, int julday)
+static
+void avx_encode_array_2byte_double(size_t datasize, 
+				   unsigned char * restrict lGrib,
+				   const double * restrict data, 
+				   double zref, double factor, size_t *gz) 
 {
-  int date;
-  int year, month, day;
+  size_t i, j, residual;
+  const double *dval = data;
+  __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
-  decode_julday(calendar, julday, &year, &month, &day);
+  const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
 
-  date = cdiEncodeDate(year, month, day);
+  const __m256d c0 = _mm256_set1_pd(zref);
+  const __m256d c1 = _mm256_set1_pd(factor);
+  const __m256d c2 = _mm256_set1_pd(0.5);
+  
+  __m256d d0, d3, d2, d1;
+  __m128i i0, i1, i2, i3;
+  __m128i s0, s1;  
 
-  return (date);
-}
+  residual = datasize % 16;
 
+  for (i = 0; i < (datasize-residual); i += 16)
+    {
+      (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
+      //_____________________________________________________________________________
 
-int time_to_sec(int time)
-{
-  int secofday;
-  int hour, minute, second;
+      d0 = _mm256_loadu_pd (dval);
+      d0 = _mm256_sub_pd (d0, c0);
+      d0 = _mm256_mul_pd (d0, c1);
+      d0 = _mm256_add_pd (d0, c2);
 
-  cdiDecodeTime(time, &hour, &minute, &second);
+      i0 = _mm256_cvttpd_epi32 (d0);
+      
+      //_____________________________________________________________________________
+      
+      d1 = _mm256_loadu_pd (dval+4);
+      d1 = _mm256_sub_pd (d1, c0);
+      d1 = _mm256_mul_pd (d1, c1);
+      d1 = _mm256_add_pd (d1, c2);
+      
+      i1 = _mm256_cvttpd_epi32 (d1);
 
-  secofday = hour*3600 + minute*60 + second;
+      //_____________________________________________________________________________
 
-  return (secofday);
-}
+      s0 = _mm_packus_epi32(i0, i1);
+      s0 = _mm_shuffle_epi8 (s0, swap);
+      (void) _mm_storeu_si128 (sgrib, s0);
 
+      //_____________________________________________________________________________
 
-int sec_to_time(int secofday)
-{
-  int time;
-  int hour, minute, second;
+      (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
 
-  hour   = secofday/3600;
-  minute = secofday/60 - hour*60;
-  second = secofday - hour*3600 - minute*60;
+      //_____________________________________________________________________________
+      
+      d2 = _mm256_loadu_pd (dval+8);
+      d2 = _mm256_sub_pd (d2, c0);
+      d2 = _mm256_mul_pd (d2, c1);
+      d2 = _mm256_add_pd (d2, c2);
+      
+      i2 = _mm256_cvttpd_epi32 (d2);
 
-  time = cdiEncodeTime(hour, minute, second);
+      //_____________________________________________________________________________
+      
+      d3 = _mm256_loadu_pd (dval+12);
+      d3 = _mm256_sub_pd (d3, c0);
+      d3 = _mm256_mul_pd (d3, c1);
+      d3 = _mm256_add_pd (d3, c2);
+      
+      i3 = _mm256_cvttpd_epi32 (d3);
 
-  return (time);
-}
+      //_____________________________________________________________________________
 
-static
-void adjust_seconds(int *julday, int64_t *secofday)
-{
-  int64_t secperday = 86400;
+      s1 = _mm_packus_epi32(i2, i3);
+      s1 = _mm_shuffle_epi8 (s1, swap);
+      (void) _mm_storeu_si128 (sgrib+1, s1);
 
-  while ( *secofday >= secperday ) 
-    { 
-      *secofday -= secperday; 
-      (*julday)++;
+      //_____________________________________________________________________________
+           
+      dval += 16;
+      sgrib += 2;
     }
 
-  while ( *secofday <  0 ) 
-    { 
-      *secofday += secperday;
-      (*julday)--;
+  if (i != datasize)
+    {
+      uint16_t ui16;
+      for ( j = i; j < datasize; j++ )
+	{
+	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
+	  lGrib[*gz+2*j  ] = ui16 >>  8;
+	  lGrib[*gz+2*j+1] = ui16;
+	}
     }
-}
+  
+  *gz += 2*datasize;
 
+  return;
+}
 
-void julday_add_seconds(int64_t seconds, int *julday, int *secofday)
-{
-  int64_t sec_of_day = *secofday;
+#define grib_encode_array_2byte_double avx_encode_array_2byte_double
 
-  sec_of_day += seconds;
+#elif defined _ENABLE_SSE4_1
 
-  adjust_seconds(julday, &sec_of_day);
+static
+void sse41_encode_array_2byte_double(size_t datasize, 
+				     unsigned char * restrict lGrib,
+				     const double * restrict data, 
+				     double zref, double factor, size_t *gz) 
+{
+  size_t i, j, residual;
+  const double *dval = data;
+  __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
-  *secofday = (int) sec_of_day;
-}
+  const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
 
-/* add days and secs to julday/secofday */
-void julday_add(int days, int secs, int *julday, int *secofday)
-{
-  int64_t sec_of_day = *secofday;
+  const __m128d c0 = _mm_set1_pd(zref);
+  const __m128d c1 = _mm_set1_pd(factor);
+  const __m128d c2 = _mm_set1_pd(0.5);
+  
+  __m128d d0, d4, d3, d2, d1;
+  __m128i i0, i1, i2, i3, i4;
+  __m128i s0, s1;  
 
-  sec_of_day += secs;
-  *julday    += days;
+  residual = datasize % 16;
 
-  adjust_seconds(julday, &sec_of_day);
+  for (i = 0; i < (datasize-residual); i += 16)
+    {
+      (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
+      //_____________________________________________________________________________
 
-  *secofday = (int) sec_of_day;
-}
+      d0 = _mm_loadu_pd (dval);
+      d0 = _mm_sub_pd (d0, c0);
+      d0 = _mm_mul_pd (d0, c1);
+      d0 = _mm_add_pd (d0, c2);
+      
+      d4 = _mm_loadu_pd (dval+2);
+      d4 = _mm_sub_pd (d4, c0);
+      d4 = _mm_mul_pd (d4, c1);
+      d4 = _mm_add_pd (d4, c2);
 
-/* subtract julday1/secofday1 from julday2/secofday2 and returns the result in seconds */
-double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs)
-{
-  int64_t sec_of_day;
-  int64_t seconds;
+      i0 = _mm_cvttpd_epi32 (d0);
+      i4 = _mm_cvttpd_epi32 (d4);  
+      i0 = _mm_unpacklo_epi64 (i0, i4);
 
-  *days = julday2 - julday1;
-  *secs = secofday2 - secofday1;
+      //_____________________________________________________________________________
+      
+      d1 = _mm_loadu_pd (dval+4);
+      d1 = _mm_sub_pd (d1, c0);
+      d1 = _mm_mul_pd (d1, c1);
+      d1 = _mm_add_pd (d1, c2);
+      
+      d4 = _mm_loadu_pd (dval+6);
+      d4 = _mm_sub_pd (d4, c0);
+      d4 = _mm_mul_pd (d4, c1);
+      d4 = _mm_add_pd (d4, c2);
+      
+      i1 = _mm_cvttpd_epi32 (d1);
+      i4 = _mm_cvttpd_epi32 (d4);  
+      i1 = _mm_unpacklo_epi64 (i1, i4);
 
-  sec_of_day = *secs;
+      //_____________________________________________________________________________
 
-  adjust_seconds(days, &sec_of_day);
+      s0 = _mm_packus_epi32(i0, i1);
+      s0 = _mm_shuffle_epi8 (s0, swap);
+      (void) _mm_storeu_si128 (sgrib, s0);
 
-  *secs = (int) sec_of_day;
+      //_____________________________________________________________________________
 
-  seconds = *days * 86400 + sec_of_day;
+      (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
 
-  return (double)seconds;
-}
+      //_____________________________________________________________________________
+      
+      d2 = _mm_loadu_pd (dval+8);
+      d2 = _mm_sub_pd (d2, c0);
+      d2 = _mm_mul_pd (d2, c1);
+      d2 = _mm_add_pd (d2, c2);
+      
+      d4 = _mm_loadu_pd (dval+10);
+      d4 = _mm_sub_pd (d4, c0);
+      d4 = _mm_mul_pd (d4, c1);
+      d4 = _mm_add_pd (d4, c2);
+      
+      i2 = _mm_cvttpd_epi32 (d2);
+      i4  = _mm_cvttpd_epi32 (d4);  
+      i2 = _mm_unpacklo_epi64 (i2, i4);
 
+      //_____________________________________________________________________________
+      
+      d3 = _mm_loadu_pd (dval+12);
+      d3 = _mm_sub_pd (d3, c0);
+      d3 = _mm_mul_pd (d3, c1);
+      d3 = _mm_add_pd (d3, c2);
+      
+      d4 = _mm_loadu_pd (dval+14);
+      d4 = _mm_sub_pd (d4, c0);
+      d4 = _mm_mul_pd (d4, c1);
+      d4 = _mm_add_pd (d4, c2);
+      
+      i3 = _mm_cvttpd_epi32 (d3);
+      i4 = _mm_cvttpd_epi32 (d4);  
+      i3 = _mm_unpacklo_epi64 (i3, i4);
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday)
-{
-  *julday = encode_julday(calendar, year, month, day);
+      //_____________________________________________________________________________
 
-  *secofday = (hour*60 + minute)*60 + second;
-}
+      s1 = _mm_packus_epi32(i2, i3);
+      s1 = _mm_shuffle_epi8 (s1, swap);
+      (void) _mm_storeu_si128 (sgrib+1, s1);
 
+      //_____________________________________________________________________________
+           
+      dval += 16;
+      sgrib += 2;
+    }
 
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second)
-{
-  decode_julday(calendar, julday, year, month, day);
+  if (i != datasize) 
+    {
+      uint16_t ui16;
+      for ( j = i; j < datasize; j++ )
+	{
+	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
+	  lGrib[*gz+2*j  ] = ui16 >>  8;
+	  lGrib[*gz+2*j+1] = ui16;
+	}
+    }
 
-  *hour   = secofday/3600;
-  *minute = secofday/60 - *hour*60;
-  *second = secofday - *hour*3600 - *minute*60;
+  *gz += 2*datasize;
+  
+  return;
 }
 
+#define grib_encode_array_2byte_double sse41_encode_array_2byte_double
 
-#ifdef TEST
-int main(void)
-{
-  int nmin;
-  int vdate0, vtime0;
-  int vdate, vtime;
-  int ijulinc;
-  int i, j = 0;
-  int year, mon, day, hour, minute, second;
-  int julday, secofday;
-  int calendar = CALENDAR_STANDARD;
+#else
 
-  /* 1 - Check valid range of years */
+#define grib_encode_array_2byte_double encode_array_2byte_double
 
-  nmin = 11000;
-  vdate0 = -80001201;
-  vtime0 = 120500;
+#endif // SIMD variants
 
-  printf("start time: %8d %4d\n", vdate0, vtime0);
 
-  for ( i = 0; i < nmin; i++ )
-    {
-      cdiDecodeDate(vdate0, &year, &mon, &day);
-      cdiDecodeTime(vtime0, &hour, &minute, &second);
+#ifdef TEST_ENCODE
 
-      julday  = date_to_julday(calendar, vdate0);
-      secofday = time_to_sec(vtime0);
+#define CAT(X,Y)      X##_##Y
+#define TEMPLATE(X,Y) CAT(X,Y)
 
-      vdate = julday_to_date(calendar, julday);
-      vtime = sec_to_time(secofday);
+#ifdef T
+#undef T
+#endif
+#define T double
 
-      if ( vdate0 != vdate || vtime0 != vtime )
-	printf("%4d %8d %4d %8d %4d %9d %9d\n",
-	       ++j, vdate0, vtime0, vdate, vtime, julday, secofday);
+#ifdef T
+#undef T
+#endif
+#define T float
 
-      year++;
-      vdate0 = cdiEncodeDate(year, mon, day);
-      vtime0 = cdiEncodeTime(hour, minute, second);
-    }
 
-  printf("stop time: %8d %4d\n", vdate0, vtime0);
+#include <sys/time.h>
 
-  /* 2 - Check time increment of one minute */
+static
+double dtime()
+{
+  double tseconds = 0.0;
+  struct timeval mytime;
+  gettimeofday(&mytime, NULL);
+  tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
+  return (tseconds);
+}
 
-  nmin = 120000;
-  ijulinc = 60;
-  vdate0 = 20001201;
-  vtime0 = 0;
+#define NRUN 10000
 
-  printf("start time: %8d %4d\n", vdate0, vtime0);
+static
+void pout(char *name, int s, unsigned char *lgrib, long datasize, double tt)
+{
+  printf("%8s: val1: %d  val2: %d  val3: %d  valn: %d  time: %gs\n", name, (int) lgrib[s*1+1], (int) lgrib[s*2+1], (int) lgrib[s*3+1], (int) lgrib[2*datasize-1], tt);
+}
 
-  julday = date_to_julday(calendar, vdate0);
-  secofday = time_to_sec(vtime0);
-  for ( i = 0; i < nmin; i++ )
-    {
-      cdiDecodeDate(vdate0, &year, &mon, &day);
-      cdiDecodeTime(vtime0, &hour, &minute, &second);
+int main(void)
+{
+  long datasize = 1000000;
+  float *dataf = NULL;
+  double *data = NULL;
+  double t_begin, t_end;
+  unsigned char *lgrib;
 
-      if ( ++minute >= 60 )
-	{
-	  minute = 0;
-	  if ( ++hour >= 24 )
-	    {
-	      hour = 0;
-	      if ( ++day >= 32 )
-		{
-		  day = 1;
-		  if ( ++mon >= 13 )
-		    {
-		      mon = 1;
-		      year++;
-		    }
-		}
-	    }
-	}
+  dataf = (float*) malloc(datasize*sizeof(float));
+  data  = (double*) malloc(datasize*sizeof(double));
+  lgrib = (unsigned char*) malloc(2*datasize*sizeof(unsigned char));
 
-      vdate0 = cdiEncodeDate(year, mon, day);
-      vtime0 = cdiEncodeTime(hour, minute, second);
+  for ( long i = 0; i < datasize; ++i ) dataf[i] = (float) (-datasize/2 + i);
+  for ( long i = 0; i < datasize; ++i ) data[i] = (double) (-datasize/2 + i);
 
-      julday_add_seconds(ijulinc, &julday, &secofday);
+  int PackStart = 0;
+  int nbpv = 16;
+  double zref = data[0];
+  size_t z;
+  double factor = 0.00390625;
+  int s = 256;
 
-      vdate = julday_to_date(calendar, julday);
-      vtime = sec_to_time(secofday);
-      if ( vdate0 != vdate || vtime0 != vtime )
-	printf("%4d %8d %4d %8d %4d %9d %9d\n",
-	       ++j, vdate0, vtime0, vdate, vtime, julday, secofday);
+  if ( 0 )
+    {
+      encode_array_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
+      encode_array_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
     }
 
-  printf("stop time: %8d %4d\n", vdate0, vtime0);
 
-  return (0);
-}
+#if   defined(__ICC)
+  printf("icc\n");
+#elif defined(__clang__)
+  printf("clang\n");
+#elif defined(__GNUC__)
+  printf("gcc\n");
 #endif
 
+  printf("float:\n");
 
-#ifdef TEST2
-int main(void)
-{
-  int i;
-  int julday, secofday;
-  int year, month, day, hour, minute, second;
-  int value = 30;
-  int factor = 86400;
-  int calendar = CALENDAR_STANDARD;
-
-  year=1979; month=1; day=15; hour=12; minute=30, second=17;
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
+    {
+      z = 0;
+      encode_array_2byte_float(datasize, lgrib, dataf, (float)zref, (float)factor, &z);
+    }
+  t_end = dtime();
+  pout("orig", s, lgrib, datasize, t_end-t_begin);
 
-  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
+    {
+      z = 0;
+      encode_array_unrolled_float(nbpv, PackStart, datasize, lgrib, dataf, (float)zref, (float)factor, &z);
+    }
+  t_end = dtime();
+  pout("unrolled", s, lgrib, datasize, t_end-t_begin);
 
-  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
+  printf("double:\n");
 
-  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
-  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, julday, secofday);
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
+    {
+      z = 0;
+      encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
+    }
+  t_end = dtime();
+  pout("orig", s, lgrib, datasize, t_end-t_begin);
 
-  for ( i = 0; i < 420; i++ )
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
     {
+      z = 0;
+      encode_array_unrolled_double(nbpv, PackStart, datasize, lgrib, data, zref, factor, &z);
+    }
+  t_end = dtime();
+  pout("unrolled", s, lgrib, datasize, t_end-t_begin);
 
-      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
-      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
-      julday_add_seconds(value*factor, &julday, &secofday);
+#if defined _ENABLE_AVX
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
+    {
+      z = 0;
+      avx_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
+    }
+  t_end = dtime();
+  pout("avx", s, lgrib, datasize, t_end-t_begin);
+#elif defined _ENABLE_SSE4_1
+  t_begin = dtime();
+  for ( int i = 0; i < NRUN; ++i )
+    {
+      z = 0;
+      sse41_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
     }
+  t_end = dtime();
+  pout("sse41", s, lgrib, datasize, t_end-t_begin);
+#endif
 
-  return (0);
+  return 0;
 }
-#endif
-#include <limits.h>
-#include <stdio.h>
+#endif // TEST_ENCODE
 
+#undef DISABLE_SIMD
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE4_1
+//#undef _GET_X86_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _ARCH_PWR6
 
+#if defined _GET_IBM_COUNTER
+#include <libhpc.h>
+#elif defined _GET_X86_COUNTER
+#include <x86intrin.h>
+#elif defined _GET_MACH_COUNTER
+#include <mach/mach_time.h>
+#endif
 
-static int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
-static int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
+#if   defined(__GNUC__) && (__GNUC__ >= 4)
+#elif defined(__ICC)    && (__ICC >= 1100)
+#elif defined(__clang__)
+#else
+#define DISABLE_SIMD
+#endif
 
-int calendar_dpy(int calendar)
-{
-  int dpy = 0;
+#define DISABLE_SIMD
 
-  if      ( calendar == CALENDAR_360DAYS ) dpy = 360;
-  else if ( calendar == CALENDAR_365DAYS ) dpy = 365;
-  else if ( calendar == CALENDAR_366DAYS ) dpy = 366;
+#ifdef DISABLE_SIMD
+# ifdef ENABLE_AVX
+#  define _ENABLE_AVX
+# endif
+# ifdef ENABLE_SSE4_1
+#  define _ENABLE_SSE4_1
+# endif
+#endif
 
-  return (dpy);
-}
+#ifndef DISABLE_SIMD
+# ifdef __AVX__
+#  define _ENABLE_AVX
+# endif
+# ifdef __SSE4_1__
+#  define _ENABLE_SSE4_1
+# endif
+#endif
 
+#if defined _ENABLE_AVX
+#include <immintrin.h>
+#elif defined _ENABLE_SSE4_1
+#include <smmintrin.h>
+#endif
 
-int days_per_month(int calendar, int year, int month)
+#if defined _ENABLE_AVX
+
+static
+void avx_decode_array_2byte_double(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
 {
-  int dayspermonth = 0;
-  int *dpm = NULL;
-  int dpy;
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
 
-  dpy = calendar_dpy(calendar);
+  double dval;
 
-  if      ( dpy == 360 ) dpm = month_360;
-  else if ( dpy == 365 ) dpm = month_365;
-  else                   dpm = month_366;
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
 
-  if ( month >= 1 && month <= 12 )
-    dayspermonth = dpm[month-1];
-  /*
-  else
-    fprintf(stderr, "days_per_month: month %d out of range\n", month);
-  */
-  if ( dpy == 0 && month == 2 )
+  __m256d ymm0 = _mm256_set1_pd(fmin);
+  __m256d ymm1 = _mm256_set1_pd(zscale);
+  
+  __m128i xmm0, xmm1, xmm2, xmm3;
+  __m256d ymm2, ymm3;
+
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
     {
-      if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
-	dayspermonth = 29;
-      else
-	dayspermonth = 28;
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
     }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
 
-  return (dayspermonth);
-}
-
-
-int days_per_year(int calendar, int year)
-{
-  int daysperyear;
-  int dpy;
+  while (nframes >= 16)
+    { 
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
 
-  dpy = calendar_dpy(calendar);
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+4, ymm3);  
+      
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib + 1);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
+      
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+8, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+12, ymm3);  
+      
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
 
-  if ( dpy == 0 )
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
     {
-      if ( calendar == CALENDAR_STANDARD )
-	{
-	  if ( year == 1582 )
-	    dpy = 355;
-	  else if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
-	    dpy = 366;
-	  else
-	    dpy = 365;
-	}
-      else
-	{
-	  if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
-	    dpy = 366;
-	  else
-	    dpy = 365;
-	}
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
     }
 
-  daysperyear = dpy;
-  
-  return (daysperyear);
+  return;
 }
 
+#elif defined _ENABLE_SSE4_1
 
-static void decode_day(int dpy, int days, int *year, int *month, int *day)
+static
+void sse41_decode_array_2byte_double(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
 {
-  int i = 0;
-  int *dpm = NULL;
-
-  *year = (days-1) / dpy;
-  days -= (*year*dpy);
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
 
-  if      ( dpy == 360 ) dpm = month_360;
-  else if ( dpy == 365 ) dpm = month_365;
-  else if ( dpy == 366 ) dpm = month_366;
+  double dval;
 
-  if ( dpm )
-    for ( i = 0; i < 12; i++ )
-      {
-	if ( days > dpm[i] ) days -= dpm[i];
-	else break;
-      }
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  __m128d dmm8 = _mm_set1_pd(fmin);
+  __m128d dmm9 = _mm_set1_pd(zscale);
+  
+  __m128i xmm4, xmm5;
+  __m128i xmm6, xmm7;
+  
+  __m128d dmm0, dmm1, dmm2, dmm3;
+  __m128d dmm4, dmm5, dmm6, dmm7;
 
-  *month = i + 1;
-  *day   = days;
-}
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+    {
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
+    }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
+  
+  while (nframes >= 16)
+    {
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm0 = _mm_cvtepi32_pd(xmm6);
+      dmm0 = _mm_add_pd(_mm_mul_pd(dmm0, dmm9), dmm8);
+      (void) _mm_stream_pd(data, dmm0);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm1 = _mm_cvtepi32_pd(xmm7);
+      dmm1 = _mm_add_pd(_mm_mul_pd(dmm1, dmm9), dmm8);
+      (void) _mm_stream_pd(data+2, dmm1);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm2 = _mm_cvtepi32_pd(xmm6);
+      dmm2 = _mm_add_pd(_mm_mul_pd(dmm2, dmm9), dmm8);
+      (void) _mm_stream_pd(data+4, dmm2);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm3 = _mm_cvtepi32_pd(xmm7);
+      dmm3 = _mm_add_pd(_mm_mul_pd(dmm3, dmm9), dmm8);
+      (void) _mm_stream_pd(data+6, dmm3);
+      
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib+1);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm4 = _mm_cvtepi32_pd(xmm6);
+      dmm4 = _mm_add_pd(_mm_mul_pd(dmm4, dmm9), dmm8);
+      (void) _mm_stream_pd(data+8, dmm4);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm5 = _mm_cvtepi32_pd(xmm7);
+      dmm5 = _mm_add_pd(_mm_mul_pd(dmm5, dmm9), dmm8);
+      (void) _mm_stream_pd(data+10, dmm5);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm6 = _mm_cvtepi32_pd(xmm6);
+      dmm6 = _mm_add_pd(_mm_mul_pd(dmm6, dmm9), dmm8);
+      (void) _mm_stream_pd(data+12, dmm6);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm7 = _mm_cvtepi32_pd(xmm7);
+      dmm7 = _mm_add_pd(_mm_mul_pd(dmm7, dmm9), dmm8);
+      (void) _mm_stream_pd(data+14, dmm7);
 
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
 
-static int encode_day(int dpy, int year, int month, int day)
-{
-  int i;
-  int *dpm = NULL;
-  long rval = (long)dpy * year + day;
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
+    {
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
+    }
 
-  if      ( dpy == 360 ) dpm = month_360;
-  else if ( dpy == 365 ) dpm = month_365;
-  else if ( dpy == 366 ) dpm = month_366;
+  return;
+}
 
-  if ( dpm ) for ( i = 0; i < month-1; i++ ) rval += dpm[i];
-  if (rval > INT_MAX || rval < INT_MIN)
-    Error("Unhandled date: %ld", rval);
+#endif
 
-  return (int)rval;
-}
+#undef DISABLE_SIMD
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE4_1
 
 
-int date_to_calday(int calendar, int date)
+void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
 {
-  int calday;
-  int dpy;
-  int year, month, day;
+  /*
 
-  dpy = calendar_dpy(calendar);
+    Purpose:
+    --------
 
-  cdiDecodeDate(date, &year, &month, &day);
+    Convert floating point number from machine
+    representation to GRIB representation.
 
-  if ( dpy == 360 || dpy == 365 || dpy == 366 )
-    calday = encode_day(dpy, year, month, day);
-  else
-    calday = encode_julday(calendar, year, month, day);
+    Input Parameters:
+    -----------------
 
-  return (calday);
-}
+       pval    - Floating point number to be converted.
+       kbits   - Number of bits in computer word.
+       kround  - Conversion type.
+                 0 , Closest number in GRIB format less than
+                     original number.
+                 1 , Closest number in GRIB format to the
+                     original number (equal to, greater than or
+                     less than original number).
 
+    Output Parameters:
+    ------------------
 
-int calday_to_date(int calendar, int calday)
-{
-  int date;
-  int dpy;
-  int year, month, day;
+       kexp    - 8 Bit signed exponent.
+       kmant   - 24 Bit mantissa.
 
-  dpy = calendar_dpy(calendar);
+    Method:
+    -------
 
-  if ( dpy == 360 || dpy == 365 || dpy == 366 )
-    decode_day(dpy, calday, &year, &month, &day);
-  else
-    decode_julday(calendar, calday, &year, &month, &day);
+    Floating point number represented as 8 bit signed
+    exponent and 24 bit mantissa in integer values.
 
-  date = cdiEncodeDate(year, month, day);
+    Externals.
+    ----------
 
-  return (date);
-}
+    decfp2    - Decode from IBM floating point format.
 
+    Reference:
+    ----------
 
-void encode_caldaysec(int calendar, int year, int month, int day, int hour, int minute, int second,
-		      int *julday, int *secofday)
-{
-  int dpy;
+    WMO Manual on Codes re GRIB representation.
+
+    Comments:
+    ---------
 
-  dpy = calendar_dpy(calendar);
+    Routine aborts if an invalid conversion type parameter
+    is used or if a 24 bit mantissa is not produced.
 
-  if ( dpy == 360 || dpy == 365 || dpy == 366 )
-    *julday = encode_day(dpy, year, month, day);
-  else
-    *julday = encode_julday(calendar, year, month, day);
+    Author:
+    -------
+     
+    John Hennessy   ECMWF   18.06.91
 
-  *secofday = hour*3600 + minute*60 + second;
-}
+    Modifications:
+    --------------
 
+    Uwe Schulzweida   MPIfM   01/04/2001
 
-void decode_caldaysec(int calendar, int julday, int secofday, 
-		      int *year, int *month, int *day, int *hour, int *minute, int *second)
-{
-  int dpy;
+    Convert to C from EMOS library version 130
 
-  dpy = calendar_dpy(calendar);
+    Uwe Schulzweida   MPIfM   02/08/2002
 
-  if ( dpy == 360 || dpy == 365 || dpy == 366 )
-    decode_day(dpy, julday, year, month, day);
-  else
-    decode_julday(calendar, julday, year, month, day);
+     - speed up by factor 1.6 on NEC SX6
+        - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
+  */
 
-  *hour   = secofday/3600;
-  *minute = secofday/60 - *hour*60;
-  *second = secofday - *hour*3600 - *minute*60;
-}
+  double rpowref;
+  double zref, zeps;
+  int iexp, isign;
+  int iround;
+  // extern int CGRIBEX_Debug;
+  extern const double _pow16tab[71];
 
+  /* ----------------------------------------------------------------- */
+  /*   Section 1 . Initialise                                          */
+  /* ----------------------------------------------------------------- */
 
-#ifdef TEST
-int main(void)
-{
-  int calendar = CALENDAR_STANDARD;
-  int nmin;
-  int vdate0, vtime0;
-  int vdate, vtime;
-  int ijulinc;
-  int i, j = 0;
-  int year, mon, day, hour, minute, second;
-  int calday, secofday;
+  /*  Check conversion type parameter. */
 
-  /* 1 - Check valid range of years */
+  iround = kround;
+  if ( iround != 0 && iround != 1 )
+    {
+      Error("Invalid conversion type = %d", iround);
 
-  nmin = 11000;
-  vdate0 = -80001201;
-  vtime0 = 120500;
+      /*  If not aborting, arbitrarily set rounding to 'up'. */
+     iround = 1;
+    }
 
-  printf("start time: %8d %4d\n", vdate0, vtime0);
+  /* ----------------------------------------------------------------- */
+  /*   Section 2 . Convert value of zero.                              */
+  /* ----------------------------------------------------------------- */
 
-  for ( i = 0; i < nmin; i++ )
+  if ( ! (fabs(pval) > 0))
     {
-      cdiDecodeDate(vdate0, &year, &mon, &day);
-      cdiDecodeTime(vtime0, &hour, &minute, &second);
+      *kexp  = 0;
+      *kmant = 0;
+      iexp   = 0;
+      isign  = 0;
+      goto LABEL900;
+    }
 
-      calday  = date_to_calday(calendar, vdate0);
-      secofday = time_to_sec(vtime0);
+  /* ----------------------------------------------------------------- */
+  /*   Section 3 . Convert other values.                               */
+  /* ----------------------------------------------------------------- */
 
-      vdate = calday_to_date(calendar, calday);
-      vtime = sec_to_time(secofday);
+  zeps = 1.0e-12;
+  if ( kbits == 32 ) zeps = 1.0e-8;
+  zref = pval;
 
-      if ( vdate0 != vdate || vtime0 != vtime )
-	printf("%4d %8d %4d %8d %4d %9d %9d\n",
-	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);
+  /*  Sign of value. */
 
-      year++;
-      vdate0 = cdiEncodeDate(year, mon, day);
-      vtime0 = cdiEncodeTime(hour, minute, second);
+  isign = 0;
+  if ( zref < 0.0 )
+    {
+      isign = 128;
+      zref  = - zref;
     }
 
-  printf("stop time: %8d %4d\n", vdate0, vtime0);
+  /*  Exponent. */
 
-  /* 2 - Check time increment of one minute */
+  iexp = (int) (log(zref)/log(16.0) + 65.0 + zeps);
 
-  nmin = 120000;
-  ijulinc = 60;
-  vdate0 = 20001201;
-  vtime0 = 0;
+  /* only ANSI C99 has log2 */
+  /* iexp = (int) (log2(zref) * 0.25 + 65.0 + zeps); */
 
-  printf("start time: %8d %4d\n", vdate0, vtime0);
+  if ( iexp < 0   ) iexp = 0;
+  if ( iexp > 127 ) iexp = 127;
 
-  calday = date_to_calday(calendar, vdate0);
-  secofday = time_to_sec(vtime0);
-  for ( i = 0; i < nmin; i++ )
-    {
-      cdiDecodeDate(vdate0, &year, &mon, &day);
-      cdiDecodeTime(vtime0, &hour, &minute, &second);
+  /*
+  rpowref = zref / pow(16.0, (double)(iexp - 70));
+  */
 
-      if ( ++minute >= 60 )
-	{
-	  minute = 0;
-	  if ( ++hour >= 24 )
-	    {
-	      hour = 0;
-	      if ( ++day >= 32 )
-		{
-		  day = 1;
-		  if ( ++mon >= 13 )
-		    {
-		      mon = 1;
-		      year++;
-		    }
-		}
-	    }
-	}
+  if ( (iexp - 70) < 0 )
+    rpowref = zref * _pow16tab[-(iexp - 70)];
+  else
+    rpowref = zref / _pow16tab[(iexp - 70)];
 
-      vdate0 = cdiEncodeDate(year, mon, day);
-      vtime0 = cdiEncodeTime(hour, minute, second);
+  /*  Mantissa. */
 
-      julday_add_seconds(ijulinc, &calday, &secofday);
+  if ( iround == 0 )
+    {
+      /*  Closest number in GRIB format less than original number. */
+      /*  Truncate for positive numbers. */
+      /*  Round up for negative numbers. */
 
-      vdate = calday_to_date(calendar, calday);
-      vtime = sec_to_time(secofday);
-      if ( vdate0 != vdate || vtime0 != vtime )
-	printf("%4d %8d %4d %8d %4d %9d %9d\n",
-	       ++j, vdate0, vtime0, vdate, vtime, calday, secofday);
+      if ( isign == 0 )
+	*kmant = (int)rpowref;
+      else
+	*kmant = (int)lround(rpowref + 0.5);
     }
+  else
+    {
+      /*  Closest number in GRIB format to the original number   */
+      /*  (equal to, greater than or less than original number). */
 
-  printf("stop time: %8d %4d\n", vdate0, vtime0);
+      *kmant = (int)lround(rpowref);
+    }
 
-  return (0);
-}
-#endif
+  /*  Check that mantissa value does not exceed 24 bits. */
+  /*  If it does, adjust the exponent upwards and recalculate */
+  /*  the mantissa. */
+  /*  16777215 = 2**24 - 1 */
 
+  if ( *kmant > 16777215 )
+    {
 
-#ifdef TEST2
-int main(void)
-{
-  int calendar = CALENDAR_STANDARD;
-  int i;
-  int calday, secofday;
-  int year, month, day, hour, minute, second;
-  int value = 30;
-  int factor = 86400;
+    LABEL350:
 
-  calendar = CALENDAR_360DAYS;
+      ++iexp;
 
-  year=1979; month=1; day=15; hour=12; minute=30; second = 0;
+      /*  Check for exponent overflow during adjustment  */
 
-  printf("calendar = %d\n", calendar);
-  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
+      if ( iexp > 127 )
+	{
+          Message("Exponent overflow");
+          Message("Original number = %30.20f", pval);
+          Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
+		  isign, iexp, *kmant);
 
-  encode_caldaysec(calendar, year, month, day, hour, minute, second, &calday, &secofday);
+	  Error("Exponent overflow");
 
-  decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
-  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, calday, secofday);
+	  /*  If not aborting, arbitrarily set value to zero  */
 
-  for ( i = 0; i < 420; i++ )
-    {
+          Message("Value arbitrarily set to zero.");
+          *kexp  = 0;
+          *kmant = 0;
+          iexp  = 0;
+          isign = 0;
+          goto LABEL900;
+	}
 
-      decode_caldaysec(calendar, calday, secofday, &year, &month, &day, &hour, &minute, &second);
-      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
-      julday_add_seconds(value*factor, &calday, &secofday);
-    }
+      if ( (iexp - 70) < 0 )
+	rpowref = zref * _pow16tab[-(iexp - 70)];
+      else
+	rpowref = zref / _pow16tab[(iexp - 70)];
 
-  return (0);
-}
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+      if ( iround == 0 )
+	{
+	  /*  Closest number in GRIB format less than original number. */
+	  /*  Truncate for positive numbers. */
+	  /*  Round up for negative numbers. */
 
-#include <limits.h>
+	  if ( isign == 0 )
+	    *kmant = (int)rpowref;
+	  else
+	    *kmant = (int)lround(rpowref + 0.5);
+	}
+      else
+	{
+	  /*  Closest number in GRIB format to the original number */
+	  /*  (equal to, greater or less than original number). */
+
+	  *kmant = (int)lround(rpowref);
+	}
 
+      /*  Repeat calculation (with modified exponent) if still have */
+      /*  mantissa overflow. */
 
-#undef  UNDEFID
-#define UNDEFID -1
+      if ( *kmant > 16777215 ) goto LABEL350;
+    }
 
-int ECHAM4 = UNDEFID;
-int ECHAM5 = UNDEFID;
-int COSMO  = UNDEFID;
+  /*  Add sign bit to exponent. */
 
-typedef struct
-{
-  int      self;
-  int      used;
-  int      instID;
-  int      modelgribID;
-  char    *name;
-}
-model_t;
+  *kexp = iexp + isign;
 
+  /* ----------------------------------------------------------------- */
+  /*   Section 9. Return                                               */
+  /* ----------------------------------------------------------------- */
 
-static int  MODEL_Debug = 0;   /* If set to 1, debugging */
+LABEL900:
+  /*
+  if ( CGRIBEX_Debug )
+    {
+      double zval;
 
-static void modelInit(void);
+      Message("Conversion type parameter = %4d", kround);
+      Message("Original number = %30.20f", pval);
 
+      zval = decfp2(*kexp, *kmant);
 
-static int modelCompareP(void *modelptr1, void *modelptr2);
-static void   modelDestroyP ( void * modelptr );
-static void   modelPrintP   ( void * modelptr, FILE * fp );
-static int    modelGetSizeP ( void * modelptr, void *context);
-static void   modelPackP    ( void * modelptr, void * buff, int size,
-                              int *position, void *context);
-static int    modelTxCode   ( void );
+      Message("Converted to      %30.20f", zval);
+      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
+    }
+  */
+  return;
+} /* confp3 */
 
-static const resOps modelOps = {
-  modelCompareP,
-  modelDestroyP,
-  modelPrintP,
-  modelGetSizeP,
-  modelPackP,
-  modelTxCode
-};
 
-static
-void modelDefaultValue ( model_t *modelptr )
+double decfp2(int kexp, int kmant)
 {
-  modelptr->self        = UNDEFID;
-  modelptr->used        = 0;
-  modelptr->instID      = UNDEFID;
-  modelptr->modelgribID = UNDEFID;
-  modelptr->name        = NULL;
-}
+  /*
 
-static model_t *
-modelNewEntry(cdiResH resH, int instID, int modelgribID, const char *name)
-{
-  model_t *modelptr;
+    Purpose:
+    --------
 
-  modelptr = (model_t *) xmalloc(sizeof(model_t));
-  modelDefaultValue ( modelptr );
-  if (resH == CDI_UNDEFID)
-    modelptr->self = reshPut(modelptr, &modelOps);
-  else
-    {
-      modelptr->self = resH;
-      reshReplace(resH, modelptr, &modelOps);
-    }
-  modelptr->used = 1;
-  modelptr->instID = instID;
-  modelptr->modelgribID = modelgribID;
-  if ( name && *name ) modelptr->name = strdupx(name);
+    Convert GRIB representation of a floating point
+    number to machine representation.
 
-  return (modelptr);
-}
+    Input Parameters:
+    -----------------
 
-void modelDefaultEntries ( void )
-{
-  int instID, i;
-  enum { nDefModels = 10 };
-  cdiResH resH[nDefModels];
+    kexp    - 8 Bit signed exponent.
+    kmant   - 24 Bit mantissa.
 
-  instID  = institutInq(  0,   0, "ECMWF", NULL);
-  /* (void)    modelDef(instID, 131, "ERA15"); */
-  /* (void)    modelDef(instID, 199, "ERA40"); */
-  instID  = institutInq(  0,   0, "MPIMET", NULL);
+    Output Parameters:
+    ------------------
 
-  resH[0] = ECHAM5  = modelDef(instID,  64, "ECHAM5.4");
-  resH[1] = modelDef(instID,  63, "ECHAM5.3");
-  resH[2] = modelDef(instID,  62, "ECHAM5.2");
-  resH[3] = modelDef(instID,  61, "ECHAM5.1");
+    Return value   - Floating point number represented
+                     by kexp and kmant.
 
-  instID  = institutInq( 98, 255, "MPIMET", NULL);
-  resH[4] = modelDef(instID,  60, "ECHAM5.0");
-  resH[5] = ECHAM4  = modelDef(instID,  50, "ECHAM4");
-  resH[6] = modelDef(instID, 110, "MPIOM1");
+    Method:
+    -------
 
-  instID  = institutInq(  0,   0, "DWD", NULL);
-  resH[7] = modelDef(instID, 149, "GME");
+    Floating point number represented as 8 bit exponent
+    and 24 bit mantissa in integer values converted to
+    machine floating point format.
 
-  instID  = institutInq(  0,   0, "MCH", NULL);
-  //(void)  = modelDef(instID, 137, "COSMO");
-  resH[8] = COSMO   = modelDef(instID, 255, "COSMO");
+    Externals:
+    ----------
 
-  instID  = institutInq(  0,   1, "NCEP", NULL);
-  resH[9] = modelDef(instID,  80, "T62L28MRF");
+    None.
 
-  /* pre-defined models are not synchronized */
-  for ( i = 0; i < nDefModels ; i++ )
-    reshSetStatus(resH[i], &modelOps, RESH_IN_USE);
-}
+    Reference:
+    ----------
 
-static
-void modelInit(void)
-{
-  static int modelInitialized = 0;
+    WMO Manual on Codes re GRIB representation.
 
-  if (modelInitialized) return;
+    Comments:
+    ---------
 
-  modelInitialized = 1;
-  char *env = getenv("MODEL_DEBUG");
-  if ( env ) MODEL_Debug = atoi(env);
-}
+    Rewritten from DECFP, to conform to programming standards.
+    Sign bit on 0 value now ignored, if present.
+    If using 32 bit reals, check power of 16 is not so small as to
+    cause overflows (underflows!); this causes warning to be given
+    on Fujitsus.
 
-int modelSize ( void )
-{
-  return reshCountType ( &modelOps );
-}
+    Author:
+    -------
 
-struct modelLoc
-{
-  char *name;
-  int instID, modelgribID, resID;
-};
+    John Hennessy   ECMWF   18.06.91
 
-static enum cdiApplyRet
-findModelByID(int resID, void *res, void *data)
-{
-  model_t *modelptr = (model_t*) res;
-  struct modelLoc *ret = (struct modelLoc*) data;
-  int instID = ret->instID, modelgribID = ret->modelgribID;
-  if (modelptr->used
-      && modelptr->instID == instID
-      && modelptr->modelgribID == modelgribID)
-    {
-      ret->resID = resID;
-      return CDI_APPLY_STOP;
-    }
-  else
-    return CDI_APPLY_GO_ON;
-}
+    Modifications:
+    --------------
 
-static enum cdiApplyRet
-findModelByName(int resID, void *res, void *data)
-{
-  model_t *modelptr = (model_t*) res;
-  struct modelLoc *ret = (struct modelLoc*) data;
-  int instID = ret->instID, modelgribID = ret->modelgribID;
-  const char *name = ret->name;
-  if (modelptr->used
-      && (instID == -1 || modelptr->instID == instID)
-      && (modelgribID == 0 || modelptr->modelgribID == modelgribID)
-      && modelptr->name)
-    {
-      const char *p = name, *q = modelptr->name;
-      while (*p != '\0' && *p == *q)
-        ++p, ++q;
-      if (*p == '\0' || *q == '\0')
-        {
-          ret->resID = resID;
-          return CDI_APPLY_STOP;
-        }
-    }
-  return CDI_APPLY_GO_ON;
-}
+    Uwe Schulzweida   MPIfM   01/04/2001
 
-int modelInq(int instID, int modelgribID, char *name)
-{
-  modelInit ();
+     - Convert to C from EMOS library version 130
+     
+    Uwe Schulzweida   MPIfM   02/08/2002
 
-  struct modelLoc searchState = { .name = name, .instID = instID,
-                                  .modelgribID = modelgribID,
-                                  .resID = UNDEFID };
-  if (name && *name)
-    cdiResHFilterApply(&modelOps, findModelByName, &searchState);
-  else
-    cdiResHFilterApply(&modelOps, findModelByID, &searchState);
-  return searchState.resID;
-}
+     - speed up by factor 2 on NEC SX6
+        - replace pow(2.0, -24.0) by constant POW_2_M24
+        - replace pow(16.0, (double)(iexp - 64)) by pow16m64tab[iexp]
+  */
+
+  double pval;
+  int iexp, isign;
+  //extern int CGRIBEX_Debug;
+  extern const double _pow16tab[71];
+  
+  /* ----------------------------------------------------------------- */
+  /*   Section 1 . Convert value of 0.0. Ignore sign bit.              */
+  /* ----------------------------------------------------------------- */
 
+  //if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
+  /*
+  if ( (kexp == 128 || kexp == 0) && kmant == 0 )
+  */
+  if ( (kexp == 128) || (kexp == 0) || (kexp == 255) )
+    {
+      pval = 0.0;
+      goto LABEL900;
+    }
 
-int modelDef(int instID, int modelgribID, const char *name)
-{
-  model_t *modelptr;
+  /* ----------------------------------------------------------------- */
+  /*   Section 2 . Convert other values.                               */
+  /* ----------------------------------------------------------------- */
 
-  modelInit ();
+  /*  Sign of value. */
 
-  modelptr = modelNewEntry(CDI_UNDEFID, instID, modelgribID, name);
+  iexp  = kexp;
+  isign = 1;
 
-  return modelptr->self;
-}
+  if ( iexp >= 128 )
+    {
+      iexp -= 128;
+      isign = -1;
+    }
 
+  /*  Decode value. */
 
-int modelInqInstitut(int modelID)
-{
-  model_t *modelptr = NULL;
+  /* pval = isign * pow(2.0, -24.0) * kmant * pow(16.0, (double)(iexp - 64)); */
 
-  modelInit ();
+  iexp -= 64;
 
-  if ( modelID != UNDEFID )
-    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+  if ( iexp < 0 )
+    pval = 1./_pow16tab[-iexp];
+  else
+    pval = _pow16tab[iexp];
 
-  return modelptr ? modelptr->instID : UNDEFID;
-}
+  pval *= isign * POW_2_M24 * kmant;
 
+  /* ----------------------------------------------------------------- */
+  /*   Section 9. Return to calling routine.                           */
+  /* ----------------------------------------------------------------- */
 
-int modelInqGribID(int modelID)
-{
-  model_t *modelptr = NULL;
+LABEL900:
 
-  modelInit ();
+  //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
 
-  if ( modelID != UNDEFID )
-    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+  return (pval);
+} /* decfp2 */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
 
-  return modelptr ? modelptr->modelgribID : UNDEFID;
-}
 
 
-const char *modelInqNamePtr(int modelID)
+int gribRefDate(int *isec1)
 {
-  model_t *modelptr = NULL;
+  int date, ryear, rmonth, rday;
+  int century;
 
-  modelInit ();
+  century = ISEC1_Century;
+  if ( century < 0 ) century = -century;
+  century -= 1;
 
-  if ( modelID != UNDEFID )
-    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+  ryear   = ISEC1_Year;
 
-  return modelptr ? modelptr->name : NULL;
-}
+  /* if ( century != 0 ) */
+    {
+      if ( ryear == 100 )
+	{
+	  ryear = 0;
+	  century += 1;
+	}
 
+      if ( ryear != 255 )
+	{
+	  ryear = century*100 + ryear;
+	  if ( ISEC1_Century < 0 ) ryear = -ryear;
+	}
+      else
+	ryear = 1;
+    }
 
-static int
-modelCompareP(void *modelptr1, void *modelptr2)
-{
-  model_t *model1 = modelptr1, *model2 = modelptr2;
-  int diff = (namespaceResHDecode(model1->instID).idx
-              != namespaceResHDecode(model2->instID).idx)
-    | (model1->modelgribID != model2->modelgribID)
-    | (strcmp(model1->name, model2->name) != 0);
-  return diff;
-}
+  rmonth  = ISEC1_Month;
+  rday    = ISEC1_Day;
 
+  date = cdiEncodeDate(ryear, rmonth, rday);
 
-void modelDestroyP ( void * modelptr )
-{
-  model_t *mp = (model_t*) modelptr;
-  if (mp->name)
-    free(mp->name);
-  free(mp);
+  return (date) ;
 }
 
 
-void modelPrintP   ( void * modelptr, FILE * fp )
+int gribRefTime(int *isec1)
 {
-  model_t *mp = (model_t*) modelptr;
+  int time, rhour, rminute;
 
-  if ( !mp ) return;
+  rhour   = ISEC1_Hour;
+  rminute = ISEC1_Minute;
 
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "# modelID %d\n", mp->self);
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "self          = %d\n", mp->self );
-  fprintf ( fp, "used          = %d\n", mp->used );
-  fprintf ( fp, "instID        = %d\n", mp->instID );
-  fprintf ( fp, "modelgribID   = %d\n", mp->modelgribID );
-  fprintf ( fp, "name          = %s\n", mp->name ? mp->name : "NN" );
+  time = cdiEncodeTime(rhour, rminute, 0);
+
+  return (time) ;
 }
 
 
-static int
-modelTxCode ( void )
+int gribTimeIsFC(int *isec1)
 {
-  return MODEL;
-}
+  int isFC = FALSE;
+  int time_period;
 
-enum {
-  model_nints = 4,
-};
+  if ( ISEC1_TimeRange == 10 )
+    time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
+  else
+    time_period = ISEC1_TimePeriod1;
 
+  if ( time_period > 0 && ISEC1_Day > 0 )
+    {
+      if ( ISEC1_TimeRange == 0 || ISEC1_TimeRange == 10 ) isFC = TRUE;
+    }
 
-static int modelGetSizeP(void * modelptr, void *context)
-{
-  model_t *p = (model_t*)modelptr;
-  size_t txsize = (size_t)serializeGetSize(model_nints, DATATYPE_INT, context)
-    + (size_t)serializeGetSize(p->name?(int)strlen(p->name) + 1:0, DATATYPE_TXT, context);
-  xassert(txsize <= INT_MAX);
-  return (int)txsize;
+  return (isFC);
 }
 
 
-static void modelPackP(void * modelptr, void * buf, int size, int *position, void *context)
+void gribDateTime(int *isec1, int *date, int *time)
 {
-  model_t *p = (model_t*) modelptr;
-  int tempbuf[model_nints];
-  tempbuf[0] = p->self;
-  tempbuf[1] = p->instID;
-  tempbuf[2] = p->modelgribID;
-  tempbuf[3] = p->name ? (int)strlen(p->name) + 1 : 0;
-  serializePack(tempbuf, model_nints, DATATYPE_INT, buf, size, position, context);
-  if (p->name)
-    serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
-}
+  static int lprint = TRUE;
+  int julday, secofday;
+  int64_t addsec = 0;
+  int64_t time_period = 0;
+  extern int grib_calendar;
 
-int
-modelUnpack(void *buf, int size, int *position, int originNamespace, void *context,
-            int force_id)
-{
-  int tempbuf[model_nints];
-  char *name;
-  serializeUnpack(buf, size, position, tempbuf, model_nints, DATATYPE_INT, context);
-  if (tempbuf[3] != 0)
+  int century = ISEC1_Century;
+  int ryear   = ISEC1_Year;
+
+  if ( century == -255 && ryear == 127 )
     {
-      name = (char *)xmalloc((size_t)tempbuf[3]);
-      serializeUnpack(buf, size, position,
-                      name, tempbuf[3], DATATYPE_TXT, context);
+      century = 0;
+      ryear = 0;
     }
   else
     {
-      name = "";
-    }
-  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
-  model_t *mp = modelNewEntry(force_id?targetID:CDI_UNDEFID,
-                              namespaceAdaptKey(tempbuf[1], originNamespace),
-                              tempbuf[2], name);
-  if (tempbuf[3] != 0)
-    free(name);
-  xassert(!force_id
-          || (mp->self == namespaceAdaptKey(tempbuf[0], originNamespace)));
-  return mp->self;
-}
+      if ( century < 0 ) century = -century;
+      century -= 1;
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+      /* if ( century != 0 ) */
+      {
+        if ( ryear == 100 )
+          {
+            ryear = 0;
+            century += 1;
+          }
 
-#include <assert.h>
-#include <limits.h>
+        if ( ryear != 255 )
+          {
+            ryear = century*100 + ryear;
+            if ( ISEC1_Century < 0 ) ryear = -ryear;
+          }
+        else
+          ryear = 1;
+      }
+    }
 
+  int rmonth  = ISEC1_Month;
+  int rday    = ISEC1_Day;
 
-#undef  UNDEFID
-#define UNDEFID  -1
+  int rhour   = ISEC1_Hour;
+  int rminute = ISEC1_Minute;
+  int second  = 0;
 
-int ECMWF  = UNDEFID;
-int MPIMET = UNDEFID;
-int DWD    = UNDEFID;
-int MCH    = UNDEFID;
+  /* printf("ref %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute); */
 
-typedef struct
-{
-  int    self;
-  int    used;
-  int    center;
-  int    subcenter;
-  char  *name;
-  char  *longname;
-}
-institute_t;
+  if ( ISEC1_TimeRange == 10 )
+    time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
+  else if ( ISEC1_TimeRange >=2 && ISEC1_TimeRange <= 5 )
+    time_period = ISEC1_TimePeriod2;
+  else if ( ISEC1_TimeRange == 0 )
+    time_period = ISEC1_TimePeriod1;
 
+  if ( time_period > 0 && rday > 0 )
+    {
+      encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, second, &julday, &secofday);
 
-static int instituteCompareKernel(institute_t *ip1, institute_t *ip2);
-static void instituteDestroyP(institute_t *instituteptr);
-static void   institutePrintP(institute_t *instituteptr, FILE * fp);
-static int instituteGetPackSize(institute_t *instituteptr, void *context);
-static void   institutePackP    ( void * instituteptr, void *buf, int size, int *position, void *context );
-static int    instituteTxCode   ( void );
+      addsec = 0;
+      switch ( ISEC1_TimeUnit )
+	{
+	case ISEC1_TABLE4_MINUTE:    addsec =    60 * time_period; break;
+	case ISEC1_TABLE4_QUARTER:   addsec =   900 * time_period; break;
+	case ISEC1_TABLE4_30MINUTES: addsec =  1800 * time_period; break;
+	case ISEC1_TABLE4_HOUR:      addsec =  3600 * time_period; break;
+	case ISEC1_TABLE4_3HOURS:    addsec = 10800 * time_period; break;
+	case ISEC1_TABLE4_6HOURS:    addsec = 21600 * time_period; break;
+	case ISEC1_TABLE4_12HOURS:   addsec = 43200 * time_period; break;
+	case ISEC1_TABLE4_DAY:       addsec = 86400 * time_period; break;
+	default:
+	  if ( lprint )
+	    {
+	      gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
+	      lprint = FALSE;
+	    }
+	  break;
+	}
 
-static const resOps instituteOps = {
-  (int (*)(void *, void *))instituteCompareKernel,
-  (void (*)(void *))instituteDestroyP,
-  (void (*)(void *, FILE *))institutePrintP,
-  (int (*)(void *, void *))instituteGetPackSize,
-  institutePackP,
-  instituteTxCode
-};
+      julday_add_seconds(addsec, &julday, &secofday);
 
-static
-void instituteDefaultValue ( institute_t * instituteptr )
-{
-  instituteptr->self       = UNDEFID;
-  instituteptr->used       = 0;
-  instituteptr->center     = UNDEFID;
-  instituteptr->subcenter  = UNDEFID;
-  instituteptr->name       = NULL;
-  instituteptr->longname   = NULL;
+      decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &second);
+    }
+  /*
+  printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
+  */
+  *date = cdiEncodeDate(ryear, rmonth, rday);
+  *time = cdiEncodeTime(rhour, rminute, 0);
+
+  return;
 }
 
-void instituteDefaultEntries ( void )
+
+void gprintf(const char *caller, const char *fmt, ...)
 {
-  cdiResH resH[]
-    = { ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts"),
-        MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology"),
-        institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology"),
-        institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology"),
-        institutDef( 78,   0, "DWD",       "Deutscher Wetterdienst"),
-        institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst"),
-        MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss"),
-        institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction"),
-        institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction"),
-        institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research"),
-        institutDef( 74,   0, "METOFFICE", "U.K. Met Office"),
-        institutDef( 97,   0, "ESA",       "European Space Agency"),
-        institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute"),
-  };
-  /*     (void) institutDef(  0,   0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
+  va_list args;
 
-  size_t n = sizeof(resH)/sizeof(*resH);
+  if ( grprsm == NULL ) Error("GRIBEX initialization missing!");
+	
+  va_start(args, fmt);
 
-  for (size_t i = 0; i < n ; i++ )
-    reshSetStatus(resH[i], &instituteOps, RESH_IN_USE);
+   fprintf(grprsm, "%-18s : ", caller);
+  vfprintf(grprsm, fmt, args);
+   fprintf(grprsm, "\n");
+
+  va_end(args);
 }
 
 
-int instituteCount ( void )
+void
+gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+	 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+	 int kleng, int *kword, char *hoper, int *kret)
 {
-  return reshCountType ( &instituteOps );
+  int yfunc = *hoper;
+
+  if ( yfunc == 'C' )
+    {
+      grib_encode_double(isec0, isec1, isec2, fsec2, isec3,
+			 fsec3, isec4, fsec4, klenp, kgrib,
+			 kleng, kword, yfunc, kret);
+    }
+  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+    {
+      grib_decode_double(isec0, isec1, isec2, fsec2, isec3,
+			 fsec3, isec4, fsec4, klenp, kgrib,
+			 kleng, kword, yfunc, kret);
+    }
+  else if ( yfunc == 'V' )
+    {
+      fprintf(stderr, "  cgribex: Version is %s\n", cgribexLibraryVersion());
+    }
+  else
+    {
+      Error("oper %c unsupported!", yfunc);
+      *kret=-9;
+    }
 }
 
 
-static int
-instituteCompareKernel(institute_t *  ip1, institute_t * ip2)
+void
+gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+	 float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+	 int kleng, int *kword, char *hoper, int *kret)
 {
-  int differ = 0;
-  size_t len1, len2;
+  int yfunc = *hoper;
 
-  if ( ip1->name )
+  if ( yfunc == 'C' )
     {
-      if ( ip1->center    > 0 && ip2->center    != ip1->center )    differ = 1;
-      if ( ip1->subcenter > 0 && ip2->subcenter != ip1->subcenter ) differ = 1;
-
-      if ( !differ )
-        {
-          if ( ip2->name )
-            {
-              len1 = strlen(ip1->name);
-              len2 = strlen(ip2->name);
-              if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
-            }
-        }
+      grib_encode_float(isec0, isec1, isec2, fsec2, isec3,
+			fsec3, isec4, fsec4, klenp, kgrib,
+			kleng, kword, yfunc, kret);
     }
-  else if ( ip1->longname )
+  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
     {
-      if ( ip2->longname )
-        {
-          len1 = strlen(ip1->longname);
-          len2 = strlen(ip2->longname);
-          if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
-        }
+      grib_decode_float(isec0, isec1, isec2, fsec2, isec3,
+			fsec3, isec4, fsec4, klenp, kgrib,
+			kleng, kword, yfunc, kret);
+    }
+  else if ( yfunc == 'V' )
+    {
+      fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
     }
   else
     {
-      if ( !( ip2->center    == ip1->center &&
-              ip2->subcenter == ip1->subcenter )) differ = 1;
+      Error("oper %c unsupported!", yfunc);
+      *kret=-9;
     }
-
-  return differ;
 }
 
 
-struct instLoc
+void
+gribExSP_old(int *isec0, int *isec1, int *isec2, float *fsec2sp, int *isec3,
+	     float *fsec3sp, int *isec4, float *fsec4sp, int klenp, int *kgrib,
+	     int kleng, int *kword, char *hoper, int *kret)
 {
-  institute_t *ip;
-  int id;
-};
+  int inum, j;
+  double fsec2dp[1024];
+  double fsec3dp[2];
+  double *fsec4dp = NULL;
+  int yfunc = *hoper;
 
-static enum cdiApplyRet
-findInstitute(int id, void *res, void *data)
-{
-  institute_t * ip1 = ((struct instLoc *)data)->ip;
-  institute_t * ip2 = (institute_t*) res;
-  if (ip2->used && !instituteCompareKernel(ip1, ip2))
+  if ( yfunc == 'C' )
     {
-      ((struct instLoc *)data)->id = id;
-      return CDI_APPLY_STOP;
+      inum = 10 + isec2[11];
+      for ( j = 0; j < inum; j++ ) fsec2dp[j] = fsec2sp[j];
+
+      fsec3dp[0] = fsec3sp[0];
+      fsec3dp[1] = fsec3sp[1];
+
+      inum = isec4[0];
+      fsec4dp = (double*) malloc(inum*sizeof(double));
+      if ( fsec4dp == NULL ) SysError("No Memory!");
+
+      for ( j = 0; j < inum; j++ ) fsec4dp[j] = fsec4sp[j];
+
+      gribExDP(isec0, isec1, isec2, fsec2dp, isec3,
+	       fsec3dp, isec4, fsec4dp, klenp, kgrib,
+	       kleng, kword, hoper, kret);
+
+      free(fsec4dp);
+    }
+  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+    {
+      if ( yfunc == 'D' || yfunc == 'R' )
+	{
+	  fsec4dp = (double*) malloc(klenp*sizeof(double));
+	  if ( fsec4dp == NULL ) SysError("No Memory!");
+	}
+
+      for ( j = 0; j < 10; j++ ) fsec2dp[j] = 0.0;
+      for ( j = 0; j <  2; j++ ) fsec3dp[j] = 0.0;
+
+      gribExDP(isec0, isec1, isec2, fsec2dp, isec3,
+	       fsec3dp, isec4, fsec4dp, klenp, kgrib,
+	       kleng, kword, hoper, kret);
+
+      inum = 10 + isec2[11];
+      for ( j = 0; j < inum; j++ ) fsec2sp[j] = fsec2dp[j];
+
+      fsec3sp[0] = fsec3dp[0];
+      fsec3sp[1] = fsec3dp[1];
+
+      if ( yfunc == 'D' || yfunc == 'R' )
+	{
+	  inum = isec4[0];
+	  for ( j = 0; j < inum; j++ )
+	    {
+	      if ( fsec4dp[j] > -FLT_MIN && fsec4dp[j] < FLT_MIN )
+		fsec4sp[j] = 0;
+	      else if ( fsec4dp[j] > FLT_MAX )
+		fsec4sp[j] = FLT_MAX;
+	      else if ( fsec4dp[j] < -FLT_MAX )
+		fsec4sp[j] = -FLT_MAX;
+	      else
+		fsec4sp[j] = fsec4dp[j];
+	    }
+
+	  free(fsec4dp);
+	}
     }
+  else if ( yfunc == 'V' )
+    fprintf(stderr, " c-gribex: Version is %s\n", cgribexLibraryVersion());
   else
-    return CDI_APPLY_GO_ON;
+    {
+      Error("oper %c unsupported!", yfunc);
+      *kret=-9;
+    }
 }
 
+int CGRIBEX_Fix_ZSE  = 0;    /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
+int CGRIBEX_Const    = 0;    /* 1: Don't pack constant fields on regular grids */
+int CGRIBEX_Debug    = 0;    /* 1: Debugging */
 
-int institutInq(int center, int subcenter, const char *name, const char *longname)
+void gribSetDebug(int debug)
 {
-  institute_t * ip_ref = (institute_t *)xmalloc(sizeof (*ip_ref));
-  ip_ref->self       = UNDEFID;
-  ip_ref->used       = 0;
-  ip_ref->center     = center;
-  ip_ref->subcenter  = subcenter;
-  ip_ref->name       = name && name[0] ? (char *)name : NULL;
-  ip_ref->longname   = longname && longname[0] ? (char *)longname : NULL;
+  CGRIBEX_Debug = debug;
 
-  struct instLoc state = { .ip = ip_ref, .id = UNDEFID };
-  cdiResHFilterApply(&instituteOps, findInstitute, &state);
+  if ( CGRIBEX_Debug )
+    Message("debug level %d", debug);
+}
 
-  free(ip_ref);
 
-  return state.id;
+void gribFixZSE(int flag)
+{
+  CGRIBEX_Fix_ZSE = flag;
+
+  if ( CGRIBEX_Debug )
+    Message("Fix ZeroShiftError set to %d", flag);
 }
 
-static
-institute_t *instituteNewEntry(cdiResH resH, int center, int subcenter,
-                               const char *name, const char *longname)
+
+void gribSetConst(int flag)
 {
-  institute_t *instituteptr = (institute_t*) xmalloc(sizeof(institute_t));
-  instituteDefaultValue(instituteptr);
-  if (resH == CDI_UNDEFID)
-    instituteptr->self = reshPut(instituteptr, &instituteOps);
-  else
-    {
-      instituteptr->self = resH;
-      reshReplace(resH, instituteptr, &instituteOps);
-    }
-  instituteptr->used = 1;
-  instituteptr->center = center;
-  instituteptr->subcenter = subcenter;
-  if ( name && *name )
-    instituteptr->name = strdupx(name);
-  if (longname && *longname)
-    instituteptr->longname = strdupx(longname);
-  return  instituteptr;
+  CGRIBEX_Const = flag;
+
+  if ( CGRIBEX_Debug )
+    Message("Const set to %d", flag);
 }
 
 
-int institutDef(int center, int subcenter, const char *name, const char *longname)
+void gribSetRound(int round)
 {
-  institute_t * instituteptr
-    = instituteNewEntry(CDI_UNDEFID, center, subcenter, name, longname);
-  return instituteptr->self;
+  UNUSED(round);
 }
 
 
-int institutInqCenter(int instID)
+void gribSetRefDP(double refval)
 {
-  institute_t * instituteptr = NULL;
-
-  if ( instID != UNDEFID )
-    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
-
-  return  instituteptr ? instituteptr->center : UNDEFID;
+  UNUSED(refval);
 }
 
 
-int institutInqSubcenter(int instID)
+void gribSetRefSP(float refval)
 {
-  institute_t * instituteptr = NULL;
+  gribSetRefDP((double) refval);
+}
 
-  if ( instID != UNDEFID )
-    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  return instituteptr ? instituteptr->subcenter: UNDEFID;
+void gribSetValueCheck(int vcheck)
+{
+  UNUSED(vcheck);
 }
+#include <string.h>
+#include <math.h>
 
 
-const char *institutInqNamePtr(int instID)
+
+void gribPrintSec0(int *isec0)
 {
-  institute_t * instituteptr = NULL;
+  /*
 
-  if ( instID != UNDEFID )
-    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+    Print the information in the Indicator
+    Section (Section 0) of decoded GRIB data.
 
-  return instituteptr ? instituteptr->name : NULL;
-}
+    Input Parameters:
 
+       isec0 - Array of decoded integers from Section 0
 
-char *institutInqLongnamePtr(int instID)
-{
-  institute_t * instituteptr = NULL;
 
-  if ( instID != UNDEFID )
-    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
+    Converted from EMOS routine GRPRS0.
 
-  return instituteptr ? instituteptr->longname : NULL;
-}
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-static enum cdiApplyRet
-activeInstitutes(int id, void *res, void *data)
-{
-  (void)id;
-  if (res && ((institute_t *)res)->used)
-    ++(*(int *)data);
-  return CDI_APPLY_GO_ON;
+  */
+
+  grsdef();
+
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " Section 0 - Indicator Section.       \n");
+  fprintf(grprsm, " -------------------------------------\n");
+  fprintf(grprsm, " Length of GRIB message (octets).     %9d\n", ISEC0_GRIB_Len);
+  fprintf(grprsm, " GRIB Edition Number.                 %9d\n", ISEC0_GRIB_Version);
 }
 
-int institutInqNumber(void)
+void gribPrintSec1(int *isec0, int *isec1)
 {
-  int instNum = 0;
+  /*
 
-  cdiResHFilterApply(&instituteOps, activeInstitutes, &instNum);
-  return instNum;
-}
+    Print the information in the Product Definition
+    Section (Section 1) of decoded GRIB data.
 
+    Input Parameters:
 
-static void
-instituteDestroyP(institute_t *instituteptr)
-{
-  xassert(instituteptr);
+       isec0 - Array of decoded integers from Section 0
 
-  int instituteID = instituteptr->self;
-  free(instituteptr->name);
-  free(instituteptr->longname);
-  reshRemove(instituteID, &instituteOps);
-  free(instituteptr);
-}
+       isec1 - Array of decoded integers from Section 1
 
+    Comments:
 
-static void institutePrintP(institute_t *ip, FILE * fp )
-{
-  if (ip)
-    fprintf(fp, "#\n"
-            "# instituteID %d\n"
-            "#\n"
-            "self          = %d\n"
-            "used          = %d\n"
-            "center        = %d\n"
-            "subcenter     = %d\n"
-            "name          = %s\n"
-            "longname      = %s\n",
-            ip->self, ip->self, ip->used, ip->center, ip->subcenter,
-            ip->name ? ip->name : "NN",
-            ip->longname ? ip->longname : "NN");
-}
+       When decoding data from Experimental Edition or Edition 0,
+       routine GRIBEX adds the additional fields available in
+       Edition 1.
 
 
-static int
-instituteTxCode ( void )
-{
-  return INSTITUTE;
-}
+    Converted from EMOS routine GRPRS1.
 
-enum {
-  institute_nints = 5,
-};
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-static int instituteGetPackSize(institute_t *ip, void *context)
-{
-  size_t namelen = strlen(ip->name), longnamelen = strlen(ip->longname);
-  xassert(namelen < INT_MAX && longnamelen < INT_MAX);
-  size_t txsize = (size_t)serializeGetSize(institute_nints, DATATYPE_INT, context)
-    + (size_t)serializeGetSize((int)namelen + 1, DATATYPE_TXT, context)
-    + (size_t)serializeGetSize((int)longnamelen + 1, DATATYPE_TXT, context);
-  xassert(txsize <= INT_MAX);
-  return (int)txsize;
-}
+  */
 
-static void institutePackP(void * instituteptr, void *buf, int size, int *position, void *context)
-{
-  institute_t *p = (institute_t*) instituteptr;
-  int tempbuf[institute_nints];
-  tempbuf[0] = p->self;
-  tempbuf[1] = p->center;
-  tempbuf[2] = p->subcenter;
-  tempbuf[3] = (int)strlen(p->name) + 1;
-  tempbuf[4] = (int)strlen(p->longname) + 1;
-  serializePack(tempbuf, institute_nints, DATATYPE_INT, buf, size, position, context);
-  serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
-  serializePack(p->longname, tempbuf[4], DATATYPE_TXT, buf, size, position, context);
-}
+  int iprev, icurr, ioffset;
+  int ibit, ierr, iout, iyear;
+  int jloop, jiloop;
+  float value;
 
-int instituteUnpack(void *buf, int size, int *position, int originNamespace,
-                    void *context, int force_id)
-{
-  int tempbuf[institute_nints];
-  int instituteID;
-  char *name, *longname;
-  serializeUnpack(buf, size, position, tempbuf, institute_nints, DATATYPE_INT, context);
-  name = (char *)xmalloc((size_t)tempbuf[3] + (size_t)tempbuf[4]);
-  longname = name + tempbuf[3];
-  serializeUnpack(buf, size, position, name, tempbuf[3], DATATYPE_TXT, context);
-  serializeUnpack(buf, size, position, longname, tempbuf[4], DATATYPE_TXT, context);
-  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
-  institute_t *ip = instituteNewEntry(force_id?targetID:CDI_UNDEFID,
-                                      tempbuf[1], tempbuf[2], name, longname);
-  instituteID = ip->self;
-  xassert(!force_id || instituteID == targetID);
-  free(name);
-  return instituteID;
-}
+  char hversion[9];
+  /*
+  char hfirst[121], hsecond[121], hthird[121], hfourth[121];
+  */
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  grsdef();
 
-#include <ctype.h>
-#include <stddef.h>
-#include <string.h>
+  /*
+    -----------------------------------------------------------------
+    Section 0 . Print required information.
+    -----------------------------------------------------------------
+  */
+
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " Section 1 - Product Definition Section.\n");
+  fprintf(grprsm, " ---------------------------------------\n");
 
+  fprintf(grprsm, " Code Table 2 Version Number.         %9d\n", isec1[0]);
+  fprintf(grprsm, " Originating centre identifier.       %9d\n", isec1[1]);
+  fprintf(grprsm, " Model identification.                %9d\n", isec1[2]);
+  fprintf(grprsm, " Grid definition.                     %9d\n", isec1[3]);
 
-#undef  UNDEFID
-#define UNDEFID -1
+  ibit = 8;
+  prtbin(isec1[4], ibit, &iout, &ierr);
+  fprintf(grprsm, " Flag (Code Table 1)                   %8.8d\n", iout);
+  fprintf(grprsm, " Parameter identifier (Code Table 2). %9d\n", isec1[5]);
 
-/*int TableDefine = 0; */ /* Define new table also if the entry already exist */
-                          /* This is needed for createtable */
+  /*
+      IERR = CHKTAB2(ISEC1,HFIRST,HSECOND,HTHIRD,HFOURTH)
+      IF( IERR .EQ. 0 ) THEN
+       DO JLOOP = 121, 1, -1
+          IF( HSECOND(JLOOP:JLOOP).NE.' ' ) THEN
+            IOFFSET = JLOOP
+            GOTO 110
+          ENDIF
+        ENDDO
+        GOTO 120
+ 110    CONTINUE
+        WRITE(*,'(2H ",A,1H")') HSECOND(1:IOFFSET)
+ 120    CONTINUE
+      ENDIF
+  */
+
+  if ( isec1[5] != 127 )
+    {
+      fprintf(grprsm, " Type of level (Code Table 3).        %9d\n", isec1[6]);
+      fprintf(grprsm, " Value 1 of level (Code Table 3).     %9d\n", isec1[7]);
+      fprintf(grprsm, " Value 2 of level (Code Table 3).     %9d\n", isec1[8]);
+    }
+  else
+    {
+      fprintf(grprsm, " Satellite identifier.                %9d\n", isec1[6]);
+      fprintf(grprsm, " Spectral band.                       %9d\n", isec1[7]);
+    }
+
+  iyear = isec1[9];
+  if ( iyear != 255 )
+    {
+      int date, time;
+      /* iyear  = ((isec1[20]-1)*100 + isec1[9]); */
+      gribDateTime(isec1, &date, &time);
+      iyear = date/10000;
+      fprintf(grprsm, " Year of reference time of data.      %9d  (%4d)\n", isec1[9], iyear);
+    }
+  else
+    {
+      fprintf(grprsm, " Year of reference time of data MISSING  (=255)\n");
+    }
+
+  fprintf(grprsm, " Month of reference time of data.     %9d\n", isec1[10]);
+  fprintf(grprsm, " Day of reference time of data.       %9d\n", isec1[11]);
+  fprintf(grprsm, " Hour of reference time of data.      %9d\n", isec1[12]);
+  fprintf(grprsm, " Minute of reference time of data.    %9d\n", isec1[13]);
+  fprintf(grprsm, " Time unit (Code Table 4).            %9d\n", isec1[14]);
+  fprintf(grprsm, " Time range one.                      %9d\n", isec1[15]);
+  fprintf(grprsm, " Time range two.                      %9d\n", isec1[16]);
+  fprintf(grprsm, " Time range indicator (Code Table 5)  %9d\n", isec1[17]);
+  fprintf(grprsm, " Number averaged.                     %9d\n", isec1[18]);
+  fprintf(grprsm, " Number missing from average.         %9d\n", isec1[19]);
+  /*
+     All ECMWF data in GRIB Editions before Edition 1 is decoded
+     as 20th century data. Other centres are decoded as missing.
+  */
+  if ( isec0[1] < 1 && isec1[1] != 98 )
+    fprintf(grprsm, " Century of reference time of data.   Not given\n");
+  else
+    fprintf(grprsm, " Century of reference time of data.   %9d\n", isec1[20]);
+
+  /*   Print sub-centre  */
+  fprintf(grprsm, " Sub-centre identifier.               %9d\n", ISEC1_SubCenterID);
+
+  /*   Decimal scale factor  */
+  fprintf(grprsm, " Units decimal scaling factor.        %9d\n", isec1[22]);
+
+  /*
+    -----------------------------------------------------------------
+    Section 1 . Print local DWD information.
+    -----------------------------------------------------------------
+  */
+  if ( (ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250) &&
+       (isec1[36] == 253     || isec1[36] == 254) )
+    {
+      fprintf(grprsm, " DWD local usage identifier.          %9d\n", isec1[36]);
+      if ( isec1[36] == 253 )
+	fprintf(grprsm, " (Database labelling and ensemble forecast)\n");
+      if ( isec1[36] == 254 )
+	fprintf(grprsm, " (Database labelling)\n");
+
+      fprintf(grprsm, " Year of database entry                     %3d  (%4d)\n", isec1[43], 1900+isec1[43]);
+      fprintf(grprsm, " Month of database entry                    %3d\n", isec1[44]);
+      fprintf(grprsm, " Day of database entry                      %3d\n", isec1[45]);
+      fprintf(grprsm, " Hour of database entry                     %3d\n", isec1[46]);
+      fprintf(grprsm, " Minute of database entry                   %3d\n", isec1[47]);
+      fprintf(grprsm, " DWD experiment number                %9d\n",isec1[48]);
+      fprintf(grprsm, " DWD run type                         %9d\n",isec1[49]);
+      if ( isec1[36] == 253 ) 
+	{
+	  fprintf(grprsm, " User id                              %9d\n",isec1[50]);
+	  fprintf(grprsm, " Experiment identifier                %9d\n",isec1[51]);
+	  fprintf(grprsm, " Ensemble identification type         %9d\n",isec1[52]);
+	  fprintf(grprsm, " Number of ensemble members           %9d\n",isec1[53]);
+	  fprintf(grprsm, " Actual number of ensemble member     %9d\n",isec1[54]);
+	  fprintf(grprsm, " Model version                            %2d.%2.2d\n",isec1[55],isec1[56]);
+	}
+    }
+
+  /*
+    -----------------------------------------------------------------
+    Section 2 . Print local ECMWF information.
+    -----------------------------------------------------------------
+  */
+  /*
+    Regular MARS labelling, or reformatted Washington EPS products.
+  */
+  if ( (ISEC1_CenterID    == 98 && ISEC1_LocalFLag ==  1) ||
+       (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag ==  1) ||
+       (ISEC1_CenterID    ==  7 && ISEC1_SubCenterID == 98) )
+    {
+      /*   Parameters common to all definitions.  */
+
+      fprintf(grprsm, " ECMWF local usage identifier.        %9d\n", isec1[36]);
+      if ( isec1[36] == 1 )
+	fprintf(grprsm, " (Mars labelling or ensemble forecast)\n");
+      if ( isec1[36] == 2 )
+        fprintf(grprsm, " (Cluster means and standard deviations)\n");
+      if ( isec1[36] == 3 )
+        fprintf(grprsm, " (Satellite image data)\n");
+      if ( isec1[36] == 4 )
+        fprintf(grprsm, " (Ocean model data)\n");
+      if ( isec1[36] == 5 )
+        fprintf(grprsm, " (Forecast probability data)\n");
+      if ( isec1[36] == 6 )
+        fprintf(grprsm, " (Surface temperature data)\n");
+      if ( isec1[36] == 7 )
+        fprintf(grprsm, " (Sensitivity data)\n");
+      if ( isec1[36] == 8 )
+        fprintf(grprsm, " (ECMWF re-analysis data)\n");
+      if ( isec1[36] == 9 )
+        fprintf(grprsm, " (Singular vectors and ensemble perturbations)\n");
+      if ( isec1[36] == 10 )
+        fprintf(grprsm, " (EPS tubes)\n");
+      if ( isec1[36] == 11 )
+        fprintf(grprsm, " (Supplementary data used by analysis)\n");
+      if ( isec1[36] == 13 )
+        fprintf(grprsm, " (Wave 2D spectra direction and frequency)\n");
+
+      fprintf(grprsm, " Class.                               %9d\n", isec1[37]);
+      fprintf(grprsm, " Type.                                %9d\n", isec1[38]);
+      fprintf(grprsm, " Stream.                              %9d\n", isec1[39]);
+      sprintf(hversion, "%4s", (char*)&isec1[40]); hversion[4] = 0;
+      fprintf(grprsm, " Version number or Experiment identifier.  %4s\n", hversion);
+      /*
+	ECMWF Local definition 1.
+	(MARS labelling or ensemble forecast data)
+      */
+      if ( isec1[36] == 1 )
+	{
+	  fprintf(grprsm, " Forecast number.                     %9d\n", isec1[41]);
+	  if ( isec1[39] != 1090 )
+	    fprintf(grprsm, " Total number of forecasts.           %9d\n", isec1[42]);
+
+	  return;
+	}
+      /*
+	ECMWF Local definition 2.
+	(Cluster means and standard deviations)
+      */
+      if ( isec1[36] == 2 )
+	{
+	  fprintf(grprsm, " Cluster number.                      %9d\n", isec1[41]);
+	  fprintf(grprsm, " Total number of clusters.            %9d\n", isec1[42]);
+	  fprintf(grprsm, " Clustering method.                   %9d\n", isec1[43]);
+	  fprintf(grprsm, " Start time step when clustering.     %9d\n", isec1[44]);
+	  fprintf(grprsm, " End time step when clustering.       %9d\n", isec1[45]);
+	  fprintf(grprsm, " Northern latitude of domain.         %9d\n", isec1[46]);
+	  fprintf(grprsm, " Western longitude of domain.         %9d\n", isec1[47]);
+	  fprintf(grprsm, " Southern latitude of domain.         %9d\n", isec1[48]);
+	  fprintf(grprsm, " Eastern longitude of domain.         %9d\n", isec1[49]);
+	  fprintf(grprsm, " Operational forecast in cluster      %9d\n", isec1[50]);
+	  fprintf(grprsm, " Control forecast in cluster          %9d\n", isec1[51]);
+	  fprintf(grprsm, " Number of forecasts in cluster.      %9d\n", isec1[52]);
+
+	  for (jloop = 0; jloop < isec1[52]; jloop++)
+	    fprintf(grprsm, " Forecast number                      %9d\n", isec1[jloop+53]);
 
+	  return;
+	}
+      /*
+	ECMWF Local definition 3.
+	(Satellite image data)
+      */
+      if ( isec1[36] == 3 )
+	{
+	  fprintf(grprsm, " Satellite spectral band.             %9d\n", isec1[41]);
+	  fprintf(grprsm, " Function code.                       %9d\n", isec1[42]);
+	  return;
+	}
+      /*
+	ECMWF Local definition 4.
+	(Ocean model data)
+      */
+      if ( isec1[36] == 4 )
+	{
+	  fprintf(grprsm, " Satellite spectral band.             %9d\n", isec1[41]);
+	  if ( isec1[39] != 1090 )
+	    fprintf(grprsm, " Function code.                       %9d\n", isec1[42]);
+	  fprintf(grprsm, " Coordinate structure definition.\n");
+	  fprintf(grprsm, " Fundamental spatial reference system.%9d\n", isec1[43]);
+	  fprintf(grprsm, " Fundamental time reference.          %9d\n", isec1[44]);
+	  fprintf(grprsm, " Space unit flag.                     %9d\n", isec1[45]);
+	  fprintf(grprsm, " Vertical coordinate definition.      %9d\n", isec1[46]);
+	  fprintf(grprsm, " Horizontal coordinate definition.    %9d\n", isec1[47]);
+	  fprintf(grprsm, " Time unit flag.                      %9d\n", isec1[48]);
+	  fprintf(grprsm, " Time coordinate definition.          %9d\n", isec1[49]);
+	  fprintf(grprsm, " Position definition.     \n");
+	  fprintf(grprsm, " Mixed coordinate field flag.         %9d\n", isec1[50]);
+	  fprintf(grprsm, " Coordinate 1 flag.                   %9d\n", isec1[51]);
+	  fprintf(grprsm, " Averaging flag.                      %9d\n", isec1[52]);
+	  fprintf(grprsm, " Position of level 1.                 %9d\n", isec1[53]);
+	  fprintf(grprsm, " Position of level 2.                 %9d\n", isec1[54]);
+	  fprintf(grprsm, " Coordinate 2 flag.                   %9d\n", isec1[55]);
+	  fprintf(grprsm, " Averaging flag.                      %9d\n", isec1[56]);
+	  fprintf(grprsm, " Position of level 1.                 %9d\n", isec1[57]);
+	  fprintf(grprsm, " Position of level 2.                 %9d\n", isec1[58]);
+	  fprintf(grprsm, " Grid Definition.\n");
+	  fprintf(grprsm, " Coordinate 3 flag (x-axis)           %9d\n", isec1[59]);
+	  fprintf(grprsm, " Coordinate 4 flag (y-axis)           %9d\n", isec1[60]);
+	  fprintf(grprsm, " Coordinate 4 of first grid point.    %9d\n", isec1[61]);
+	  fprintf(grprsm, " Coordinate 3 of first grid point.    %9d\n", isec1[62]);
+	  fprintf(grprsm, " Coordinate 4 of last grid point.     %9d\n", isec1[63]);
+	  fprintf(grprsm, " Coordinate 3 of last grid point.     %9d\n", isec1[64]);
+	  fprintf(grprsm, " i - increment.                       %9d\n", isec1[65]);
+	  fprintf(grprsm, " j - increment.                       %9d\n", isec1[66]);
+	  fprintf(grprsm, " Flag for irregular grid coordinates. %9d\n", isec1[67]);
+	  fprintf(grprsm, " Flag for normal or staggered grids.  %9d\n", isec1[68]);
+	  fprintf(grprsm, " Further information.\n");
+	  fprintf(grprsm, " Further information flag.            %9d\n", isec1[69]);
+	  fprintf(grprsm, " Auxiliary information.\n");
+	  fprintf(grprsm, " No. entries in horizontal coordinate %9d\n", isec1[70]);
+	  fprintf(grprsm, " No. entries in mixed coordinate defn.%9d\n", isec1[71]);
+	  fprintf(grprsm, " No. entries in grid coordinate list. %9d\n", isec1[72]);
+	  fprintf(grprsm, " No. entries in auxiliary array.      %9d\n", isec1[73]);
+	  /*
+	    Horizontal coordinate supplement.
+	  */
+	  fprintf(grprsm, " Horizontal coordinate supplement.\n");
+	  if ( isec1[70] == 0 )
+	    {
+	      fprintf(grprsm, "(None).\n");
+	    }
+	  else
+	    {
+	      fprintf(grprsm, "Number of items = %d\n", isec1[70]);
+	      for (jloop = 0; jloop < isec1[70]; jloop++)
+		fprintf(grprsm, "         %12d\n", isec1[74+jloop]);
+	    }
+	  /*
+	    Mixed coordinate definition.
+	  */
+	  fprintf(grprsm, " Mixed coordinate definition.\n");
+	  if ( isec1[71] == 0 )
+	    {
+	      fprintf(grprsm, "(None).\n");
+	    }
+	  else
+	    {
+	      fprintf(grprsm, "Number of items = %d\n", isec1[71]);
+	      ioffset = 74 + isec1[70];
+	      for (jloop = 0; jloop < isec1[71]; jloop++)
+		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
+	    }
+	  /*
+	    Grid coordinate list.
+	  */
+	  fprintf(grprsm, " Grid coordinate list. \n");
+	  if ( isec1[72] == 0 )
+	    {
+	      fprintf(grprsm, "(None).\n");
+	    }
+	  else
+	    {
+	      fprintf(grprsm, "Number of items = %d\n", isec1[72]);
+	      ioffset = 74 + isec1[70] + isec1[71];
+	      for (jloop = 0; jloop < isec1[72]; jloop++)
+		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
+	    }
+	  /*
+	    Auxiliary array.
+	  */
+	  fprintf(grprsm, " Auxiliary array.      \n");
+	  if ( isec1[73] == 0 )
+	    {
+	      fprintf(grprsm, "(None).\n");
+	    }
+	  else
+	    {
+	      fprintf(grprsm, "Number of items = %d\n", isec1[73]);
+	      ioffset = 74 + isec1[70] + isec1[71] + isec1[72];
+	      for (jloop = 0; jloop < isec1[73]; jloop++)
+		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
+	    }
+	  /*
+	    Post-auxiliary array.
+	  */
+	  fprintf(grprsm, " Post-auxiliary array. \n");
+	  ioffset = 74 + isec1[70] + isec1[71] + isec1[72] + isec1[73];
+	  if ( isec1[ioffset] == 0 )
+	    {
+	      fprintf(grprsm, "(None).\n");
+	    }
+	  else
+	    {
+	      fprintf(grprsm, "Number of items = %d\n", isec1[ioffset]);
+	      for (jloop = 1; jloop < isec1[ioffset]; jloop++)
+		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
+	    }
 
-#define MAX_TABLE  256
-#define MAX_PARS   1024
+	  return;
+	}
+      /*
+	ECMWF Local definition 5.
+	(Forecast probability data)
+      */
+      if ( isec1[36] == 5 )
+	{
+	  fprintf(grprsm, " Forecast probability number          %9d\n", isec1[41]);
+	  fprintf(grprsm, " Total number of forecast probabilities %7d\n", isec1[42]);
+	  fprintf(grprsm, " Threshold units decimal scale factor %9d\n", isec1[43]);
+	  fprintf(grprsm, " Threshold indicator(1=lower,2=upper,3=both) %2d\n", isec1[44]);
+	  if ( isec1[44]  !=  2 )
+	    fprintf(grprsm, " Lower threshold value                %9d\n", isec1[45]);
+	  if ( isec1[44]  !=  1 )
+	    fprintf(grprsm, " Upper threshold value                %9d\n", isec1[46]);
+	  return;
+	}
+      /*
+	ECMWF Local definition 6.
+	(Surface temperature data)
+      */
+      if ( isec1[36] == 6 )
+	{
+	  iyear = isec1[43];
+	  if ( iyear > 100 )
+	    {
+	      if ( iyear < 19000000 ) iyear = iyear + 19000000;
+	      fprintf(grprsm, " Date of SST field used               %9d\n", iyear);
+	    }
+	  else
+	    fprintf(grprsm, "Date of SST field used               Not given\n");
+	}
+      if ( isec1[44] == 0 )
+	fprintf(grprsm, " Type of SST field (= climatology)    %9d\n", isec1[44]);
+      if ( isec1[44] == 1 )
+	fprintf(grprsm, " Type of SST field (= 1/1 degree)     %9d\n", isec1[44]);
+      if ( isec1[44] == 2 )
+	fprintf(grprsm, " Type of SST field (= 2/2 degree)     %9d\n", isec1[44]);
 
-typedef struct
-{
-  int    used;
-  PAR   *pars;
-  int    npars;
-  int    modelID;
-  int    number;
-  char  *name;
-}
-PARTAB;
+      fprintf(grprsm, " Number of ICE fields used:           %9d\n", isec1[45]);
 
-static PARTAB parTable[MAX_TABLE];
-static int  parTableSize = MAX_TABLE;
-static int  parTableNum  = 0;
-static int  ParTableInit = 0;
+      for (jloop = 1; jloop <= isec1[45]; jloop++)
+	{
+	  iyear = isec1[44+(jloop*2)];
+	  if ( iyear > 100 )
+	    {
+              if ( iyear < 19000000 ) iyear = iyear + 19000000;
+	      fprintf(grprsm, " Date of ICE field%3d                 %9d\n", jloop, iyear);
+	      fprintf(grprsm, " Satellite number (ICE field%3d)      %9d\n", jloop,
+		     isec1[45+(jloop*2)]);
+	    }
+	  else
+	    fprintf(grprsm, "Date of SST field used               Not given\n");
+	}
+      /*
+	ECMWF Local definition 7.
+	(Sensitivity data)
+      */
+      if ( isec1[36] == 7 )
+	{
+	  if ( isec1[38]  ==  51 )
+	    fprintf(grprsm, " Forecast number                      %9d\n", isec1[41]);
+	  if ( isec1[38]  !=  51 )
+	    fprintf(grprsm, " Iteration number                     %9d\n", isec1[41]);
+	  if ( isec1[38]  !=  52 )
+	    fprintf(grprsm, " Total number of diagnostics          %9d\n", isec1[42]);
+	  if ( isec1[38]  ==  52 )
+	    fprintf(grprsm, " No.interations in diag. minimisation %9d\n", isec1[42]);
+	  fprintf(grprsm, " Domain(0=Global,1=Europe,2=N.Hem.,3=S.Hem.) %2d\n", isec1[43]);
+	  fprintf(grprsm, " Diagnostic number                    %9d\n", isec1[44]);
+	}
+      /*
+	ECMWF Local definition 8.
+	(ECMWF re-analysis data)
+      */
+      if ( isec1[36] == 8 )
+	{
+	  if ( (isec1[39] == 1043) ||
+	       (isec1[39] == 1070) ||
+	       (isec1[39] == 1071) )
+	    {
+	      fprintf(grprsm, " Interval between reference times     %9d\n", isec1[41]);
+	      for (jloop = 43; jloop <= 54; jloop++)
+		{
+		  jiloop = jloop + 8;
+		  fprintf(grprsm, " ERA section 1 octet %2d.              %9d\n",
+			 jiloop, isec1[jloop-1]);
+		}
+	    }
+	  else
+	    {
+	      for (jloop = 42; jloop <= 54; jloop++)
+		{
+		  jiloop = jloop + 8;
+		  fprintf(grprsm, " ERA section 1 octet %2d.              %9d\n",
+			 jiloop, isec1[jloop-1]);
+		}
+	    }
+	  return;
+	}
 
-static char *tablePath = NULL;
+      if ( isec1[38] > 4  && isec1[38] < 9 )
+	{
+	  fprintf(grprsm, " Simulation number.                   %9d\n", isec1[41]);
+	  fprintf(grprsm, " Total number of simulations.         %9d\n", isec1[42]);
+	}
+      /*
+	ECMWF Local definition 9.
+	(Singular vectors and ensemble perturbations)
+      */
+      if ( isec1[36] == 9 )
+	{
+	  if ( isec1[38] == 60 )
+	    fprintf(grprsm, " Perturbed ensemble forecast number   %9d\n", isec1[41]);
+	  if ( isec1[38] == 61 )
+	    fprintf(grprsm, " Initial state perturbation number    %9d\n", isec1[41]);
+	  if ( isec1[38] == 62 )
+	    fprintf(grprsm, " Singular vector number               %9d\n", isec1[41]);
+	  if ( isec1[38] == 62 )
+	    {
+	      fprintf(grprsm, " Number of iterations                 %9d\n", isec1[42]);
+	      fprintf(grprsm, " Number of singular vectors computed  %9d\n", isec1[43]);
+	      fprintf(grprsm, " Norm used at initial time            %9d\n", isec1[44]);
+	      fprintf(grprsm, " Norm used at final time              %9d\n", isec1[45]);
+	      fprintf(grprsm, " Multiplication factor                %9d\n", isec1[46]);
+    	      fprintf(grprsm, " Latitude of north-west corner        %9d\n", isec1[47]);
+    	      fprintf(grprsm, " Longitude of north-west corner       %9d\n", isec1[48]);
+	      fprintf(grprsm, " Latitude of south-east corner        %9d\n", isec1[49]);
+	      fprintf(grprsm, " Longitude of south-east corner       %9d\n", isec1[50]);
+	      fprintf(grprsm, " Accuracy                             %9d\n", isec1[51]);
+	      fprintf(grprsm, " Number of singular vectors evolved   %9d\n", isec1[52]);
+	      fprintf(grprsm, " Ritz number one                      %9d\n", isec1[53]);
+	      fprintf(grprsm, " Ritz number two                      %9d\n", isec1[54]);
+	    }
+	}
+      /*
+	ECMWF Local definition 10.
+	(EPS tubes)
+      */
+      if ( isec1[36] == 10 )
+	{
+	  fprintf(grprsm, " Tube number                          %9d\n", isec1[41]);
+          fprintf(grprsm, " Total number of tubes                %9d\n", isec1[42]);
+          fprintf(grprsm, " Central cluster definition           %9d\n", isec1[43]);
+          fprintf(grprsm, " Parameter                            %9d\n", isec1[44]);
+          fprintf(grprsm, " Type of level                        %9d\n", isec1[45]);
+          fprintf(grprsm, " Northern latitude of domain of tubing%9d\n", isec1[46]);
+          fprintf(grprsm, " Western longitude of domain of tubing%9d\n", isec1[47]);
+          fprintf(grprsm, " Southern latitude of domain of tubing%9d\n", isec1[48]);
+          fprintf(grprsm, " Eastern longitude of domain of tubing%9d\n", isec1[49]);
+          fprintf(grprsm, " Tube number of operational forecast  %9d\n", isec1[50]);
+          fprintf(grprsm, " Tube number of control forecast      %9d\n", isec1[51]);
+          fprintf(grprsm, " Height/pressure of level             %9d\n", isec1[52]);
+          fprintf(grprsm, " Reference step                       %9d\n", isec1[53]);
+          fprintf(grprsm, " Radius of central cluster            %9d\n", isec1[54]);
+          fprintf(grprsm, " Ensemble standard deviation          %9d\n", isec1[55]);
+          fprintf(grprsm, " Dist.of tube extreme to ensemble mean%9d\n", isec1[56]);
+          fprintf(grprsm, " Number of forecasts in the tube      %9d\n", isec1[57]);
 
-static void tableDefModelID(int tableID, int modelID);
-static void tableDefNum(int tableID, int tablenum);
+          fprintf(grprsm, " List of ensemble forecast numbers:\n");
+          for (jloop = 1; jloop <=  isec1[57]; jloop++)
+	    fprintf(grprsm, "    %9d\n", isec1[57+jloop]);
+	}
+      /*
+	ECMWF Local definition 11.
+	(Supplementary data used by the analysis)
+      */
+      if ( isec1[36] == 11 )
+	{
+	  fprintf(grprsm, " Details of analysis which used the supplementary data:\n");
+	  fprintf(grprsm, "   Class                              %9d\n", isec1[41]);
+	  fprintf(grprsm, "   Type                               %9d\n", isec1[42]);
+	  fprintf(grprsm, "   Stream                             %9d\n", isec1[43]);
+	  /*
+	  sprintf(hversion, "%8d", isec1[44]);
+	  fprintf(grprsm, "   Version number/experiment identifier:   %4s\n", &hversion[4]);
+	  */
+	  iyear = isec1[45];
+	  if ( iyear > 50 )
+	    iyear = iyear + 1900;
+	  else
+	    iyear = iyear + 2000;
 
+	  fprintf(grprsm, "   Year                               %9d\n", iyear);
+	  fprintf(grprsm, "   Month                              %9d\n", isec1[46]);
+	  fprintf(grprsm, "   Day                                %9d\n", isec1[47]);
+	  fprintf(grprsm, "   Hour                               %9d\n", isec1[48]);
+	  fprintf(grprsm, "   Minute                             %9d\n", isec1[49]);
+	  fprintf(grprsm, "   Century                            %9d\n", isec1[50]);
+	  fprintf(grprsm, "   Originating centre                 %9d\n", isec1[51]);
+	  fprintf(grprsm, "   Sub-centre                         %9d\n", isec1[52]);
+	}
+      /*
+	ECMWF Local definition 12.
+      */
+      if ( isec1[36] == 12 )
+	{
+	  fprintf(grprsm, " (Mean, average, etc)\n");
+          fprintf(grprsm, " Start date of the period              %8d\n", isec1[41]);
+          fprintf(grprsm, " Start time of the period                  %4.4d\n", isec1[42]);
+          fprintf(grprsm, " Finish date of the period             %8d\n", isec1[43]);
+          fprintf(grprsm, " Finish time of the period                 %4.4d\n", isec1[44]);
+          fprintf(grprsm, " Verifying date of the period          %8d\n", isec1[45]);
+          fprintf(grprsm, " Verifying time of the period              %4.4d\n", isec1[46]);
+          fprintf(grprsm, " Code showing method                   %8d\n", isec1[47]);
+          fprintf(grprsm, " Number of different time intervals used  %5d\n", isec1[48]);
+          fprintf(grprsm, " List of different time intervals used:\n");
+          iprev  = isec1[49];
+          icurr  = 0;
+          unsigned icount = 0;
+          for (jloop = 1; jloop <= isec1[48]; jloop++)
+	    {
+	      icurr = isec1[48+jloop];
+	      if ( icurr != iprev )
+		{
+		  if ( icount == 1 )
+		    fprintf(grprsm, "  - interval %5.4d used       once\n", iprev);
+		  if ( icount == 2 )
+		    fprintf(grprsm, "  - interval %5.4d used       twice\n", iprev);
+		  if ( icount > 2 )
+		    fprintf(grprsm, "  - interval %5.4d used %5u times\n",  iprev, icount);
+		  iprev  = icurr;
+		  icount = 1;
+		}
+	      else
+		icount = icount + 1;
+	    }
+	  if ( icount == 1 )
+	    fprintf(grprsm, "  - interval %5.4d used       once\n", iprev);
+	  if ( icount == 2 )
+	    fprintf(grprsm, "  - interval %5.4d used       twice\n", iprev);
+	  if ( icount > 2 )
+	    fprintf(grprsm, "  - interval %5.4d used %5u times\n",  iprev, icount);
+	}
+      /*
+	ECMWF Local definition 13.
+	(Wave 2D spectra direction and frequency)
+      */
+      if ( isec1[36] == 13 )
+	{
+          fprintf(grprsm, " Direction number                     %9d\n", isec1[43]);
+	  fprintf(grprsm, " Frequency number                     %9d\n", isec1[44]);
+	  fprintf(grprsm, " Total number of directions           %9d\n", isec1[45]);
+	  fprintf(grprsm, " Total number of frequencies          %9d\n", isec1[46]);
+	  fprintf(grprsm, " Scale factor applied to directions   %9d\n", isec1[47]);
+	  fprintf(grprsm, " Scale factor applied to frequencies  %9d\n", isec1[48]);
+	  fprintf(grprsm, " List of directions:\n");
+          for (jloop = 1; jloop <= isec1[45]; jloop++)
+            {
+	      value = (float)(isec1[48+jloop])/(float)(isec1[47]);
+	      if ( isec1[43] == jloop )
+		fprintf(grprsm, " %2.2d:%15.7f   <-- this field value\n",  jloop, value);
+	      else
+		fprintf(grprsm, "%2.2d:%15.7f\n",  jloop, value);
+            }
+	  fprintf(grprsm, " List of frequencies:\n");
+          for (jloop = 1; jloop <= isec1[46]; jloop++)
+	    {
+	      value = (float)(isec1[48+isec1[45]+jloop])/(float)(isec1[48]);
+	      if ( isec1[44] == jloop )
+		fprintf(grprsm, " %2.2d:%15.7f   <-- this field value\n",  jloop, value);
+	      else
+		fprintf(grprsm, "%2.2d:%15.7f\n",  jloop, value);
 
-void tableDefEntry(int tableID, int id, const char *name,
-		   const char *longname, const char *units)
-{
-  int item;
+	      if ( isec1[49+isec1[45]+isec1[46]] != 0 )
+		{
+		  fprintf(grprsm, " System number (65535 = missing)      %9d\n",
+			 isec1[49+isec1[45]+isec1[46]]);
+		  fprintf(grprsm, " Method number (65535 = missing)      %9d\n",
+			 isec1[50+isec1[45]+isec1[46]]);
+		}
+	    }
+	  /*
+	    ECMWF Local definition 14.
+	    (Brightness temperature)
+	  */
+	  if ( isec1[36] == 14 )
+	    {
+	      fprintf(grprsm, " Channel number                       %9d\n", isec1[43]);
+	      fprintf(grprsm, " Scale factor applied to frequencies  %9d\n", isec1[44]);
+	      fprintf(grprsm, " Total number of frequencies          %9d\n", isec1[45]);
+	      fprintf(grprsm, " List of frequencies:\n");
+              for (jloop = 1; jloop <= isec1[45]; jloop++)
+		{
+		  value = (float)(isec1[45+jloop])/(float)(isec1[44]);
+		  if ( isec1[43] == jloop )
+		    fprintf(grprsm, " %3d:%15.9f   <-- this channel\n", jloop, value);
+		  else
+		    fprintf(grprsm, " %3d:%15.9f\n", jloop, value);
+		}
+	    }
+	  /*
+	    ECMWF Local definition 15.
+	    (Ocean ensemble seasonal forecast)
+	  */
+	  if ( isec1[36] == 15 )
+	    {
+	      fprintf(grprsm, " Ensemble member number               %9d\n", isec1[41]);
+	      fprintf(grprsm, " System number                        %9d\n", isec1[42]);
+	      fprintf(grprsm, " Method number                        %9d\n", isec1[43]);
+	    }
+	  /*
+	    ECMWF Local definition 16.
+	    (Seasonal forecast monthly mean atmosphere data)
+	  */
+        if ( isec1[36] == 16 )
+	  {
+	    fprintf(grprsm, " Ensemble member number               %9d\n", isec1[41]);
+	    fprintf(grprsm, " System number                        %9d\n", isec1[43]);
+	    fprintf(grprsm, " Method number                        %9d\n", isec1[44]);
+	    fprintf(grprsm, " Verifying month                      %9d\n", isec1[45]);
+	    fprintf(grprsm, " Averaging period                     %9d\n", isec1[46]);
+	  }
+	/*
+	  ECMWF Local definition 17.
+	  (Sst or sea-ice used by analysis)
+	*/
+        if ( isec1[36] == 17 )
+	  {
+	    iyear = isec1[43];
+	    if ( iyear > 100 )
+	      {
+		if ( iyear < 19000000 ) iyear = iyear + 19000000;
+		fprintf(grprsm, " Date of sst/ice field used           %9d\n", iyear);
+	      }
+	    else
+              fprintf(grprsm, " Date of sst/ice field used           Not given\n");
+      
+	    if ( isec1[44] == 0 )
+	      fprintf(grprsm, " Type of sst/ice field (= climatology)%9d\n", isec1[44]);
+	    if ( isec1[44] == 1 )
+	      fprintf(grprsm, " Type of sst/ice field (= 1/1 degree) %9d\n", isec1[44]);
+	    if ( isec1[44] == 2 )
+	      fprintf(grprsm, " Type of sst/ice field (= 2/2 degree) %9d\n", isec1[44]);
 
-  if ( tableID >= 0 && tableID < MAX_TABLE && parTable[tableID].used) { } else
-    Error("Invalid table ID %d", tableID);
-  item = parTable[tableID].npars++;
-  parTable[tableID].pars[item].id       = id;
-  parTable[tableID].pars[item].dupflags = 0;
-  parTable[tableID].pars[item].name     = NULL;
-  parTable[tableID].pars[item].longname = NULL;
-  parTable[tableID].pars[item].units    = NULL;
+	    fprintf(grprsm, " Number of ICE fields used:           %9d\n", isec1[45]);
 
-  if ( name && strlen(name) > 0 )
-    {
-      parTable[tableID].pars[item].name     = strdupx(name);
-      parTable[tableID].pars[item].dupflags |= TABLE_DUP_NAME;
-    }
-  if ( longname && strlen(longname) > 0 )
-    {
-      parTable[tableID].pars[item].longname = strdupx(longname);
-      parTable[tableID].pars[item].dupflags |= TABLE_DUP_LONGNAME;
+	    for (jloop = 1; jloop < isec1[45]; jloop++)
+	      {
+		iyear = isec1[44+(jloop*2)];
+		if ( iyear > 100 )
+		  {
+		    if ( iyear < 19000000 ) iyear = iyear + 19000000;
+		    fprintf(grprsm, " Date of ICE field%3d                 %9d\n", jloop,
+			   iyear);
+		    fprintf(grprsm, " Satellite number (ICE field%3d)      %9d\n", jloop,
+			   isec1[45+(jloop*2)]);
+		  }
+		else
+		  fprintf(grprsm, "Date of sst/ice field used           Not given\n");
+	      } 
+	  }
+	}
     }
-  if ( units && strlen(units) > 0 )
+  /*
+    -----------------------------------------------------------------
+    Section 3 . Print Washington ensemble product information.
+    -----------------------------------------------------------------
+  */
+  /*
+    Washington EPS products (but not reformatted Washington EPS
+    products.
+  */
+  if ( (isec1[1] == 7 && isec1[23] == 1) && (! (ISEC1_SubCenterID == 98)) )
     {
-      parTable[tableID].pars[item].units    = strdupx(units);
-      parTable[tableID].pars[item].dupflags |= TABLE_DUP_UNITS;
+      /*   CALL KWPRS1 (iSEC0,iSEC1)*/
     }
-}
-
-static void tableLink(int tableID, const PAR *pars, int npars)
-{
-  int item;
-
-  for ( item = 0; item < npars; item++ )
+  /*
+    -----------------------------------------------------------------
+    Section 4 . Print local MPIM information.
+    -----------------------------------------------------------------
+  */
+  if (isec1[ 1] == 252 && isec1[36] == 1)
     {
-      parTable[tableID].pars[item].id       = pars[item].id;
-      parTable[tableID].pars[item].dupflags = 0;
-      parTable[tableID].pars[item].name     = pars[item].name;
-      parTable[tableID].pars[item].longname = pars[item].longname;
-      parTable[tableID].pars[item].units    = pars[item].units;
+      fprintf(grprsm, " MPIM local usage identifier.         %9d\n", isec1[36]);
+      fprintf(grprsm, " Type of ensemble forecast            %9d\n", isec1[37]);
+      fprintf(grprsm, " Individual ensemble member           %9d\n", isec1[38]);
+      fprintf(grprsm, " Number of forecasts in ensemble      %9d\n", isec1[39]);
     }
-
-  parTable[tableID].npars = npars;
-}
-
-static void parTableInitEntry(int tableID)
-{
-  parTable[tableID].used    = 0;
-  parTable[tableID].pars    = NULL;
-  parTable[tableID].npars   = 0;
-  parTable[tableID].modelID = UNDEFID;
-  parTable[tableID].number  = UNDEFID;
-  parTable[tableID].name    = NULL;
 }
 
-static void tableGetPath(void)
+void printQuasi(int *isec2)
 {
-  char *path;
-
-  path = getenv("TABLEPATH");
-
-  if ( path ) tablePath = strdupx(path);
   /*
-  printf("tablePath = %s\n", tablePath);
-  */
-}
-
-static void parTableFinalize(void)
-{
-  for (int tableID = 0; tableID < MAX_TABLE; ++tableID)
-    if (parTable[tableID].used)
-      {
-        int npars = parTable[tableID].npars;
-        for (int item = 0; item < npars; ++item)
-          {
-            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_NAME)
-              free((void *)parTable[tableID].pars[item].name);
-            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_LONGNAME)
-              free((void *)parTable[tableID].pars[item].longname);
-            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_UNITS)
-              free((void *)parTable[tableID].pars[item].units);
-          }
-        free(parTable[tableID].pars);
-        free(parTable[tableID].name);
-      }
-}
-
-static void parTableInit(void)
-{
-  ParTableInit = 1;
-
-  atexit(parTableFinalize);
-  if ( cdiPartabIntern )
-    tableDefault();
-
-  tableGetPath();
-}
 
-static int tableNewEntry()
-{
-  int tableID = 0;
-  static int init = 0;
+    Print the qusai-regular information in the Grid Description
+    Section (Section 2) of decoded GRIB data.
 
-  if ( ! init )
-    {
-      for ( tableID = 0; tableID < parTableSize; tableID++ )
-	parTableInitEntry(tableID);
-      init = 1;
-    }
+    Input Parameters:
 
-  /*
-    Look for a free slot in parTable.
-  */
-  for ( tableID = 0; tableID < parTableSize; tableID++ )
-    {
-      if ( ! parTable[tableID].used ) break;
-    }
+       isec2 - Array of decoded integers from Section 2.
 
-  if ( tableID == parTableSize )
-    Error("no more entries!");
+    Comments:
 
-  parTable[tableID].used = 1;
-  parTableNum++;
+       Only data representation types catered for are Gaussian
+       grid, latitude/longitude grid, Spherical Harmonics,
+       Polar stereographic and Space view perspective.
 
-  return (tableID);
-}
+    Converted from EMOS routine PTQUASI.
 
-static int
-decodeForm1(char *pline, char *name, char *longname, char *units)
-{
-  char *pstart, *pend;
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-  /* FIXME: parse success isn't verified */
-  /* long level =  */strtol(pline, &pline, 10);
-  while ( isspace((int) *pline) ) pline++;
+  */
 
-  pstart = pline;
-  while ( ! (isspace((int) *pline) || *pline == 0) ) pline++;
-  size_t len = (size_t)(pline - pstart);
-  if ( len > 0 )
-    {
-      memcpy(name, pstart, len);
-      name[len] = 0;
-    }
-  else
-    return (0);
+  char yout[64];
+  int nextlat, latcnt;
+  int j;
+  int ntos;
 
-  len = strlen(pline);
-  if ( len == 0 ) return (0);
+  /*
+    -----------------------------------------------------------------
+    Section 1. Print quasi-grid data.
+    -----------------------------------------------------------------
+  */
+  /*
+    See if scanning is north->south or south->north
+  */
+  fprintf(grprsm, "  Number of points along a parallel varies.\n");
 
-  /* Format 1 : code name add mult longname [units] */
-  /* FIXME: successful parse isn't verified */
-  /* double add  =  */strtod(pline, &pline);
-  /* FIXME: successful parse isn't verified */
-  /* double mult =  */strtod(pline, &pline);
+  ntos = ( fmod((double) isec2[10], 128.) < 64 );
 
-  while ( isspace((int) *pline) ) pline++;
+  if ( ntos )
+    fprintf(grprsm, "  Number of points.   Parallel. (North to South)\n");
+  else
+    fprintf(grprsm, "  Number of points.   Parallel. (South to North)\n");
 
-  len = strlen(pline);
-  if ( len > 0 )
+  /*  Display number of points for each latitude */
+  latcnt  = isec2[2];
+  nextlat = 0;
+  memset(yout, ' ', (size_t) 11);
+
+  for ( j = 0; j < latcnt; j++ )
     {
-      pstart = pline;
-      pend = strrchr(pline, '[');
-      if ( pend == pstart )
-        len = 0;
-      else
-        {
-          if ( pend )
-            pend--;
-          else
-            pend = pstart + len;
-          while ( isspace((int) *pend) ) pend--;
-          len = (size_t)(pend - pstart + 1);
-        }
-      if ( len > 0 )
+      nextlat = nextlat + 1;
+      sprintf(yout, "%4d", nextlat);
+
+      /*       Finished?  */
+      if ( nextlat > latcnt ) break;
+      if ( nextlat == latcnt )
 	{
-	  memcpy(longname, pstart, len);
-	  longname[len] = 0;
+	  fprintf(grprsm, " %5d                %-12s\n", isec2[nextlat+21], yout);
+	  break;
 	}
-      pstart = strrchr(pline, '[');
-      if ( pstart )
+      /*
+	Look for neighbouring latitudes with same number of points
+      */
+      unsigned nrepeat = 0;
+
+    LABEL110:
+      /*
+	If neighbouring latitudes have same number of points
+	increase the repeat count.
+      */
+      if ( isec2[nextlat+21+1] == isec2[nextlat+21] )
 	{
-	  pstart++;
-	  while ( isspace((int) *pstart) ) pstart++;
-	  pend = strchr(pstart, ']');
-	  if ( ! pend ) return (0);
-	  pend--;
-	  while ( isspace((int) *pend) ) pend--;
-	  len = (size_t)(pend - pstart + 1);
-	  if ( len > 0 )
-	    {
-	      memcpy(units, pstart, len);
-	      units[len] = 0;
-	    }
+          nrepeat = nrepeat + 1;
+          nextlat = nextlat + 1;
+	  if ( nextlat < latcnt ) goto LABEL110;
 	}
+      /*
+	Display neighbouring latitudes with same number of points as
+	'nn to mm'.
+      */
+      if ( nrepeat >= 1 )
+	{
+	  strncpy(yout+4, " to", 3);
+	  sprintf(yout+7, "%5d", nextlat);
+        }
+      fprintf(grprsm, " %5d                %-12s\n", isec2[nextlat+21], yout);
+      memset(yout, ' ', (size_t) 11);
     }
-
-  return (0);
 }
 
-static int
-decodeForm2(char *pline, char *name, char *longname, char *units)
+void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2)
 {
-  /* Format 2 : code | name | longname | units */
-  char *pend;
-  size_t len;
+  /*
 
-  pline = strchr(pline, '|');
-  pline++;
+    Print the information in the Grid Description
+    Section (Section 2) of decoded GRIB data.
 
-  while ( isspace((int) *pline) ) pline++;
-  if (*pline != '|')
-    {
-      pend = strchr(pline, '|');
-      if ( ! pend )
-        {
-          pend = pline;
-          while ( ! isspace((int) *pend) ) pend++;
-          len = (size_t)(pend - pline);
-          if ( len > 0 )
-            {
-              memcpy(name, pline, len);
-              name[len] = 0;
-            }
-          return (0);
-        }
-      else
-        {
-          pend--;
-          while ( isspace((int) *pend) ) pend--;
-          len = (size_t)(pend - pline + 1);
-          if ( len > 0 )
-            {
-              memcpy(name, pline, len);
-              name[len] = 0;
-            }
-        }
-    }
-  else
-    name[0] = '\0';
+    Input Parameters:
 
-  pline = strchr(pline, '|');
-  pline++;
-  while ( isspace((int) *pline) ) pline++;
-  pend = strchr(pline, '|');
-  if ( !pend ) pend = strchr(pline, 0);
-  pend--;
-  while ( isspace((int) *pend) ) pend--;
-  len = (size_t)(pend - pline + 1);
-  if ( len > 0 )
-    {
-      memcpy(longname, pline, len);
-      longname[len] = 0;
-    }
+       isec0  - Array of decoded integers from Section 0
 
-  pline = strchr(pline, '|');
-  if ( pline )
-    {
-      pline++;
-      while ( isspace((int) *pline) ) pline++;
-      pend = strchr(pline, '|');
-      if ( !pend ) pend = strchr(pline, 0);
-      pend--;
-      while ( isspace((int) *pend) ) pend--;
-      ptrdiff_t len = pend - pline + 1;
-      if ( len < 0 ) len = 0;
-      memcpy(units, pline, (size_t)len);
-      units[len] = 0;
-    }
+       isec2  - Array of decoded integers from Section 2
 
-  return (0);
-}
+       fsec2  - Array of decoded floats from Section 2
 
-int tableRead(const char *tablefile)
-{
-  char line[1024], *pline;
-  int lnr = 0;
-  int id;
-  char name[256], longname[256], units[256];
-  int tableID = UNDEFID;
-  int err;
-  char *tablename;
-  FILE *tablefp;
+    Comments:
 
-  tablefp = fopen(tablefile, "r");
-  if ( tablefp == NULL ) return (tableID);
+       Only data representation types catered for are Gaussian
+       grid, latitude/longitude grid, Spherical Harmonics,
+       Polar stereographic and Space view perspective.
 
-  tablename = strrchr(tablefile, '/');
-  if ( tablename == 0 ) tablename = (char *) tablefile;
-  else                  tablename++;
 
-  tableID = tableDef(-1, 0, tablename);
+    Converted from EMOS routine GRPRS2.
 
-  while ( fgets(line, 1023, tablefp) )
-    {
-      size_t len = strlen(line);
-      if ( line[len-1] == '\n' ) line[len-1] = '\0';
-      lnr++;
-      id       = CDI_UNDEFID;
-      name[0]     = 0;
-      longname[0] = 0;
-      units[0]    = 0;
-      if ( line[0] == '#' ) continue;
-      pline = line;
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-      len = strlen(pline);
-      if ( len < 4 ) continue;
-      while ( isspace((int) *pline) ) pline++;
-      id = atoi(pline);
-      /*
-      if ( id > 255 ) id -= 256;
-      */
-      if ( id == 0 ) continue;
+  */
 
-      while ( isdigit((int) *pline) ) pline++; 
+  int i, ibit, iedit, ierr, iout, iresol;
 
-      if ( strchr(pline, '|') )
-	err = decodeForm2(pline, name, longname, units);
+  grsdef();
+  /*
+    -----------------------------------------------------------------
+    Section 1 . Print GRIB Edition number.
+    -----------------------------------------------------------------
+  */
+  iedit = isec0[1];
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " Section 2 - Grid Description Section.\n");
+  fprintf(grprsm, " -------------------------------------\n");
+  /*
+    -----------------------------------------------------------------
+    Section 2 . Print spherical harmonic data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] == 50 || isec2[0] == 60 || 
+       isec2[0] == 70 || isec2[0] == 80 )
+    {
+      fprintf(grprsm, " Data represent type = spectral     (Table 6) %9d\n", isec2[0]);
+      fprintf(grprsm, " J - Pentagonal resolution parameter.         %9d\n", isec2[1]);
+      fprintf(grprsm, " K - Pentagonal resolution parameter.         %9d\n", isec2[2]);
+      fprintf(grprsm, " M - Pentagonal resolution parameter.         %9d\n", isec2[3]);
+      fprintf(grprsm, " Representation type (Table 9)                %9d\n", isec2[4]);
+      fprintf(grprsm, " Representation mode (Table 10).              %9d\n", isec2[5]);
+      for (i = 7; i <= 11; i++)
+        fprintf(grprsm, " Not used.                                    %9d\n", isec2[i-1]);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      goto LABEL800;
+    }
+  /*
+    -----------------------------------------------------------------
+    Section 3 . Print Gaussian grid data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] ==  4 || isec2[0] == 14 || 
+       isec2[0] == 24 || isec2[0] == 34 )
+    {
+      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+      fprintf(grprsm, " Data represent type = gaussian     (Table 6) %9d\n", isec2[0]);
+      /*
+	Quasi-regular grids introduced in Edition 1.
+      */
+      if ( isec2[16] == 0 || iedit < 1 )
+	fprintf(grprsm, " Number of points along a parallel.           %9d\n", isec2[1]);
       else
-	err = decodeForm1(pline, name, longname, units);
+      	printQuasi(isec2);
 
-      if ( err ) continue;
+      fprintf(grprsm, " Number of points along a meridian.           %9d\n", isec2[2]);
+      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
+      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
 
-      if ( strlen(name) == 0 ) sprintf(name, "var%d", id);
+      ibit = 8;
+      iresol = isec2[5] + isec2[17] + isec2[18];
+      prtbin(iresol, ibit, &iout, &ierr);
 
-      tableDefEntry(tableID, id, name, longname, units);
-    }
+      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
+      fprintf(grprsm, " Latitude of last grid point.                 %9d\n", isec2[6]);
+      fprintf(grprsm, " Longitude of last grid point.                %9d\n", isec2[7]);
+      /*
+	Print increment if given.
+      */
+      if ( isec2[5] == 128 )
+	fprintf(grprsm, " i direction (East-West) increment.           %9d\n", isec2[8]);
+      else
+	fprintf(grprsm, " i direction (East-West) increment            Not given\n");
 
-  return (tableID);
-}
+      fprintf(grprsm, " Number of parallels between pole and equator.%9d\n", isec2[9]);
 
-static int tableFromEnv(int modelID, int tablenum)
-{
-  int tableID = UNDEFID;
-  char tablename[256] = {'\0'};
-  int tablenamefound = 0;
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
 
-  const char *modelName;
-  if ( (modelName = modelInqNamePtr(modelID)) )
-    {
-      strcpy(tablename, modelName);
-      if ( tablenum )
-	{
-	  size_t len = strlen(tablename);
-	  sprintf(tablename+len, "_%03d", tablenum);
-	}
-      tablenamefound = 1;
-    }
-  else
-    {
-      int instID = modelInqInstitut(modelID);
-      if ( instID != UNDEFID )
-	{
-          const char *instName;
-	  if ( (instName = institutInqNamePtr(instID)) )
-	    {
-	      strcpy(tablename, instName);
-	      if ( tablenum )
-		{
-		  size_t len = strlen(tablename);
-		  sprintf(tablename+len, "_%03d", tablenum);
-		}
-	      tablenamefound = 1;
-	    }
-	}
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      goto LABEL800;
     }
-
-  if ( tablenamefound )
+  /*
+    -----------------------------------------------------------------
+    Section 4 . Print Latitude / longitude grid data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] ==  0 || isec2[0] == 10 || 
+       isec2[0] == 20 || isec2[0] == 30 )
     {
-      size_t lenp = 0, lenf;
-      char *tablefile = NULL;
-      if ( tablePath )
-	lenp = strlen(tablePath);
-      lenf = strlen(tablename);
-      /* if (tablePath) printf("tablePath = %s\n", tablePath); */
-      /* if (tablename) printf("tableName = %s\n", tablename); */
-      tablefile = (char *) malloc(lenp+lenf+3);
-      if ( tablePath )
-	{
-	  strcpy(tablefile, tablePath);
-	  strcat(tablefile, "/");
-	}
+      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+      fprintf(grprsm, " Data represent type = lat/long     (Table 6) %9d\n", isec2[0]);
+      /*
+	Quasi-regular lat/long grids also possible.
+      */
+      if ( isec2[16] == 0 )
+	fprintf(grprsm, " Number of points along a parallel.           %9d\n", isec2[1]);
       else
-	tablefile[0] = '\0';
-      strcat(tablefile, tablename);
-      /* if (tablefile) printf("tableFile = %s\n", tablefile); */
-
-      tableID = tableRead(tablefile);
-      if ( tableID != UNDEFID )
-	{
-	  tableDefModelID(tableID, modelID);
-	  tableDefNum(tableID, tablenum);
-	}
-      /* printf("tableID = %d %s\n", tableID, tablefile); */
+        printQuasi(isec2);
 
-      free(tablefile);
-    }
+      fprintf(grprsm, " Number of points along a meridian.           %9d\n", isec2[2]);
+      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
+      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
 
-  return (tableID);
-}
+      ibit = 8;
+      iresol = isec2[5] + isec2[17] + isec2[18];
+      prtbin(iresol, ibit, &iout, &ierr);
 
-int tableInq(int modelID, int tablenum, const char *tablename)
-{
-  int tableID = UNDEFID;
-  int modelID2 = UNDEFID;
-  char tablefile[256] = {'\0'};
+      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
+      fprintf(grprsm, " Latitude of last grid point.                 %9d\n", isec2[6]);
+      fprintf(grprsm, " Longitude of last grid point.                %9d\n", isec2[7]);
+      /*
+	Print increment if given.
+      */
+      if ( isec2[8] < 0 )
+	fprintf(grprsm, " i direction (East-West) increment            Not given\n");
+      else
+	fprintf(grprsm, " i direction (East-West) increment.           %9d\n", isec2[8]);
 
-  if ( ! ParTableInit ) parTableInit();
+      if ( isec2[9] < 0 )
+	fprintf(grprsm, " j direction (North-South) increment          Not given\n");
+      else
+	fprintf(grprsm, " j direction (North-South) increment.         %9d\n", isec2[9]);
+    
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
 
-  if ( tablename )
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      goto LABEL800;
+    }
+  /*
+    -----------------------------------------------------------------
+    Section 5 . Print polar stereographic data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] == 5 )
     {
-      size_t len;
-      strcpy(tablefile, tablename);
-      /*
-      printf("tableInq: tablefile = >%s<\n", tablefile);
-      */
-      /* search for internal table */
-      for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
-	{
-	  if ( parTable[tableID].used && parTable[tableID].name )
-	    {
-	      /* len = strlen(parTable[tableID].name); */
-	      len = strlen(tablename);
-	      if ( memcmp(parTable[tableID].name, tablename, len) == 0 ) break;
-	    }
-	}
-      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
-      if ( CDI_Debug )
-	Message("tableID = %d tablename = %s", tableID, tablename);
+      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+      fprintf(grprsm, " Data represent type = polar stereo (Table 6) %9d\n", isec2[0]);
+      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
+      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
+      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
+      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
+      ibit = 8;
+      iresol = isec2[17] + isec2[18];
+      prtbin(iresol, ibit, &iout, &ierr);
+      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
+      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
+      fprintf(grprsm, " X direction increment.                       %9d\n", isec2[8]);
+      fprintf(grprsm, " Y direction increment.                       %9d\n", isec2[9]);
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      fprintf(grprsm, " Projection centre flag.                      %9d\n", isec2[12]);
+      goto LABEL800;
+    }
+  /*
+    -----------------------------------------------------------------
+    Section 6 . Print Lambert conformal data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] == 3 )
+    {
+      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+      fprintf(grprsm, " Data represent type = Lambert      (Table 6) %9d\n", isec2[0]);
+      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
+      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
+      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
+      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
+      ibit = 8;
+      iresol = isec2[17] + isec2[18] + isec2[5];
+      prtbin(iresol, ibit, &iout, &ierr);
+      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
+      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
+      fprintf(grprsm, " X direction increment.                       %9d\n", isec2[8]);
+      fprintf(grprsm, " Y direction increment.                       %9d\n", isec2[9]);
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      fprintf(grprsm, " Projection centre flag.                      %9d\n", isec2[12]);
+      fprintf(grprsm, " Latitude intersection 1 - Latin 1 -.         %9d\n", isec2[13]);
+      fprintf(grprsm, " Latitude intersection 2 - Latin 2 -.         %9d\n", isec2[14]);
+      fprintf(grprsm, " Latitude of Southern Pole.                   %9d\n", isec2[19]);
+      fprintf(grprsm, " Longitude of Southern Pole.                  %9d\n", isec2[20]);
+      goto LABEL800;
+    }
+  /*
+    -----------------------------------------------------------------
+    Section 7 . Print space view perspective or orthographic data.
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] == 90 )
+    {
+      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
+      fprintf(grprsm, " Data represent type = space/ortho  (Table 6) %9d\n", isec2[0]);
+      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
+      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
+      fprintf(grprsm, " Latitude of sub-satellite point.             %9d\n", isec2[3]);
+      fprintf(grprsm, " Longitude of sub-satellite point.            %9d\n", isec2[4]);
+      iresol = isec2[17] + isec2[18];
+      fprintf(grprsm, " Diameter of the earth in x direction.        %9d\n", isec2[6]);
+      fprintf(grprsm, " Y coordinate of sub-satellite point.         %9d\n", isec2[9]);
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
+      fprintf(grprsm, " Altitude of the camera.                      %9d\n", isec2[13]);
+      fprintf(grprsm, " Y coordinate of origin of sector image.      %9d\n", isec2[14]);
+      fprintf(grprsm, " X coordinate of origin of sector image.      %9d\n", isec2[15]);
+      goto LABEL800;
     }
-  else
+  /*
+    -----------------------------------------------------------------
+    Section 7.5 . Print ocean data
+    -----------------------------------------------------------------
+  */
+  /*
+  if ( isec2[0] == 192 && ISEC1_CenterID == 98 )
     {
-      for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
-	{
-	  if ( parTable[tableID].used )
-	    {
-	      if ( parTable[tableID].modelID == modelID &&
-		   parTable[tableID].number  == tablenum ) break;
-	    }
-	}
-
-      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
-
-      if ( tableID == UNDEFID )
-	{
-	  if ( modelID != UNDEFID )
-	    {
-              const char *modelName;
-	      if ( (modelName = modelInqNamePtr(modelID)) )
-		{
-		  strcpy(tablefile, modelName);
-		  size_t len = strlen(tablefile);
-		  for ( size_t i = 0; i < len; i++)
-		    if ( tablefile[i] == '.' ) tablefile[i] = '\0';
-		  modelID2 = modelInq(-1, 0, tablefile);
-		}
-	    }
-	  if ( modelID2 != UNDEFID )
-	    for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
-	      {
-		if ( parTable[tableID].used )
-		  {
-		    if ( parTable[tableID].modelID == modelID2 &&
-			 parTable[tableID].number  == tablenum ) break;
-		  }
-	      }
-	}
-
-      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
+      fprintf(grprsm, " Data represent type = ECMWF ocean  (Table 6) %9d\n", isec2[0]);
+      if ( isec2[1] ==  32767 )
+	fprintf(grprsm, " Number of points along the first axis.       Not used\n");
+      else
+	fprintf(grprsm, " Number of points along the first axis.       %9d\n", isec2[1]);
 
-      if ( tableID == UNDEFID && modelID != UNDEFID )
-	tableID = tableFromEnv(modelID, tablenum);
+      if ( isec2[2] ==  32767 )
+	fprintf(grprsm, " Number of points along the second axis.      Not used\n");
+      else
+	fprintf(grprsm, " Number of points along the second axis.      %9d\n", isec2[2]);
 
-      if ( CDI_Debug )
-	if ( tablename )
-	  Message("tableID = %d tablename = %s", tableID, tablename);
+      ibit = 8;
+      prtbin(isec2[10], ibit, &iout, &ierr);
+      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
+      goto LABEL800;
     }
-
-  return (tableID);
-}
-
-int tableDef(int modelID, int tablenum, const char *tablename)
-{
-  int tableID = UNDEFID;
-
-  if ( ! ParTableInit ) parTableInit();
-  /*
-  if ( ! (modelID == UNDEFID && tablenum == 0) )
-    tableID = tableInq(modelID, tablenum, tablename);
     */
-  if ( tableID == UNDEFID )
+  /*
+    -----------------------------------------------------------------
+    Section 7.6 . Print triangular data
+    -----------------------------------------------------------------
+  */
+  if ( isec2[0] == 192 /* && ISEC1_CenterID == 78 */ )
     {
-      tableID = tableNewEntry();
-
-      parTable[tableID].modelID = modelID;
-      parTable[tableID].number  = tablenum;
-      if ( tablename )
-	parTable[tableID].name = strdupx(tablename);
-
-      parTable[tableID].pars = (PAR *) malloc(MAX_PARS * sizeof(PAR));
+      fprintf(grprsm, " Data represent type = triangular   (Table 6) %9d\n", isec2[0]);
+      fprintf(grprsm, " Number of factor 2 in factorisation of Ni.   %9d\n", isec2[1]);
+      fprintf(grprsm, " Number of factor 3 in factorisation of Ni.   %9d\n", isec2[2]);
+      fprintf(grprsm, " Number of diamonds (Nd).                     %9d\n", isec2[3]);
+      fprintf(grprsm, " Number of triangular subdivisions of the\n");
+      fprintf(grprsm, "           icosahedron (Ni).                  %9d\n", isec2[4]);
+      fprintf(grprsm, " Flag for orientation of diamonds (Table A).  %9d\n", isec2[5]);
+      fprintf(grprsm, " Latitude of pole point.                      %9d\n", isec2[6]);
+      fprintf(grprsm, " Longitude of pole point.                     %9d\n", isec2[7]);
+      fprintf(grprsm, " Longitude of the first diamond.              %9d\n", isec2[8]);
+      fprintf(grprsm, " Flag for storage sequence (Table B).         %9d\n", isec2[9]);
+      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
+      goto LABEL800;
     }
+  /*
+    -----------------------------------------------------------------
+    Drop through to here => representation type not catered for.
+    -----------------------------------------------------------------
+  */
+  fprintf(grprsm, "GRPRS2 :Data representation type not catered for -%d\n", isec2[0]);
 
-  return (tableID);
-}
-
-static void tableDefModelID(int tableID, int modelID)
-{
-  parTable[tableID].modelID = modelID;
-}
-
-static void tableDefNum(int tableID, int tablenum)
-{
-  parTable[tableID].number  = tablenum;
-}
-
-int tableInqNum(int tableID)
-{
-  int number = 0;
+  goto LABEL900;
+  /*
+    -----------------------------------------------------------------
+    Section 8 . Print vertical coordinate parameters,
+                rotated grid information,
+                stretched grid information, if any.
+    -----------------------------------------------------------------
+  */
+ LABEL800:;
+  /*
+    Vertical coordinate parameters ...
+  */
+  if ( isec2[11] != 0 )
+    {
+      fprintf(grprsm, " \n");
+      fprintf(grprsm, " Vertical Coordinate Parameters.\n");
+      fprintf(grprsm, " -------------------------------\n");
+      for ( i = 10; i < isec2[11]+10; i++ )
+	fprintf(grprsm, "    %20.12f\n", fsec2[i]);
+    }
+  /*
+    Rotated and stretched grids introduced in Edition 1.
+  */
+  if ( iedit < 1 ) goto LABEL900;
+  /*
+    Rotated grid information ...
+  */
+  if ( isec2[0] == 10 || isec2[0] == 30 || 
+       isec2[0] == 14 || isec2[0] == 34 || 
+       isec2[0] == 60 || isec2[0] == 80 || 
+       isec2[0] == 30 )
+    {
+      fprintf(grprsm, " \n");
+      fprintf(grprsm, " Latitude of southern pole of rotation.       %9d\n", isec2[12]);
+      fprintf(grprsm, " Longitude of southern pole of rotation.      %9d\n", isec2[13]);
+      fprintf(grprsm, " Angle of rotation.                     %20.10f\n", fsec2[0]);
+    }
+  /*
+    Stretched grid information ...
+  */
+  if ( isec2[0] == 20 || isec2[0] == 30 || 
+       isec2[0] == 24 || isec2[0] == 34 || 
+       isec2[0] == 70 || isec2[0] == 80 )
+    {
+      fprintf(grprsm, " \n");
+      fprintf(grprsm, " Latitude of pole of stretching.              %9d\n", isec2[14]);
+      fprintf(grprsm, " Longitude of pole of stretching.             %9d\n", isec2[15]);
+      fprintf(grprsm, " Stretching factor.                     %20.10f\n", fsec2[1]);
+    }
 
-  if ( tableID >= 0 && tableID < MAX_TABLE )
-    number = parTable[tableID].number;
+ LABEL900:;
 
-  return (number);
+  return;
 }
 
-int tableInqModel(int tableID)
+void gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2sp)
 {
-  int modelID = -1;
+  int inum;
+  int j;
+  double *fsec2;
 
-  if ( tableID >= 0 && tableID < MAX_TABLE )
-    modelID = parTable[tableID].modelID;
+  inum = 10 + isec2[11];
 
-  return (modelID);
-}
+  fsec2 = (double*) malloc(inum*sizeof(double));
+  if ( fsec2 == NULL ) SysError("No Memory!");
 
-static void partabCheckID(int item)
-{
-  if ( item < 0 || item >= parTableSize )
-    Error("item %d undefined!", item);
+  for ( j = 0; j < inum; j++ )
+     fsec2[j] = fsec2sp[j];
+  
+  gribPrintSec2DP(isec0, isec2, fsec2);
 
-  if ( ! parTable[item].name )
-    Error("item %d name undefined!", item);
+  free(fsec2);
 }
 
-char *tableInqNamePtr(int tableID)
+void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3)
 {
-  char *tablename = NULL;
-
-  if ( CDI_Debug )
-    Message("tableID = %d", tableID);
+  /*
 
-  if ( ! ParTableInit ) parTableInit();
+    Print the information in the Bit-Map Section
+    (Section 3) of decoded GRIB data.
 
-  if ( tableID >= 0 && tableID < parTableSize )
-    if ( parTable[tableID].name )
-      tablename = parTable[tableID].name;
+    Input Parameters:
 
-  return (tablename);
-}
+       isec0  - Array of decoded integers from Section 0
 
-void tableWrite(const char *ptfile, int tableID)
-{
-  int item, npars;
-  size_t maxname = 4, maxlname = 10, maxunits = 2;
-  FILE *ptfp;
-  int tablenum, modelID, instID = CDI_UNDEFID;
-  int center = 0, subcenter = 0;
-  const char *instnameptr = NULL, *modelnameptr = NULL;
+       isec3  - Array of decoded integers from Section 3
 
-  if ( CDI_Debug )
-    Message("write parameter table %d to %s", tableID, ptfile);
+       fsec3  - Array of decoded floats from Section 3
 
-  if ( tableID == UNDEFID )
-    {
-      Warning("parameter table ID undefined");
-      return;
-    }
 
-  partabCheckID(tableID);
+    Converted from EMOS routine GRPRS3.
 
-  ptfp = fopen(ptfile, "w");
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-  npars = parTable[tableID].npars;
+  */
 
-  for ( item = 0; item < npars; item++)
-    {
-      if ( parTable[tableID].pars[item].name )
-	{
-	  size_t lenname = strlen(parTable[tableID].pars[item].name);
-	  if ( lenname  > maxname )  maxname  = lenname;
-	}
+  UNUSED(isec0);
 
-      if ( parTable[tableID].pars[item].longname )
-	{
-	  size_t lenlname = strlen(parTable[tableID].pars[item].longname);
-	  if ( lenlname > maxlname ) maxlname = lenlname;
-	}
+  grsdef();
 
-      if ( parTable[tableID].pars[item].units )
-	{
-	  size_t lenunits = strlen(parTable[tableID].pars[item].units);
-	  if ( lenunits > maxunits ) maxunits = lenunits;
-	}
-    }
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " Section 3 - Bit-map Section.\n");
+  fprintf(grprsm, " -------------------------------------\n");
 
-  tablenum = tableInqNum(tableID);
-  modelID = parTable[tableID].modelID;
-  if ( modelID != CDI_UNDEFID )
-    {
-      modelnameptr = modelInqNamePtr(modelID);
-      instID = modelInqInstitut(modelID);
-    }
-  if ( instID != CDI_UNDEFID )
-    {
-      center = institutInqCenter(instID);
-      subcenter = institutInqSubcenter(instID);
-      instnameptr = institutInqNamePtr(instID);
-    }
+  if ( isec3[0] != 0 )
+    fprintf(grprsm, " Predetermined bit-map number.                %9d\n", isec3[0]);
+  else
+    fprintf(grprsm, " No predetermined bit-map.\n");
 
-  fprintf(ptfp, "# Parameter table\n");
-  fprintf(ptfp, "#\n");
-  if ( tablenum )
-    fprintf(ptfp, "# TABLE_ID=%d\n", tablenum);
-  fprintf(ptfp, "# TABLE_NAME=%s\n", parTable[tableID].name);
-  if ( modelnameptr )
-    fprintf(ptfp, "# TABLE_MODEL=%s\n", modelnameptr);
-  if ( instnameptr )
-    fprintf(ptfp, "# TABLE_INSTITUT=%s\n", instnameptr);
-  if ( center )
-    fprintf(ptfp, "# TABLE_CENTER=%d\n", center);
-  if ( subcenter )
-    fprintf(ptfp, "# TABLE_SUBCENTER=%d\n", subcenter);
-  fprintf(ptfp, "#\n");
-  fprintf(ptfp, "#\n");
-  fprintf(ptfp, "# id       = parameter ID\n");
-  fprintf(ptfp, "# name     = variable name\n");
-  fprintf(ptfp, "# title    = long name (description)\n");
-  fprintf(ptfp, "# units    = variable units\n");
-  fprintf(ptfp, "#\n");
-  fprintf(ptfp, "# The format of each record is:\n");
-  fprintf(ptfp, "#\n");
-  fprintf(ptfp, "# id | %-*s | %-*s | %-*s\n",
-	  (int)maxname,  "name",
-	  (int)maxlname, "title",
-	  (int)maxunits, "units");
-	  
-  for ( item = 0; item < npars; item++)
-    {
-      const char *name = parTable[tableID].pars[item].name,
-        *longname = parTable[tableID].pars[item].longname,
-        *units = parTable[tableID].pars[item].units;
-      if ( name == NULL ) name = " ";
-      if ( longname == NULL ) longname = " ";
-      if ( units == NULL ) units = " ";
-      fprintf(ptfp, "%4d | %-*s | %-*s | %-*s\n",
-	      parTable[tableID].pars[item].id,
-	      (int)maxname, name,
-	      (int)maxlname, longname,
-	      (int)maxunits, units);
-    }
+  fprintf(grprsm, " Missing data value for integer data.    %14d\n", isec3[1]);
 
-  fclose(ptfp);
+  fprintf(grprsm, " Missing data value for real data. %20.6g\n", fsec3[1]);
 }
 
-
-void tableWriteC(const char *filename, int tableID)
+void gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3sp)
 {
-  FILE *ptfp = fopen(filename, "w");
-  if (!ptfp)
-    Error("failed to open file \"%s\"!", filename);
-  if ( CDI_Debug )
-    Message("write parameter table %d to %s", tableID, filename);
-  tableFWriteC(ptfp, tableID);
-  fclose(ptfp);
+  double fsec3[2];
+
+  fsec3[0] = fsec3sp[0];
+  fsec3[1] = fsec3sp[1];
+  
+  gribPrintSec3DP(isec0, isec3, fsec3);
 }
 
-void tableFWriteC(FILE *ptfp, int tableID)
+void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4)
 {
-  const char chelp[] = "";
-  int item, npars;
-  size_t maxname = 0, maxlname = 0, maxunits = 0;
-  char tablename[256];
-
+  /*
 
-  if ( tableID == UNDEFID )
-    {
-      Warning("parameter table ID undefined");
-      return;
-    }
+    Print the information in the Binary Data Section
+    (Section 4) of decoded GRIB data.
 
-  partabCheckID(tableID);
+    Input Parameters:
 
-  npars = parTable[tableID].npars;
+       isec0  - Array of decoded integers from Section 0
 
-  for ( item = 0; item < npars; item++)
-    {
-      if ( parTable[tableID].pars[item].name )
-	{
-	  size_t lenname = strlen(parTable[tableID].pars[item].name);
-	  if ( lenname  > maxname )  maxname  = lenname;
-	}
+       isec4  - Array of decoded integers from Section 4
 
-      if ( parTable[tableID].pars[item].longname )
-	{
-	  size_t lenlname = strlen(parTable[tableID].pars[item].longname);
-	  if ( lenlname > maxlname ) maxlname = lenlname;
-	}
+       fsec4  - Array of decoded floats from Section 4
 
-      if ( parTable[tableID].pars[item].units )
-	{
-	  size_t lenunits = strlen(parTable[tableID].pars[item].units);
-	  if ( lenunits > maxunits ) maxunits = lenunits;
-	}
-    }
 
-  strncpy(tablename, parTable[tableID].name, sizeof (tablename));
-  tablename[sizeof (tablename) - 1] = '\0';
-  {
-    size_t len = strlen(tablename);
-    for (size_t i = 0; i < len; i++ )
-      if ( tablename[i] == '.' ) tablename[i] = '_';
-  }
-  fprintf(ptfp, "static const PAR %s[] = {\n", tablename);
+    Converted from EMOS routine GRPRS4.
 
-  for ( item = 0; item < npars; item++ )
-    {
-      size_t len = strlen(parTable[tableID].pars[item].name),
-        llen = parTable[tableID].pars[item].longname
-        ? strlen(parTable[tableID].pars[item].longname) : 0,
-        ulen = parTable[tableID].pars[item].units
-        ? strlen(parTable[tableID].pars[item].units) : 0;
-      fprintf(ptfp, "  {%4d, 0, \"%s\", %-*s%c%s%s, %-*s%c%s%s %-*s},\n",
-	      parTable[tableID].pars[item].id,
-	      parTable[tableID].pars[item].name, (int)(maxname-len), chelp,
-              llen?'"':' ',
-              llen?parTable[tableID].pars[item].longname:"NULL",
-              llen?"\"":"",
-              (int)(maxlname-(llen?llen:3)), chelp,
-              ulen?'"':' ',
-              ulen?parTable[tableID].pars[item].units:"NULL",
-              ulen?"\"":"",
-              (int)(maxunits-(ulen?ulen:3)), chelp);
-    }
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-  fprintf(ptfp, "};\n\n");
-}
+  */
+  int inum;
+  int j;
 
+  UNUSED(isec0);
 
-int tableInqParCode(int tableID, char *varname, int *code)
-{
-  int item, npars;
-  int err = 0;
+  grsdef();
 
-  npars = parTable[tableID].npars;
+  /*
+    -----------------------------------------------------------------
+    Section 1 . Print integer information from isec4.
+    -----------------------------------------------------------------
+  */
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " Section 4 - Binary Data  Section.\n");
+  fprintf(grprsm, " -------------------------------------\n");
 
-  if ( tableID == UNDEFID || varname == NULL )
-    {
-      err = 1;
-    }
-  else
+  fprintf(grprsm, " Number of data values coded/decoded.         %9d\n", isec4[0]);
+  fprintf(grprsm, " Number of bits per data value.               %9d\n", isec4[1]);
+  fprintf(grprsm, " Type of data       (0=grid pt, 128=spectral).%9d\n", isec4[2]);
+  fprintf(grprsm, " Type of packing    (0=simple, 64=complex).   %9d\n", isec4[3]);
+  fprintf(grprsm, " Type of data       (0=float, 32=integer).    %9d\n", isec4[4]);
+  fprintf(grprsm, " Additional flags   (0=none, 16=present).     %9d\n", isec4[5]);
+  fprintf(grprsm, " Reserved.                                    %9d\n", isec4[6]);
+  fprintf(grprsm, " Number of values   (0=single, 64=matrix).    %9d\n", isec4[7]);
+  fprintf(grprsm, " Secondary bit-maps (0=none, 32=present).     %9d\n", isec4[8]);
+  fprintf(grprsm, " Values width       (0=constant, 16=variable).%9d\n", isec4[9]);
+  /*
+    If complex packing ..
+  */
+  if ( isec4[3] == 64 )
     {
-      for ( item = 0; item < npars; item++ )
+      if ( isec4[2] == 128 )
 	{
-	  if ( parTable[tableID].pars[item].name )
-	    if ( strcmp(parTable[tableID].pars[item].name, varname) == 0 )
-	      {
-		*code = parTable[tableID].pars[item].id;
-		break;
-	      }
+	  fprintf(grprsm, " Byte offset of start of packed data (N).     %9d\n", isec4[15]);
+	  fprintf(grprsm, " Power (P * 1000).                            %9d\n", isec4[16]);
+	  fprintf(grprsm, " Pentagonal resolution parameter J for subset.%9d\n", isec4[17]);
+	  fprintf(grprsm, " Pentagonal resolution parameter K for subset.%9d\n", isec4[18]);
+	  fprintf(grprsm, " Pentagonal resolution parameter M for subset.%9d\n", isec4[19]);
 	}
-      if ( item == npars ) err = 1;
+      else
+	{
+	  fprintf(grprsm, " Bits number of 2nd order values    (none=>0).%9d\n", isec4[10]);
+	  fprintf(grprsm, " General extend. 2-order packing (0=no,8=yes).%9d\n", isec4[11]);
+	  fprintf(grprsm, " Boustrophedonic ordering        (0=no,4=yes).%9d\n", isec4[12]);
+	  fprintf(grprsm, " Spatial differencing order          (0=none).%9d\n", isec4[13]+isec4[14]);
+        }
     }
+  /*
+    Number of non-missing values
+  */
+  if ( isec4[20] != 0 )
+    fprintf(grprsm, " Number of non-missing values                 %9d\n", isec4[20]);
+  /*
+    Information on matrix of values , if present.
+  */
+  if ( isec4[7] == 64 )
+    {
+      fprintf(grprsm, " First dimension (rows) of each matrix.       %9d\n", isec4[49]);
+      fprintf(grprsm, " Second dimension (columns) of each matrix.   %9d\n", isec4[50]);
+      fprintf(grprsm, " First dimension coordinate values definition.%9d\n", isec4[51]);
+      fprintf(grprsm, " (Code Table 12)\n");
+      fprintf(grprsm, " NC1 - Number of coefficients for 1st dimension.%7d\n", isec4[52]);
+      fprintf(grprsm, " Second dimension coordinate values definition.%8d\n", isec4[53]);
+      fprintf(grprsm, " (Code Table 12)\n");
+      fprintf(grprsm, " NC2 - Number of coefficients for 2nd dimension.%7d\n", isec4[54]);
+      fprintf(grprsm, " 1st dimension physical signifance (Table 13). %8d\n", isec4[55]);
+      fprintf(grprsm, " 2nd dimension physical signifance (Table 13).%8d\n", isec4[56]);
+    }
+  /*
+    -----------------------------------------------------------------
+    Section 2. Print values from fsec4.
+    -----------------------------------------------------------------
+  */
 
-  return (err);
-}
-
-
-int tableInqParName(int tableID, int code, char *varname)
-{
-  int item, npars;
-  int err = 0;
-
-  npars = parTable[tableID].npars;
+  inum = isec4[0];
+  if ( inum <  0 ) inum = - inum;
+  if ( inum > 20 ) inum = 20;
+  /*
+    Print first inum values.
+  */
+  fprintf(grprsm, " \n");
+  fprintf(grprsm, " First %4d data values.\n", inum);
 
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
+  if ( isec4[4] == 0 )
     {
-      for ( item = 0; item < npars; item++ )
+      /*
+	Print real values ...
+      */
+      for ( j = 0; j < inum; j++ )
 	{
-	  if ( parTable[tableID].pars[item].id == code )
+	  if ( fabs(fsec4[j]) > 0 )
 	    {
-	      if ( parTable[tableID].pars[item].name )
-		strcpy(varname, parTable[tableID].pars[item].name);
-	      break;
+	      if ( fabs(fsec4[j]) >= 0.1 && fabs(fsec4[j]) <= 1.e8 )
+		fprintf(grprsm, " %#16.8G    \n", fsec4[j]);
+	      else
+		fprintf(grprsm, " %#20.8E\n", fsec4[j]);
 	    }
+	  else
+	    fprintf(grprsm, " %#16.0f    \n", fabs(fsec4[j]));
 	}
-      if ( item == npars ) err = 1;
     }
-
-  return (err);
-}
-
-
-const char *tableInqParNamePtr(int tableID, int code)
-{
-  const char *name = NULL;
-  int item, npars;
-
-  if ( tableID != UNDEFID )
+  else
     {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
-	{
-	  if ( parTable[tableID].pars[item].id == code )
-	    {
-	      name = parTable[tableID].pars[item].name;
-	      break;
-	    }
-	}
+      /*
+	Print integer values ...
+      */
+      fprintf(grprsm, " Print of integer values not supported\n");
+      /*
+        CALL SETPAR(IBIT,IDUM,IDUM)
+        DO 212 J=1,INUM
+           INSPT = 0
+           CALL INXBIT(IVALUE,1,INSPT,FSEC4(J),1,IBIT,IBIT,'C',IRET)
+           WRITE (*,9033) IVALUE
+ 9033 FORMAT(' ',I15)
+  212   CONTINUE
+      ENDIF
+      */
     }
-
-  return (name);
 }
 
-
-const char *tableInqParLongnamePtr(int tableID, int code)
+void gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4sp)
 {
-  const char *longname = NULL;
-  int item, npars;
+  int inum;
+  int j;
+  double fsec4[20];
 
-  if ( tableID != UNDEFID )
-    {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
-	{
-	  if ( parTable[tableID].pars[item].id == code )
-	    {
-	      longname = parTable[tableID].pars[item].longname;
-	      break;
-	    }
-	}
-    }
+  inum = isec4[0];
+  if ( inum <  0 ) inum = -inum;
+  if ( inum > 20 ) inum = 20;
 
-  return (longname);
+  for ( j = 0; j < inum; j++ ) fsec4[j] = fsec4sp[j];
+  
+  gribPrintSec4DP(isec0, isec4, fsec4);
 }
 
-
-const char *tableInqParUnitsPtr(int tableID, int code)
+void gribPrintSec4Wave(int *isec4)
 {
-  const char *units = NULL;
-  int item, npars;
-
-  if ( tableID != UNDEFID )
-    {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
-	{
-	  if ( parTable[tableID].pars[item].id == code )
-	    {
-	      units = parTable[tableID].pars[item].units;
-	      break;
-	    }
-	}
-    }
-
-  return (units);
-}
+  /*
 
+    Print the wave coordinate information in the Binary Data
+    Section (Section 4) of decoded GRIB data.
 
-int tableInqParLongname(int tableID, int code, char *longname)
-{
-  int item, npars;
-  int err = 0;
+    Input Parameters:
 
-  npars = parTable[tableID].npars;
+       isec4 - Array of decoded integers from Section 4
 
-  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
-    Error("Invalid table ID %d", tableID);
+    Comments:
 
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
-    {
-      for ( item = 0; item < npars; item++ )
-	{
-	  if ( parTable[tableID].pars[item].id == code )
-	    {
-	      if ( parTable[tableID].pars[item].longname )
-		strcpy(longname, parTable[tableID].pars[item].longname);
-	      break;
-	    }
-	}
-      if ( item == npars ) err = 1;
-    }
+       Wave coordinate information held in isec4 are 32-bit floats,
+       hence the PTEMP and NTEMP used for printing are 4-byte variables.
 
-  return (err);
-}
 
+    Converted from EMOS routine GRPRS4W.
 
-int tableInqParUnits(int tableID, int code, char *units)
-{
-  int item, npars;
-  int err = 0;
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-  npars = parTable[tableID].npars;
+  */
+  int    jloop;
+  int    ntemp[100];
+  float *ptemp;
 
-  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
-    Error("Invalid table ID %d", tableID);
+  grsdef();
 
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
+  /*
+    -----------------------------------------------------------------
+    Section 1 . Print integer information from isec4.
+    -----------------------------------------------------------------
+  */
+  fprintf(grprsm, " Coefficients defining first dimension coordinates:\n");
+  for ( jloop = 0; jloop < isec4[52]; jloop++ )
     {
-      for ( item = 0; item < npars; item++ )
-	{
-	  if ( parTable[tableID].pars[item].id == code )
-	    {
-	      if ( parTable[tableID].pars[item].units )
-		strcpy(units, parTable[tableID].pars[item].units);
-	      break;
-	    }
-	}
-      if ( item == npars ) err = 1;
+      ntemp[jloop] = isec4[59 + jloop];
+      ptemp = (float *) &ntemp[jloop];
+      fprintf(grprsm, "%20.10f\n", *ptemp);
     }
-
-  return (err);
-}
-
-
-void tableInqPar(int tableID, int code, char *name, char *longname, char *units)
-{
-  int item, npars;
-
-  npars = parTable[tableID].npars;
-
-  for ( item = 0; item < npars; item++ )
+  fprintf(grprsm, " Coefficients defining second dimension coordinates:\n");
+  for ( jloop = 0; jloop < isec4[54]; jloop++ )
     {
-      if ( parTable[tableID].pars[item].id == code )
-	{
-	  if ( parTable[tableID].pars[item].name )
-	    strcpy(name, parTable[tableID].pars[item].name);
-	  if ( parTable[tableID].pars[item].longname )
-	    strcpy(longname, parTable[tableID].pars[item].longname);
-	  if ( parTable[tableID].pars[item].units )
-	    strcpy(units, parTable[tableID].pars[item].units);
-	  break;
-	}
+      ntemp[jloop] = isec4[59 + isec4[52] + jloop];
+      ptemp = (float *) &ntemp[jloop];
+      fprintf(grprsm, "%20.10f\n", *ptemp);
     }
 }
-
-int tableInqNumber(void)
-{
-  if ( ! ParTableInit ) parTableInit();
-
-  return (parTableNum);
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#include <stdio.h>
 #include <string.h>
-#include <float.h>
-#include <sys/types.h>
-
+#include <ctype.h>
 
 
-#undef  IsBigendian
-#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
 
-void cdiPrintDatatypes(void)
+int gribOpen(const char *filename, const char *mode)
 {
-  /* IsBigendian returns 1 for big endian byte order */
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
+  int fileID = fileOpen(filename, mode);
 
-  fprintf (stderr, "+-------------+-------+\n");
-  fprintf (stderr, "| types       | bytes |\n");
-  fprintf (stderr, "+-------------+-------+\n");
-  fprintf (stderr, "| void *      |   %3d |\n", (int) sizeof(void *));
-  fprintf (stderr, "+-------------+-------+\n");
-  fprintf (stderr, "| char        |   %3d |\n", (int) sizeof(char));
-  fprintf (stderr, "+-------------+-------+\n");
-  fprintf (stderr, "| short       |   %3d |\n", (int) sizeof(short));
-  fprintf (stderr, "| int         |   %3d |\n", (int) sizeof(int));
-  fprintf (stderr, "| long        |   %3d |\n", (int) sizeof(long));
-  fprintf (stderr, "| long long   |   %3d |\n", (int) sizeof(long long));
-  fprintf (stderr, "| size_t      |   %3d |\n", (int) sizeof(size_t));
-  fprintf (stderr, "| off_t       |   %3d |\n", (int) sizeof(off_t));
-  fprintf (stderr, "+-------------+-------+\n");
-  fprintf (stderr, "| float       |   %3d |\n", (int) sizeof(float));
-  fprintf (stderr, "| double      |   %3d |\n", (int) sizeof(double));
-  fprintf (stderr, "| long double |   %3d |\n", (int) sizeof(long double));
-  fprintf (stderr, "+-------------+-------+\n\n");
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
-  fprintf (stderr, "+-------------+-----------+\n");
-  fprintf (stderr, "| INT32       | %-9s |\n", STRING(INT32));
-  fprintf (stderr, "| INT64       | %-9s |\n", STRING(INT64));
-  fprintf (stderr, "| FLT32       | %-9s |\n", STRING(FLT32));
-  fprintf (stderr, "| FLT64       | %-9s |\n", STRING(FLT64));
-  fprintf (stderr, "+-------------+-----------+\n");
+#if defined (__sun)
+  if ( fileID != FILE_UNDEFID && tolower(*mode) == 'r' )
+    {
+      fileSetBufferType(fileID, FILE_BUFTYPE_MMAP);
+    }
+#endif
 
-  if ( IsBigendian() )
-    fprintf (stderr, "\n  byte ordering is BIGENDIAN\n\n");
-  else
-    fprintf (stderr, "\n  byte ordering is LITTLEENDIAN\n\n");
+  return fileID;  
 }
 
-static char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-"
-  "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
-  "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
-
-enum {
-  uuidNumHexChars = 36,
-};
 
-void uuid2str(const unsigned char *uuid, char *uuidstr)
+void gribClose(int fileID)
 {
-
-  if ( uuid == NULL || uuidstr == NULL ) return;
-
-  int iret = sprintf(uuidstr, uuidFmt,
-                     uuid[0], uuid[1], uuid[2], uuid[3],
-                     uuid[4], uuid[5], uuid[6], uuid[7],
-                     uuid[8], uuid[9], uuid[10], uuid[11],
-                     uuid[12], uuid[13], uuid[14], uuid[15]);
-
-  if ( iret != uuidNumHexChars ) uuidstr[0] = 0;
+  fileClose(fileID);
 }
 
 
-int str2uuid(const char *uuidstr, unsigned char *uuid)
+off_t gribGetPos(int fileID)
 {
-  if ( uuid == NULL || uuidstr == NULL || strlen(uuidstr) != uuidNumHexChars)
-    return -1;
-
-  int iret = sscanf(uuidstr, uuidFmt,
-                    &uuid[0], &uuid[1], &uuid[2], &uuid[3],
-                    &uuid[4], &uuid[5], &uuid[6], &uuid[7],
-                    &uuid[8], &uuid[9], &uuid[10], &uuid[11],
-                    &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
-  if ( iret != CDI_UUID_SIZE ) return -1;
-  return iret;
+  return fileGetPos(fileID);
 }
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <math.h>
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-#ifndef  M_PI
-#define  M_PI        3.14159265358979323846  /* pi */
-#endif
-
-#ifndef  M_SQRT2
-#define  M_SQRT2     1.41421356237309504880
-#endif
-
 
-static
-void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag, 
-            double *pw, double *pdxn, double *pxmod)
+int gribCheckFiletype(int fileID)
 {
-  double zdlk;
-  double zdlldn;
-  double zdlx;
-  double zdlmod;
-  double zdlxn;
-
-  size_t ik, jn;
+  int found = 0;
+  char buffer[4];
 
-  /* 1.0 Newton iteration step */
+  if ( fileRead(fileID, buffer, 4) != 4 ) return found;
 
-  zdlx = pdx;
-  zdlk = 0.0;
-  if (kodd == 0) 
+  if ( memcmp(buffer, "GRIB", 4) == 0 )
     {
-      zdlk = 0.5*pfn[0];
+      found = 1;
+      if ( CGRIBEX_Debug ) Message("found GRIB file = %s", fileInqName(fileID));
     }
-  zdlxn  = 0.0;
-  zdlldn = 0.0;
-
-  ik = 1;
-
-  if (kflag == 0) 
+  else
     {
-      for(size_t jn = 2-kodd; jn <= kn; jn += 2) 
+      long offset;
+      int ierr = gribFileSeek(fileID, &offset);
+      fileRewind(fileID);
+      if ( !ierr )
 	{
-	  /* normalised ordinary Legendre polynomial == \overbar{p_n}^0 */
-	  zdlk   = zdlk + pfn[ik]*cos((double)(jn)*zdlx);
-	  /* normalised derivative == d/d\theta(\overbar{p_n}^0) */
-	  zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
-	  ik++;
+	  found = 1;
+	  if ( CGRIBEX_Debug ) Message("found seek GRIB file = %s", fileInqName(fileID));
 	}
-      /* Newton method */
-      zdlmod = -(zdlk/zdlldn);
-      zdlxn = zdlx + zdlmod;
-      *pdxn = zdlxn;
-      *pxmod = zdlmod;
     }
 
-  /* 2.0 Compute weights */
+  return found;
+}
 
-  if (kflag == 1) 
+
+int gribCheckSeek(int fileID, long *offset, int *version)
+{
+  int ierr = gribFileSeek(fileID, offset);
+
+  *version = -1;
+  if ( !ierr )
     {
-      for(jn = 2-kodd; jn <= kn; jn += 2) 
-	{
-	  /* normalised derivative */
-	  zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
-	  ik++;
-	}
-      *pw = (double)(2*kn+1)/(zdlldn*zdlldn);
+      char buffer[4];
+     if ( fileRead(fileID, buffer, 4) == 4 )
+	*version = buffer[3];
     }
 
-  return;
+  return ierr;
 }
 
-static
-void gawl(double *pfn, double *pl, double *pw, size_t kn)
-{
-  double pmod = 0;
-  int iflag;
-  int itemax;
-  double zw = 0;
-  double zdlx;
-  double zdlxn = 0;
-
-  /* 1.0 Initizialization */
 
-  iflag  =  0;
-  itemax = 20;
+int gribFileSeekOld(int fileID, long *offset)
+{
+  /* position file pointer after GRIB */
+  int ch;
+  int buffersize = 4096;
+  unsigned char buffer[4096];
+  int retry = 4096;
+  int i;
 
-  size_t iodd   = (kn % 2);
+  *offset = 0;
 
-  zdlx   =  *pl;
+  void *fileptr = filePtr(fileID);
 
-  /* 2.0 Newton iteration */
+  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[0] = ch;
+  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[1] = ch;
+  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[2] = ch;
+  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[3] = ch;
+  /*
+  fileRead(fileID, buffer, 4);
+  */
 
-  for (int jter = 1; jter <= itemax+1; jter++)
+  while ( retry-- )
     {
-      cpledn(kn, iodd, pfn, zdlx, iflag, &zw, &zdlxn, &pmod);
-      zdlx = zdlxn;
-      if (iflag == 1) break;
-      if (fabs(pmod) <= DBL_EPSILON*1000.0) iflag = 1;
+      for ( i = 0; i < buffersize-4; ++i )
+	{
+	  if (buffer[i  ] == 'G' && 
+	      buffer[i+1] == 'R' &&
+	      buffer[i+2] == 'I' &&
+	      buffer[i+3] == 'B')
+	    {
+	      if ( CGRIBEX_Debug )
+		Message("record offset = %d", (int) *offset);
+	      return (0);
+	    }
+	  else
+	    {
+	      ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[i+4] = ch;
+	      (*offset)++;
+	    }
+	}
+      buffer[0] = buffer[i  ];
+      buffer[1] = buffer[i+1];
+      buffer[2] = buffer[i+2];
+      buffer[3] = buffer[i+3];
     }
 
-  *pl = zdlxn;
-  *pw = zw;
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  return;
+  return 1;
 }
 
-static
-void gauaw(size_t kn, double *restrict pl, double *restrict pw)
+
+int gribFileSeek(int fileID, long *offset)
 {
-  /*
-   * 1.0 Initialize Fourier coefficients for ordinary Legendre polynomials
-   *
-   * Belousov, Swarztrauber, and ECHAM use zfn(0,0) = sqrt(2)
-   * IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 (zfn(0,0) = 2.0)
-   */
-  double *zfn, *zfnlat;
+  /* position file pointer after GRIB */
+  const long GRIB = 0x47524942;
+  long code = 0;
+  int ch;
+  int retry = 4096*4096;
 
-  double z, zfnn;
+  *offset = 0;
 
-  zfn    = (double *) malloc((kn+1) * (kn+1) * sizeof(double));
-  zfnlat = (double *) malloc((kn/2+1+1)*sizeof(double));
+  void *fileptr = filePtr(fileID);
 
-  zfn[0] = M_SQRT2;
-  for (size_t jn = 1; jn <= kn; jn++)
+  while ( retry-- )
     {
-      zfnn = zfn[0];
-      for (size_t jgl = 1; jgl <= jn; jgl++)
-	{
-	  zfnn *= sqrt(1.0-0.25/((double)(jgl*jgl))); 
-	}
-
-      zfn[jn*(kn+1)+jn] = zfnn;
+      ch = filePtrGetc(fileptr);
+      if ( ch == EOF ) return (-1);
+    
+      code = ( (code << 8) + ch ) & 0xFFFFFFFF;
 
-      size_t iodd = jn % 2;
-      for (size_t jgl = 2; jgl <= jn-iodd; jgl += 2) 
+      if ( code == GRIB )
 	{
-	  zfn[jn*(kn+1)+jn-jgl] = zfn[jn*(kn+1)+jn-jgl+2]
-	    *((double)((jgl-1)*(2*jn-jgl+2)))/((double)(jgl*(2*jn-jgl+1)));
+	  if ( CGRIBEX_Debug )
+	    Message("record offset = %d", (int) *offset);
+	  return (0);
 	}
+
+      (*offset)++;
     }
 
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  /* 2.0 Gaussian latitudes and weights */
+  return 1;
+}
 
-  size_t iodd = kn % 2;
-  size_t ik = iodd;
-  for (size_t jgl = iodd; jgl <= kn; jgl += 2)
-    {
-      zfnlat[ik] = zfn[kn*(kn+1)+jgl];
-      ik++;
-    } 
 
-  /*
-   * 2.1 Find first approximation of the roots of the
-   *     Legendre polynomial of degree kn.
-   */
+int gribFileSeekTest(int fileID, long *offset)
+{
+  /* position file pointer after GRIB */
+  const long GRIB = 0x47524942;
+  long code = 0;
+  int ch;
+  int i = 0;
+  const int buffersize = 8;
+  unsigned char buffer[8];
+  int retry = 4096*4096;
+  int nread = 0;
 
-  size_t ins2 = kn/2+(kn % 2);
+  *offset = 0;
 
-  for (size_t jgl = 1; jgl <= ins2; jgl++) 
+  void *fileptr = filePtr(fileID);
+
+  while ( retry-- )
     {
-      z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2)); 
-      pl[jgl-1] = z+1.0/(tan(z)*((double)(8*kn*kn)));
-    }
+      if ( i >= nread )
+	{
+	  nread = (int) filePtrRead(fileptr, buffer, buffersize);
+	  if ( nread == 0 ) return (-1);
+	  i = 0;
+	}
 
-  /* 2.2 Computes roots and weights for transformed theta */
+      ch = buffer[i++];
+      code = ( (code << 8) + ch ) & 0xFFFFFFFF;
 
-  for (size_t jgl = ins2; jgl >= 1 ; jgl--) 
-    {
-      size_t jglm1 = jgl-1;
-      gawl(zfnlat, &(pl[jglm1]), &(pw[jglm1]), kn);
-    }
+      if ( code == GRIB )
+	{
+	  /* printf("end: %d %d\n", nread, i); */
+	  if ( CGRIBEX_Debug )
+	    Message("record offset = %d", (int) *offset);
 
-  /* convert to physical latitude */
+	  if ( i != nread ) fileSetPos(fileID, (off_t) i-nread, SEEK_CUR);
 
-  for (size_t jgl = 0; jgl < ins2; jgl++) 
-    {
-      pl[jgl] = cos(pl[jgl]);
-    }
+	  return (0);
+	}
 
-  for (size_t jgl = 1; jgl <= kn/2; jgl++) 
-    {
-      size_t jglm1 = jgl-1;
-      size_t isym =  kn-jgl;
-      pl[isym] =  -pl[jglm1];
-      pw[isym] =  pw[jglm1];
+      (*offset)++;
     }
 
-  free(zfnlat);
-  free(zfn);
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  return;
+  return 1;
 }
 
-#if 0
-static
-void gauaw_old(double *pa, double *pw, int nlat)
-{
-  /*
-   * Compute Gaussian latitudes.  On return pa contains the
-   * sine of the latitudes starting closest to the north pole and going
-   * toward the south
-   *
-   */
-
-  const int itemax = 20;
 
-  int isym, iter, ins2, jn, j;
-  double za, zw, zan;
-  double z, zk, zkm1, zkm2, zx, zxn, zldn, zmod;
+int gribReadSize(int fileID)
+{
+  void *fileptr = filePtr(fileID);
+  off_t pos = fileGetPos(fileID); 
 
-  /*
-   * Perform the Newton loop
-   * Find 0 of Legendre polynomial with Newton loop
-   */
+  unsigned b1 = (unsigned) filePtrGetc(fileptr);
+  unsigned b2 = (unsigned) filePtrGetc(fileptr);
+  unsigned b3 = (unsigned) filePtrGetc(fileptr);
 
-  ins2 = nlat/2 + nlat%2;
+  int gribsize = gribrec_len(b1, b2, b3);
+  int gribversion = filePtrGetc(fileptr);
 
-  for ( j = 0; j < ins2; j++ )
+  if ( gribsize == 24 )
     {
-      z = (double) (4*(j+1)-1)*M_PI / (double) (4*nlat+2);
-      pa[j] = cos(z + 1.0/(tan(z)*(double)(8*nlat*nlat)));
+      if ( gribversion != 1 && gribversion != 2 ) gribversion = 0;
     }
 
-  for ( j = 0; j < ins2; j++ )
+  if ( CGRIBEX_Debug )
+    Message("gribversion = %d", gribversion);
+
+  if ( gribversion == 0 )
     {
+      int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
+      int issize = 4, essize = 4;
+      int flag;
 
-      za = pa[j];
+      pdssize = gribsize;
+      fileSetPos(fileID, (off_t) 3, SEEK_CUR);
+      if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
+      flag = filePtrGetc(fileptr);
+      if ( CGRIBEX_Debug ) Message("flag        = %d", flag);
+  
+      fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
 
-      iter = 0;
-      do
+      if ( flag & 128 )
 	{
-	  iter++;
-	  zk = 0.0;
+	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	  gdssize = (b1 << 16) + (b2 << 8) + b3;
+	  fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
+	  if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
+	}
 
-	  /* Newton iteration step */
+      if ( flag & 64 )
+	{
+	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	  bmssize = (b1 << 16) + (b2 << 8) + b3;
+	  fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
+	  if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
+	}
 
-	  zkm2 = 1.0;
-	  zkm1 = za;
-	  zx = za;
-	  for ( jn = 2; jn <= nlat; jn++ )
-	    {
-	      zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double)(jn);
-	      zkm2 = zkm1;
-	      zkm1 = zk;
-	    }
-	  zkm1 = zkm2;
-	  zldn = ((double) (nlat)*(zkm1-zx*zk)) / (1.-zx*zx);
-	  zmod = -zk/zldn;
-	  zxn = zx+zmod;
-	  zan = zxn;
+      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+      bdssize = (b1 << 16) + (b2 << 8) + b3;
+      if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
 
-	  /* computes weight */
+      gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
+    }
+  else if ( gribversion == 1 )
+    {
+      if ( gribsize > JP23SET ) /* Large GRIB record */
+	{
+	  int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
+	  int issize = 4, essize = 4;
+	  int flag;
 
-	  zkm2 = 1.0;
-	  zkm1 = zxn;
-	  zx = zxn;
-	  for ( jn = 2; jn <= nlat; jn++ )
+	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	  pdssize = (b1 << 16) + (b2 << 8) + b3;
+	  if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
+
+	  for ( int i = 0; i < 5; ++i ) flag = filePtrGetc(fileptr);
+	  if ( CGRIBEX_Debug ) Message("flag        = %d", flag);
+  
+	  fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
+
+	  if ( flag & 128 )
 	    {
-	      zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double) (jn);
-	      zkm2 = zkm1;
-	      zkm1 = zk;
+	      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	      gdssize = (b1 << 16) + (b2 << 8) + b3;
+	      fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
+	      if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
+	    }
+	  
+	  if ( flag & 64 )
+	    {
+	      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	      bmssize = (b1 << 16) + (b2 << 8) + b3;
+	      fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
+	      if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
 	    }
-	  zkm1 = zkm2;
-	  zw = (1.0-zx*zx) / ((double) (nlat*nlat)*zkm1*zkm1);
-	  za = zan;
-	}
-      while ( iter <= itemax && fabs(zmod) >= DBL_EPSILON );
 
-      pa[j] = zan;
-      pw[j] = 2.0*zw;
-    }
+	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
+	  bdssize = (b1 << 16) + (b2 << 8) + b3;
+	  bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
+	  if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
 
-#if defined (SX)
-#pragma vdir nodep
-#endif
-  for (j = 0; j < nlat/2; j++)
+	  gribsize = issize+pdssize+gdssize+bmssize+bdssize+essize;
+	}
+    }
+  else if ( gribversion == 2 )
     {
-      isym = nlat-(j+1);
-      pa[isym] = -pa[j];
-      pw[isym] =  pw[j];
+      int i;
+      /* we set gribsize the following way because it doesn't matter then
+	 whether int is 4 or 8 bytes long - we don't have to care if the size
+	 really fits: if it does not, the record can not be read at all */
+      gribsize = 0;
+      for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | filePtrGetc(fileptr);
+    }
+  else
+    {
+      gribsize = 0;
+      Warning("GRIB version %d unsupported!", gribversion);
     }
 
-  return;
-}
-#endif
+  if ( filePtrEOF(fileptr) ) gribsize = 0;
 
-void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
-{
-  //gauaw_old(pa, pw, nlat);
-  gauaw(nlat, pa, pw);
-}
+  if ( CGRIBEX_Debug )
+    Message("gribsize    = %d", gribsize);
 
-/*
-#define NGL  48
+  fileSetPos(fileID, pos, SEEK_SET);
 
-int main (int rgc, char *argv[])
-{
-  int ngl = NGL;
-  double plo[NGL], pwo[NGL];
-  double pl[NGL], pw[NGL];
+  return gribsize;
+}
 
-  int i;
 
-  gauaw(ngl, pl, pw);
-  gauaw_old(plo, pwo, ngl);
-  for (i = 0; i < ngl; i++)
+int gribGetSize(int fileID)
+{
+  long offset;
+  int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
+  if ( ierr > 0 )
     {
-      pl[i]  = asin(pl[i])/M_PI*180.0;
-      plo[i] = asin(plo[i])/M_PI*180.0;
+      Warning("GRIB record not found!");
+      return (0);
     }
 
-  for (i = 0; i < ngl; i++)
+  if      ( ierr == -1 ) return 0;
+  else if ( ierr ==  1 ) return 0;
+
+  int recSize = gribReadSize(fileID);
+
+  if ( CGRIBEX_Debug ) Message("recsize = %d", recSize);
+
+  fileSetPos(fileID, (off_t) -4, SEEK_CUR);
+
+  return recSize;
+}
+
+
+int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
+{
+  long offset;
+  int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
+  if ( ierr > 0 )
     {
-      fprintf(stderr, "%4d%25.18f%25.18f%25.18f%25.18f\n", i+1, pl[i], pw[i], pl[i]-plo[i], pw[i]-pwo[i]);
+      Warning("GRIB record not found!");
+      return (-2);
     }
 
-  return 0;
-}
-*/
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  if      ( ierr == -1 ) { *buffersize = 0; return -1; }
+  else if ( ierr ==  1 ) { *buffersize = 0; return -2; }
 
-#include <string.h>
-#include <math.h>
+  size_t recSize  = gribReadSize(fileID);
+  size_t readSize = recSize;
 
+  if ( readSize > *buffersize )
+    {
+      readSize = *buffersize;
+      ierr = -3;          // Tell the caller that the buffer was insufficient.
+    }
 
+  *buffersize = recSize;  // Inform the caller about the record size.
 
-extern void zaxisGetIndexList(int, int *);
-extern void zaxisDefLtype2(int zaxisID, int ltype2);
+  // Write the stuff to the buffer that has already been read in gribFileSeek().
+  buffer[0] = 'G';
+  buffer[1] = 'R';
+  buffer[2] = 'I';
+  buffer[3] = 'B';
 
+  readSize -= 4;
+  // Read the rest of the record into the buffer.
+  size_t nread = fileRead(fileID, &buffer[4], readSize);
 
-#undef  UNDEFID
-#define UNDEFID -1
+  if ( nread != readSize ) ierr = 1;
 
-static size_t Vctsize = 0;
-static double *Vct = NULL;
+  return ierr;
+}
 
-static int numberOfVerticalLevels = 0;
-static int numberOfVerticalGrid = 0;
-static unsigned char uuidVGrid[CDI_UUID_SIZE];
 
-typedef struct
+int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
 {
-  int      level1;
-  int      level2;
-  int      recID;
-  int      lindex;
+  int  nwrite = 0;
+
+  if ( (nwrite = fileWrite(fileID, buffer, buffersize)) != (int) buffersize )
+    {
+      perror(__func__);
+      nwrite = -1;
+    }
+
+  return nwrite;
 }
-leveltable_t;
 
-typedef struct
+
+int gribrec_len(unsigned b1, unsigned b2, unsigned b3)
 {
-  int           param;
-  int           prec;
-  int           tsteptype;
-  int           timave;
-  int           timaccu;
-  int           gridID;
-  int           zaxistype;
-  int           ltype1;     /* GRIB first level type */
-  int           ltype2;     /* GRIB second level type */
-  int           lbounds;
-  int           level_sf;
-  int           level_unit;
-  int           zaxisID;
-  unsigned      nlevels;
-  int           levelTableSize;
-  leveltable_t *levelTable;
-  int           instID;
-  int           modelID;
-  int           tableID;
-  int           comptype;       // compression type
-  int           complevel;      // compression level
-  int           lmissval;
-  double        missval;
-  char         *name;
-  char         *stdname;
-  char         *longname;
-  char         *units;
-  ensinfo_t    *ensdata;
-  int           typeOfGeneratingProcess;
-  int           productDefinitionTemplate;
-#if  defined  (HAVE_LIBGRIB_API)
-  /* (Optional) list of keyword/double value pairs */
-  int           opt_grib_dbl_nentries;
-  char         *opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
-  double        opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
-  /* (Optional) list of keyword/integer value pairs */
-  int           opt_grib_int_nentries;
-  char         *opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
-  int           opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
-#endif
+  /*
+    If bit 7 of b1 is set, we have to rescale by factor of 120.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  int needRescaling = b1 & (1 << 7);
+  
+  int gribsize = (((b1&127) << 16)+(b2<<8) + b3);
+
+  if ( needRescaling ) gribsize *= 120;
+
+  return gribsize;
 }
-vartable_t;
 
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 
-static vartable_t *vartable;
-static int varTablesize = 0;
-static int nvars = 0;
+
+FILE *grprsm = NULL;
+double fref;
+double fmaxval;
+int nfref;
+int nfmaxval;
+int nrnd;
+int ndbg;
+int nvck;
+int nonoff;
+int noabort;
+int num2ok;
+int next2o;
+int nloc2o;
+int nsubce;
+int grib_calendar = -1;
 
 
-static
-void paramInitEntry(int varID, int param)
+void gribSetCalendar(int calendar)
 {
-  vartable[varID].param          = param;
-  vartable[varID].prec           = 0;
-  vartable[varID].tsteptype      = TSTEP_INSTANT;
-  vartable[varID].timave         = 0;
-  vartable[varID].timaccu        = 0;
-  vartable[varID].gridID         = UNDEFID;
-  vartable[varID].zaxistype      = 0;
-  vartable[varID].ltype1         = 0;
-  vartable[varID].ltype2         = -1;
-  vartable[varID].lbounds        = 0;
-  vartable[varID].level_sf       = 0;
-  vartable[varID].level_unit     = 0;
-  vartable[varID].levelTable     = NULL;
-  vartable[varID].levelTableSize = 0;
-  vartable[varID].nlevels        = 0;
-  vartable[varID].instID         = UNDEFID;
-  vartable[varID].modelID        = UNDEFID;
-  vartable[varID].tableID        = UNDEFID;
-  vartable[varID].typeOfGeneratingProcess   = UNDEFID;
-  vartable[varID].productDefinitionTemplate = UNDEFID;
-  vartable[varID].comptype       = COMPRESS_NONE;
-  vartable[varID].complevel      = 1;
-  vartable[varID].lmissval       = 0;
-  vartable[varID].missval        = 0;
-  vartable[varID].name           = NULL;
-  vartable[varID].stdname        = NULL;
-  vartable[varID].longname       = NULL;
-  vartable[varID].units          = NULL;
-  vartable[varID].ensdata        = NULL;
+  grib_calendar = calendar;
 }
 
-static
-int varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *name)
+
+void grsdef(void)
 {
-  int varID;
+  /*
+C---->
+C**** GRSDEF - Initial (default) setting of common area variables
+C              for GRIBEX package.
+C
+C     Purpose.
+C     --------
+C
+C     Sets initial values for common area variables for all
+C     routines of GRIBEX package, if not already done.
+C
+C**   Interface.
+C     ----------
+C
+C     CALL GRSDEF
+C
+C     Input Parameters.
+C     -----------------
+C
+C     None.
+C
+C     Output Parameters.
+C     ------------------
+C
+C     None.
+C
+C     Method.
+C     -------
+C
+C     Self-explanatory.
+C
+C     Externals.
+C     ----------
+C
+C     None.
+C
+C     Reference.
+C     ----------
+C
+C     See subroutine GRIBEX.
+C
+C     Comments.
+C     ---------
+C
+C     None
+C
+C     Author.
+C     -------
+C
+C     J. Clochard, Meteo France, for ECMWF - March 1998.
+C
+C     Modifications.
+C     --------------
+C
+C     J. Clochard, Meteo France, for ECMWF - June 1999.
+C     Add variable NSUBCE.
+C     Use a static variable to determine if initialisation has already
+C     been done. NUSER removed .
+C     Reverse defaults for NEXT2O and NLOC2O, for consistency with
+C     version 13.023 of software .
+C
+  */
+  /*
+C     ----------------------------------------------------------------
+C*    Section 0 . Definition of variables.
+C     ----------------------------------------------------------------
+  */
+  char *envString;
+  char *env_stream;
+  static int lfirst = TRUE;
+  extern int CGRIBEX_Const;
+
+  if ( ! lfirst ) return;
 
-  for ( varID = 0; varID < varTablesize; varID++ )
+  /*
+    ----------------------------------------------------------------
+    Section 1 . Set values, conditionally.
+    ----------------------------------------------------------------
+  */
+  /*
+    Common area variables have not been set. Set them.
+    
+    User supplied reference value.
+  */
+  fref   = 0.0;
+  /*
+    Reference value supplied by user flag. Set to off.
+  */
+  nfref  = 0;
+  /*
+    User supplied maximum value.
+  */
+  fmaxval   = 0.0;
+  /*
+    Maximum value supplied by user flag. Set to off.
+  */
+  nfmaxval  = 0;
+  /*
+    Set rounding to 120 bytes on.
+  */
+  nrnd   = 1;
+  /*
+    Set GRIB calendar.
+  */
+  if ( grib_calendar == -1 )
+    {
+      grib_calendar = CALENDAR_PROLEPTIC;
+  
+      envString = getenv("GRIB_CALENDAR");
+      if ( envString )
+	{
+	  if      ( strncmp(envString, "standard", 8) == 0 )
+	    grib_calendar = CALENDAR_STANDARD;
+	  else if ( strncmp(envString, "proleptic", 9) == 0 )
+	    grib_calendar = CALENDAR_PROLEPTIC;
+	  else if ( strncmp(envString, "360days", 7) == 0 )
+	    grib_calendar = CALENDAR_360DAYS;
+	  else if ( strncmp(envString, "365days", 7) == 0 )
+	    grib_calendar = CALENDAR_365DAYS;
+	  else if ( strncmp(envString, "366days", 7) == 0 )
+	    grib_calendar = CALENDAR_366DAYS;
+	  else if ( strncmp(envString, "none", 4) == 0 )
+	    grib_calendar = CALENDAR_NONE;
+	}
+    }
+  /*
+    Set debug print off.
+  */
+  ndbg   = 0;
+  
+  envString = getenv("GRIBEX_DEBUG");
+  if ( envString != NULL )
     {
-      if ( vartable[varID].param      == param       &&
-	   vartable[varID].zaxistype  == zaxistype   &&
-	   vartable[varID].ltype1     == ltype1      &&
-	   vartable[varID].tsteptype  == tsteptype )
-        {
-          if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
-            {
-              if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
-            }
-          else
-            {
-              return (varID);
-            }
-        }
+      if ( !strncmp(envString, "ON", 2) )
+        ndbg = 1;
+      else if( *envString == '1')
+        ndbg = 1;
+      else if( *envString == '2')
+        ndbg = 2;
+      else
+        ndbg = 0;
     }
-
-  return (UNDEFID);
-}
-
-static
-void varFree(void)
-{
-  int varID;
-
-  for ( varID = 0; varID < nvars; varID++ )
+  /*
+    Set GRIBEX compatibility mode.
+  */
+  envString = getenv("GRIB_GRIBEX_MODE_ON");
+  if ( envString != NULL )
     {
-      if ( vartable[varID].levelTable )
-	free(vartable[varID].levelTable);
-
-      if ( vartable[varID].name )     free(vartable[varID].name);
-      if ( vartable[varID].stdname )  free(vartable[varID].stdname);
-      if ( vartable[varID].longname ) free(vartable[varID].longname);
-      if ( vartable[varID].units )    free(vartable[varID].units);
-      if ( vartable[varID].ensdata )  free(vartable[varID].ensdata);
+      if ( atoi(envString) == 1 ) CGRIBEX_Const = 0;
     }
 
-  if ( vartable )
-    free(vartable);
-
-  vartable = NULL;
-  varTablesize = 0;
-  nvars = 0;
-
-  if ( Vct )
-    free(Vct);
-
-  Vct = NULL;
-  Vctsize = 0;
-}
-
-static
-int levelNewEntry(int varID, int level1, int level2)
-{
-  int levelID = 0;
-  int levelTableSize;
-  leveltable_t *levelTable;
-
-  levelTableSize = vartable[varID].levelTableSize;
-  levelTable     = vartable[varID].levelTable;
-
   /*
-    Look for a free slot in levelTable.
-    (Create the table the first time through).
+    Set GRIB value checking on.
   */
-  if ( ! levelTableSize )
+  nvck   = 1;
+  
+  envString = getenv("GRIBEX_CHECK");
+  if ( envString )
     {
-      int i;
-
-      levelTableSize = 2;
-      levelTable = (leveltable_t *)xmalloc((size_t)levelTableSize
-                                           * sizeof (leveltable_t));
-      if( levelTable == NULL )
-	{
-          Message("levelTableSize = %d", levelTableSize);
-	  SysError("Allocation of leveltable failed!");
-	}
-
-      for( i = 0; i < levelTableSize; i++ )
-	levelTable[i].recID = UNDEFID;
+      if ( !strncmp(envString, "OFF", 3) )
+        nvck = 0;
+      else
+        nvck = 1;
     }
-  else
+  /*
+    See if output stream needs changing
+  */
+  grprsm = stdout;
+  env_stream = getenv("GRPRS_STREAM");
+  if ( env_stream )
     {
-      while( levelID < levelTableSize )
+      if ( isdigit((int) env_stream[0]) )
 	{
-	  if ( levelTable[levelID].recID == UNDEFID ) break;
-	  levelID++;
+	  int unit;
+	  unit = atoi(env_stream);
+	  if ( unit < 1 || unit > 99 )
+	    Warning("Invalid number for GRPRS_STREAM: %d", unit);
+	  else if ( unit == 2 )
+	    grprsm = stderr;
+	  else if ( unit == 6 )
+	    grprsm = stdout;
+	  else
+	    {
+	      char filename[] = "unit.00";
+	      sprintf(filename, "%2.2d", unit);
+	      grprsm = fopen(filename, "w");
+	      if ( ! grprsm )
+		SysError("GRPRS_STREAM = %d", unit);
+	    }
+	}
+      else
+	{
+	  if ( env_stream[0] )
+	    {
+	      grprsm = fopen(env_stream, "w");
+	      if ( ! grprsm )
+		SysError("GRPRS_STREAM = %s", env_stream);
+	    }
 	}
     }
   /*
-    If the table overflows, double its size.
+    Set P factor switch to default, user supplies the P factor.
   */
-  if( levelID == levelTableSize )
-    {
-      int i;
+  nonoff = 0;
+  /*
+    Set abort flag to NO abort
+  */
+  noabort = 1;
+  /*
+    Mark common area values set by user.
+  */
+  lfirst = FALSE;
+  /*
+    Exhaustive use of all possible second-order packing methods
+    for HOPER='K'. Set to off.
+  */
+  num2ok  = 0;
+  /*
+    Use of extended second-order packing methods for grid-point
+    encoding (HOPER='C' and 'K'). Set to on.
+  */
+  next2o  = 1;
+  /*
+    Use of non-local second-order packing methods for grid-point
+    encoding (HOPER='C' and 'K'). Set to on.
+  */
+  nloc2o  = 1;
+  /*
+    Use of (all valid) sub-centre values for ECMWF fields encoding .
+    encoding. Set to off.
+  */
+  nsubce  = 0;
+}
 
-      levelTableSize = 2*levelTableSize;
-      levelTable = (leveltable_t *)xrealloc(levelTable, (size_t)levelTableSize
-                                            * sizeof (leveltable_t));
-      if( levelTable == NULL )
-	{
-          Message("levelTableSize = %d", levelTableSize);
-	  SysError("Reallocation of leveltable failed");
-	}
-      levelID = levelTableSize/2;
+/* pack 8-bit bytes from 64-bit words to a packed buffer */
+/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (unsigned char) up[i]; */
 
-      for( i = levelID; i < levelTableSize; i++ )
-	levelTable[i].recID = UNDEFID;
-    }
+long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc)
+{
+#if defined (CRAY)
+  (void) _pack(up, cp, bc, tc);
+#else
+  U_BYTEORDER;
+  unsigned char *cp0;
+  unsigned INT64 upi, *up0, *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
+  long head, trail, inner, i, j;
+  long ipack = sizeof(INT64);
+  
+  /* Bytes until first word boundary in destination buffer */
 
-  levelTable[levelID].level1   = level1;
-  levelTable[levelID].level2   = level2;
-  levelTable[levelID].lindex   = levelID;
+  head = ( (long) cp ) & (ipack-1);
+  if ( head != 0 ) head = ipack - head;
 
-  vartable[varID].nlevels = (unsigned)levelID+1;
-  vartable[varID].levelTableSize = levelTableSize;
-  vartable[varID].levelTable = levelTable;
+  inner = bc - head;
 
-  return (levelID);
-}
+  /* Trailing bytes which do not make a full word */
 
-#define  UNDEF_PARAM  -4711
+  trail = inner & (ipack-1);
 
-static
-int paramNewEntry(int param)
-{
-  int varID = 0;
+  /* Number of bytes/words to be processed in fast loop */
 
-  /*
-    Look for a free slot in vartable.
-    (Create the table the first time through).
-  */
-  if ( ! varTablesize )
-    {
-      int i;
+  inner -= trail;
+  inner /= ipack;
 
-      varTablesize = 2;
-      vartable = (vartable_t *)xmalloc((size_t)varTablesize
-                                       * sizeof (vartable_t));
-      if( vartable == NULL )
-	{
-          Message("varTablesize = %d", varTablesize);
-	  SysError("Allocation of vartable failed");
-	}
+  ip0 = up + head;
+  ip1 = ip0 + 1;
+  ip2 = ip0 + 2;
+  ip3 = ip0 + 3;
+  ip4 = ip0 + 4;
+  ip5 = ip0 + 5;
+  ip6 = ip0 + 6;
+  ip7 = ip0 + 7;
 
-      for( i = 0; i < varTablesize; i++ )
-	{
-	  vartable[i].param = UNDEF_PARAM;
-#if  defined  (HAVE_LIBGRIB_API)
-	  vartable[i].opt_grib_int_nentries = 0;
-	  vartable[i].opt_grib_dbl_nentries = 0;
+  up0 = (unsigned INT64 *) (cp + head);
+
+  /* Here we should process any bytes until the first word boundary 
+   * of our destination buffer 
+   * That code is missing so far  because our output buffer is 
+   * word aligned by FORTRAN 
+   */
+
+  j = 0;
+
+  if ( IS_BIGENDIAN() )
+    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
 #endif
+      for ( i = 0 ; i < inner ; i++ )
+	{
+	  upi =             (   ip0[j]          << 56 ) 
+	                 |  ( ( ip1[j] & 0xFF ) << 48 )
+	                 |  ( ( ip2[j] & 0xFF ) << 40 )
+	                 |  ( ( ip3[j] & 0xFF ) << 32 )
+	                 |  ( ( ip4[j] & 0xFF ) << 24 ) ;
+	  up0[i] = upi   |  ( ( ip5[j] & 0xFF ) << 16 )
+	                 |  ( ( ip6[j] & 0xFF ) <<  8 )
+	                 |    ( ip7[j] & 0xFF ) ;
+	  j += ipack;
 	}
     }
   else
     {
-      while( varID < varTablesize )
+      for ( i = 0 ; i < inner ; i++ )
 	{
-	  if ( vartable[varID].param == UNDEF_PARAM ) break;
-	  varID++;
+	  upi =             (   ip7[j]          << 56 ) 
+	                 |  ( ( ip6[j] & 0xFF ) << 48 )
+                         |  ( ( ip5[j] & 0xFF ) << 40 )
+                         |  ( ( ip4[j] & 0xFF ) << 32 )
+                         |  ( ( ip3[j] & 0xFF ) << 24 ) ;
+	  up0[i] = upi   |  ( ( ip2[j] & 0xFF ) << 16 )
+                         |  ( ( ip1[j] & 0xFF ) <<  8 )
+                         |    ( ip0[j] & 0xFF ) ;
+	  j += ipack;
 	}
     }
-  /*
-    If the table overflows, double its size.
-  */
-  if ( varID == varTablesize )
-    {
-      int i;
-
-      varTablesize = 2 * varTablesize;
-      vartable = (vartable_t *)xrealloc(vartable, (size_t)varTablesize
-                                        * sizeof (vartable_t));
-      if( vartable == NULL )
-	{
-          Message("varTablesize = %d", varTablesize);
-	  SysError("Reallocation of vartable failed!");
-	}
-      varID = varTablesize/2;
 
-      for( i = varID; i < varTablesize; i++ )
+  cp0 = (unsigned char *) ( up0 + inner );
+  if ( trail > 0 )
+    {
+      up0[inner] = 0;
+      for ( i = 0 ; i < trail ; i ++ )
 	{
-	  vartable[i].param = UNDEF_PARAM;
-#if  defined  (HAVE_LIBGRIB_API)
-	  vartable[i].opt_grib_int_nentries = 0;
-	  vartable[i].opt_grib_dbl_nentries = 0;
-#endif
+	  *cp0 = (unsigned char) ip0[ipack*inner+i];
+	  cp0++;
 	}
     }
 
-  paramInitEntry(varID, param);
-
-  return (varID);
+  if ( tc != -1 )
+    {
+      bc++;
+      *cp0 = (unsigned char) tc;
+    }
+#endif
+  return (bc);
 }
 
+/* unpack 8-bit bytes from a packed buffer with 64-bit words */
+/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT64) cp[i]; */
 
-void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int level_sf, int level_unit, int prec,
-		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
-		  const char *name, const char *stdname, const char *longname, const char *units)
+long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc)
 {
-  int varID = UNDEFID;
-  int levelID = -1;
+  U_BYTEORDER;
+  const unsigned char *cp0;
+  unsigned INT64 *up0;
+  unsigned INT64 *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
+  long head, trail, inner, i, j;
+  long offset;
+  long ipack = sizeof(INT64);
 
-  if ( ! (cdiSplitLtype105 == 1 && zaxistype == ZAXIS_HEIGHT) )
-    varID = varGetEntry(param, zaxistype, ltype1, tsteptype, name);
+  UNUSED(tc);
 
-  if ( varID == UNDEFID )
-    {
-      nvars++;
-      varID = paramNewEntry(param);
-      vartable[varID].gridID     = gridID;
-      vartable[varID].zaxistype  = zaxistype;
-      vartable[varID].ltype1     = ltype1;
-      vartable[varID].ltype2     = ltype2;
-      vartable[varID].lbounds    = lbounds;
-      vartable[varID].level_sf   = level_sf;
-      vartable[varID].level_unit = level_unit;
-      vartable[varID].tsteptype  = tsteptype;
-      if ( numavg ) vartable[varID].timave = 1;
+  /* Bytes until first word boundary in source buffer */
 
-      if ( name )     if ( name[0] )     vartable[varID].name     = strdup(name);
-      if ( stdname )  if ( stdname[0] )  vartable[varID].stdname  = strdup(stdname);
-      if ( longname ) if ( longname[0] ) vartable[varID].longname = strdup(longname);
-      if ( units )    if ( units[0] )    vartable[varID].units    = strdup(units);
-    }
-  else
-    {
-      char paramstr[32];
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+  head = ( (long) cp ) & (ipack-1);
+  if ( head != 0 ) head = ipack - head;
+  if ( head > bc ) head = bc;
 
-      if ( vartable[varID].gridID != gridID )
-	{
-	  Message("param = %s gridID = %d", paramstr, gridID);
-	  Error("horizontal grid must not change for same parameter!");
-	}
-      if ( vartable[varID].zaxistype != zaxistype )
-	{
-	  Message("param = %s zaxistype = %d", paramstr, zaxistype);
-	  Error("zaxistype must not change for same parameter!");
-	}
-    }
+  inner = bc - head;
 
-  if ( prec > vartable[varID].prec ) vartable[varID].prec = prec;
+  /* Trailing bytes which do not make a full word */
+ 
+  trail = inner & (ipack-1);
+ 
+  /* Number of bytes/words to be processed in fast loop */
 
-  levelID = levelNewEntry(varID, level1, level2);
-  vartable[varID].levelTable[levelID].recID = recID;
+  inner -= trail;
+  inner /= ipack;
 
-  *pvarID   = varID;
-  *plevelID = levelID;
-}
-/*
-static
-int dblcmp(const void *s1, const void *s2)
-{
-  int cmp = 0;
+  ip0 = up + head;
+  ip1 = ip0 + 1;
+  ip2 = ip0 + 2;
+  ip3 = ip0 + 3;
+  ip4 = ip0 + 4;
+  ip5 = ip0 + 5;
+  ip6 = ip0 + 6;
+  ip7 = ip0 + 7;
 
-  if      ( *((double *) s1) < *((double *) s2) ) cmp = -1;
-  else if ( *((double *) s1) > *((double *) s2) ) cmp =  1;
+  up0 = (unsigned INT64 *) (cp + head);
 
-  return (cmp);
-}
-*/
-static
-int cmpLevelTable(const void* s1, const void* s2)
-{
-  int cmp = 0;
-  const leveltable_t* x = (const leveltable_t*) s1;
-  const leveltable_t* y = (const leveltable_t*) s2;
-  /*
-  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
-  */
-  if      ( x->level1 < y->level1 ) cmp = -1;
-  else if ( x->level1 > y->level1 ) cmp =  1;
+  /* Process any bytes until the first word boundary 
+   * of our source buffer 
+   */
+  for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT64) cp[i];
 
-  return (cmp);
-}
+  j = 0;
 
-static
-int cmpLevelTableInv(const void* s1, const void* s2)
-{
-  int cmp = 0;
-  const leveltable_t* x = (const leveltable_t*) s1;
-  const leveltable_t* y = (const leveltable_t*) s2;
-  /*
-  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
-  */
-  if      ( x->level1 < y->level1 ) cmp =  1;
-  else if ( x->level1 > y->level1 ) cmp = -1;
+  if ( IS_BIGENDIAN() )
+    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+      for ( i = 0 ; i < inner ; i++ )
+	{
+	  ip0[j] = (up0[i] >> 56) & 0xFF;
+	  ip1[j] = (up0[i] >> 48) & 0xFF;
+	  ip2[j] = (up0[i] >> 40) & 0xFF;
+	  ip3[j] = (up0[i] >> 32) & 0xFF;
+	  ip4[j] = (up0[i] >> 24) & 0xFF;
+	  ip5[j] = (up0[i] >> 16) & 0xFF;
+	  ip6[j] = (up0[i] >>  8) & 0xFF;
+	  ip7[j] = (up0[i])       & 0xFF;
 
-  return (cmp);
-}
+	  j += ipack;
+	}
+    }
+  else
+    {
+      for ( i = 0 ; i < inner ; i++ )
+	{
+	  ip7[j] = (up0[i] >> 56) & 0xFF;
+	  ip6[j] = (up0[i] >> 48) & 0xFF;
+	  ip5[j] = (up0[i] >> 40) & 0xFF;
+	  ip4[j] = (up0[i] >> 32) & 0xFF;
+	  ip3[j] = (up0[i] >> 24) & 0xFF;
+	  ip2[j] = (up0[i] >> 16) & 0xFF;
+	  ip1[j] = (up0[i] >>  8) & 0xFF;
+	  ip0[j] = (up0[i])       & 0xFF;
 
+	  j += ipack;
+	}
+    }
 
-typedef struct
-{
-  int      varid;
-  int      param;
-  int      ltype;
+  if ( trail > 0 )
+    {
+      offset = head + ipack*inner;
+      cp0 = cp + offset;
+      for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT64) cp0[i];
+    }
+  /*
+  if ( tc != -1 ) {
+    bc++;
+    *cp0 = (unsigned char) tc;
+  }
+  */
+  return (bc);
 }
-param_t;
 
+/* pack 8-bit bytes from 32-bit words to a packed buffer */
+/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (char) up[i]; */
 
-static
-int cmpparam(const void* s1, const void* s2)
+#if  defined  (INT32)
+long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc)
 {
-  const param_t* x = (const param_t*) s1;
-  const param_t* y = (const param_t*) s2;
+  U_BYTEORDER;
+  unsigned char *cp0;
+  unsigned INT32 *up0, *ip0, *ip1, *ip2, *ip3;
+  long head, trail, inner, i, j;
+  long ipack = sizeof(INT32);
+  
+  /* Bytes until first word boundary in destination buffer */
+
+  head = ( (long) cp ) & (ipack-1);
+  if ( head != 0 ) head = ipack - head;
 
-  int cmp = (( x->param > y->param ) - ( x->param < y->param )) * 2
-           + ( x->ltype > y->ltype ) - ( x->ltype < y->ltype );
+  inner = bc - head;
 
-  return (cmp);
-}
+  /* Trailing bytes which do not make a full word */
 
+  trail = inner & (ipack-1);
 
-void cdi_generate_vars(stream_t *streamptr)
-{
-  int varID, gridID, zaxisID;
-  int instID, modelID, tableID;
-  int param, zaxistype, ltype1, ltype2;
-  int prec;
-  int tsteptype;
-  int timave, timaccu;
-  int lbounds;
-  int comptype;
-  char name[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
-  double *dlevels = NULL;
-  double *dlevels1 = NULL;
-  double *dlevels2 = NULL;
-  int index, varid;
-  double level_sf = 1;
-  int vlistID = streamptr->vlistID;
+  /* Number of bytes/words to be processed in fast loop */
+
+  inner -= trail;
+  inner /= ipack;
 
-  int *varids = (int *)xmalloc((size_t)nvars*sizeof(int));
-  for ( varID = 0; varID < nvars; varID++ ) varids[varID] = varID;
+  ip0 = up + head;
+  ip1 = ip0 + 1;
+  ip2 = ip0 + 2;
+  ip3 = ip0 + 3;
 
-  if ( streamptr->sortname )
-    {
-      param_t **varInfo;
-      varInfo    = (param_t **)xmalloc((size_t)nvars * sizeof (param_t *));
-      varInfo[0] = (param_t *)xmalloc((size_t)nvars * sizeof (param_t));
+  up0 = (unsigned INT32 *) (cp + head);
 
-      for ( int index = 1; index < nvars; index++ )
-	varInfo[index] = varInfo[0] + index;
+  /* Here we should process any bytes until the first word boundary 
+   * of our destination buffer 
+   * That code is missing so far  because our output buffer is 
+   * word aligned by FORTRAN 
+   */
 
-      for ( varid = 0; varid < nvars; varid++ )
+  j = 0;
+
+  if ( IS_BIGENDIAN() )
+    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+      for ( i = 0 ; i < inner ; i++ )
 	{
-	  varInfo[varid]->varid = varids[varid];
-	  varInfo[varid]->param = vartable[varid].param;
-	  varInfo[varid]->ltype = vartable[varid].ltype1;
+	  up0[i] =          (   ip0[j]          << 24 ) 
+	                 |  ( ( ip1[j] & 0xFF ) << 16 )
+	                 |  ( ( ip2[j] & 0xFF ) <<  8 )
+	                 |    ( ip3[j] & 0xFF ) ;
+	  j += ipack;
 	}
-      qsort(varInfo[0], (size_t)nvars, sizeof(param_t), cmpparam);
-      for ( varid = 0; varid < nvars; varid++ )
+    }
+  else
+    {
+      for ( i = 0 ; i < inner ; i++ )
 	{
-	  varids[varid] = varInfo[varid]->varid;
+	  up0[i] =          (   ip3[j]          << 24 ) 
+	                 |  ( ( ip2[j] & 0xFF ) << 16 )
+                         |  ( ( ip1[j] & 0xFF ) <<  8 )
+                         |    ( ip0[j] & 0xFF ) ;
+	  j += ipack;
 	}
-      free(varInfo[0]);
-      free(varInfo);
     }
 
-  for ( index = 0; index < nvars; index++ )
+  cp0 = (unsigned char *) ( up0 + inner );
+  if ( trail > 0 )
     {
-      varid      = varids[index];
-
-      gridID     = vartable[varid].gridID;
-      param      = vartable[varid].param;
-      unsigned nlevels = vartable[varid].nlevels;
-      ltype1     = vartable[varid].ltype1;
-      ltype2     = vartable[varid].ltype2;
-      zaxistype = vartable[varid].zaxistype;
-      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && cdiDefaultLeveltype != -1 )
-	zaxistype = cdiDefaultLeveltype;
-      lbounds    = vartable[varid].lbounds;
-      prec       = vartable[varid].prec;
-      instID     = vartable[varid].instID;
-      modelID    = vartable[varid].modelID;
-      tableID    = vartable[varid].tableID;
-      tsteptype  = vartable[varid].tsteptype;
-      timave     = vartable[varid].timave;
-      timaccu    = vartable[varid].timaccu;
-      comptype   = vartable[varid].comptype;
-
-      level_sf  = 1;
-      if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
-
-      zaxisID = UNDEFID;
-
-      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
-	   vartable[varid].levelTable[0].level1 == 0 )
-	zaxistype = ZAXIS_SURFACE;
-
-      dlevels = (double *) malloc(nlevels*sizeof(double));
-
-      if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
-	                      level_sf*vartable[varid].levelTable[levelID].level2)/2;
-      else
-	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
-
-      if ( nlevels > 1 )
+      up0[inner] = 0;
+      for ( i = 0 ; i < trail ; i ++ )
 	{
-          bool linc = true, ldec = true, lsort = false;
-          for (unsigned levelID = 1; levelID < nlevels; levelID++ )
-            {
-              /* check increasing of levels */
-              linc &= (dlevels[levelID] > dlevels[levelID-1]);
-              /* check decreasing of levels */
-              ldec &= (dlevels[levelID] < dlevels[levelID-1]);
-            }
-          /*
-           * always sort pressure z-axis to ensure
-           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 > levelID2
-           * unless already sorted in decreasing order
-           */
-          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
-            {
-              qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTableInv);
-              lsort = true;
-            }
-          /*
-           * always sort hybrid and depth-below-land z-axis to ensure
-           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 < levelID2
-           * unless already sorted in increasing order
-           */
-          else if ( (!linc && !ldec) ||
-                    zaxistype == ZAXIS_HYBRID ||
-                    zaxistype == ZAXIS_DEPTH_BELOW_LAND )
-            {
-              qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
-              lsort = true;
-            }
-
-          if ( lsort )
-            {
-              if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
-                  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
-                                      level_sf*vartable[varid].levelTable[levelID].level2)/2.;
-              else
-                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
-                  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
-            }
+	  *cp0 = (unsigned char) ip0[ipack*inner+i];
+	  cp0++;
 	}
+    }
 
-      if ( lbounds )
-	{
-	  dlevels1 = (double *) malloc(nlevels*sizeof(double));
-	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
-	    dlevels1[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
-	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
-	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
-	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
-        }
+  if ( tc != -1 )
+    {
+      bc++;
+      *cp0 = (unsigned char) tc;
+    }
 
-      char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
-      zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, lbounds, dlevels1, dlevels2,
-                            (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
+  return (bc);
+}
+#endif
 
-      if ( ltype1 != ltype2 && ltype2 != -1 )
-        {
-          zaxisDefLtype2(zaxisID, ltype2);
-        }
+/* unpack 8-bit bytes from a packed buffer with 32-bit words */
+/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT32) cp[i]; */
 
-      if ( zaxisInqType(zaxisID) == ZAXIS_REFERENCE )
-        {
-          if ( numberOfVerticalLevels > 0 ) zaxisDefNlevRef(zaxisID, numberOfVerticalLevels);
-          if ( numberOfVerticalGrid > 0 ) zaxisDefNumber(zaxisID, numberOfVerticalGrid);
-          if ( !cdiUUIDIsNull(uuidVGrid) ) zaxisDefUUID(zaxisID, uuidVGrid);
-        }
+#if  defined  (INT32)
+long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc)
+{
+  U_BYTEORDER;
+  const unsigned char *cp0;
+  unsigned INT32 *up0;
+  unsigned INT32 *ip0, *ip1, *ip2, *ip3;
+  long head, trail, inner, i, j;
+  long offset;
+  long ipack = sizeof(INT32);
 
-      if ( lbounds ) free(dlevels1);
-      if ( lbounds ) free(dlevels2);
-      free(dlevels);
+  UNUSED(tc);
 
-      varID = stream_new_var(streamptr, gridID, zaxisID);
-      varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
+  /* Bytes until first word boundary in source buffer */
 
-      vlistDefVarParam(vlistID, varID, param);
-      vlistDefVarDatatype(vlistID, varID, prec);
-      vlistDefVarTimave(vlistID, varID, timave);
-      vlistDefVarTimaccu(vlistID, varID, timaccu);
-      vlistDefVarCompType(vlistID, varID, comptype);
+  head = ( (long) cp ) & (ipack-1);
+  if ( head != 0 ) head = ipack - head;
+  if ( head > bc ) head = bc;
 
-      if ( vartable[varid].typeOfGeneratingProcess != UNDEFID )
-        vlistDefVarTypeOfGeneratingProcess(vlistID, varID, vartable[varid].typeOfGeneratingProcess);
+  inner = bc - head;
 
-      if ( vartable[varid].productDefinitionTemplate != UNDEFID )
-        vlistDefVarProductDefinitionTemplate(vlistID, varID, vartable[varid].productDefinitionTemplate);
+  /* Trailing bytes which do not make a full word */
+ 
+  trail = inner & (ipack-1);
+ 
+  /* Number of bytes/words to be processed in fast loop */
 
-      if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);
+  inner -= trail;
+  inner /= ipack;
 
-      if ( vartable[varid].name )     vlistDefVarName(vlistID, varID, vartable[varid].name);
-      if ( vartable[varid].stdname )  vlistDefVarStdname(vlistID, varID, vartable[varid].stdname);
-      if ( vartable[varid].longname ) vlistDefVarLongname(vlistID, varID, vartable[varid].longname);
-      if ( vartable[varid].units )    vlistDefVarUnits(vlistID, varID, vartable[varid].units);
+  ip0 = up + head;
+  ip1 = ip0 + 1;
+  ip2 = ip0 + 2;
+  ip3 = ip0 + 3;
 
-      if ( vartable[varid].ensdata )  vlistDefVarEnsemble(vlistID, varID, vartable[varid].ensdata->ens_index,
-	                                                  vartable[varid].ensdata->ens_count,
-							  vartable[varid].ensdata->forecast_init_type);
+  up0 = (unsigned INT32 *) (cp + head);
 
-#if  defined  (HAVE_LIBGRIB_API)
-      /* ---------------------------------- */
-      /* Local change: 2013-04-23, FP (DWD) */
-      /* ---------------------------------- */
+  /* Process any bytes until the first word boundary 
+   * of our source buffer 
+   */
+  for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT32) cp[i];
 
-      int    i;
-      vlist_t *vlistptr;
-      vlistptr = vlist_to_pointer(vlistID);
-      for (i=0; i<vartable[varid].opt_grib_int_nentries; i++)
-        {
-          int idx = vlistptr->vars[varID].opt_grib_int_nentries;
-          vlistptr->vars[varID].opt_grib_int_nentries++;
-          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
-          vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
-          vlistptr->vars[varID].opt_grib_int_val[idx] = vartable[varid].opt_grib_int_val[idx];
-          vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(vartable[varid].opt_grib_int_keyword[idx]);
-        }
-      for (i=0; i<vartable[varid].opt_grib_dbl_nentries; i++)
-        {
-          int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
-          vlistptr->vars[varID].opt_grib_dbl_nentries++;
-          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
-          vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
-          vlistptr->vars[varID].opt_grib_dbl_val[idx] = vartable[varid].opt_grib_dbl_val[idx];
-          vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(vartable[varid].opt_grib_dbl_keyword[idx]);
-        }
-      /* note: if the key is not defined, we do not throw an error! */
-#endif
+  j = 0;
 
-      if ( cdiDefaultTableID != UNDEFID )
+  if ( IS_BIGENDIAN() )
+    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+      for ( i = 0 ; i < inner ; i++ )
 	{
-	  int pdis, pcat, pnum;
-	  cdiDecodeParam(param, &pnum, &pcat, &pdis);
-	  if ( tableInqParNamePtr(cdiDefaultTableID, pnum) )
-	    {
-	      if ( tableID != UNDEFID )
-		{
-		  strcpy(name, tableInqParNamePtr(cdiDefaultTableID, pnum));
-		  vlistDefVarName(vlistID, varID, name);
-		  if ( tableInqParLongnamePtr(cdiDefaultTableID, pnum) )
-		    {
-		      strcpy(longname, tableInqParLongnamePtr(cdiDefaultTableID, pnum));
-		      vlistDefVarLongname(vlistID, varID, longname);
-		    }
-		  if ( tableInqParUnitsPtr(cdiDefaultTableID, pnum) )
-		    {
-		      strcpy(units, tableInqParUnitsPtr(cdiDefaultTableID, pnum));
-		      vlistDefVarUnits(vlistID, varID, units);
-		    }
-		}
-	      else
-		tableID = cdiDefaultTableID;
-	    }
-	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID  != UNDEFID )  instID = cdiDefaultInstID;
-	}
+	  ip0[j] = (up0[i] >> 24) & 0xFF;
+	  ip1[j] = (up0[i] >> 16) & 0xFF;
+	  ip2[j] = (up0[i] >>  8) & 0xFF;
+	  ip3[j] = (up0[i])       & 0xFF;
 
-      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
-      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
-      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
+	  j += ipack;
+	}
     }
-
-  for ( index = 0; index < nvars; index++ )
+  else
     {
-      varID     = index;
-      varid     = varids[index];
-
-      unsigned nlevels = vartable[varid].nlevels;
-      /*
-      for ( levelID = 0; levelID < nlevels; levelID++ )
-	{
-	  printf("%d %d %d %d %d\n", varID, levelID,
-		 vartable[varid].levelTable[levelID].lindex,
-		 vartable[varid].levelTable[levelID].recID,
-		 vartable[varid].levelTable[levelID].level1);
-	}
-      */
-      for (unsigned levelID = 0; levelID < nlevels; levelID++)
+      for ( i = 0 ; i < inner ; i++ )
 	{
-	  streamptr->vars[varID].level[levelID] = vartable[varid].levelTable[levelID].recID;
-          unsigned lindex;
-	  for (lindex = 0; lindex < nlevels; lindex++ )
-	    if ( levelID == (unsigned)vartable[varid].levelTable[lindex].lindex ) break;
-
-	  if ( lindex == nlevels )
-	    Error("Internal problem! lindex not found.");
+	  ip3[j] = (up0[i] >> 24) & 0xFF;
+	  ip2[j] = (up0[i] >> 16) & 0xFF;
+	  ip1[j] = (up0[i] >>  8) & 0xFF;
+	  ip0[j] = (up0[i])       & 0xFF;
 
-	  streamptr->vars[varID].lindex[levelID] = (int)lindex;
+	  j += ipack;
 	}
     }
 
-  free(varids);
-
-  varFree();
-}
-
-
-void varDefVCT(size_t vctsize, double *vctptr)
-{
-  if ( Vct == NULL && vctptr != NULL && vctsize > 0 )
+  if ( trail > 0 )
     {
-      Vctsize = vctsize;
-      Vct = (double *) malloc(vctsize*sizeof(double));
-      memcpy(Vct, vctptr, vctsize*sizeof(double));
+      offset = head + ipack*inner;
+      cp0 = cp + offset;
+      for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT32) cp0[i];
     }
-}
-
+  /*
+  if ( tc != -1 ) {
+    bc++;
+    *cp0 = (unsigned char) tc;
+  }
+  */
 
-void varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE])
-{
-  numberOfVerticalLevels = nhlev;
-  numberOfVerticalGrid = nvgrid;
-  memcpy(uuidVGrid, uuid, CDI_UUID_SIZE);
+  return (bc);
 }
+#endif
+#include <stdio.h>
 
-
-int varDefGrid(int vlistID, const grid_t *grid, int mode)
+void prtbin(int kin, int knbit, int *kout, int *kerr)
 {
   /*
-    mode: 0 search in vlist and grid table
-          1 search in grid table
-   */
-  int gridglobdefined = FALSE;
-  int griddefined;
-  int ngrids;
-  int gridID = CDI_UNDEFID;
-  int index;
-  vlist_t *vlistptr;
-  int * gridIndexList, i;
 
-  vlistptr = vlist_to_pointer(vlistID);
+    Produces a decimal number with ones and zeroes
+    corresponding to the ones and zeroes of the input
+    binary number.
+    eg input number 1011 binary, output number 1011 decimal.
 
-  griddefined = FALSE;
-  ngrids = vlistptr->ngrids;
 
-  if ( mode == 0 )
-    for ( index = 0; index < ngrids; index++ )
-      {
-	gridID = vlistptr->gridIDs[index];
-	if ( gridID == UNDEFID )
-	  Error("Internal problem: undefined gridID %d!", gridID);
+    Input Parameters:
+    
+       kin   - Integer variable containing binary number.
 
-	if ( gridCompare(gridID, grid) == 0 )
-	  {
-	    griddefined = TRUE;
-	    break;
-	  }
-      }
+       knbit - Number of bits in binary number.
 
-  if ( ! griddefined )
-    {
-      ngrids = gridSize();
-      if ( ngrids > 0 )
-        {
-          gridIndexList = (int*)xmalloc((size_t)ngrids * sizeof(int));
-          gridGetIndexList ( ngrids, gridIndexList );
-          for ( i = 0; i < ngrids; i++ )
-            {
-              gridID = gridIndexList[i];
-              if ( gridCompare(gridID, grid) == 0 )
-                {
-                  gridglobdefined = TRUE;
-                  break;
-                }
-            }
-          if ( gridIndexList ) free ( gridIndexList );
-        }
+    Output Parameters:
 
-      ngrids = vlistptr->ngrids;
-      if ( mode == 1 )
-	for ( index = 0; index < ngrids; index++ )
-	  if ( vlistptr->gridIDs[index] == gridID )
-	    {
-	      gridglobdefined = FALSE;
-	      break;
-	    }
-    }
+       kout  - Integer variable containing decimal value
+               with ones and zeroes corresponding to those of
+	       the input binary number.
 
-  if ( ! griddefined )
-    {
-      if ( ! gridglobdefined ) gridID = gridGenerate(grid);
-      ngrids = vlistptr->ngrids;
-      vlistptr->gridIDs[ngrids] = gridID;
-      vlistptr->ngrids++;
-    }
+       kerr  - 0, If no error.
+               1, Number of bits in binary number exceeds
+	          maximum allowed or is less than 1.
 
-  return (gridID);
-}
 
+    Converted from EMOS routine PRTBIN.
 
-int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, char *longname, char *units, int ltype1)
-{
-  int differ = 1;
-  int levelID;
-  int zlbounds = 0;
-  int ltype_is_equal = FALSE;
+       Uwe Schulzweida   MPIfM   01/04/2001
 
-  if ( ltype1 == zaxisInqLtype(zaxisID) ) ltype_is_equal = TRUE;
+  */
+  int idec;
+  int ik;
+  int itemp;
+  int j;
 
-  if ( ltype_is_equal && (zaxistype == zaxisInqType(zaxisID) || zaxistype == ZAXIS_GENERIC) )
+  /*
+    Check length of binary number to ensure decimal number
+    generated will fit in the computer word - in this case will
+    it fit in a Cray 48 bit integer?
+  */
+  if ( knbit < 1 || knbit > 14 )
     {
-      if ( zaxisInqLbounds(zaxisID, NULL) > 0 ) zlbounds = 1;
-      if ( nlevels == zaxisInqSize(zaxisID) && zlbounds == lbounds )
-	{
-	  const double *dlevels;
-	  char zlongname[CDI_MAX_NAME];
-	  char zunits[CDI_MAX_NAME];
-
-	  dlevels = zaxisInqLevelsPtr(zaxisID);
-	  for ( levelID = 0; levelID < nlevels; levelID++ )
-	    {
-	      if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
-		break;
-	    }
-
-	  if ( levelID == nlevels ) differ = 0;
+      *kerr = 1;
+      printf(" prtbin : Error in binary number length - %3d bits.\n", knbit);
+      return;
+    }
+  else
+    *kerr = 0;
+  /*
+    -----------------------------------------------------------------
+    Section 1. Generate required number.
+    -----------------------------------------------------------------
+  */
+  *kout = 0;
+  ik    = kin;
+  idec  = 1;
 
-	  if ( ! differ )
-	    {
-	      zaxisInqLongname(zaxisID, zlongname);
-	      zaxisInqUnits(zaxisID, zunits);
-	      if ( longname && zlongname[0] )
-		{
-		  if ( strcmp(longname, zlongname) != 0 ) differ = 1;
-		}
-	      if ( units && zunits[0] )
-		{
-		  if ( strcmp(units, zunits) != 0 ) differ = 1;
-		}
-	    }
-	}
+  for ( j = 0; j < knbit; j++ )
+    {
+      itemp = ik - ( (ik/2)*2 );
+      *kout = (*kout) + itemp * idec;
+      ik    = ik / 2;
+      idec  = idec * 10;
     }
 
-  return (differ);
+  return;
 }
 
 
-int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
-		double *levels1, double *levels2, int vctsize, double *vct, char *name,
-		char *longname, char *units, int prec, int mode, int ltype1)
+void ref2ibm(double *pref, int kbits)
 {
   /*
-    mode: 0 search in vlist and zaxis table
-          1 search in zaxis table
-   */
-  int zaxisdefined;
-  int nzaxis;
-  int zaxisID = UNDEFID;
-  int index;
-  int zaxisglobdefined = 0;
-  vlist_t *vlistptr;
-  int i;
 
-  vlistptr = vlist_to_pointer(vlistID);
+    Purpose:
+    --------
 
-  zaxisdefined = 0;
-  nzaxis = vlistptr->nzaxis;
+    Code and check reference value in IBM format
 
-  if ( mode == 0 )
-    for ( index = 0; index < nzaxis; index++ )
-      {
-	zaxisID = vlistptr->zaxisIDs[index];
+    Input Parameters:
+    -----------------
 
-	if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
-	  {
-	    zaxisdefined = 1;
-	    break;
-	  }
-      }
+    pref       - Reference value
+    kbits      - Number of bits per computer word.
 
-  if ( ! zaxisdefined )
-    {
-      nzaxis = zaxisSize();
-      if ( nzaxis > 0 )
-        {
-          int *zaxisIndexList;
-          zaxisIndexList = (int *)xmalloc((size_t)nzaxis * sizeof (int));
-          zaxisGetIndexList ( nzaxis, zaxisIndexList );
-          for ( i = 0; i < nzaxis; i++ )
-            {
-              zaxisID = zaxisIndexList[i];
-              if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
-                {
-                  zaxisglobdefined = 1;
-                  break;
-                }
-            }
-          if ( zaxisIndexList ) free ( zaxisIndexList );
-        }
+    Output Parameters:
+    ------------------
 
-      nzaxis = vlistptr->nzaxis;
-      if ( mode == 1 )
-	for ( index = 0; index < nzaxis; index++ )
-	  if ( vlistptr->zaxisIDs[index] == zaxisID )
-	    {
-	      zaxisglobdefined = FALSE;
-	      break;
-	    }
-    }
+    pref       - Reference value
 
-  if ( ! zaxisdefined )
-    {
-      if ( ! zaxisglobdefined )
-	{
-	  zaxisID = zaxisCreate(zaxistype, nlevels);
-	  zaxisDefLevels(zaxisID, levels);
-	  if ( lbounds )
-	    {
-	      zaxisDefLbounds(zaxisID, levels1);
-	      zaxisDefUbounds(zaxisID, levels2);
-	    }
+    Method:
+    -------
 
-	  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
-	    {
-	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels+1)) */
-	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels)) */
-	      if ( vctsize > 0 )
-		zaxisDefVct(zaxisID, vctsize, vct);
-	      else
-		Warning("VCT missing");
-	    }
+    Codes in IBM format, then decides to ensure that reference 
+    value used for packing is not different from that stored
+    because of packing differences.
 
-	  zaxisDefName(zaxisID, name);
-	  zaxisDefLongname(zaxisID, longname);
-	  zaxisDefUnits(zaxisID, units);
-	  zaxisDefPrec(zaxisID, prec);
-	  zaxisDefLtype(zaxisID, ltype1);
-	}
+    Externals.
+    ----------
 
-      nzaxis = vlistptr->nzaxis;
-      vlistptr->zaxisIDs[nzaxis] = zaxisID;
-      vlistptr->nzaxis++;
-    }
+    confp3    - Encode into IBM floating point format.
+    decfp2    - Decode from IBM floating point format.
 
-  return (zaxisID);
-}
+    Reference:
+    ----------
 
+    None.
 
-void varDefMissval(int varID, double missval)
-{
-  vartable[varID].lmissval = 1;
-  vartable[varID].missval = missval;
-}
+    Comments:
+    --------
 
+    None.
 
-void varDefCompType(int varID, int comptype)
-{
-  if ( vartable[varID].comptype == COMPRESS_NONE )
-    vartable[varID].comptype = comptype;
-}
+    Author:
+    -------
 
+    J.D.Chambers     ECMWF      17:05:94
 
-void varDefCompLevel(int varID, int complevel)
-{
-  vartable[varID].complevel = complevel;
-}
+    Modifications:
+    --------------
 
+    Uwe Schulzweida   MPIfM   01/04/2001
 
-int varInqInst(int varID)
-{
-  return (vartable[varID].instID);
-}
+    Convert to C from EMOS library version 130
+
+  */
 
+  static int itrnd;
+  static int kexp, kmant;
+  static double ztemp, zdumm;
+  extern int CGRIBEX_Debug;
 
-void varDefInst(int varID, int instID)
-{
-  vartable[varID].instID = instID;
-}
+  /* ----------------------------------------------------------------- */
+  /*   Section 1. Convert to and from IBM format.                      */
+  /* ----------------------------------------------------------------- */
 
+  /*  Convert floating point reference value to IBM representation. */
 
-int varInqModel(int varID)
-{
-  return (vartable[varID].modelID);
-}
+  itrnd = 1;
+  zdumm = ztemp = *pref;
+  confp3(zdumm, &kexp, &kmant, kbits, itrnd);
 
+  if ( kexp == 0 && kmant == 0 ) return;
 
-void varDefModel(int varID, int modelID)
-{
-  vartable[varID].modelID = modelID;
-}
+  /*  Set reference value to that actually stored in the GRIB code. */
 
+  *pref = decfp2(kexp, kmant);
 
-int varInqTable(int varID)
-{
-  return (vartable[varID].tableID);
-}
+  /*  If the nearest number which can be represented in */
+  /*  GRIB format is greater than the reference value,  */
+  /*  find the nearest number in GRIB format lower      */
+  /*  than the reference value.                         */
 
+  if ( ztemp < *pref )
+    {
+      /*  Convert floating point to GRIB representation */
+      /*  using truncation to ensure that the converted */
+      /*  number is smaller than the original one.      */
 
-void varDefTable(int varID, int tableID)
-{
-  vartable[varID].tableID = tableID;
-}
+      itrnd = 0;
+      zdumm = *pref = ztemp;
+      confp3(zdumm, &kexp, &kmant, kbits, itrnd);
 
+      /*  Set reference value to that stored in the GRIB code. */
 
-void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type)
-{
-  if ( vartable[varID].ensdata == NULL )
-      vartable[varID].ensdata = (ensinfo_t *)xmalloc( sizeof( ensinfo_t ) );
+      *pref = decfp2(kexp, kmant);
 
-  vartable[varID].ensdata->ens_index = ens_idx;
-  vartable[varID].ensdata->ens_count = ens_count;
-  vartable[varID].ensdata->forecast_init_type = forecast_type;
-}
+      if ( ztemp < *pref )
+	{
+	  if ( CGRIBEX_Debug )
+	    {
+	      Message("Reference value error.");
+	      Message("Notify Met.Applications Section.");
+	      Message("ZTEMP = ", ztemp);
+	      Message("PREF = ", pref);
+	    }
+	  *pref = ztemp;
+	}
+    }
+
+  return;
+} /* ref2ibm */
+#include <string.h>
 
 
-void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess)
+int correct_bdslen(int bdslen, long recsize, long gribpos)
 {
-  vartable[varID].typeOfGeneratingProcess = typeOfGeneratingProcess;
+  /*
+    If a very large product, the section 4 length field holds
+    the number of bytes in the product after section 4 upto
+    the end of the padding bytes.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  if ( recsize > JP23SET ) bdslen = recsize - gribpos - bdslen;
+  return (bdslen);
 }
 
 
-void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate)
+int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
+		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize)
 {
-  vartable[varID].productDefinitionTemplate = productDefinitionTemplate;
-}
+  unsigned char *pds, *gds, *bms, *bds;
+  unsigned char *bufpointer, *is, *section;
+  int gribversion, grib1offset;
+  long gribsize = 0, recsize;
+  int bdslen;
 
+  *gribrecsize = 0;
+  *pdsp = NULL;
+  *gdsp = NULL;
+  *bmsp = NULL;
+  *bdsp = NULL;
 
-#if  defined  (HAVE_LIBGRIB_API)
-void varDefOptGribInt(int varID, long lval, const char *keyword)
-{
-  int idx = vartable[varID].opt_grib_int_nentries;
-  vartable[varID].opt_grib_int_nentries++;
-  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
-  vartable[varID].opt_grib_int_val[idx] = (int) lval;
-  vartable[varID].opt_grib_int_keyword[idx] = strdupx(keyword);
-}
-#endif
+  section = gribbuffer;
+  is = gribbuffer;
+  if ( ! GRIB_START(section) )
+    {
+      fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
+	      section[0], section[1], section[2], section[3]);
+      return (-1);
+    }
 
+  recsize = gribrec_len(section[4], section[5], section[6]);
 
-#if  defined  (HAVE_LIBGRIB_API)
-void varDefOptGribDbl(int varID, double dval, const char *keyword)
-{
-  int idx = vartable[varID].opt_grib_dbl_nentries;
-  vartable[varID].opt_grib_dbl_nentries++;
-  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
-  vartable[varID].opt_grib_dbl_val[idx] = dval;
-  vartable[varID].opt_grib_dbl_keyword[idx] = strdupx(keyword);
+  gribversion = GRIB_EDITION(section);
+  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
+
+  if ( gribversion == 1 )
+    grib1offset = 4;
+  else
+    grib1offset = 0;
+
+  pds = is + 4 + grib1offset;
+  bufpointer = pds + PDS_Len;
+  gribsize += 4 + grib1offset + PDS_Len;
+
+  if ( PDS_HAS_GDS )
+    {
+      gds = bufpointer;
+      bufpointer += GDS_Len;
+      gribsize += GDS_Len;
+    }
+  else
+    {
+      gds = NULL;
+    }
+
+  if ( PDS_HAS_BMS )
+    {
+      bms = bufpointer;
+      bufpointer += BMS_Len;
+      gribsize += BMS_Len;
+    }
+  else
+    {
+      bms = NULL;
+    }
+
+  bds = bufpointer;
+  bdslen = BDS_Len;
+  bdslen = correct_bdslen(bdslen, recsize, gribsize);
+  bufpointer += bdslen;
+  gribsize += bdslen;
+  gribsize += 4;
+
+  *pdsp = pds;
+  *gdsp = gds;
+  *bmsp = bms;
+  *bdsp = bds;
+
+  *gribrecsize = gribsize;
+
+  if ( gribbufsize < gribsize )
+    {
+      fprintf(stderr, "Length of GRIB message is inconsistent (grib_buffer_size=%ld < grib_record_size=%ld)!\n", gribbufsize, gribsize);
+      return (1);
+    }
+
+  /* end section - "7777" in ascii */
+  if ( !GRIB_FIN(bufpointer) )
+    {
+      fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
+	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
+      return (-2);
+    }
+
+  return (0);
 }
-#endif
 
 
-#if  defined  (HAVE_LIBGRIB_API)
-int varOptGribNentries(int varID)
+int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
+		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
+		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp)
 {
-  int nentries = 0;
-  nentries = vartable[varID].opt_grib_int_nentries + vartable[varID].opt_grib_dbl_nentries;
-  return (nentries);
-}
-#endif
+  unsigned char *section;
+  long sec_len;
+  int sec_num;
+  int gribversion;
+  int i, msec;
+  long gribsize;
+  long grib_len = 0;
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  UNUSED(gribbufsize);
 
+  *idsp = NULL;
+  *lusp = NULL;
+  *gdsp = NULL;
+  *pdsp = NULL;
+  *drsp = NULL;
+  *bmsp = NULL;
+  *bdsp = NULL;
 
+  section = gribbuffer;
+  sec_len = 16;
 
-#if  defined  (HAVE_LIBGRIB_API)
-/* list of additional GRIB2 keywords which are read by the open process */
-int    cdiNAdditionalGRIBKeys = 0;
-char*  cdiAdditionalGRIBKeys[MAX_OPT_GRIB_ENTRIES];
-#endif
+  if ( !GRIB_START(section) )
+    {
+      fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
+	      section[0], section[1], section[2], section[3]);
+      return (-1);
+    }
 
-extern void zaxisGetIndexList ( int, int * );
+  gribversion = GRIB_EDITION(section);
+  if ( gribversion != 2 )
+    {
+      fprintf(stderr, "wrong GRIB version %d\n", gribversion);
+      return (-1);      
+    }
 
-static int VLIST_Debug = 0;
+  gribsize = 0;
+  for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
 
-static void vlist_initialize(void);
+  grib_len += sec_len;
+  section  += sec_len;
 
-#if  defined  (HAVE_LIBPTHREAD)
-#  include <pthread.h>
+  /* section 1 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "ids %d %ld\n", sec_num, sec_len);
 
-static pthread_once_t  _vlist_init_thread = PTHREAD_ONCE_INIT;
+  if ( sec_num != 1 )
+    {
+      fprintf(stderr, "Unexpected section1 number %d\n", sec_num);
+      return (-1);
+    }
 
-#  define VLIST_INIT()        \
-  pthread_once(&_vlist_init_thread, vlist_initialize)
+  *idsp = section;
 
-#else
+  grib_len += sec_len;
+  section  += sec_len;
 
-static int vlistIsInitialized = 0;
+  /* section 2 and 3 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "lus %d %ld\n", sec_num, sec_len);
 
-#  define VLIST_INIT()               \
-  if ( !vlistIsInitialized ) vlist_initialize()
-#endif
+  if ( sec_num == 2 )
+    {
+      *lusp = section;
 
+      grib_len += sec_len;
+      section  += sec_len;
 
-static int
-vlist_compare(vlist_t *a, vlist_t *b)
-{
-  int diff;
-  diff = (a->nvars != b->nvars) | (a->ngrids != b->ngrids)
-    | (a->nzaxis != b->nzaxis) | (a->instID != b->instID)
-    | (a->modelID != b->modelID) | (a->tableID != b->tableID)
-    | (a->ntsteps != b->ntsteps) | (a->atts.nelems != b->atts.nelems);
-  int nvars = a->nvars;
-  for (int varID = 0; varID < nvars; ++varID)
-    diff |= vlistVarCompare(a, varID, b, varID);
-  size_t natts = a->atts.nelems;
-  for (size_t attID = 0; attID < natts; ++attID)
-    diff |= vlist_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
-  return diff;
-}
+      /* section 3 */
+      sec_len = GRIB2_SECLEN(section);
+      sec_num = GRIB2_SECNUM(section);
+      //fprintf(stderr, "gds %d %ld\n", sec_num, sec_len);
 
-static void
-vlistPrintKernel(vlist_t *vlistptr, FILE * fp );
-static void
-vlist_delete(vlist_t *vlistptr);
+      *gdsp = section;
+    }
+  else if ( sec_num == 3 )
+    {
+      *gdsp = section;
+    }
+  else
+    {
+      fprintf(stderr, "Unexpected section3 number %d\n", sec_num);
+      return (-1);
+    }
 
-static int  vlistGetSizeP ( void * vlistptr, void *context);
-static void vlistPackP    ( void * vlistptr, void * buff, int size,
-                            int *position, void *context);
-static int  vlistTxCode   ( void );
+  grib_len += sec_len;
+  section  += sec_len;
 
-#if !defined(__cplusplus)
-const
-#endif
-resOps vlistOps = {
-  (valCompareFunc)vlist_compare,
-  (valDestroyFunc)vlist_delete,
-  (valPrintFunc)vlistPrintKernel
-  , vlistGetSizeP,
-  vlistPackP,
-  vlistTxCode
-};
+  /* section 4 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "pds %d %ld\n", sec_num, sec_len);
 
+  if ( sec_num != 4 )
+    {
+      fprintf(stderr, "Unexpected section4 number %d\n", sec_num);
+      return (-1);
+    }
 
-vlist_t *vlist_to_pointer(int vlistID)
-{
-  VLIST_INIT();
-  return (vlist_t*) reshGetVal(vlistID, &vlistOps );
-}
+  *pdsp = section;
 
-static
-void vlist_init_entry(vlist_t *vlistptr)
-{
-  vlistptr->locked         = 0;
-  vlistptr->self           = CDI_UNDEFID;
-  vlistptr->nvars          = 0;
-  vlistptr->vars           = NULL;
-  vlistptr->ngrids         = 0;
-  vlistptr->nzaxis         = 0;
-  vlistptr->taxisID        = CDI_UNDEFID;
-  vlistptr->instID         = cdiDefaultInstID;
-  vlistptr->modelID        = cdiDefaultModelID;
-  vlistptr->tableID        = cdiDefaultTableID;
-  vlistptr->varsAllocated  = 0;
-  vlistptr->ntsteps        = CDI_UNDEFID;
-  vlistptr->atts.nalloc    = MAX_ATTRIBUTES;
-  vlistptr->atts.nelems    = 0;
-}
+  grib_len += sec_len;
+  section  += sec_len;
+
+  /* section 5 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "drs %d %ld\n", sec_num, sec_len);
+
+  if ( sec_num != 5 )
+    {
+      fprintf(stderr, "Unexpected section5 number %d\n", sec_num);
+      return (-1);
+    }
+
+  *drsp = section;
 
-static
-vlist_t *vlist_new_entry(cdiResH resH)
-{
-  vlist_t *vlistptr = (vlist_t*) xmalloc(sizeof(vlist_t));
-  vlist_init_entry(vlistptr);
-  if (resH == CDI_UNDEFID)
-    vlistptr->self = reshPut(vlistptr, &vlistOps);
-  else
+  grib_len += sec_len;
+  section  += sec_len;
+
+  /* section 6 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "bms %d %ld\n", sec_num, sec_len);
+
+  if ( sec_num != 6 )
     {
-      vlistptr->self = resH;
-      reshReplace(resH, vlistptr, &vlistOps);
+      fprintf(stderr, "Unexpected section6 number %d\n", sec_num);
+      return (-1);
     }
-  return (vlistptr);
-}
 
-static
-void vlist_delete_entry(vlist_t *vlistptr)
-{
-  int idx;
+  *bmsp = section;
 
-  idx = vlistptr->self;
+  grib_len += sec_len;
+  section  += sec_len;
 
-  reshRemove(idx, &vlistOps );
+  /* section 7 */
+  sec_len = GRIB2_SECLEN(section);
+  sec_num = GRIB2_SECNUM(section);
+  //fprintf(stderr, "bds %d %ld\n", sec_num, sec_len);
 
-  free(vlistptr);
+  if ( sec_num != 7 )
+    {
+      fprintf(stderr, "Unexpected section7 number %d\n", sec_num);
+      return (-1);
+    }
 
-  if ( VLIST_Debug )
-    Message("Removed idx %d from vlist list", idx);
-}
+  *bdsp = section;
 
-static
-void vlist_initialize(void)
-{
-  char *env;
+  grib_len += sec_len;
+  section  += sec_len;
 
-  env = getenv("VLIST_DEBUG");
-  if ( env ) VLIST_Debug = atoi(env);
-#ifndef HAVE_LIBPTHREAD
-  vlistIsInitialized = TRUE;
-#endif
-}
+  /* skip multi GRIB sections */
+  msec = 1;
+  while ( !GRIB_FIN(section) )
+    {
+      sec_len = GRIB2_SECLEN(section);
+      sec_num = GRIB2_SECNUM(section);
 
-static
-void vlist_copy(vlist_t *vlistptr2, vlist_t *vlistptr1)
-{
-  int vlistID2 = vlistptr2->self;
-  memcpy(vlistptr2, vlistptr1, sizeof(vlist_t));
-  vlistptr2->atts.nelems = 0;
-  vlistptr2->self = vlistID2;
-}
+      if ( sec_num < 1 || sec_num > 7 ) break;
 
-void vlist_lock(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      if ( sec_num == 7 )
+	fprintf(stderr, "Skipped unsupported multi GRIB section %d!\n", ++msec);
 
-  if ( !vlistptr->locked )
+      if ( (grib_len + sec_len) > gribsize ) break;
+
+      grib_len += sec_len;
+      section  += sec_len;
+    }
+
+  /* end section - "7777" in ASCII */
+  if ( !GRIB_FIN(section) )
     {
-      vlistptr->locked = 1;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
+	      section[0], section[1], section[2], section[3]);
+      return (-2);
     }
+
+  return (0);
 }
 
 
-void vlist_unlock(int vlistID)
+int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
+			int *intnum, float *fltnum, off_t *bignum)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  unsigned char *pds, *gds, *bms, *bds;
+  unsigned char *bufpointer, *is, *section;
+  int gribversion, grib1offset;
+  long gribsize = 0;
+  off_t dpos, bpos = 0;
+  int bdslen;
+  float bsf;
 
-  if ( vlistptr->locked )
+  section = gribbuffer;
+  is = gribbuffer;
+  if ( ! GRIB_START(section) )
     {
-      vlistptr->locked = 0;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
+	      section[0], section[1], section[2], section[3]);
+      return (-1);
     }
-}
-
-/*
- at Function  vlistCreate
- at Title     Create a variable list
 
- at Prototype int vlistCreate(void)
+  gribversion = GRIB_EDITION(section);
+  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
 
- at Example
-Here is an example using @func{vlistCreate} to create a variable list
-and add a variable with @func{vlistDefVar}.
+  if ( gribversion == 1 )
+    grib1offset = 4;
+  else
+    grib1offset = 0;
 
- at Source
-   ...
-int vlistID, varID;
-   ...
-vlistID = vlistCreate();
-varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
-   ...
-streamDefVlist(streamID, vlistID);
-   ...
-vlistDestroy(vlistID);
-   ...
- at EndSource
- at EndFunction
-*/
-int vlistCreate(void)
-{
-  cdiInitialize();
+  pds = is + 4 + grib1offset;
+  bufpointer = pds + PDS_Len;
+  gribsize += 4 + grib1offset + PDS_Len;
 
-  VLIST_INIT();
+  if ( PDS_HAS_GDS )
+    {
+      gds = bufpointer;
+      bufpointer += GDS_Len;
+      gribsize += GDS_Len;
+    }
+  else
+    {
+      gds = NULL;
+    }
 
-  vlist_t *vlistptr = vlist_new_entry(CDI_UNDEFID);
-  return (vlistptr->self);
-}
+  if ( PDS_HAS_BMS )
+    {
+      bms = bufpointer;
+      bufpointer += BMS_Len;
 
-static void
-vlist_delete(vlist_t *vlistptr)
-{
-  int vlistID = vlistptr->self;
+      bpos = recpos + gribsize + 6;
 
-  vlistDelAtts(vlistID, CDI_GLOBAL);
+      gribsize += BMS_Len;
+    }
+  else
+    {
+      bms = NULL;
+    }
 
-  int nvars = vlistptr->nvars;
+  bds = bufpointer;
 
-  for (int varID = 0; varID < nvars; varID++ )
-    {
-      if ( vlistptr->vars[varID].levinfo )  free(vlistptr->vars[varID].levinfo);
-      if ( vlistptr->vars[varID].name )     free(vlistptr->vars[varID].name);
-      if ( vlistptr->vars[varID].longname ) free(vlistptr->vars[varID].longname);
-      if ( vlistptr->vars[varID].stdname )  free(vlistptr->vars[varID].stdname);
-      if ( vlistptr->vars[varID].units )    free(vlistptr->vars[varID].units);
+  dpos = recpos + gribsize + 11;
 
-      if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
+  bdslen = BDS_Len;
+  bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
+  bufpointer += bdslen;
+  gribsize += bdslen;
+  gribsize += 4;
 
-#if  defined  (HAVE_LIBGRIB_API)
-      for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
-	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
-	  free(vlistptr->vars[varID].opt_grib_int_keyword[i]);
-      }
-      for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++) {
-	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
-	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
-      }
-#endif
+  if ( gribsize > recsize )
+    {
+      fprintf(stderr, "GRIB buffer size %ld too small! Min size = %ld\n", recsize, gribsize);
+      return (1);
+    }
 
-      vlistDelAtts(vlistID, varID);
+  /* end section - "7777" in ascii */
+  if ( !GRIB_FIN(bufpointer) )
+    {
+      fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
+	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
     }
 
-  if ( vlistptr->vars ) free(vlistptr->vars);
+  bsf = BDS_BinScale;
+  if ( bsf > 32767 ) bsf = 32768-bsf;
+  bsf = pow(2.0,(double)bsf);
 
-  vlist_delete_entry(vlistptr);
+  bignum[0] = dpos;
+  if ( bms ) bignum[1] = bpos;
+  else       bignum[1] = -999;
+  intnum[0] = BDS_NumBits;
+
+  /*  fltnum[0] = 1.0; */
+  fltnum[0] = pow(10.0, (double)PDS_DecimalScale);
+  fltnum[1] = bsf;
+  fltnum[2] = BDS_RefValue;
+  /*
+  printf("intnum %d %d %d\n", intnum[0], intnum[1], intnum[2]);
+  printf("fltnum %g %g %g\n", fltnum[0], fltnum[1], fltnum[2]);
+  */
+  return (0);
 }
 
 
-/*
- at Function  vlistDestroy
- at Title     Destroy a variable list
+void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  static int header = 1;
+  int GridType, level, nerr;
+  unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  double cr = 1;
+  int bdslen;
+  int llarge = 0;
 
- at Prototype void vlistDestroy(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+  if ( header )
+    {
+      fprintf(stdout, 
+      "  Rec : Off Position   Size : V PDS  GDS    BMS    BDS : Code Level :  LType GType: CR LL\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
+    }
 
- at EndFunction
-*/
-void vlistDestroy(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  is = gribbuffer;
 
-  if ( vlistptr->locked )
-    Warning("Destroying of a locked object (vlistID=%d) failed!", vlistID);
+  if ( gribrec_len(is[4], is[5], is[6]) > JP23SET ) llarge = 1;
+
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
+    {
+      fprintf(stdout, "%5d :%4ld %8ld %6ld : GRIB message error\n", nrec, offset, recpos, recsize);
+      return;
+    }
+
+  if ( gds == NULL )
+    GridType = -1;
   else
-    vlist_delete(vlistptr);
-}
+    GridType = GDS_GridType;
 
-/*
- at Function  vlistCopy
- at Title     Copy a variable list
+  if ( PDS_LevelType == 100 )
+    level = PDS_Level * 100;
+  else if ( PDS_LevelType == 99 )
+    level = PDS_Level;
+  else if ( PDS_LevelType == 109 )
+    level = PDS_Level;
+  else
+    level = PDS_Level1;
 
- at Prototype void vlistCopy(int vlistID2, int vlistID1)
- at Parameter
-    @Item  vlistID2  Target variable list ID.
-    @Item  vlistID1  Source variable list ID.
+  bdslen = BDS_Len;
+  bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
 
- at Description
-The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
+  if ( ((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130) )
+    {
+      int s1, s2;
+      s1 = gribrec_len(bds[14], bds[15], bds[16]);
+      s2 = gribrec_len(gribbuffer[4], gribbuffer[5], gribbuffer[6]);
+      cr = ((double)s1)/s2;
+    }
 
- at EndFunction
-*/
-void vlistCopy(int vlistID2, int vlistID1)
-{
-  vlist_t *vlistptr1, *vlistptr2;
+  fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d%4d%5d %6d %6d : %3d %6d : %5d %5d %6.4g  %c",
+	  nrec, offset, recpos, recsize, GRIB_EDITION(is),
+	  PDS_Len, GDS_Len, BMS_Len, bdslen,
+	  PDS_Parameter, level, PDS_LevelType, GridType, cr, llarge?'T':'F');
 
-  vlistptr1 = vlist_to_pointer(vlistID1);
-  vlistptr2 = vlist_to_pointer(vlistID2);
+  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+  fprintf(stdout, "\n");
+}
 
-  var_t *vlist2vars = vlistptr2->vars;
-  vlist_copy(vlistptr2, vlistptr1);
 
-  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  static int header = 1;
+  int nerr;
+  unsigned char *is  = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  unsigned char *ids = NULL, *lus = NULL, *drs = NULL;
+  long ids_len = 0, lus_len = 0, gds_len = 0, pds_len = 0, drs_len = 0, bms_len = 0, bds_len = 0;
+  int gridtype, paramnum, level1type /*, level2type*/;
+  int level1 /*, level1sf*/;
+  /* int level2, level2sf; */
+  double cr = 1;
 
-  if ( vlistptr1->vars )
+  if ( header )
     {
-      int nvars = vlistptr1->nvars;
+      fprintf(stdout, 
+      "  Rec : Off Position   Size : V IDS LUS GDS PDS  DRS    BMS    BDS : Code Level :  LType GType: CR\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
+    }
 
-      //vlistptr2->varsAllocated = nvars;
-      vlistptr2->vars
-        = xrealloc(vlist2vars,
-                   (size_t)vlistptr2->varsAllocated * sizeof (var_t));
-      memcpy(vlistptr2->vars, vlistptr1->vars,
-             (size_t)vlistptr2->varsAllocated * sizeof (var_t));
+  is = gribbuffer;
 
-      for ( int varID = 0; varID < nvars; varID++ )
-        {
-          if ( vlistptr1->vars[varID].name )
-            vlistptr2->vars[varID].name = strdupx(vlistptr1->vars[varID].name);
+  nerr = grib2Sections(gribbuffer, recsize, &ids, &lus, &gds, &pds, &drs, &bms, &bds);
+  if ( nerr )
+    {
+      fprintf(stdout, "%5d :%4ld %8ld %6ld : error\n", nrec, offset, recpos, recsize);
+      return;
+    }
 
-          if ( vlistptr1->vars[varID].longname )
-            vlistptr2->vars[varID].longname = strdupx(vlistptr1->vars[varID].longname);
+  if ( ids ) ids_len = GRIB2_SECLEN(ids);
+  if ( lus ) lus_len = GRIB2_SECLEN(lus);
+  if ( gds ) gds_len = GRIB2_SECLEN(gds);
+  if ( pds ) pds_len = GRIB2_SECLEN(pds);
+  if ( drs ) drs_len = GRIB2_SECLEN(drs);
+  if ( bms ) bms_len = GRIB2_SECLEN(bms);
+  if ( bds ) bds_len = GRIB2_SECLEN(bds);
 
-          if ( vlistptr1->vars[varID].stdname )
-            vlistptr2->vars[varID].stdname = strdupx(vlistptr1->vars[varID].stdname);
+  /*
+  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+    {
+      int s1, s2;
+      s1 = ((int) ((bds[14]<<16)+(bds[15]<<8)+bds[16]));
+      s2 = ((int) ((gribbuffer[4]<<16)+(gribbuffer[5]<<8)+gribbuffer[6]));
+      cr = ((double)s1)/s2;
+    }
+  */
+  gridtype   = GET_UINT2(gds[12],gds[13]);
+  paramnum   = GET_UINT1(pds[10]);
+  level1type = GET_UINT1(pds[22]);
+  /* level1sf   = GET_UINT1(pds[23]); */
+  level1     = GET_UINT4(pds[24],pds[25],pds[26],pds[27]);
+  /* level2type = GET_UINT1(pds[28]); */
+  /* level2sf   = GET_UINT1(pds[29]); */
+  /* level2     = GET_UINT4(pds[30],pds[31],pds[32],pds[33]); */
+  /*
+  printf("level %d %d %d %d %d %d %d\n", level1type, level1sf, level1, level1*level1sf, level2sf, level2, level2*level2sf);
+  */
+  fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d %3ld %3ld %3ld %3ld %4ld %6ld %6ld : %3d%7d : %5d %5d %6.4g\n",
+	  nrec, offset, recpos, recsize, GRIB_EDITION(is),
+	  ids_len, lus_len, gds_len, pds_len, drs_len, bms_len, bds_len,
+	  paramnum, level1, level1type, gridtype, cr);
+}
 
-          if ( vlistptr1->vars[varID].units )
-            vlistptr2->vars[varID].units = strdupx(vlistptr1->vars[varID].units);
 
-          if ( vlistptr1->vars[varID].ensdata )
-            {
-              vlistptr2->vars[varID].ensdata = (ensinfo_t *) malloc(sizeof(ensinfo_t));
-              memcpy(vlistptr2->vars[varID].ensdata,
-                     vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
-            }
-#if  defined  (HAVE_LIBGRIB_API)
-          /* ---------------------------------- */
-          /* Local change: 2013-01-28, FP (DWD) */
-          /* ---------------------------------- */
-
-	  vlistptr2->vars[varID].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-	  for (int i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
-	    if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-	      vlistptr2->vars[varID].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-	      vlistptr2->vars[varID].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-	      vlistptr2->vars[varID].opt_grib_int_update[i]  = TRUE;
-	    }
-	  }
-	  vlistptr2->vars[varID].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-	  for (int i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
-	    if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-	      vlistptr2->vars[varID].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-	      vlistptr2->vars[varID].opt_grib_dbl_update[i]  = TRUE;
-	    }
-	  }
-#endif
+void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  int gribversion;
 
-	  vlistptr2->vars[varID].atts.nelems = 0;
-	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
+  gribversion = gribVersion(gribbuffer, recsize);
 
-          if ( vlistptr1->vars[varID].levinfo )
-            {
-              size_t nlevs
-                = (size_t)zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-              vlistptr2->vars[varID].levinfo
-                = xmalloc(nlevs * sizeof (levinfo_t));
-              memcpy(vlistptr2->vars[varID].levinfo,
-                     vlistptr1->vars[varID].levinfo,
-                     nlevs * sizeof (levinfo_t));
-            }
-	}
+  if ( gribversion == 0 || gribversion == 1 )
+    grib1PrintALL(nrec, offset, recpos, recsize, gribbuffer);
+  else if ( gribversion == 2 )
+    grib2PrintALL(nrec, offset, recpos, recsize, gribbuffer);
+  else
+    {
+      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+	      nrec, offset, recpos, recsize, gribversion); 
     }
 }
 
-/*
- at Function  vlistDuplicate
- at Title     Duplicate a variable list
 
- at Prototype int vlistDuplicate(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  static int header = 1;
+  unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  int century, subcenter, decimalscale, nerr;
+  int fc_num = 0;
+  int year = 0, date;
 
- at Description
-The function @func{vlistDuplicate} duplicates the variable list from vlistID1.
+  UNUSED(recpos);
 
- at Result
- at func{vlistDuplicate} returns an identifier to the duplicated variable list.
+  if ( header )
+    {
+      fprintf(stdout, 
+      "  Rec : PDS Tab Cen Sub Ver Grid Code LTyp Level1 Level2    Date  Time P1 P2 TU TR NAVE Scale FCnum CT\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
+    }
 
- at EndFunction
-*/
-int vlistDuplicate(int vlistID)
-{
-  int vlistIDnew = vlistCreate();
-  vlistCopy(vlistIDnew, vlistID);
-  return (vlistIDnew);
+  is = gribbuffer;
+
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
+    {
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
+    }
+
+  switch(GRIB_EDITION(is))
+    {   
+    case 0:
+      year                = GET_UINT1(pds[12]);
+      century             = 1;
+      subcenter           = 0;
+      decimalscale        = 0;
+      break;
+    case 1:
+      year                = PDS_Year;
+      century             = PDS_Century;
+      subcenter           = PDS_Subcenter;
+      decimalscale        = PDS_DecimalScale;
+      break;
+    default:
+      fprintf(stderr, "Grib version %d not supported!", GRIB_EDITION(is));
+      exit(EXIT_FAILURE);
+    }
+
+  if ( PDS_Len > 28 )
+    if ( PDS_CenterID    == 98 || PDS_Subcenter == 98 ||
+	(PDS_CenterID    ==  7 && PDS_Subcenter == 98) )
+      if ( pds[40] == 1 )
+	fc_num = GET_UINT1(pds[49]);
+
+  if ( year < 0 )
+    {
+      date = (-year)*10000+PDS_Month*100+PDS_Day;
+      century = -century;
+    }
+  else
+    {
+      date =    year*10000+PDS_Month*100+PDS_Day;
+    }
+      
+  fprintf(stdout, "%5d :%4d%4d%4d%4d%4d %4d %4d%4d%7d%7d %8d%6d%3d%3d%3d%3d%5d%6d%5d%4d", nrec,
+	  PDS_Len,  PDS_CodeTable,   PDS_CenterID, subcenter, PDS_ModelID,
+	  PDS_GridDefinition, PDS_Parameter, PDS_LevelType, PDS_Level1, PDS_Level2,
+	  date, PDS_Time, PDS_TimePeriod1, PDS_TimePeriod2, PDS_TimeUnit, PDS_TimeRange,
+	  PDS_AvgNum, decimalscale, fc_num, century);
+
+  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+  fprintf(stdout, "\n");
 }
 
 
-void vlistClearFlag(int vlistID)
+void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int varID, levID;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int gribversion;
 
-  for ( varID = 0; varID < vlistptr->nvars; varID++ )
+  gribversion = gribVersion(gribbuffer, recsize);
+
+  if ( gribversion == 0 || gribversion == 1 )
+    grib1PrintPDS(nrec, recpos, recsize, gribbuffer);
+  /*
+  else if ( gribversion == 2 )
+    grib2PrintPDS(nrec, recpos, recsize, gribbuffer);
+  */
+  else
     {
-      vlistptr->vars[varID].flag = FALSE;
-      if ( vlistptr->vars[varID].levinfo )
-        {
-          int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
-          for ( levID = 0; levID < nlevs; levID++ )
-            {
-              vlistptr->vars[varID].levinfo[levID].flag = FALSE;
-            }
-        }
+      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+	      nrec, 0L, recpos, recsize, gribversion); 
     }
 }
 
-static
-int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *levels,
-                         const double *lbounds, const double *ubounds, int vctsize, const double *vct)
+
+void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int zaxisID = CDI_UNDEFID;
-  int zaxisglobdefined = 0;
-  int has_bounds = FALSE;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  int zaxisdefined = 0;
-  int nzaxis = vlistptr->nzaxis;
+  static int header = 1;
+  int nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
 
-  if ( lbounds && ubounds ) has_bounds = TRUE;
+  UNUSED(recpos);
 
-  for ( int index = 0; index < nzaxis; ++index )
+  if ( header )
     {
-      zaxisID = vlistptr->zaxisIDs[index];
-
-      if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
-        {
-          zaxisdefined = 1;
-          break;
-        }
+      fprintf(stdout, 
+      "  Rec : GDS  NV PVPL Typ : xsize ysize   Lat1   Lon1   Lat2   Lon2    dx    dy\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
     }
 
-  if ( ! zaxisdefined )
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      nzaxis = zaxisSize();
-      if ( nzaxis > 0 )
-        {
-          int *zaxisIndexList = (int *)xmalloc((size_t)nzaxis * sizeof (int));
-          reshLock();
-          zaxisGetIndexList ( nzaxis, zaxisIndexList );
-          for ( int index = 0; index < nzaxis; ++index )
-            {
-              zaxisID = zaxisIndexList[index];
-              if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
-                {
-                  zaxisglobdefined = 1;
-                  break;
-                }
-            }
-          reshUnlock();
-          free(zaxisIndexList);
-        }
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
     }
 
-  if ( ! zaxisdefined )
-    {
-      if ( ! zaxisglobdefined )
-	{
-	  zaxisID = zaxisCreate(zaxistype, nlevels);
-	  zaxisDefLevels(zaxisID, levels);
-	  if ( has_bounds )
-	    {
-	      zaxisDefLbounds(zaxisID, lbounds);
-	      zaxisDefUbounds(zaxisID, ubounds);
-	    }
-
-	  if ( zaxistype == ZAXIS_HYBRID )
-	    {
-	      if ( vctsize > 0 )
-		zaxisDefVct(zaxisID, vctsize, vct);
-	      else
-		Warning("VCT missing");
-	    }
-	}
+  fprintf(stdout, "%5d :", nrec);
 
-      nzaxis = vlistptr->nzaxis;
-      vlistptr->zaxisIDs[nzaxis] = zaxisID;
-      vlistptr->nzaxis++;
-    }
+  if ( gds )
+    fprintf(stdout, "%4d%4d%4d %4d :%6d%6d%7d%7d%7d%7d%6d%6d",
+	    GDS_Len,  GDS_NV,   GDS_PVPL, GDS_GridType,
+	    GDS_NumLon,   GDS_NumLat,
+	    GDS_FirstLat, GDS_FirstLon,
+	    GDS_LastLat,  GDS_LastLon,
+	    GDS_LonIncr,  GDS_LatIncr);
+  else
+    fprintf(stdout, " Grid Description Section not defined");
 
-  return (zaxisID);
+  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+  fprintf(stdout, "\n");
 }
 
-/*
- at Function  vlistCopyFlag
- at Title     Copy some entries of a variable list
-
- at Prototype void vlistCopyFlag(int vlistID2, int vlistID1)
- at Parameter
-    @Item  vlistID2  Target variable list ID.
-    @Item  vlistID1  Source variable list ID.
 
- at Description
-The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 to vlistID2.
-
- at EndFunction
-*/
-void vlistCopyFlag(int vlistID2, int vlistID1)
+void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
-  vlist_copy(vlistptr2, vlistptr1);
+  int gribversion;
 
-  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+  gribversion = gribVersion(gribbuffer, recsize);
 
-  if ( vlistptr1->vars )
+  if ( gribversion == 0 || gribversion == 1 )
+    grib1PrintGDS(nrec, recpos, recsize, gribbuffer);
+  /*
+  else if ( gribversion == 2 )
+    grib2PrintGDS(nrec, recpos, recsize, gribbuffer);
+  */
+  else
     {
-      int nvars = vlistptr1->nvars;
-      int nvars2 = 0;
-      int varID2;
-
-      vlistptr2->ngrids = 0;
-      vlistptr2->nzaxis = 0;
+      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+	      nrec, 0L, recpos, recsize, gribversion); 
+    }
+}
 
-      for ( int varID = 0; varID < nvars; varID++ )
-        nvars2 += (vlistptr1->vars[varID].flag != 0);
 
-      vlistptr2->nvars = nvars2;
-      vlistptr2->varsAllocated = nvars2;
-      if ( nvars2 > 0 )
-        vlistptr2->vars  = (var_t *)xmalloc((size_t)nvars2*sizeof(var_t));
-      else
-        vlistptr2->vars  = NULL;
+void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  static int header = 1;
+  int level, nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
 
-      varID2 = 0;
-      for ( int varID = 0; varID < nvars; varID++ )
-	if ( vlistptr1->vars[varID].flag )
-	  {
-	    vlistptr2->vars[varID2].flag = FALSE;
-	    int zaxisID = vlistptr1->vars[varID].zaxisID;
-	    int gridID  = vlistptr1->vars[varID].gridID;
+  UNUSED(recpos);
 
-	    memcpy(&vlistptr2->vars[varID2], &vlistptr1->vars[varID], sizeof(var_t));
+  if ( header )
+    {
+      fprintf(stdout, 
+      "  Rec : Code Level     BMS    Size\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
+    }
 
-	    vlistptr1->vars[varID].fvarID = varID2;
-	    vlistptr2->vars[varID2].fvarID = varID;
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
+    {
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
+    }
 
-	    vlistptr2->vars[varID2].mvarID = varID2;
+  if ( PDS_LevelType == 100 )
+    level = PDS_Level * 100;
+  else if ( PDS_LevelType == 99 )
+    level = PDS_Level;
+  else
+    level = PDS_Level1;
 
-	    if ( vlistptr1->vars[varID].name )
-	      vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);
+  fprintf(stdout, "%5d :", nrec);
 
-	    if ( vlistptr1->vars[varID].longname )
-	      vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);
+  if ( bms )
+    fprintf(stdout, "%4d%7d %7d %7d",
+	    PDS_Parameter, level,
+	    BMS_Len, BMS_BitmapSize);
+  else
+    fprintf(stdout, "%4d%7d Bit Map Section not defined", PDS_Parameter, level);
 
-	    if ( vlistptr1->vars[varID].stdname )
-	      vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);
+  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+  fprintf(stdout, "\n");
+}
 
-	    if ( vlistptr1->vars[varID].units )
-	      vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
 
-            if ( vlistptr1->vars[varID].ensdata )
-              {
-                vlistptr2->vars[varID2].ensdata = (ensinfo_t *)xmalloc(sizeof(ensinfo_t));
-                memcpy(vlistptr2->vars[varID2].ensdata,
-                       vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
-              }
+void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  int gribversion;
 
-#if  defined  (HAVE_LIBGRIB_API)
-	    /* ---------------------------------- */
-	    /* Local change: 2013-01-28, FP (DWD) */
-	    /* ---------------------------------- */
-
-	    int i;
-	    vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-	    for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
-	      if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-		vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-		vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-                vlistptr2->vars[varID2].opt_grib_int_update[i]  = TRUE;
-	      }
-	    }
-	    vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-	    for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
-	      if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-		vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-                vlistptr2->vars[varID2].opt_grib_dbl_update[i]  = TRUE;
-	      }
-	    }
-#endif
+  gribversion = gribVersion(gribbuffer, recsize);
 
-	    vlistptr2->vars[varID2].atts.nelems = 0;
-	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
+  if ( gribversion == 0 || gribversion == 1 )
+    grib1PrintBMS(nrec, recpos, recsize, gribbuffer);
+  /*
+  else if ( gribversion == 2 )
+    grib2PrintBMS(nrec, recpos, recsize, gribbuffer);
+  */
+  else
+    {
+      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+	      nrec, 0L, recpos, recsize, gribversion); 
+    }
+}
 
-	    int nlevs  = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-	    int nlevs2 = 0;
-            if ( vlistptr1->vars[varID].levinfo )
-              for ( int levID = 0; levID < nlevs; levID++ )
-                nlevs2 += (vlistptr1->vars[varID].levinfo[levID].flag != 0);
 
-	    vlistptr2->vars[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs2 * sizeof (levinfo_t));
+void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  static int header = 1;
+  int level, nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  double cr = 1;
+  double refval, scale;
 
-	    if ( nlevs != nlevs2 )
-	      {
-		int nvct = 0;
-		double *lbounds = NULL, *ubounds = NULL;
-		const double *vct = NULL;
-                char ctemp[CDI_MAX_NAME];
+  UNUSED(recpos);
 
-		zaxisID = vlistptr1->vars[varID].zaxisID;
-		double *levels = (double *)xmalloc((size_t)nlevs2 * sizeof (double));
-                int levID2 = 0;
-                if (!vlistptr1->vars[varID].levinfo)
-                  cdiVlistCreateVarLevInfo(vlistptr1, varID);
-                for ( int levID = 0; levID < nlevs; ++levID )
-                  if ( vlistptr1->vars[varID].levinfo[levID].flag )
-                    {
-                      vlistptr1->vars[varID].levinfo[levID].flevelID = levID2;
-                      vlistptr1->vars[varID].levinfo[levID].mlevelID = levID2;
-                      levels[levID2++] = zaxisInqLevel(zaxisID, levID);
-                    }
-		int zaxisType = zaxisInqType(zaxisID);
+  if ( header )
+    {
+      fprintf(stdout, 
+      "  Rec : Code Level     BDS Flag     Scale   RefValue Bits  CR\n");
+/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
+      header = 0;
+    }
 
-		if ( zaxisType == ZAXIS_HYBRID )
-		  {
-		    nvct = zaxisInqVctSize(zaxisID);
-		    vct  = zaxisInqVctPtr(zaxisID);
-		  }
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
+    {
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
+    }
 
-                if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-                  {
-                    lbounds = (double *)xmalloc(2 * (size_t)nlevs2 * sizeof (double));
-                    ubounds = lbounds + nlevs2;
+  if ( PDS_LevelType == 100 )
+    level = PDS_Level * 100;
+  else if ( PDS_LevelType == 99 )
+    level = PDS_Level;
+  else
+    level = PDS_Level1;
 
-                    double *lbounds1 = (double *)xmalloc(2 * (size_t)nlevs * sizeof (double)),
-                      *ubounds1 = lbounds1 + nlevs;
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
+    {
+      int s1, s2;
+      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
+      cr = ((double)s1)/s2;
+    }
 
-                    zaxisInqLbounds(zaxisID, lbounds1);
-                    zaxisInqUbounds(zaxisID, ubounds1);
+  refval = BDS_RefValue;
 
-                    int levID2 = 0;
-                    for ( int levID = 0; levID < nlevs; ++levID )
-                      if ( vlistptr1->vars[varID].levinfo[levID].flag )
-                        {
-                          lbounds[levID2] = lbounds1[levID];
-                          ubounds[levID2] = ubounds1[levID];
-                          levID2++;
-                        }
+  if ( BDS_BinScale < 0 )
+    scale = 1.0/pow(2.0, (double) -BDS_BinScale);
+  else
+    scale = pow(2.0, (double) BDS_BinScale);
 
-                    free(lbounds1);
-                  }
+  if ( PDS_DecimalScale )
+    {
+      double decscale;
+      decscale = pow(10.0, (double)-PDS_DecimalScale);
+      refval *= decscale;
+      scale  *= decscale;
+    }
 
-		int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct);
-		free(levels);
-                free(lbounds);
+  fprintf(stdout, "%5d :", nrec);
 
-                zaxisInqName(zaxisID, ctemp);
-                zaxisDefName(zaxisID2, ctemp);
-                zaxisInqLongname(zaxisID, ctemp);
-                zaxisDefLongname(zaxisID2, ctemp);
-                zaxisInqUnits(zaxisID, ctemp);
-                zaxisDefUnits(zaxisID2, ctemp);
+  if ( bds )
+    fprintf(stdout, "%4d%7d %7d %4d %8.5g %11.5g%4d %6.4g",
+	    PDS_Parameter, level,
+	    BDS_Len, BDS_Flag, scale, refval, BDS_NumBits, cr);
+  else
+    fprintf(stdout, " Binary Data Section not defined");
 
-		zaxisID = zaxisID2;
-		vlistptr2->vars[varID2].zaxisID = zaxisID2;
-	      }
+  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
+  fprintf(stdout, "\n");
+}
 
-	    for ( int levID = 0; levID < nlevs2; levID++ )
-	      {
-		vlistptr2->vars[varID2].levinfo[levID].flag  = FALSE;
-		vlistptr2->vars[varID2].levinfo[levID].index = -1;
-	      }
 
-	    int levID2 = 0;
-	    for ( int levID = 0; levID < nlevs; levID++ )
-	      if ( vlistptr1->vars[varID].levinfo[levID].flag )
-		{
-		  vlistptr2->vars[varID2].levinfo[levID2].flevelID = levID;
-		  vlistptr2->vars[varID2].levinfo[levID2].mlevelID = levID;
-		  levID2++;
-		}
+void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+{
+  int gribversion;
 
-            vlistAdd2GridIDs(vlistptr2, gridID);
-            vlistAdd2ZaxisIDs(vlistptr2, zaxisID);
+  gribversion = gribVersion(gribbuffer, recsize);
 
-	    varID2++;
-	  }
+  if ( gribversion == 0 || gribversion == 1 )
+    grib1PrintBDS(nrec, recpos, recsize, gribbuffer);
+  /*
+  else if ( gribversion == 2 )
+    grib2PrintBDS(nrec, recpos, recsize, gribbuffer);
+  */
+  else
+    {
+      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
+	      nrec, 0L, recpos, recsize, gribversion); 
     }
 }
 
-/*
- at Function  vlistCat
- at Title     Concatenate two variable lists
-
- at Prototype void vlistCat(int vlistID2, int vlistID1)
- at Parameter
-    @Item  vlistID2  Target variable list ID.
-    @Item  vlistID1  Source variable list ID.
-
- at Description
-Concatenate the variable list vlistID1 at the end of vlistID2.
 
- at EndFunction
-*/
-void vlistCat(int vlistID2, int vlistID1)
+void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
+  int level, nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  double cr = 1;
 
-  int nvars1 = vlistptr1->nvars;
-  int nvars2 = vlistptr2->nvars;
-  int nvars = nvars1 + nvars2;
-  vlistptr2->nvars = nvars;
+  UNUSED(recpos);
 
-  if ( nvars > vlistptr2->varsAllocated )
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      vlistptr2->varsAllocated = nvars;
-      vlistptr2->vars = xrealloc(vlistptr2->vars,
-                                 (size_t)nvars * sizeof (var_t));
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
     }
-  memcpy(vlistptr2->vars+nvars2, vlistptr1->vars,
-         (size_t)nvars1 * sizeof (var_t));
 
-  for (int varID = 0; varID < nvars1; varID++ )
+  if ( nerr > 0 )
     {
-      int varID2 = varID + nvars2;
-      vlistptr1->vars[varID].fvarID = varID2;
-      vlistptr2->vars[varID2].fvarID = varID;
+      fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
+      return;
+    }
 
-      vlistptr1->vars[varID].mvarID = varID2;
-      vlistptr2->vars[varID2].mvarID = varID;
+  if ( PDS_LevelType == 100 )
+    level = PDS_Level * 100;
+  else if ( PDS_LevelType == 99 )
+    level = PDS_Level;
+  else
+    level = PDS_Level1;
 
-      if ( vlistptr1->vars[varID].param < 0 )
-	{
-	  int pnum, pcat, pdis;
-	  cdiDecodeParam(vlistptr1->vars[varID].param, &pnum, &pcat, &pdis);
-	  pnum = -(varID2+1);
-	  vlistptr2->vars[varID2].param = cdiEncodeParam(pnum, pcat, pdis);
-	}
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
+    {
+      int s1, s2;
+      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
+      cr = ((double)s1)/s2;
+    }
 
-      if ( vlistptr1->vars[varID].name )
-        vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+    {
+      fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
+    }
+}
 
-      if ( vlistptr1->vars[varID].longname )
-        vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);
 
-      if ( vlistptr1->vars[varID].stdname )
-        vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);
+static
+void repair1(unsigned char *gbuf, long gbufsize)
+{
+  long i;
+  int nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  /* int recLen; */
+  unsigned char *source;
+  size_t sourceLen;
+  int bds_len, bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress */;
+  int bds_head = 11;
+  int bds_ext = 0, bds_ubits;
+  int datstart = 0;
+  /* int llarge = FALSE; */
 
-      if ( vlistptr1->vars[varID].units )
-        vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
+  long gribrecsize;
+  nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
+    {
+      fprintf(stdout, "GRIB message error\n");
+      return;
+    }
 
-      int nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-      if (vlistptr1->vars[varID].levinfo)
-        {
-          vlistptr2->vars[varID2].levinfo
-            = (levinfo_t *)xmalloc((size_t)nlevs * sizeof (levinfo_t));
-          memcpy(vlistptr2->vars[varID2].levinfo,
-                 vlistptr1->vars[varID].levinfo,
-                 (size_t)nlevs * sizeof (levinfo_t));
-        }
+  if ( nerr > 0 )
+    {
+      fprintf(stdout, "GRIB data corrupted!\n");
+      return;
+    }
 
-      if ( vlistptr1->vars[varID].ensdata )
-        {
-          vlistptr2->vars[varID2].ensdata = (ensinfo_t *) malloc(sizeof(ensinfo_t));
-          memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
-        }
+  /* recLen = gribrec_len(gbuf[4], gbuf[5], gbuf[6]); */
+  /* if ( recLen > JP23SET ) llarge = TRUE; */
 
-#if  defined  (HAVE_LIBGRIB_API)
-      /* ---------------------------------- */
-      /* Local change: 2013-01-28, FP (DWD) */
-      /* ---------------------------------- */
+  bds_len   = BDS_Len;
+  bds_nbits = BDS_NumBits;
+  bds_flag  = BDS_Flag;
+  bds_ubits = bds_flag & 15;
+  lspherc   =  bds_flag >> 7;
+  lcomplex  = (bds_flag >> 6)&1;
+  /* lcompress = (bds_flag >> 4)&1; */
 
-      vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-      int n = vlistptr1->vars[varID].opt_grib_int_nentries;
-      for (int i = 0; i < n; ++i) {
-	if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-	  vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-	  vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-          vlistptr2->vars[varID2].opt_grib_int_update[i]  = TRUE;
+  if ( lspherc )
+    {
+      if ( lcomplex  )
+	{
+	  int jup, ioff;
+	  jup  = bds[15];
+	  ioff = (jup+1)*(jup+2);
+	  bds_ext = 4 + 3 + 4*ioff;
 	}
-      }
-      vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-      n = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-      for (int i = 0; i < n; i++) {
-	if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-	  vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-          vlistptr2->vars[varID2].opt_grib_dbl_update[i]  = TRUE;
+      else
+	{
+	  bds_ext = 4;
 	}
-      }
-#endif
+    }
 
-      vlistptr2->vars[varID2].atts.nelems = 0;
-      vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
+  datstart = bds_head + bds_ext;
 
-      vlistAdd2GridIDs(vlistptr2, vlistptr1->vars[varID].gridID);
-      vlistAdd2ZaxisIDs(vlistptr2, vlistptr1->vars[varID].zaxisID);
-    }
-}
+  source = bds + datstart;
 
-/*
- at Function  vlistMerge
- at Title     Merge two variable lists
+  sourceLen = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
 
- at Prototype void vlistMerge(int vlistID2, int vlistID1)
- at Parameter
-    @Item  vlistID2  Target variable list ID.
-    @Item  vlistID1  Source variable list ID.
+  if ( bds_nbits == 24 )
+    {
+      long nelem;
+      unsigned char *pbuf;
+      nelem = sourceLen/3;
+      pbuf = (unsigned char*) malloc(sourceLen);
+      for ( i = 0; i < nelem; i++ )
+	{
+	  pbuf[3*i  ] = source[        i];
+	  pbuf[3*i+1] = source[  nelem+i];
+	  pbuf[3*i+2] = source[2*nelem+i];
+	}
+      memcpy(source, pbuf, sourceLen);
+      free(pbuf);
+    }
+}
 
- at Description
-Merge the variable list vlistID1 to the variable list vlistID2.
 
- at EndFunction
-*/
-void vlistMerge(int vlistID2, int vlistID1)
+void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
 {
-  int varID = 0;
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
-
-  int nvars1 = vlistptr1->nvars;
-  int nvars2 = vlistptr2->nvars;
+  int level, nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  double cr = 1;
 
-  if ( nvars1 == nvars2 )
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      for ( varID = 0; varID < nvars2; varID++ )
-	{
-	  if ( vlistptr1->vars[varID].name && vlistptr2->vars[varID].name )
-	    {
-	      if ( strcmp(vlistptr1->vars[varID].name,
-			  vlistptr2->vars[varID].name) != 0 ) break;
-	    }
-	  else
-	    {
-	      if ( vlistptr1->vars[varID].param != vlistptr2->vars[varID].param )
-		break;
-	    }
-	}
+      fprintf(stdout, "%5d : GRIB message error\n", nrec);
+      return;
     }
 
-  if ( varID == nvars2 ) /* same variables in vlistID1 and vlistID2 */
+  if ( nerr > 0 )
     {
-      for ( varID = 0; varID < nvars2; varID++ )
-        {
-          vlistptr1->vars[varID].fvarID = varID;
-          vlistptr2->vars[varID].fvarID = varID;
+      fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
+      return;
+    }
 
-          vlistptr1->vars[varID].mvarID = varID;
-          vlistptr2->vars[varID].mvarID = varID;
+  if ( PDS_LevelType == 100 )
+    level = PDS_Level * 100;
+  else if ( PDS_LevelType == 99 )
+    level = PDS_Level;
+  else
+    level = PDS_Level1;
 
-          int nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-          int nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
+    {
+      int s1, s2;
+      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
+      cr = ((double)s1)/s2;
+    }
 
-          int nlevs = nlevs1 + nlevs2;
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+    {
+      fprintf(stdout, "Repair GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
+      repair1(gribbuffer, recsize);
+    }
+}
+#include <stdio.h>
+#include <string.h>
 
-          /*
-          fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
-          */
-          if (vlistptr1->vars[varID].levinfo)
-            {
-              vlistptr2->vars[varID].levinfo =
-                (levinfo_t*)xrealloc(vlistptr2->vars[varID].levinfo,
-                                     (size_t)nlevs * sizeof(levinfo_t));
+#if defined (HAVE_CONFIG_H)
+#endif
 
-              memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
-                     vlistptr1->vars[varID].levinfo,
-                     (size_t)nlevs1 * sizeof (levinfo_t));
-            }
-          else
-            cdiVlistCreateVarLevInfo(vlistptr1, varID);
-	  for ( int levID = 0; levID < nlevs1; levID++ )
-	    {
-	      vlistptr1->vars[varID].levinfo[levID].mlevelID = nlevs2 + levID;
-	    }
-	}
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
+#if defined(__cplusplus)
+extern "C" {
+#endif
+#if defined (HAVE_LIBAEC)
+#  include <libaec.h>
+#else
+#  include <szlib.h>
+#endif
+#if defined (__cplusplus)
+}
+#endif
 
-      int *lvar = (int *)xcalloc((size_t)nvars2, sizeof(int));
+#if defined (HAVE_LIBAEC)
+#  define AEC_FLAGS           (AEC_DATA_MSB | AEC_DATA_PREPROCESS)
+#else
+#  define OPTIONS_MASK        (SZ_RAW_OPTION_MASK | SZ_MSB_OPTION_MASK | SZ_NN_OPTION_MASK)
+#endif
 
-      for ( varID = 0; varID < nvars2; varID++ )
-        {
-          if ( lvar[varID] == TRUE ) continue;
+#  define PIXELS_PER_BLOCK    (8)
+#  define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
 
-          int zaxisID1 = vlistptr1->vars[varID].zaxisID;
-          int zaxisID2 = vlistptr2->vars[varID].zaxisID;
-          /*
-          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
-          */
-          int nlevs1 = zaxisInqSize(zaxisID1);
-          int nlevs2 = zaxisInqSize(zaxisID2);
-          /*
-          fprintf(stderr, "zaxis %d %d %d %d\n", zaxisID1, zaxisID2, nlevs1, nlevs2);
-          */
-          int nlevs = nlevs1 + nlevs2;
+#  define MIN_COMPRESS        (0.95)
+#  define MIN_SIZE            (256)
+#endif
 
-          int zaxisID = zaxisDuplicate(zaxisID2);
+#define  Z_SZIP  128
+#define  Z_AEC   130
 
-          zaxisResize(zaxisID, nlevs);
 
-          double *levels = (double *)xmalloc((size_t)nlevs1 * sizeof(double));
+#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
+				     (var[offset+1] = 0xFF & (value >>  8)), \
+				     (var[offset+2] = 0xFF & (value      )))
+#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
+				     (var[offset+1] = 0xFF & (value >> 16)), \
+				     (var[offset+2] = 0xFF & (value >>  8)), \
+				     (var[offset+3] = 0xFF & (value      )))
 
-          zaxisInqLevels(zaxisID1, levels);
-          /*
-          for ( levID = 0; levID < nlevs1; levID++ )
-            fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vlistptr2->vars[varID].nlevs, levels[levID]);
-          */
-          for ( int levID = 0; levID < nlevs1; levID++ )
-            zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
 
-          free(levels);
+int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
+{
+  /* urecsize : uncompressed record size  */
+  int compress = 0;
+  int nerr;
+  /* int  bds_len, bds_nbits, lspherc, lcomplex; */
+  int bds_flag, lcompress;
+  long gribsize = 0;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  int gribversion;
 
-          for ( int index = 0; index < vlistptr2->nzaxis; index++ )
-            if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
-              vlistptr2->zaxisIDs[index] = zaxisID;
+  gribversion = gribVersion(gribbuffer, recsize);
 
-          for ( int varID2 = 0; varID2 < nvars2; varID2++ )
-            if ( lvar[varID2] == FALSE && vlistptr2->vars[varID2].zaxisID == zaxisID2 )
-              {
-                vlistptr2->vars[varID2].zaxisID = zaxisID;
-                lvar[varID2] = TRUE;
-              }
-        }
+  if ( gribversion == 2 ) return (compress);
 
-      free(lvar);
-    }
-  else
+  long gribrecsize;
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      vlistCat(vlistID2, vlistID1);
+      fprintf(stdout, "GRIB message error\n");
+      return (compress);
     }
-}
 
-/*
- at Function  vlistNvars
- at Title     Number of variables in a variable list
+  if ( nerr > 0 )
+    {
+      fprintf(stdout, "GRIB data corrupted!\n");
+      return (compress);
+    }
 
- at Prototype int vlistNvars(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+  /* bds_len   = BDS_Len; */
+  /* bds_nbits = BDS_NumBits; */
+  bds_flag  = BDS_Flag;
+  /* lspherc   =  bds_flag >> 7; */
+  /* lcomplex  = (bds_flag >> 6)&1; */
+  lcompress = (bds_flag >> 4)&1;
 
- at Description
-The function @func{vlistNvars} returns the number of variables in the variable list vlistID.
+  *urecsize = 0;
+  if ( lcompress )
+    {
+      compress = BDS_Z;
+      if ( compress == Z_SZIP || compress == Z_AEC )
+	{
+	  gribsize = gribrec_len(bds[14], bds[15], bds[16]);
+	}
+    }
 
- at Result
- at func{vlistNvars} returns the number of variables in a variable list.
+  *urecsize = gribsize;
 
- at EndFunction
-*/
-int vlistNvars(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->nvars);
+  return (compress);
 }
 
 
-int vlistNrecs(int vlistID)
+int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
 {
-  int nrecs = 0;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
-    nrecs +=  zaxisInqSize(vlistptr->vars[varID].zaxisID);
-
-  return (nrecs);
-}
-
+  int nerr;
+  int gribLen;
+  int rec_len;
+  int llarge = FALSE;
+#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
+  static int libszwarn = 1;
+#endif
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
 
-int vlistNumber(int vlistID)
-{
-  int number, number2, datatype;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
+  if ( gribLen > JP23SET ) llarge = TRUE;
 
-  datatype = vlistptr->vars[0].datatype;
-  if (  datatype== DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    number = CDI_COMP;
-  else
-    number = CDI_REAL;
+  rec_len = gribLen;
 
-  for ( int varID = 1; varID < vlistptr->nvars; varID++ )
+  long gribrecsize;
+  nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      datatype = vlistptr->vars[varID].datatype;
-      if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-        number2 = CDI_COMP;
-      else
-        number2 = CDI_REAL;
-
-      if ( number2 != number )
-        {
-          number = CDI_BOTH;
-          break;
-        }
+      fprintf(stdout, "GRIB message error\n");
+      return (rec_len);
     }
 
-  return (number);
-}
-
-/*
- at Function  vlistNgrids
- at Title     Number of grids in a variable list
-
- at Prototype int vlistNgrids(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+  if ( nerr > 0 )
+    {
+      fprintf(stdout, "GRIB data corrupted!\n");
+      return (rec_len);
+    }
 
- at Description
-The function @func{vlistNgrids} returns the number of grids in the variable list vlistID.
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
 
- at Result
- at func{vlistNgrids} returns the number of grids in a variable list.
+  {
+    long i;
+    int bdsLen;
+    int gribLenOld = 0;
+    int status;
+    size_t datstart, datsize;
+#if defined (HAVE_LIBAEC)
+    struct aec_stream strm;
+#else
+    SZ_com_t sz_param;          /* szip parameter block */
+#endif
+    unsigned char *dest, *source;
+    size_t destLen, sourceLen;
+    int bits_per_sample;
+    int bds_len, bds_nbits, bds_flag, lspherc, lcomplex,/* lcompress,*/ bds_ubits;
+    int bds_head = 11;
+    int bds_ext = 0;
+    int bds_zoffset, bds_zstart;
+    unsigned char *pbuf = NULL;
 
- at EndFunction
-*/
-int vlistNgrids(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+    bds_zstart  = 14;
+    bds_zoffset = 12;
+    if ( llarge ) bds_zoffset += 2;
 
-  return (vlistptr->ngrids);
-}
+    bds_len   = BDS_Len;
+    bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
+    bds_nbits = BDS_NumBits;
+    bds_flag  = BDS_Flag;
+    bds_ubits = bds_flag & 15;
+    lspherc   =  bds_flag >> 7;
+    lcomplex  = (bds_flag >> 6)&1;
+    /* lcompress = (bds_flag >> 4)&1; */
+    
+    if ( bds_nbits != 8 && bds_nbits != 16 && bds_nbits != 24 && bds_nbits != 32 )
+      {
+	static int linfo = 1;
+	if ( linfo && bds_nbits != 0 )
+	  {
+	    linfo = 0;
+	    fprintf(stderr, "GRIB szip only supports 8, 16, 24 and 32 bit data!\n");
+	  }
+	return (rec_len);
+      }
 
-/*
- at Function  vlistNzaxis
- at Title     Number of zaxis in a variable list
+#if defined (HAVE_LIBSZ)
+    if ( bds_nbits == 24 )
+      bits_per_sample    = 8;
+    else
+#endif
+      bits_per_sample    = bds_nbits;
 
- at Prototype int vlistNzaxis(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+#if defined (HAVE_LIBAEC)
+    strm.bits_per_sample = bits_per_sample;
+    strm.block_size      = PIXELS_PER_BLOCK;
+    strm.rsi             = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
+    strm.flags           = AEC_FLAGS;
+    if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE; 
+#else
+    sz_param.options_mask        = OPTIONS_MASK;
+    sz_param.bits_per_pixel      = bits_per_sample;
+    sz_param.pixels_per_block    = PIXELS_PER_BLOCK;
+    sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
+#endif
 
- at Description
-The function @func{vlistNzaxis} returns the number of zaxis in the variable list vlistID.
+    if ( lspherc )
+      {
+	if ( lcomplex  )
+	  {
+	    int jup, ioff;
+	    jup  = bds[15];
+	    ioff = (jup+1)*(jup+2);
+	    bds_ext = 4 + 3 + 4*ioff;
+	  }
+	else
+	  {
+	    bds_ext = 4;
+	  }
+      }
 
- at Result
- at func{vlistNzaxis} returns the number of zaxis in a variable list.
+    datstart = bds_head + bds_ext;
 
- at EndFunction
-*/
-int vlistNzaxis(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+    datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
 
-  return (vlistptr->nzaxis);
-}
+    if ( datsize < MIN_SIZE ) return (rec_len);
+    /*
+    fprintf(stderr, "%d %d %d %d\n", bds_len, datstart, bds_len - datstart, datsize);
+    */
+    sourceLen = datsize;
+    destLen   = sbufsize;
+    
+    source = bds + datstart;
+    dest = sbuf;
 
+#if defined (HAVE_LIBSZ)
+    if ( bds_nbits == 24 )
+      {
+	long nelem;
+	nelem = sourceLen/3;
+	pbuf = (unsigned char*) malloc(sourceLen);
+	for ( i = 0; i < nelem; i++ )
+	  {
+	    pbuf[        i] = source[3*i  ];
+	    pbuf[  nelem+i] = source[3*i+1];
+	    pbuf[2*nelem+i] = source[3*i+2];
+	  }
+	source = pbuf;
+      }
+#endif
 
-void vlistDefNtsteps(int vlistID, int nts)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#if defined (HAVE_LIBAEC)
+    strm.next_in = source;
+    strm.avail_in = sourceLen;
+    strm.next_out = dest;
+    strm.avail_out = destLen;
 
-  if (vlistptr->ntsteps != nts)
-    {
-      vlistptr->ntsteps = nts;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+    status = aec_buffer_encode(&strm);
+    if ( status != AEC_OK )
+      {
+       	if ( status != AEC_DATA_ERROR )
+	  Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+      }
 
-// This function is used in CDO!
-int vlistNtsteps(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+    destLen = strm.total_out;
+#else
+    status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
+    if ( status != SZ_OK )
+      {
+	if ( status == SZ_NO_ENCODER_ERROR )
+	  Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_PARAM_ERROR )
+	  Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_MEM_ERROR )
+	  Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_OUTBUFF_FULL )
+	  /*Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2)*/;
+	else
+	  Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+      }
+#endif
+    
+    if ( pbuf ) free(pbuf);
+    /*
+    fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
+    */
+    if ( destLen < MIN_COMPRESS*sourceLen )
+      {
+	source = bds + datstart + bds_zoffset;
+	memcpy(source, dest, destLen);
+	
+	/* ----++++ number of unused bits at end of section) */
 
-  return (int)vlistptr->ntsteps;
-}
+	BDS_Flag -= bds_ubits;
+    
+	gribLenOld = gribLen;
 
-static void
-vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
-{
-  char paramstr[32];
+	if ( bds_ext )
+	  for ( i = bds_ext-1; i >= 0; --i )
+	    bds[bds_zoffset+bds_head+i] = bds[bds_head+i];
 
-  fprintf ( fp, "#\n# vlistID %d\n#\n", vlistptr->self);
+	/*
+	fprintf(stderr, "destLen, datsize, datstart %d %d %d\n", destLen, datsize, datstart);
+	*/
+	/*	memcpy(bds + datstart + bds_zoffset, source, destLen); */
+	/*
+	  fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
+	    (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
+	*/
+	if ( llarge )
+	  {
+	    if ( gribLenOld%120 )
+	      {
+		fprintf(stderr, "Internal problem, record length not multiple of 120!");
+		while ( gribLenOld%120 ) gribLenOld++;
+	      }
+	    gribLenOld = gribLenOld / (-120);
+	    gribLenOld = JP23SET - gribLenOld + 1;
 
-  int nvars = vlistptr->nvars;
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen4(bds, bds_zstart+3, sourceLen);
+	    SetLen4(bds, bds_zstart+7, destLen);
+	  }
+	else
+	  {
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen3(bds, bds_zstart+3, sourceLen);
+	    SetLen3(bds, bds_zstart+6, destLen);
+	  }
 
-  fprintf(fp, "nvars   %d\n"
-          "ngrids  %d\n"
-          "nzaxis  %d\n"
-          "taxisID %d\n"
-          "instID  %d\n"
-          "modelID %d\n"
-          "tableID %d\n",
-          nvars, vlistptr->ngrids, vlistptr->nzaxis, vlistptr->taxisID,
-          vlistptr->instID, vlistptr->modelID, vlistptr->tableID);
+	bdsLen = datstart + bds_zoffset + destLen;
 
-  if ( nvars > 0 )
-    {
-      fprintf(fp, " varID param    gridID zaxisID tsteptype flag "
-              " name     longname iorank\n");
-      for ( int varID = 0; varID < nvars; varID++ )
-        {
-          int param = vlistptr->vars[varID].param;
-          int gridID = vlistptr->vars[varID].gridID;
-          int zaxisID = vlistptr->vars[varID].zaxisID;
-	  int tsteptype = vlistptr->vars[varID].tsteptype;
-          const char *name = vlistptr->vars[varID].name;
-          const char *longname = vlistptr->vars[varID].longname;
-          const char *units = vlistptr->vars[varID].units;
-          int flag = vlistptr->vars[varID].flag;
-          int iorank = vlistptr->vars[varID].iorank;
+	bds[11] = 0;
+	bds[12] = 0;
+#if defined (HAVE_LIBAEC)
+	BDS_Z   = Z_AEC;
+#else
+	BDS_Z   = Z_SZIP;
+#endif
 
-          cdiParamToString(param, paramstr, sizeof(paramstr));
-          fprintf(fp, "%6d %-8s %6d %6d %6d %5d %-8s"
-                  " %s %6d",
-                  varID, paramstr, gridID, zaxisID, tsteptype, flag,
-                  name ? name : "", longname ? longname : "",
-                  iorank);
+	BDS_Flag += 16;
+	if ( (bdsLen%2) == 1 )
+	  {
+	    BDS_Flag += 8;
+	    bds[bdsLen++] = 0;
+	  }
 
-          if ( units ) fprintf(fp, "   [%s]", units);
-          fputs("\n", fp);
-        }
+	SetLen3(bds, 0, bdsLen);
 
-      fputs("\n"
-            " varID  levID fvarID flevID mvarID mlevID  index  dtype  flag  level\n", fp);
-      for ( int varID = 0; varID < nvars; varID++ )
-        {
-          int zaxisID = vlistptr->vars[varID].zaxisID;
-          int nlevs = zaxisInqSize(zaxisID);
-          int fvarID = vlistptr->vars[varID].fvarID;
-          int mvarID = vlistptr->vars[varID].mvarID;
-          int dtype    = vlistptr->vars[varID].datatype;
-          for ( int levID = 0; levID < nlevs; levID++ )
-            {
-              levinfo_t li;
-              if (vlistptr->vars[varID].levinfo)
-                li = vlistptr->vars[varID].levinfo[levID];
-              else
-                li = DEFAULT_LEVINFO(levID);
-              int flevID = li.flevelID;
-              int mlevID = li.mlevelID;
-              int index  = li.index;
-              int flag   = li.flag;
-              double level  = zaxisInqLevel(zaxisID, levID);
+	gribLen = (bds - dbuf) + bdsLen;
 
-              fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
-                      varID, levID, fvarID, flevID, mvarID, mlevID, index,
-                      dtype, flag, level);
-            }
-        }
+	dbuf[gribLen++] = '7';
+	dbuf[gribLen++] = '7';
+	dbuf[gribLen++] = '7';
+	dbuf[gribLen++] = '7';
 
-      fputs("\n"
-            " varID  size iorank\n", fp);
-      for ( int varID = 0; varID < nvars; varID++ )
-        fprintf(fp, "%3d %8d %6d\n", varID,
-                zaxisInqSize(vlistptr->vars[varID].zaxisID)
-                * gridInqSize(vlistptr->vars[varID].gridID),
-                vlistptr->vars[varID].iorank);
-    }
-}
+	if ( llarge )
+	  {
+	    long itemp;
+	    long bdslen = gribLen - 4;
 
+	    /*
+	      If a very large product, the section 4 length field holds
+	      the number of bytes in the product after section 4 upto
+	      the end of the padding bytes.
+	      This is a fixup to get round the restriction on product lengths
+	      due to the count being only 24 bits. It is only possible because
+	      the (default) rounding for GRIB products is 120 bytes.
+	    */
+	    while ( gribLen%120 ) dbuf[gribLen++] = 0;
 
-void vlistPrint(int vlistID)
-{
-  if ( vlistID == CDI_UNDEFID ) return;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  vlistPrintKernel(vlistptr, stdout);
-}
+	    itemp = gribLen / (-120);
+	    itemp = JP23SET - itemp + 1;
 
-/*
- at Function  vlistDefTaxis
- at Title     Define the time axis
+	    SetLen3(dbuf, 4, itemp);
 
- at Prototype void vlistDefTaxis(int vlistID, int taxisID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}.
+	    bdslen = gribLen - bdslen;
 
- at Description
-The function @func{vlistDefTaxis} defines the time axis of a variable list.
+	    SetLen3(bds, 0, bdslen);
+	  }
+	else
+	  {
+	    SetLen3(dbuf, 4, gribLen);
+	  }
+      }
+    else
+      {
+      }
+    /*
+    fprintf(stderr, "%3d %3d griblen in %6d  out %6d  CR %g   slen %6d dlen %6d  CR %g\n",
+	    PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
+	    ((double)gribLenOld)/gribLen, sourceLen, destLen,
+	    ((double)sourceLen)/destLen);
+    */
+  }
 
- at EndFunction
-*/
-void vlistDefTaxis(int vlistID, int taxisID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#else
+  
+  UNUSED(sbuf);
+  UNUSED(sbufsize);
 
-  if (vlistptr->taxisID != taxisID)
+  if ( libszwarn )
     {
-      vlistptr->taxisID = taxisID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      Warning("Compression disabled, szlib or libaec not available!");
+      libszwarn = 0;
     }
-}
-
-/*
- at Function  vlistInqTaxis
- at Title     Get the time axis
-
- at Prototype int vlistInqTaxis(int vlistID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-
- at Description
-The function @func{vlistInqTaxis} returns the time axis of a variable list.
+#endif
 
- at Result
- at func{vlistInqTaxis} returns an identifier to the time axis.
+  if ( llarge )
+    while ( gribLen%120 ) dbuf[gribLen++] = 0;
+  else
+    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
 
- at EndFunction
-*/
-int vlistInqTaxis(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  rec_len = gribLen;
 
-  return (vlistptr->taxisID);
+  return (rec_len);
 }
 
 
-void vlistDefTable(int vlistID, int tableID)
+int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
+  static int libszwarn = 1;
+#endif
+  int nerr;
+  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  int bdsLen, recLen, gribLen = 0;
+  unsigned char *dest, *source;
+  size_t destLen, sourceLen;
+  int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
+  int bds_head = 11;
+  int bds_ext = 0;
+  int bds_zoffset, bds_zstart;
+  int datstart = 0;
+  int llarge = FALSE;
 
-  if (vlistptr->tableID != tableID)
+  UNUSED(dbufsize);
+
+  long gribrecsize;
+  nerr = grib1Sections(sbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      vlistptr->tableID = tableID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      fprintf(stdout, "GRIB message error\n");
+      return (0);
     }
-}
 
+  if ( nerr > 0 )
+    {
+      fprintf(stdout, "GRIB data corrupted!\n");
+      return (0);
+    }
 
-int vlistInqTable(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  bds_zstart = 14;
 
-  return (vlistptr->tableID);
-}
+  recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
+  if ( recLen > JP23SET ) llarge = TRUE;
 
+  bds_zoffset = 12;
+  if ( llarge ) bds_zoffset += 2;
 
-void vlistDefInstitut(int vlistID, int instID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* bds_len   = BDS_Len; */
+  bds_nbits = BDS_NumBits;
+  bds_flag  = BDS_Flag;
+  lspherc   =  bds_flag >> 7;
+  lcomplex  = (bds_flag >> 6)&1;
+  /* lcompress = (bds_flag >> 4)&1; */
 
-  if (vlistptr->instID != instID)
+  if ( lspherc )
     {
-      vlistptr->instID = instID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      if ( lcomplex  )
+	{
+	  int jup, ioff;
+	  jup  = bds[bds_zoffset+15];
+	  ioff = (jup+1)*(jup+2);
+	  bds_ext = 4 + 3 + 4*ioff;
+	}
+      else
+	{
+	  bds_ext = 4;
+	}
     }
-}
 
+  datstart = bds_head + bds_ext;
 
-int vlistInqInstitut(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  int instID = vlistptr->instID;
+  source = bds + datstart + bds_zoffset;
+  if ( llarge )
+    sourceLen = ((size_t) ((bds[21]<<24)+(bds[22]<<16)+(bds[23]<<8)+bds[24]));
+  else
+    sourceLen = ((size_t) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
 
-  if ( instID == CDI_UNDEFID )
+  nerr = grib1Sections(dbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  if ( nerr < 0 )
     {
-      instID  = vlistInqVarInstitut(vlistID, 0);
+      fprintf(stdout, "GRIB message error\n");
+      return (0);
+    }
 
-      for ( int varID = 1; varID < vlistptr->nvars; varID++ )
-        if ( instID != vlistInqVarInstitut(vlistID, varID) )
-          {
-            instID = CDI_UNDEFID;
-            break;
-      }
-      vlistDefInstitut(vlistID, instID);
+  if ( nerr > 0 )
+    {
+      fprintf(stdout, "GRIB data corrupted!\n");
+      return (0);
     }
 
-  return (instID);
-}
+  dest = bds + datstart;
+   if ( llarge )
+    destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
+  else
+    destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
+  BDS_Flag -= 16;
 
-void vlistDefModel(int vlistID, int modelID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  bdsLen = datstart + destLen;
 
-  if (vlistptr->modelID != modelID)
-    {
-      vlistptr->modelID = modelID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
+  {
+    int status;
+    long i;
+    size_t tmpLen;
+    int bds_ubits;
+    int bits_per_sample;
+#if defined (HAVE_LIBAEC)
+    struct aec_stream strm;
+#else
+    SZ_com_t sz_param;          /* szip parameter block */
+#endif
 
+#if defined (HAVE_LIBSZ)
+    if ( bds_nbits == 24 )
+      bits_per_sample    = 8;
+    else
+#endif
+      bits_per_sample    = bds_nbits;
 
-int vlistInqModel(int vlistID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#if defined (HAVE_LIBAEC)
+    strm.bits_per_sample         = bits_per_sample;
+    strm.block_size              = PIXELS_PER_BLOCK;
+    strm.rsi                     = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
+    strm.flags                   = AEC_FLAGS;
+    if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE; 
+#else
+    sz_param.options_mask        = OPTIONS_MASK;
+    sz_param.bits_per_pixel      = bits_per_sample;
+    sz_param.pixels_per_block    = PIXELS_PER_BLOCK;
+    sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
+#endif
 
-  int modelID = vlistptr->modelID;
+    if ( bds_ext )
+      for ( i = 0; i < bds_ext; ++i )
+	bds[bds_head+i] = bds[bds_zoffset+bds_head+i];
 
-  if ( modelID == CDI_UNDEFID )
-    {
-      modelID = vlistInqVarModel(vlistID, 0);
+    /*
+    fprintf(stderr, "gribUnzip: sourceLen %ld; destLen %ld\n", (long)sourceLen, (long)destLen);
+    fprintf(stderr, "gribUnzip: sourceOff %d; destOff %d\n", bds[12], bds[11]);
+    fprintf(stderr, "gribUnzip: reclen %d; bdslen %d\n", recLen, bdsLen);
+    */
 
-      for ( int varID = 1; varID < vlistptr->nvars; varID++ )
-        if ( modelID != vlistInqVarModel(vlistID, varID) )
-          {
-            modelID = CDI_UNDEFID;
-            break;
-          }
+    tmpLen = destLen;
+#if defined (HAVE_LIBAEC)
+    strm.next_in   = source;
+    strm.avail_in  = sourceLen;
+    strm.next_out  = dest;
+    strm.avail_out = tmpLen;
 
-      vlistDefModel(vlistID, modelID);
-    }
+    status = aec_buffer_decode(&strm);
+    if ( status != AEC_OK )
+      Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
 
-  return (modelID);
-}
+    tmpLen = strm.total_out;
+#else
+    status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
+    if ( status != SZ_OK )
+      {
+	if ( status == SZ_NO_ENCODER_ERROR )
+	  Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_PARAM_ERROR )
+	  Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_MEM_ERROR )
+	  Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else if ( status == SZ_OUTBUFF_FULL )
+	  Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2);
+	else
+	  Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+      }
+#endif
+    /*
+    fprintf(stderr, "gribUnzip: sl = %ld  dl = %ld   tl = %ld\n",
+	    (long)sourceLen, (long)destLen,(long) tmpLen);
+    */
+    if ( tmpLen != destLen )
+      Warning("unzip size differ: code %3d level %3d  ibuflen %ld ubuflen %ld",
+	      PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
 
+#if defined (HAVE_LIBSZ)
+    if ( bds_nbits == 24 )
+      {
+	long nelem;
+	unsigned char *pbuf;
+	nelem = tmpLen/3;
+	pbuf = (unsigned char*) malloc(tmpLen);
+	for ( i = 0; i < nelem; i++ )
+	  {
+	    pbuf[3*i  ] = dest[        i];
+	    pbuf[3*i+1] = dest[  nelem+i];
+	    pbuf[3*i+2] = dest[2*nelem+i];
+	  }
+	memcpy(dest, pbuf, tmpLen);
+	free(pbuf);
+      }
+#endif
 
-int vlistGridsizeMax(int vlistID)
-{
-  int gridsizemax = 0;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+    bds_ubits = BDS_Flag & 15;
+    BDS_Flag -= bds_ubits;
 
-  for ( int index = 0 ; index < vlistptr->ngrids ; index++ )
-    {
-      int gridID = vlistptr->gridIDs[index];
-      int gridsize = gridInqSize(gridID);
-      if ( gridsize > gridsizemax ) gridsizemax = gridsize;
-    }
+    if ( (bdsLen%2) == 1 )
+      {
+	BDS_Flag += 8;
+	bds[bdsLen++] = 0;
+      }
 
-  return (gridsizemax);
-}
+    SetLen3(bds, 0, bdsLen);
 
+    gribLen = (bds - dbuf) + bdsLen;
+    
+    dbuf[gribLen++] = '7';
+    dbuf[gribLen++] = '7';
+    dbuf[gribLen++] = '7';
+    dbuf[gribLen++] = '7';
 
-int vlistGrid(int vlistID, int index)
-{
-  int gridID = CDI_UNDEFID;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+    if ( llarge )
+      {
+	long itemp;
+        bdsLen = gribLen - 4;
+	/*
+	  If a very large product, the section 4 length field holds
+	  the number of bytes in the product after section 4 upto
+	  the end of the padding bytes.
+	  This is a fixup to get round the restriction on product lengths
+	  due to the count being only 24 bits. It is only possible because
+	  the (default) rounding for GRIB products is 120 bytes.
+	*/
+	while ( gribLen%120 ) dbuf[gribLen++] = 0;
 
-  if ( index < vlistptr->ngrids && index >= 0 )
-    gridID = vlistptr->gridIDs[index];
+	if ( gribLen != recLen )
+	  fprintf(stderr, "Internal problem, recLen and gribLen differ!\n");
+	
+	itemp = gribLen / (-120);
+	itemp = JP23SET - itemp + 1;
+	
+	SetLen3(dbuf, 4, itemp);
 
-  return (gridID);
+	bdsLen = gribLen - bdsLen;
+	    
+	SetLen3(bds, 0, bdsLen);
+      }
+    else
+      {
+	SetLen3(dbuf, 4, recLen);
+      }
+    /*
+    fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
+    */
+    if ( llarge )
+      while ( gribLen%120 ) dbuf[gribLen++] = 0;
+    else
+      while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+    /*
+    fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
+    */
+  }
+#else
+  UNUSED(bds_nbits);
+  UNUSED(sourceLen);
+  UNUSED(source);
+  UNUSED(bdsLen);
+  UNUSED(dest);
+  
+  if ( libszwarn )
+    {
+      Warning("Decompression disabled, szlib or libaec not available!");
+      libszwarn = 0;
+    }
+#endif
+
+  return (gribLen);
 }
+#include <stdio.h>
+#include <math.h>
 
 
-int vlistGridIndex(int vlistID, int gridID)
+/* calculate_pfactor: source code from grib_api-1.8.0 */
+double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation)
 {
-  int index;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  for ( index = 0 ; index < vlistptr->ngrids ; index++ )
-    if ( gridID == vlistptr->gridIDs[index] ) break;
+  /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
+  long loop, index, m, n = 0;
+  double pFactor, zeps = 1.0e-15;
+  long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
+  double* weights, range, * norms;
+  double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
+  double numerator = 0.0, denominator = 0.0, slope;
 
-  if ( index == vlistptr->ngrids ) index = -1;
+  /*
+  // Setup the weights
+   */
 
-  return (index);
-}
+  range = (double) (ismax - ismin +1);
 
+  weights = (double*) malloc((ismax+1)*sizeof(double));
+  for( loop = ismin; loop <= ismax; loop++ )
+    weights[loop] = range / (double) (loop-ismin+1);
+  /*
+  // Compute norms
+  // Handle values 2 at a time (real and imaginary parts).
+   */
+  norms = (double*) malloc((ismax+1)*sizeof(double));
 
-void vlistChangeGridIndex(int vlistID, int index, int gridID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
+  /*
+  // Form norms for the rows which contain part of the unscaled subset.
+   */
 
-  int gridIDold = vlistptr->gridIDs[index];
-  if (gridIDold != gridID)
-    {
-      vlistptr->gridIDs[index] = gridID;
+  index = -2;
+  for( m = 0; m < subsetTruncation; m++ )
+    for( n = m; n <= fieldTruncation; n++ ) {
+      index += 2;
+      if( n >= subsetTruncation ) {
+        double tval = spectralField[index];
+        tval=tval<0?-tval:tval;
+        norms[n] = norms[n] > tval ? norms[n] : tval;
+        tval = spectralField[index+1];
+        tval=tval<0?-tval:tval;
+        norms[n] = norms[n] > tval ? norms[n] : tval;
+      }
+    }
+  /*
+  // Form norms for the rows which do not contain part of the unscaled subset.
+   */
 
-      int nvars = vlistptr->nvars;
-      for ( int varID = 0; varID < nvars; varID++ )
-        if ( vlistptr->vars[varID].gridID == gridIDold )
-          vlistptr->vars[varID].gridID = gridID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+  for( m = subsetTruncation; m <= fieldTruncation; m++ )
+    for( n = m; n <= fieldTruncation; n++ ) {
+      double tval = spectralField[index];
+      index += 2;
+      tval=tval<0?-tval:tval;
+      norms[n] = norms[n] > tval ? norms[n] : tval;
+      tval = spectralField[index+1];
+      tval=tval<0?-tval:tval;
+      norms[n] = norms[n] > tval ? norms[n] : tval;
     }
-}
 
+  /*
+  // Ensure the norms have a value which is not too small in case of
+  // problems with math functions (e.g. LOG).
+   */
 
-void vlistChangeGrid(int vlistID, int gridID1, int gridID2)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  for( loop = ismin; loop <= ismax; loop++ ) {
+    norms[n] = norms[n] > zeps ? norms[n] : zeps;
+    if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
+  }
 
-  if (gridID1 != gridID2)
-    {
-      int ngrids = vlistptr->ngrids;
-      for ( int index = 0; index < ngrids; index++ )
-        {
-          if ( vlistptr->gridIDs[index] == gridID1 )
-            {
-              vlistptr->gridIDs[index] = gridID2;
-              break;
-            }
-        }
-      int nvars = vlistptr->nvars;
-      for ( int varID = 0; varID < nvars; varID++ )
-        if ( vlistptr->vars[varID].gridID == gridID1 )
-          vlistptr->vars[varID].gridID = gridID2;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  /*
+  // Do linear fit to find the slope
+   */
+
+  for( loop = ismin; loop <= ismax; loop++ ) {
+    x = log( (double) (loop*(loop+1)) );
+    y = log( norms[loop] );
+    weightedSumOverX = weightedSumOverX + x * weights[loop];
+    weightedSumOverY = weightedSumOverY + y * weights[loop];
+    sumOfWeights = sumOfWeights + weights[loop];
+  }
+  weightedSumOverX = weightedSumOverX / sumOfWeights;
+  weightedSumOverY = weightedSumOverY / sumOfWeights;
 
+  /*
+  // Perform a least square fit for the equation
+   */
+
+  for( loop = ismin; loop <= ismax; loop++ ) {
+
+    x = log( (double)(loop*(loop+1)) );
+    y = log( norms[loop] );
+    numerator =
+      numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
+    denominator =
+      denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
+  }
+  slope = numerator / denominator;
 
-int vlistZaxis(int vlistID, int index)
-{
-  int zaxisID = CDI_UNDEFID;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  free(weights);
+  free(norms);
 
-  if ( index < vlistptr->nzaxis && index >= 0 )
-    zaxisID = vlistptr->zaxisIDs[index];
+  pFactor = -slope;
+  if( pFactor < -9999.9 ) pFactor = -9999.9;
+  if( pFactor > 9999.9 )  pFactor = 9999.9;
 
-  return (zaxisID);
+  return pFactor;
 }
 
-int vlistZaxisIndex(int vlistID, int zaxisID)
+static
+int rowina2(double *p, int ko, int ki, double *pw,
+	    int kcode, double msval, int *kret)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* System generated locals */
+  int pw_dim1, pw_offset, i_1;
 
-  int index;
-  for ( index = 0 ; index < vlistptr->nzaxis ; index++ )
-    if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
+  /* Local variables */
+  double zwt1, zrdi, zpos;
+  int jl, ip;
+  double zdo, zwt;
 
-  if ( index == vlistptr->nzaxis ) index = -1;
+  /* Parameter adjustments */
+  --p;
+  pw_dim1 = ko + 3;
+  pw_offset = pw_dim1;
+  pw -= pw_offset;
 
-  return (index);
-}
+  /* **** ROWINA2 - Interpolation of row of values. */
+  /*     Input Parameters. */
+  /*     ----------------- */
+  /*     P      - Row of values to be interpolated. */
+  /*              Dimension must be at least KO. */
+  /*     KO     - Number of values required. */
+  /*     KI     - Number of values in P on input. */
+  /*     PW     - Working array. */
+  /*              Dimension must be at least (0:KO+2,3). */
+  /*     KCODE  - Interpolation required. */
+  /*              1 , linear. */
+  /*              3 , cubic. */
+  /*     PMSVAL - Value used for missing data indicator. */
 
+  /*     Output Parameters. */
+  /*     ------------------ */
+  /*     P     - Now contains KO values. */
+  /*     KRET  - Return code */
+  /*             0, OK */
+  /*             Non-zero, error */
 
-void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /*     Author. */
+  /*     ------- */
+  /*     J.D.Chambers    ECMWF     22.07.94 */
 
-  int zaxisIDold = vlistptr->zaxisIDs[index];
-  if (zaxisIDold != zaxisID)
-    {
-      vlistptr->zaxisIDs[index] = zaxisID;
+  /*     ********************************    */
+  /*     Section 1.  Linear interpolation .. */
+  /*     ********************************    */
 
-      int nlevs = zaxisInqSize(zaxisID),
-        nlevsOld = zaxisInqSize(zaxisIDold);
-      int nvars = vlistptr->nvars;
-      for ( int varID = 0; varID < nvars; varID++ )
-        if ( vlistptr->vars[varID].zaxisID == zaxisIDold )
-          {
-            vlistptr->vars[varID].zaxisID = zaxisID;
-            if ( vlistptr->vars[varID].levinfo && nlevs != nlevsOld )
-              {
-                vlistptr->vars[varID].levinfo = (levinfo_t *)xrealloc(vlistptr->vars[varID].levinfo, (size_t)nlevs * sizeof (levinfo_t));
+  *kret = 0;
 
-                for ( int levID = 0; levID < nlevs; levID++ )
-                  vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
-              }
-          }
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  if ( kcode == 1 )
+    {
+      /*    Move input values to work array */
+      for ( jl = 1; jl <= ki; ++jl )
+	pw[jl + pw_dim1] = p[jl];
 
+      /*    Arrange wrap-around value in work array */
+      pw[ki + 1 + pw_dim1] = p[1];
 
-void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
-{
-  int nlevs1 = zaxisInqSize(zaxisID1), nlevs2 = zaxisInqSize(zaxisID2);
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      /*    Set up constants to be used to figure out weighting for */
+      /*    values in interpolation. */
+      zrdi = (double) ki;
+      zdo = 1.0 / (double) ko;
 
-  int nzaxis = vlistptr->nzaxis;
-  for ( int index = 0; index < nzaxis; index++ )
-    {
-      if ( vlistptr->zaxisIDs[index] == zaxisID1 )
-        {
-          vlistptr->zaxisIDs[index] = zaxisID2;
-          break;
-        }
-    }
+      /*    Loop through the output points */
+      for ( jl = 1; jl <= ko; ++jl )
+	{
 
-  int nvars = vlistptr->nvars;
-  for ( int varID = 0; varID < nvars; varID++ )
-    if ( vlistptr->vars[varID].zaxisID == zaxisID1 )
-      {
-        vlistptr->vars[varID].zaxisID = zaxisID2;
+	  /*    Calculate weight from the start of row */
+	  zpos = (jl - 1) * zdo;
+	  zwt = zpos * zrdi;
 
-        if ( vlistptr->vars[varID].levinfo && nlevs2 != nlevs1 )
-          {
-            vlistptr->vars[varID].levinfo
-              = (levinfo_t *)xrealloc(vlistptr->vars[varID].levinfo,
-                                      (size_t)nlevs2 * sizeof(levinfo_t));
+	  /*    Get the current array position(minus 1) from the weight - */
+	  /*    note the implicit truncation. */
+	  ip = (int) zwt;
 
-            for ( int levID = 0; levID < nlevs2; levID++ )
-              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
-          }
-      }
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+	  /*    If the left value is missing, use the right value */
+	  if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+	    {
+	      p[jl] = pw[ip + 2 + pw_dim1];
+	    }
+	  /*    If the right value is missing, use the left value */
+	  else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+	    {
+	      p[jl] = pw[ip + 1 + pw_dim1];
+	    }
+	  /*    If neither missing, interpolate ... */
+	  else
+	    {
 
+	      /*       Adjust the weight to range (0.0 to 1.0) */
+	      zwt -= ip;
 
-int vlistHasTime(int vlistID)
-{
-  int hastime = FALSE;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	      /*       Interpolate using the weighted values on either side */
+	      /*       of the output point position */
+	      p[jl] = (1.0 - zwt) * pw[ip + 1 + pw_dim1] +
+		zwt * pw[ip + 2 + pw_dim1];
+	    }
+	}
 
-  for ( int varID = 0; varID <  vlistptr->nvars; varID++ )
-    if ( vlistptr->vars[varID].tsteptype != TSTEP_CONSTANT )
-      {
-        hastime = TRUE;
-        break;
-      }
+      /*     *******************************    */
+      /*     Section 2.  Cubic interpolation .. */
+      /*     *******************************    */
 
-  return (hastime);
-}
+    }
+  else if ( kcode == 3 )
+    {
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          if ( IS_EQUAL(p[jl], msval) )
+	    {
+	      fprintf(stderr," ROWINA2: ");
+	      fprintf(stderr," Cubic interpolation not supported");
+	      fprintf(stderr," for fields containing missing data.\n");
+	      *kret = 1;
+	      goto L900;
+	    }
+          pw[jl + pw_dim1] = p[jl];
+	}
+      pw[pw_dim1] = p[ki];
+      pw[ki + 1 + pw_dim1] = p[1];
+      pw[ki + 2 + pw_dim1] = p[2];
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          pw[jl + (pw_dim1 << 1)] =
+	        - pw[jl - 1 + pw_dim1] / 3.0 -
+	          pw[jl     + pw_dim1] * 0.5 +
+	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
+          pw[jl + 1 + pw_dim1 * 3] =
+                  pw[jl - 1 + pw_dim1] / 6.0 -
+                  pw[jl     + pw_dim1] +
+                  pw[jl + 1 + pw_dim1] * 0.5 +
+                  pw[jl + 2 + pw_dim1] / 3.0;
+	}
 
-enum {
-  vlist_nints=6,
-};
+      scm0_double(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+		  &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
 
-static int
-vlistTxCode ( void )
-{
-  return VLIST;
-}
+      zrdi = (double) ki;
+      zdo = 1.0 / (double) ko;
+      for ( jl = 1; jl <= ko; ++jl )
+	{
+          zpos = (jl - 1) * zdo;
+          zwt = zpos * zrdi;
+          ip = (int) zwt + 1;
+          zwt = zwt + 1.0 - ip;
+          zwt1 = 1.0 - zwt;
+          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
+	}
 
+    }
+  else
+    {
+      /*    **************************************    */
+      /*    Section 3.  Invalid interpolation code .. */
+      /*    **************************************    */
+      fprintf(stderr," ROWINA2:");
+      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+      *kret = 2;
+    }
 
-static
-int  vlistGetSizeP ( void * vlistptr, void *context)
-{
-  int txsize, varID;
-  vlist_t *p = (vlist_t*) vlistptr;
-  txsize = serializeGetSize(vlist_nints, DATATYPE_INT, context);
-  txsize += serializeGetSize(1, DATATYPE_LONG, context);
-  txsize += vlistAttsGetSize(p, CDI_GLOBAL, context);
-  for ( varID = 0; varID <  p->nvars; varID++ )
-    txsize += vlistVarGetPackSize(p, varID, context);
-  return txsize;
-}
+L900:
+    return 0;
+} /* rowina2 */
 
 
-static
-void vlistPackP ( void * vlistptr, void * buf, int size, int *position,
-                  void *context )
+
+int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
+	    double *ztemp, double msval, int *kret)
 {
-  int varID, tempbuf[vlist_nints];
-  vlist_t *p = (vlist_t*) vlistptr;
-  tempbuf[0] = p->self;
-  tempbuf[1] = p->nvars;
-  tempbuf[2] = p->taxisID;
-  tempbuf[3] = p->tableID;
-  tempbuf[4] = p->instID;
-  tempbuf[5] = p->modelID;
-  serializePack(tempbuf, vlist_nints, DATATYPE_INT, buf, size, position, context);
-  serializePack(&p->ntsteps, 1, DATATYPE_LONG, buf, size, position, context);
+   /* System generated locals */
+   int i_1, i_2;
+   int kcode = 1;
 
-  vlistAttsPack(p, CDI_GLOBAL, buf, size, position, context);
-  for ( varID = 0; varID < p->nvars; varID++ )
-    {
-      vlistVarPack(p, varID, buf, size, position, context);
-    }
-}
+   /* Local variables */
+   int ilii, ilio, icode;
+   double *zline = NULL;
+   double *zwork = NULL;
+   int iregno, iquano, j210, j220, j230, j240, j225;
 
-void vlistUnpack(char * buf, int size, int *position, int originNamespace,
-                 void *context, int force_id)
-{
-  int tempbuf[vlist_nints];
-  serializeUnpack(buf, size, position, tempbuf, vlist_nints, DATATYPE_INT, context);
-  int nvars = tempbuf[1];
-  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
-  vlist_t *p = vlist_new_entry(force_id?targetID:CDI_UNDEFID);
-  xassert(!force_id || p->self == targetID);
-  if (!force_id)
-    targetID = p->self;
-  p->taxisID = namespaceAdaptKey(tempbuf[2], originNamespace);
-  p->tableID = tempbuf[3];
-  p->instID = namespaceAdaptKey(tempbuf[4], originNamespace);
-  p->modelID = namespaceAdaptKey(tempbuf[5], originNamespace);
-  serializeUnpack(buf, size, position, &p->ntsteps, 1, DATATYPE_LONG, context);
-  vlistAttsUnpack(targetID, CDI_GLOBAL, buf, size, position, context);
-  for (int varID = 0; varID < nvars; varID++ )
-    vlistVarUnpack(targetID, buf, size, position, originNamespace, context);
-}
 
+   zline = (double*) malloc(2*klon*sizeof(double));
+   if ( zline == NULL ) SysError("No Memory!");
 
-void vlist_check_contents(int vlistID)
-{
-  int index, nzaxis, zaxisID;
+   zwork = (double*) malloc(3*(2*klon+3)*sizeof(double));
+   if ( zwork == NULL ) SysError("No Memory!");
 
-  nzaxis = vlistNzaxis(vlistID);
+   /* Parameter adjustments */
+   --pfield;
+   --kpoint;
 
-  for ( index = 0; index < nzaxis; index++ )
-    {
-      zaxisID = vlistZaxis(vlistID, index);
-      if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
-	cdiCheckZaxis(zaxisID);
-    }
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
+/* **** QU2REG - Convert quasi-regular grid data to regular. */
+/*     Input Parameters. */
+/*     ----------------- */
+/*     PFIELD     - Array containing quasi-regular grid */
+/*                  data. */
+/*     KPOINT     - Array containing list of the number of */
+/*                  points on each latitude (or longitude) of */
+/*                  the quasi-regular grid. */
+/*     KLAT       - Number of latitude lines */
+/*     KLON       - Number of longitude lines */
+/*     KCODE      - Interpolation required. */
+/*                  1 , linear - data quasi-regular on */
+/*                               latitude lines. */
+/*                  3 , cubic -  data quasi-regular on */
+/*                               latitude lines. */
+/*                  11, linear - data quasi-regular on */
+/*                               longitude lines. */
+/*                  13, cubic -  data quasi-regular on */
+/*                               longitude lines. */
+/*     PMSVAL     - Value used for missing data indicator. */
+/*     Output Parameters. */
+/*     ------------------ */
+/*     KRET       - return code */
+/*                  0 = OK */
+/*                  non-zero indicates fatal error */
+/*     PFIELD     - Array containing regular grid data. */
+/*     Author. */
+/*     ------- */
+/*     J.D.Chambers     ECMWF      22.07.94 */
+/*     J.D.Chambers     ECMWF      13.09.94 */
+/*     Add return code KRET and remove calls to ABORT. */
 
-#include <assert.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
 
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
 
+   *kret = 0;
 
-static
-cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
-{
-  cdi_atts_t *attsp = NULL;
+/* Check input parameters. */
 
-  if ( varID == CDI_GLOBAL )
-    {
-      attsp = &vlistptr->atts;
-    }
-  else
-    {
-      if ( varID >= 0 && varID < vlistptr->nvars )
-	attsp = &(vlistptr->vars[varID].atts);
-    }
+   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+      fprintf(stderr," QU2REG :");
+      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+      *kret = 1;
+      goto L900;
+   }
 
-  return (attsp);
-}
+/* Set array indices to 0. */
 
-static
-cdi_att_t *find_att(cdi_atts_t *attsp, const char *name)
-{
-  xassert(attsp != NULL);
+   ilii = 0;
+   ilio = 0;
 
-  if ( attsp->nelems == 0 ) return NULL;
+/* Establish values of loop parameters. */
 
-  size_t slen = strlen(name);
-  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
+   if (kcode > 10) {
 
-  cdi_att_t *atts = attsp->value;
-  for ( size_t attid = 0; attid < attsp->nelems; attid++ )
-    {
-      cdi_att_t *attp = atts + attid;
-      if ( attp->namesz == slen && memcmp(attp->name, name, slen) == 0 )
-        return (attp); /* Normal return */
-    }
+/*    Quasi-regular along longitude lines. */
 
-  return (NULL);
-}
+      iquano = klon;
+      iregno = klat;
+      icode = kcode - 10;
+   } else {
 
-static
-cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
-{
-  cdi_att_t *attp;
-  size_t slen;
+/*    Quasi-regular along latitude lines. */
 
-  xassert(attsp != NULL);
-  xassert(name  != NULL);
+      iquano = klat;
+      iregno = klon;
+      icode = kcode;
+   }
 
-  if ( attsp->nelems == attsp->nalloc ) return (NULL);
+/*     -------------------------------------------------------- */
+/**    Section 2. Interpolate field from quasi to regular grid. */
+/*     -------------------------------------------------------- */
 
-  attp = &(attsp->value[attsp->nelems]);
-  attsp->nelems++;
+   i_1 = iquano;
+   for (j230 = 1; j230 <= i_1; ++j230) {
 
-  slen = strlen(name);
-  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
+      if (iregno != kpoint[j230]) {
 
-  attp->name = (char *) malloc(slen+1);
-  memcpy(attp->name, name, slen+1);
-  attp->namesz = slen;
-  attp->xvalue = NULL;
+/*       Line contains less values than required,so */
+/*       extract quasi-regular grid values for a line */
 
-  return (attp);
-}
+         i_2 = kpoint[j230];
+         for (j210 = 1; j210 <= i_2; ++j210) {
+            ++ilii;
+            zline[j210 - 1] = pfield[ilii];
+         }
 
-static
-void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t xsz, const void *xvalue)
-{
-  xassert(attp != NULL);
+/*       and interpolate this line. */
 
-  attp->xsz = xsz;
-  attp->indtype = indtype;
-  attp->exdtype = exdtype;
-  attp->nelems  = nelems;
+         rowina2(zline, iregno, kpoint[j230], zwork, icode, msval, kret);
+         if (*kret != 0) goto L900;
 
-  if ( xsz > 0 )
-    {
-      attp->xvalue = xrealloc(attp->xvalue, xsz);
-      memcpy(attp->xvalue, xvalue, xsz);
-    }
-}
+/*       Add regular grid values for this line to the
+         temporary array. */
 
-/*
- at Function  vlistInqNatts
- at Title     Get number of variable attributes
+         i_2 = iregno;
+         for (j220 = 1; j220 <= i_2; ++j220) {
+            ++ilio;
+            ztemp[ilio - 1] = zline[j220 - 1];
+         }
 
- at Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  nattsp   Pointer to location for returned number of variable attributes.
+      } else {
 
- at Description
-The function @func{vlistInqNatts} gets the number of variable attributes assigned to this variable.
+/*       Line contains the required number of values, so add */
+/*       this line to the temporary array. */
 
- at EndFunction
-*/
-int vlistInqNatts(int vlistID, int varID, int *nattsp)
-{
-  int status = CDI_NOERR;
-  vlist_t *vlistptr;
-  cdi_atts_t *attsp;
+         i_2 = iregno;
+         for (j225 = 1; j225 <= i_2; ++j225) {
+            ++ilio;
+            ++ilii;
+            ztemp[ilio - 1] = pfield[ilii];
+         }
+      }
+   }
+
+/* Copy temporary array to user array. */
 
-  vlistptr = vlist_to_pointer(vlistID);
+   i_1 = klon * klat;
+   for (j240 = 1; j240 <= i_1; ++j240) {
+      pfield[j240] = ztemp[j240 - 1];
+   }
 
-  attsp = get_attsp(vlistptr, varID);
-  xassert(attsp != NULL);
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
 
-  *nattsp = (int)attsp->nelems;
+L900:
 
-  return (status);
-}
+   free(zline);
+   free(zwork);
 
-/*
- at Function  vlistInqAtt
- at Title     Get information about an attribute
+   return 0;
+} /* qu2reg2 */
 
- at Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  attnum   Attribute number (from 0 to natts-1).
-    @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
-    @Item  typep    Pointer to location for returned attribute type.
-    @Item  lenp     Pointer to location for returned attribute number.
 
- at Description
-The function @func{vlistInqAtt} gets information about an attribute.
 
- at EndFunction
-*/
-int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
+
+void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
 {
-  int status = CDI_NOERR;
-  cdi_att_t *attp = NULL;
+  double power;
+  double *scale = (double*) malloc((trunc+1)*sizeof(double));
+  int  n, m;
+  int  index;
 
-  xassert(name != NULL);
+  if ( scale == NULL ) SysError("No Memory!");
 
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( pcScale < -10000 || pcScale > 10000 )
+    {
+      fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
+      return;
+   }
 
-  cdi_atts_t *attsp = get_attsp(vlistptr, varID);
-  xassert(attsp != NULL);
+  /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
 
-  if ( attnum >= 0 && attnum < (int)attsp->nelems )
-    attp = &(attsp->value[attnum]);
+  if ( pcScale == 0 ) return;
 
-  if ( attp != NULL ) /* name in use */
-    {
-      memcpy(name, attp->name, attp->namesz+1);
-      *typep  = attp->exdtype;
-      *lenp   = (int)attp->nelems;
-    }
-  else
+  power = (double) pcScale / 1000.;
+  scale[0] = 1.0;
+
+  for ( n = 1; n <= trunc; n++ )
     {
-      name[0] =  0;
-      *typep  = -1;
-      *lenp   =  0;
-      status  = -1;
+      if (pcScale != 1000)
+         scale[n] = pow((double) (n*(n+1)), power);
+      else
+         scale[n] =     (double) (n*(n+1));
     }
 
-  return (status);
-}
-
-
-int vlistDelAtts(int vlistID, int varID)
-{
-  int status = CDI_NOERR;
-  vlist_t *vlistptr;
-  cdi_att_t *attp = NULL;
-  cdi_atts_t *attsp;
-  int attid;
+  if ( inv )
+    for ( n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
 
-  vlistptr = vlist_to_pointer(vlistID);
+  /* Scale the values */
 
-  attsp = get_attsp(vlistptr, varID);
-  xassert(attsp != NULL);
+  index = 0;
 
-  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
-    {
-      attp = &(attsp->value[attid]);
-      if ( attp->name   ) free(attp->name);
-      if ( attp->xvalue ) free(attp->xvalue);
-    }
+  for ( m = 0;   m < pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n >= pcStart )
+	  {
+	    fpdata[index  ] *= scale[n];
+	    fpdata[index+1] *= scale[n];
+	  }
+	index += 2;
+      }
 
-  attsp->nelems = 0;
+  for ( m = pcStart; m <= trunc; m++ )
+    for ( n = m;     n <= trunc; n++ )
+      {
+	fpdata[index  ] *= scale[n];
+	fpdata[index+1] *= scale[n];
+	index += 2;
+      }
 
-  return (status);
+  free(scale);
 }
 
 
-int vlistDelAtt(int vlistID, int varID, const char *name)
+void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
 {
-  int status = CDI_NOERR;
+  T *fphelp = (T*) malloc(nsp*sizeof(T));
+  int  m, n;
+  int  index, inext;
 
-  UNUSED(vlistID);
-  UNUSED(varID);
-  UNUSED(name);
+  if ( fphelp == NULL ) SysError("No Memory!");
 
-  fprintf(stderr, "vlistDelAtt not implemented!\n");
+  index = inext = 0;
 
-  return (status);
+  for ( m = 0;   m <= pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( pcStart >= n )
+	  {
+	    fphelp[index  ] = fpdata[inext++];
+	    fphelp[index+1] = fpdata[inext++];
+	  }
+	index += 2;
+      }
+
+  index = 0;
+  for ( m = 0;   m <= trunc; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n > pcStart )
+	  {
+	    fphelp[index  ] = fpdata[inext++];
+	    fphelp[index+1] = fpdata[inext++];
+	  }
+	index += 2;
+      }
+
+  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+
+  free(fphelp);
 }
 
-static
-int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
+
+void TEMPLATE(gather_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
 {
-  int status = CDI_NOERR;
-  vlist_t *vlistptr;
-  cdi_att_t *attp;
-  cdi_atts_t *attsp;
+  T *fphelp = (T*) malloc(nsp*sizeof(T));
+  int  m, n;
+  int  index, inext;
 
-  if ( len != 0 && xp == NULL ) /* Null arg */
-    {
-      return (CDI_EINVAL);
-    }
+  if ( fphelp == NULL ) SysError("No Memory!");
 
-  vlistptr = vlist_to_pointer(vlistID);
+  index = inext = 0;
 
-  attsp = get_attsp(vlistptr, varID);
-  xassert(attsp != NULL);
+  for ( m = 0;   m <= pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( pcStart >= n )
+	  {
+	    fphelp[inext++] = fpdata[index];
+	    fphelp[inext++] = fpdata[index+1];
+	  }
+	index += 2;
+      }
 
-  attp = find_att(attsp, name);
-  if ( attp == NULL )
-    attp = new_att(attsp, name);
+  index = 0;
+  for ( m = 0;   m <= trunc; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n > pcStart )
+	  {
+	    fphelp[inext++] = fpdata[index];
+	    fphelp[inext++] = fpdata[index+1];
+	  }
+	index += 2;
+      }
 
-  if ( attp != NULL )
-    fill_att(attp, indtype, exdtype, len, xsz, xp);
+  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
 
-  return (status);
+  free(fphelp);
 }
 
-static
-int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
+
+void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
 {
-  int status = CDI_NOERR;
-  vlist_t *vlistptr;
-  cdi_att_t *attp;
-  cdi_atts_t *attsp;
-  size_t xsz;
+  /* System generated locals */
+  double r_1;
 
-  if ( mxsz != 0 && xp == NULL ) /* Null arg */
-    {
-      return (CDI_EINVAL);
-    }
+  /* Local variables */
+  int jl;
+  double zfac, zeps, zbeta;
+  double zalpha;
 
-  vlistptr = vlist_to_pointer(vlistID);
+  /* **** SCM0   - Apply SCM0 limiter to derivative estimates. */
+  /* output: */
+  /*   pdl   = the limited derivative at the left edge of the interval */
+  /*   pdr   = the limited derivative at the right edge of the interval */
+  /* inputs */
+  /*   pdl   = the original derivative at the left edge */
+  /*   pdr   = the original derivative at the right edge */
+  /*   pfl   = function value at the left edge of the interval */
+  /*   pfr   = function value at the right edge of the interval */
+  /*   klg   = number of intervals where the derivatives are limited */
 
-  attsp = get_attsp(vlistptr, varID);
-  xassert(attsp != NULL);
+  /*  define constants */
 
-  attp = find_att(attsp, name);
-  if ( attp != NULL ) /* name in use */
+  zeps = 1.0e-12;
+  zfac = (1.0 - zeps) * 3.0;
+
+  for ( jl = 0; jl < klg; ++jl )
     {
-      if ( attp->indtype == indtype )
+      if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
 	{
-	  xsz = attp->xsz;
-	  if ( mxsz < xsz ) xsz = mxsz;
-	  if ( xsz > 0 )
-	    memcpy(xp, attp->xvalue, xsz);
+	  zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
+	  zbeta  = pdr[jl] / (pfr[jl] - pfl[jl]);
+	  if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
+	  if ( zbeta  <= 0.0 ) pdr[jl] = 0.0;
+	  if ( zalpha > zfac ) pdl[jl] = zfac * (pfr[jl] - pfl[jl]);
+	  if ( zbeta  > zfac ) pdr[jl] = zfac * (pfr[jl] - pfl[jl]);
 	}
       else
 	{
-	  Warning("Attribute %s has wrong data type!", name);
-          status = -2;
+	  pdl[jl] = 0.0;
+	  pdr[jl] = 0.0;
 	}
     }
-  else
-    {
-      //Warning("Internal problem, attribute %s not found!", name);
-      status = -1;
-    }
+} /* scm0 */
 
-  return (status);
-}
+static
+int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
+			int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
+{
+  /*
+C---->
+C**** ROWINA3 - Interpolation of row of values.
+C
+C     Purpose.
+C     --------
+C
+C     Interpolate a row of values.
+C
+C
+C**   Interface.
+C     ----------
+C
+C     CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
+C
+C
+C     Input Parameters.
+C     -----------------
+C
+C     P      - Row of values to be interpolated.
+C              Dimension must be at least KO.
+C
+C     KO     - Number of values required.
+C
+C     KI     - Number of values in P on input.
+C
+C     PW     - Working array.
+C              Dimension must be at least (0:KO+2,3).
+C
+C     KCODE  - Interpolation required.
+C              1 , linear.
+C              3 , cubic.
+C
+C     PMSVAL - Value used for missing data indicator.
+C
+C     OMISNG - True if missing values are present in field.
+C
+C     OPERIO - True if input field is periodic.
+C
+C     OVEGGY - True if 'nearest neighbour' processing must be used
+C              for interpolation
+C
+C     Output Parameters.
+C     ------------------
+C
+C     P     - Now contains KO values.
+C     KRET  - Return code
+C             0, OK
+C             Non-zero, error
+C
+C
+C     Method.
+C     -------
+C
+C     Linear or cubic interpolation performed as required.
+C
+C     Comments.
+C     ---------
+C
+C     This is a version of ROWINA which allows for missing data
+C     values and hence for bitmapped fields.
+C
+C
+C     Author.
+C     -------
+C
+C     J.D.Chambers    ECMWF     22.07.94
+C
+C
+C     Modifications.
+C     --------------
+C
+C     J.D.Chambers    ECMWF     13.09.94
+C     Add return code KRET and remove calls to ABORT.
+C
+C     J. Clochard, Meteo France, for ECMWF - January 1998.
+C     Addition of OMISNG and OPERIO arguments.
+C
+C
+C     -----------------------------------------------------------------
+*/
+  /* System generated locals */
+  int pw_dim1, pw_offset, i_1;
 
+  /* Local variables */
+  int jl, ip;
+  double zwt1, zrdi, zpos;
+  double zdo, zwt;
 
-int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
-{
-  int status = CDI_NOERR;
-  vlist_t *vlistptr1;
-  cdi_att_t *attp = NULL;
-  cdi_atts_t *attsp1;
-  int attid;
+  UNUSED(omisng);
 
-  vlistptr1 = vlist_to_pointer(vlistID1);
+  /* Parameter adjustments */
+  --p;
+  pw_dim1 = ko + 3;
+  pw_offset = pw_dim1;
+  pw -= pw_offset;
 
-  attsp1 = get_attsp(vlistptr1, varID_1);
-  xassert(attsp1 != NULL);
+  *kret = 0;
 
-  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
+  if ( kcode == 1 )
     {
-      attp = &(attsp1->value[attid]);
-      vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
-    }
+      /*    Move input values to work array */
+      for ( jl = 1; jl <= ki; ++jl )
+	pw[jl + pw_dim1] = p[jl];
 
-  return (status);
-}
+      if ( operio )
+	{
+	  /* Arrange wrap-around value in work array */
+	  pw[ki + 1 + pw_dim1] = p[1];
 
-/*
- at Function  vlistDefAttInt
- at Title     Define an integer attribute
+	  /* Set up constants to be used to figure out weighting for */
+	  /* values in interpolation. */
+	  zrdi = (double) ki;
+	  zdo = 1.0 / (double) ko;
+	}
+      else
+	{
+	  /* Repeat last value, to cope with "implicit truncation" below */
+	  pw[ki + 1 + pw_dim1] = p[ki];
 
- at Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
+	  /* Set up constants to be used to figure out weighting for */
+	  /* values in interpolation. */
+	  zrdi = (double) (ki-1);
+	  zdo = 1.0 / (double) (ko-1);
+ 	}
 
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  type     External data type (@func{DATATYPE_INT16} or @func{DATATYPE_INT32}).
-    @Item  len      Number of values provided for the attribute.
-    @Item  ip       Pointer to one or more integer values.
+      /*    Loop through the output points */
+      for ( jl = 1; jl <= ko; ++jl )
+	{
 
- at Description
-The function @func{vlistDefAttInt} defines an integer attribute.
+	  /* Calculate weight from the start of row */
+	  zpos = (jl - 1) * zdo;
+	  zwt = zpos * zrdi;
 
- at EndFunction
-*/
-int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
-{
-  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (int), ip);
-}
+	  /* Get the current array position(minus 1) from the weight - */
+	  /* note the implicit truncation. */
+	  ip = (int) zwt;
+		  
+	  /* Adjust the weight to range (0.0 to 1.0) */
+	  zwt -= ip;
 
-/*
- at Function  vlistDefAttFlt
- at Title     Define a floating point attribute
+          /* If 'nearest neighbour' processing must be used */
+	  if ( oveggy )
+	    {
+              if ( zwt < 0.5 )
+                p[jl] = pw[ip + 1 + pw_dim1];
+	      else
+		p[jl] = pw[ip + 2 + pw_dim1];
+	    }
+	  else
+	    {
+	      /*    If the left value is missing, use the right value */
+	      if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+		{
+		  p[jl] = pw[ip + 2 + pw_dim1];
+		}
+	      /*    If the right value is missing, use the left value */
+	      else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+		{
+		  p[jl] = pw[ip + 1 + pw_dim1];
+		}
+	      /*    If neither missing, interpolate ... */
+	      else
+		{
+		  /*  Interpolate using the weighted values on either side */
+		  /*  of the output point position */
+		  p[jl] = (1.0 - zwt) * pw[ip+1 + pw_dim1] +
+		                  zwt * pw[ip+2 + pw_dim1];
+		}
+	    }
+	}
+    }
+  else if ( kcode == 3 )
+    {
+      /*     *******************************    */
+      /*     Section 2.  Cubic interpolation .. */
+      /*     *******************************    */
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          if ( IS_EQUAL(p[jl], msval) )
+	    {
+	      fprintf(stderr," ROWINA3: ");
+	      fprintf(stderr," Cubic interpolation not supported");
+	      fprintf(stderr," for fields containing missing data.\n");
+	      *kret = 1;
+	      goto L900;
+	    }
+          pw[jl + pw_dim1] = p[jl];
+	}
+      pw[pw_dim1] = p[ki];
+      pw[ki + 1 + pw_dim1] = p[1];
+      pw[ki + 2 + pw_dim1] = p[2];
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          pw[jl + (pw_dim1 << 1)] =
+	        - pw[jl - 1 + pw_dim1] / 3.0 -
+	          pw[jl     + pw_dim1] * 0.5 +
+	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
+          pw[jl + 1 + pw_dim1 * 3] =
+                  pw[jl - 1 + pw_dim1] / 6.0 -
+                  pw[jl     + pw_dim1] +
+                  pw[jl + 1 + pw_dim1] * 0.5 +
+                  pw[jl + 2 + pw_dim1] / 3.0;
+	}
 
- at Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
+      TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+		       &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
 
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  type     External data type (@func{DATATYPE_FLT32} or @func{DATATYPE_FLT64}).
-    @Item  len      Number of values provided for the attribute.
-    @Item  dp       Pointer to one or more floating point values.
+      zrdi = (double) ki;
+      zdo = 1.0 / (double) ko;
+      for ( jl = 1; jl <= ko; ++jl )
+	{
+          zpos = (jl - 1) * zdo;
+          zwt = zpos * zrdi;
+          ip = (int) zwt + 1;
+          zwt = zwt + 1.0 - ip;
+          zwt1 = 1.0 - zwt;
+          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
+	}
 
- at Description
-The function @func{vlistDefAttFlt} defines a floating point attribute.
+    }
+  else
+    {
+      /*    **************************************    */
+      /*    Section 3.  Invalid interpolation code .. */
+      /*    **************************************    */
+      fprintf(stderr," ROWINA3:");
+      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+      *kret = 2;
+    }
 
- at EndFunction
-*/
-int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
-{
-  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (double), dp);
-}
+L900:
+    return 0;
+} /* rowina3 */
 
-/*
- at Function  vlistDefAttTxt
- at Title     Define a text attribute
 
- at Prototype int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
+int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
+			T msval, int *kret, int omisng, int operio, int oveggy)
+{
+  /*
+C**** QU2REG3 - Convert quasi-regular grid data to regular.
+C
+C     Purpose.
+C     --------
+C
+C     Convert quasi-regular grid data to regular,
+C     using either a linear or cubic interpolation.
+C
+C
+C**   Interface.
+C     ----------
+C
+C     CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
+C    X            OVEGGY)
+C
+C
+C     Input Parameters.
+C     -----------------
+C
+C     PFIELD     - Array containing quasi-regular grid data.
+C
+C     KPOINT     - Array containing list of the number of
+C                  points on each latitude (or longitude) of
+C                  the quasi-regular grid.
+C
+C     KLAT       - Number of latitude lines
+C
+C     KLON       - Number of longitude lines
+C
+C     KCODE      - Interpolation required.
+C                  1 , linear - data quasi-regular on latitude lines.
+C                  3 , cubic -  data quasi-regular on latitude lines.
+C                  11, linear - data quasi-regular on longitude lines.
+C                  13, cubic -  data quasi-regular on longitude lines.
+C
+C     PMSVAL     - Value used for missing data indicator.
+C
+C     OMISNG     - True if missing values are present in field.
+C
+C     OPERIO     - True if input field is periodic.
+C
+C     OVEGGY     - True if 'nearest neighbour' processing must be used
+C                  for interpolation
+C
+C
+C     Output Parameters.
+C     ------------------
+C
+C     KRET       - return code
+C                  0 = OK
+C                  non-zero indicates fatal error
+C
+C
+C     Output Parameters.
+C     ------------------
+C
+C     PFIELD     - Array containing regular grid data.
+C
+C
+C     Method.
+C     -------
+C
+C     Data is interpolated and expanded into a temporary array,
+C     which is then copied back into the user's array.
+C     Returns an error code if an invalid interpolation is requested
+C     or field size exceeds array dimensions.
+C
+C     Comments.
+C     ---------
+C
+C     This routine is an adaptation of QU2REG to allow missing data
+C     values, and hence bit mapped fields.
+C
+C
+C     Author.
+C     -------
+C
+C     J.D.Chambers     ECMWF      22.07.94
+C
+C
+C     Modifications.
+C     --------------
+C
+C     J.D.Chambers     ECMWF      13.09.94
+C     Add return code KRET and remove calls to ABORT.
+C
+C     J.D.Chambers     ECMWF        Feb 1997
+C     Allow for 64-bit pointers
+C
+C     J. Clochard, Meteo France, for ECMWF - January 1998.
+C     Addition of OMISNG and OPERIO arguments.
+C     Fix message for longitude number out of bounds, and routine
+C     name in title and formats.
+C
+*/
+   /* System generated locals */
+   int i_1, i_2;
+   int kcode = 1;
 
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  len      Number of values provided for the attribute.
-    @Item  tp       Pointer to one or more character values.
+   /* Local variables */
+   int ilii, ilio, icode;
+   int iregno, iquano, j210, j220, j230, j240, j225;
+   T *ztemp = NULL;
+   T *zline = NULL;
+   T *zwork = NULL;
 
- at Description
-The function @func{vlistDefAttTxt} defines a text attribute.
+   ztemp = (T*) malloc(klon*klat*sizeof(T));
+   if ( ztemp == NULL ) SysError("No Memory!");
 
- at EndFunction
-*/
-int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
-{
-  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t)len, (size_t)len, tp);
-}
+   zline = (T*) malloc(2*klon*sizeof(T));
+   if ( zline == NULL ) SysError("No Memory!");
 
-/*
- at Function  vlistInqAttInt
- at Title     Get the value(s) of an integer attribute
+   zwork = (T*) malloc(3*(2*klon+3)*sizeof(T));
+   if ( zwork == NULL ) SysError("No Memory!");
 
- at Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  mlen     Number of allocated values provided for the attribute.
-    @Item  ip       Pointer location for returned integer attribute value(s).
+   /* Parameter adjustments */
+   --pfield;
+   --kpoint;
 
- at Description
-The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
 
- at EndFunction
-*/
-int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
-{
-  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, (size_t)mlen * sizeof (int), ip);
-}
+   *kret = 0;
 
-/*
- at Function  vlistInqAttFlt
- at Title     Get the value(s) of a floating point attribute
+/* Check input parameters. */
 
- at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  mlen     Number of allocated values provided for the attribute.
-    @Item  dp       Pointer location for returned floating point attribute value(s).
+   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+      fprintf(stderr," QU2REG :");
+      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+      *kret = 1;
+      goto L900;
+   }
 
- at Description
-The function @func{vlistInqAttFlt} gets the values(s) of a floating point attribute.
+/* Set array indices to 0. */
 
- at EndFunction
-*/
-int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
-{
-  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, (size_t)mlen * sizeof (double), dp);
-}
+   ilii = 0;
+   ilio = 0;
 
-/*
- at Function  vlistInqAttTxt
- at Title     Get the value(s) of a text attribute
+/* Establish values of loop parameters. */
 
- at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
-    @Item  name     Attribute name.
-    @Item  mlen     Number of allocated values provided for the attribute.
-    @Item  tp       Pointer location for returned text attribute value(s).
+   if (kcode > 10) {
 
- at Description
-The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
+/*    Quasi-regular along longitude lines. */
 
- at EndFunction
-*/
-int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
-{
-  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, (size_t)mlen * sizeof (char), tp);
-}
+      iquano = klon;
+      iregno = klat;
+      icode = kcode - 10;
+   } else {
 
-enum {
-  vlist_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
-};
+/*    Quasi-regular along latitude lines. */
 
-static inline int
-vlistAttTypeLookup(cdi_att_t *attp)
-{
-  int type;
-  switch (attp->indtype)
-  {
-  case DATATYPE_FLT:
-    type = DATATYPE_FLT64;
-    break;
-  case DATATYPE_INT:
-  case DATATYPE_TXT:
-    type = attp->indtype;
-    break;
-  default:
-    xabort("Unknown datatype encountered in attribute %s: %d\n",
-            attp->name, attp->indtype);
-  }
-  return type;
-}
+      iquano = klat;
+      iregno = klon;
+      icode = kcode;
+   }
 
+/*     -------------------------------------------------------- */
+/**    Section 2. Interpolate field from quasi to regular grid. */
+/*     -------------------------------------------------------- */
 
-int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB,
-                      int attnum)
-{
-  cdi_atts_t *attspa = get_attsp(a, varIDA),
-    *attspb = get_attsp(b, varIDB);
-  if (attspa == NULL && attspb == NULL)
-    return 0;
-  xassert(attnum >= 0 && attnum < (int)attspa->nelems
-          && attnum < (int)attspb->nelems);
-  cdi_att_t *attpa = attspa->value + attnum,
-    *attpb = attspb->value + attnum;
-  size_t len;
-  if ((len = attpa->namesz) != attpb->namesz)
-    return 1;
-  int diff;
-  if ((diff = memcmp(attpa->name, attpb->name, len)))
-    return 1;
-  if (attpa->indtype != attpb->indtype
-      || attpa->exdtype != attpb->exdtype
-      || attpa->nelems != attpb->nelems)
-    return 1;
-  return memcmp(attpa->xvalue, attpb->xvalue, attpa->xsz);
-}
+   i_1 = iquano;
+   for (j230 = 1; j230 <= i_1; ++j230) {
 
+      if (iregno != kpoint[j230]) {
 
-static int
-vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
-{
-  cdi_atts_t *attsp;
-  cdi_att_t *attp;
+/*       Line contains less values than required,so */
+/*       extract quasi-regular grid values for a line */
 
-  xassert(attsp = get_attsp(vlistptr, varID));
-  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
-  attp = &(attsp->value[attnum]);
-  int txsize = serializeGetSize(vlist_att_nints, DATATYPE_INT, context)
-    + serializeGetSize((int)attp->namesz, DATATYPE_TXT, context);
-  txsize += serializeGetSize((int)attp->nelems, vlistAttTypeLookup(attp), context);
-  return txsize;
-}
+         i_2 = kpoint[j230];
+         for (j210 = 1; j210 <= i_2; ++j210) {
+            ++ilii;
+            zline[j210 - 1] = pfield[ilii];
+         }
 
-int
-vlistAttsGetSize(vlist_t *p, int varID, void *context)
-{
-  cdi_atts_t *attsp = get_attsp(p, varID);
-  int txsize = serializeGetSize(1, DATATYPE_INT, context);
-  size_t numAtts = attsp->nelems;
-  for (size_t i = 0; i < numAtts; ++i)
-    txsize += vlistAttGetSize(p, varID, (int)i, context);
-  return txsize;
-}
+/*       and interpolate this line. */
 
-static void
-vlistAttPack(vlist_t *vlistptr, int varID, int attnum,
-             void * buf, int size, int *position, void *context)
-{
-  cdi_atts_t *attsp;
-  cdi_att_t *attp;
-  int tempbuf[vlist_att_nints];
+         TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
+         if (*kret != 0) goto L900;
 
-  xassert(attsp = get_attsp(vlistptr, varID));
-  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
-  attp = &(attsp->value[attnum]);
-  tempbuf[0] = (int)attp->namesz;
-  tempbuf[1] = attp->exdtype;
-  tempbuf[2] = attp->indtype;
-  tempbuf[3] = (int)attp->nelems;
-  serializePack(tempbuf, vlist_att_nints, DATATYPE_INT, buf, size, position, context);
-  serializePack(attp->name, (int)attp->namesz, DATATYPE_TXT, buf, size, position, context);
-  serializePack(attp->xvalue, (int)attp->nelems, vlistAttTypeLookup(attp),
-                buf, size, position, context);
-}
+/*       Add regular grid values for this line to the
+         temporary array. */
 
-void
-vlistAttsPack(vlist_t *p, int varID,
-              void * buf, int size, int *position, void *context)
-{
-  cdi_atts_t *attsp = get_attsp(p, varID);
-  size_t numAtts = attsp->nelems;
-  int numAttsI = (int)numAtts;
-  xassert(numAtts <= INT_MAX);
-  serializePack(&numAttsI, 1, DATATYPE_INT, buf, size, position, context);
-  for (size_t i = 0; i < numAtts; ++i)
-    vlistAttPack(p, varID, (int)i, buf, size, position, context);
-}
+         i_2 = iregno;
+         for (j220 = 1; j220 <= i_2; ++j220) {
+            ++ilio;
+            ztemp[ilio - 1] = zline[j220 - 1];
+         }
 
-static void
-vlistAttUnpack(int vlistID, int varID,
-               void * buf, int size, int *position, void *context)
-{
-  int tempbuf[vlist_att_nints];
+      } else {
 
-  serializeUnpack(buf, size, position,
-                  tempbuf, vlist_att_nints, DATATYPE_INT, context);
-  char *attName = (char *)xmalloc((size_t)tempbuf[0] + 1);
-  serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
-  attName[tempbuf[0]] = '\0';
-  int attVDt;
-  size_t elemSize;
-  switch (tempbuf[2])
-  {
-  case DATATYPE_FLT:
-    attVDt = DATATYPE_FLT64;
-    elemSize = sizeof(double);
-    break;
-  case DATATYPE_INT:
-    attVDt = DATATYPE_INT;
-    elemSize = sizeof(int);
-    break;
-  case DATATYPE_TXT:
-    attVDt = DATATYPE_TXT;
-    elemSize = 1;
-    break;
-  default:
-    xabort("Unknown datatype encountered in attribute %s: %d\n",
-           attName, tempbuf[2]);
-  }
-  void *attData = (void *)xmalloc(elemSize * (size_t)tempbuf[3]);
-  serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
-  vlist_def_att(tempbuf[2], tempbuf[1], vlistID, varID, attName,
-                (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
-  free(attName);
-  free(attData);
-}
+/*       Line contains the required number of values, so add */
+/*       this line to the temporary array. */
 
-void
-vlistAttsUnpack(int vlistID, int varID,
-                void * buf, int size, int *position, void *context)
-{
-  int numAtts, i;
-  serializeUnpack(buf, size, position, &numAtts, 1, DATATYPE_INT, context);
-  for (i = 0; i < numAtts; ++i)
-  {
-    vlistAttUnpack(vlistID, varID, buf, size, position, context);
-  }
-}
+         i_2 = iregno;
+         for (j225 = 1; j225 <= i_2; ++j225) {
+            ++ilio;
+            ++ilii;
+            ztemp[ilio - 1] = pfield[ilii];
+         }
+      }
+   }
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+/* Copy temporary array to user array. */
 
-#include <limits.h>
+   i_1 = klon * klat;
+   for (j240 = 1; j240 <= i_1; ++j240) {
+      pfield[j240] = ztemp[j240 - 1];
+   }
 
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
 
-static
-void vlistvarInitEntry(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+L900:
 
-  vlistptr->vars[varID].fvarID        = varID;
-  vlistptr->vars[varID].mvarID        = varID;
-  vlistptr->vars[varID].flag          = 0;
-  vlistptr->vars[varID].param         = 0;
-  vlistptr->vars[varID].datatype      = CDI_UNDEFID;
-  vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
-  vlistptr->vars[varID].timave        = 0;
-  vlistptr->vars[varID].timaccu       = 0;
-  vlistptr->vars[varID].typeOfGeneratingProcess   = 0;
-  vlistptr->vars[varID].productDefinitionTemplate = -1;
-  vlistptr->vars[varID].chunktype     = cdiChunkType;
-  vlistptr->vars[varID].xyz           = 321;
-  vlistptr->vars[varID].gridID        = CDI_UNDEFID;
-  vlistptr->vars[varID].zaxisID       = CDI_UNDEFID;
-  vlistptr->vars[varID].instID        = CDI_UNDEFID;
-  vlistptr->vars[varID].modelID       = CDI_UNDEFID;
-  vlistptr->vars[varID].tableID       = CDI_UNDEFID;
-  vlistptr->vars[varID].missvalused   = FALSE;
-  vlistptr->vars[varID].missval       = cdiDefaultMissval;
-  vlistptr->vars[varID].addoffset     = 0.0;
-  vlistptr->vars[varID].scalefactor   = 1.0;
-  vlistptr->vars[varID].name          = NULL;
-  vlistptr->vars[varID].longname      = NULL;
-  vlistptr->vars[varID].stdname       = NULL;
-  vlistptr->vars[varID].units         = NULL;
-  vlistptr->vars[varID].extra         = NULL;
-  vlistptr->vars[varID].levinfo       = NULL;
-  vlistptr->vars[varID].comptype      = COMPRESS_NONE;
-  vlistptr->vars[varID].complevel     = 1;
-  vlistptr->vars[varID].atts.nalloc   = MAX_ATTRIBUTES;
-  vlistptr->vars[varID].atts.nelems   = 0;
-  vlistptr->vars[varID].lvalidrange   = 0;
-  vlistptr->vars[varID].validrange[0] = VALIDMISS;
-  vlistptr->vars[varID].validrange[1] = VALIDMISS;
-  vlistptr->vars[varID].ensdata       = NULL;
-  vlistptr->vars[varID].iorank        = CDI_UNDEFID;
+   free(zwork);
+   free(zline);
+   free(ztemp);
 
-#if  defined  (HAVE_LIBGRIB_API)
-  /* ---------------------------------- */
-  /* Local change: 2013-01-28, FP (DWD) */
-  /* ---------------------------------- */
+   return 0;
+} /* qu2reg3 */
 
-  vlistptr->vars[varID].opt_grib_dbl_nentries = 0;
-  vlistptr->vars[varID].opt_grib_int_nentries = 0;
-  int i;
-  for (i=0; i<MAX_OPT_GRIB_ENTRIES; i++) {
-    vlistptr->vars[varID].opt_grib_int_val[i] =   0;
-    vlistptr->vars[varID].opt_grib_dbl_val[i] = 0.0;
-    vlistptr->vars[varID].opt_grib_int_update[i] = FALSE;
-    vlistptr->vars[varID].opt_grib_dbl_update[i] = FALSE;
-    vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
-    vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
-  } // for
+#endif /* T */
+
+#ifdef T
+#undef T
 #endif
-}
+#define T float
+#ifdef T
 
-static
-int vlistvarNewEntry(int vlistID)
+void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
 {
-  int varID = 0;
-  int vlistvarSize;
-  var_t *vlistvar;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  double power;
+  double *scale = (double*) malloc((trunc+1)*sizeof(double));
+  int  n, m;
+  int  index;
 
-  vlistvarSize = vlistptr->varsAllocated;
-  vlistvar     = vlistptr->vars;
-  /*
-    Look for a free slot in vlistvar.
-    (Create the table the first time through).
-  */
-  if ( ! vlistvarSize )
+  if ( scale == NULL ) SysError("No Memory!");
+
+  if ( pcScale < -10000 || pcScale > 10000 )
     {
-      vlistvarSize = 2;
-      vlistvar = (var_t *)xmalloc((size_t)vlistvarSize * sizeof (var_t));
-      for (int i = 0; i < vlistvarSize; i++ )
-	vlistvar[i].isUsed = FALSE;
-    }
-  else
+      fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
+      return;
+   }
+
+  /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
+
+  if ( pcScale == 0 ) return;
+
+  power = (double) pcScale / 1000.;
+  scale[0] = 1.0;
+
+  for ( n = 1; n <= trunc; n++ )
     {
-      while (varID < vlistvarSize && vlistvar[varID].isUsed)
-        ++varID;
+      if (pcScale != 1000)
+         scale[n] = pow((double) (n*(n+1)), power);
+      else
+         scale[n] =     (double) (n*(n+1));
     }
-  /*
-    If the table overflows, double its size.
-  */
-  if ( varID == vlistvarSize )
-    {
-      int i;
 
-      vlistvarSize = 2*vlistvarSize;
-      vlistvar = (var_t *)xrealloc(vlistvar,
-                                   (size_t)vlistvarSize * sizeof(var_t));
-      varID = vlistvarSize/2;
+  if ( inv )
+    for ( n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
 
-      for ( i = varID; i < vlistvarSize; i++ )
-	vlistvar[i].isUsed = FALSE;
-    }
+  /* Scale the values */
 
-  vlistptr->varsAllocated = vlistvarSize;
-  vlistptr->vars          = vlistvar;
+  index = 0;
 
-  vlistvarInitEntry(vlistID, varID);
+  for ( m = 0;   m < pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n >= pcStart )
+	  {
+	    fpdata[index  ] *= scale[n];
+	    fpdata[index+1] *= scale[n];
+	  }
+	index += 2;
+      }
 
-  vlistptr->vars[varID].isUsed = TRUE;
+  for ( m = pcStart; m <= trunc; m++ )
+    for ( n = m;     n <= trunc; n++ )
+      {
+	fpdata[index  ] *= scale[n];
+	fpdata[index+1] *= scale[n];
+	index += 2;
+      }
 
-  return (varID);
+  free(scale);
 }
 
-static
-void vlistCheckVarID(const char *caller, int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr == NULL )
-    Errorc("vlist undefined!");
+void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+{
+  T *fphelp = (T*) malloc(nsp*sizeof(T));
+  int  m, n;
+  int  index, inext;
 
-  if ( varID < 0 || varID >= vlistptr->nvars )
-    Errorc("varID %d undefined!", varID);
+  if ( fphelp == NULL ) SysError("No Memory!");
 
-  if ( ! vlistptr->vars[varID].isUsed )
-    Errorc("varID %d undefined!", varID);
-}
+  index = inext = 0;
 
-/*
- at Function  vlistDefVar
- at Title     Define a Variable
+  for ( m = 0;   m <= pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( pcStart >= n )
+	  {
+	    fphelp[index  ] = fpdata[inext++];
+	    fphelp[index+1] = fpdata[inext++];
+	  }
+	index += 2;
+      }
 
- at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
- at Parameter
-    @Item  vlistID   Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  zaxisID   Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  tsteptype One of the set of predefined CDI timestep types.
-                     The valid CDI timestep types are @func{TSTEP_CONSTANT} and @func{TSTEP_INSTANT}.
+  index = 0;
+  for ( m = 0;   m <= trunc; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n > pcStart )
+	  {
+	    fphelp[index  ] = fpdata[inext++];
+	    fphelp[index+1] = fpdata[inext++];
+	  }
+	index += 2;
+      }
 
- at Description
-The function @func{vlistDefVar} adds a new variable to vlistID.
+  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
 
- at Result
- at func{vlistDefVar} returns an identifier to the new variable.
+  free(fphelp);
+}
 
- at Example
-Here is an example using @func{vlistCreate} to create a variable list
-and add a variable with @func{vlistDefVar}.
 
- at Source
-   ...
-int vlistID, varID;
-   ...
-vlistID = vlistCreate();
-varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_INSTANT);
-   ...
-streamDefVlist(streamID, vlistID);
-   ...
-vlistDestroy(vlistID);
-   ...
- at EndSource
- at EndFunction
-*/
-int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+void TEMPLATE(gather_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if ( CDI_Debug )
-    Message("gridID = %d  zaxisID = %d  tsteptype = %d", gridID, zaxisID, tsteptype);
+  T *fphelp = (T*) malloc(nsp*sizeof(T));
+  int  m, n;
+  int  index, inext;
 
-  int varID = vlistvarNewEntry(vlistID);
+  if ( fphelp == NULL ) SysError("No Memory!");
 
-  vlistptr->nvars++;
+  index = inext = 0;
 
-  vlistptr->vars[varID].gridID  = gridID;
-  vlistptr->vars[varID].zaxisID = zaxisID;
-  vlistptr->vars[varID].tsteptype = tsteptype;
+  for ( m = 0;   m <= pcStart; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( pcStart >= n )
+	  {
+	    fphelp[inext++] = fpdata[index];
+	    fphelp[inext++] = fpdata[index+1];
+	  }
+	index += 2;
+      }
 
-  if ( tsteptype < 0 )
-    {
-      Message("Unexpected tstep type %d, set to TSTEP_INSTANT!", tsteptype);
-      vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
-    }
+  index = 0;
+  for ( m = 0;   m <= trunc; m++ )
+    for ( n = m; n <= trunc; n++ )
+      {
+	if ( n > pcStart )
+	  {
+	    fphelp[inext++] = fpdata[index];
+	    fphelp[inext++] = fpdata[index+1];
+	  }
+	index += 2;
+      }
 
-  vlistAdd2GridIDs(vlistptr, gridID);
-  vlistAdd2ZaxisIDs(vlistptr, zaxisID);
+  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
 
-  vlistptr->vars[varID].param = cdiEncodeParam(-(varID + 1), 255, 255);
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-  return (varID);
+  free(fphelp);
 }
 
-void
-cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID)
+
+void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
 {
-  xassert(varID >= 0 && varID < vlistptr->nvars
-          && vlistptr->vars[varID].levinfo == NULL);
-  int zaxisID = vlistptr->vars[varID].zaxisID;
-  size_t nlevs = (size_t)zaxisInqSize(zaxisID);
+  /* System generated locals */
+  double r_1;
 
-  vlistptr->vars[varID].levinfo
-    = (levinfo_t*)xmalloc((size_t)nlevs * sizeof(levinfo_t));
+  /* Local variables */
+  int jl;
+  double zfac, zeps, zbeta;
+  double zalpha;
 
-  for (size_t levID = 0; levID < nlevs; levID++ )
-    vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO((int)levID);
-}
+  /* **** SCM0   - Apply SCM0 limiter to derivative estimates. */
+  /* output: */
+  /*   pdl   = the limited derivative at the left edge of the interval */
+  /*   pdr   = the limited derivative at the right edge of the interval */
+  /* inputs */
+  /*   pdl   = the original derivative at the left edge */
+  /*   pdr   = the original derivative at the right edge */
+  /*   pfl   = function value at the left edge of the interval */
+  /*   pfr   = function value at the right edge of the interval */
+  /*   klg   = number of intervals where the derivatives are limited */
 
-/*
- at Function  vlistDefVarParam
- at Title     Define the parameter number of a Variable
+  /*  define constants */
 
- at Prototype void vlistDefVarParam(int vlistID, int varID, int param)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  param    Parameter number.
+  zeps = 1.0e-12;
+  zfac = (1.0 - zeps) * 3.0;
 
- at Description
-The function @func{vlistDefVarParam} defines the parameter number of a variable.
+  for ( jl = 0; jl < klg; ++jl )
+    {
+      if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
+	{
+	  zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
+	  zbeta  = pdr[jl] / (pfr[jl] - pfl[jl]);
+	  if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
+	  if ( zbeta  <= 0.0 ) pdr[jl] = 0.0;
+	  if ( zalpha > zfac ) pdl[jl] = zfac * (pfr[jl] - pfl[jl]);
+	  if ( zbeta  > zfac ) pdr[jl] = zfac * (pfr[jl] - pfl[jl]);
+	}
+      else
+	{
+	  pdl[jl] = 0.0;
+	  pdr[jl] = 0.0;
+	}
+    }
+} /* scm0 */
 
- at EndFunction
-*/
-void vlistDefVarParam(int vlistID, int varID, int param)
+static
+int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
+			int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /*
+C---->
+C**** ROWINA3 - Interpolation of row of values.
+C
+C     Purpose.
+C     --------
+C
+C     Interpolate a row of values.
+C
+C
+C**   Interface.
+C     ----------
+C
+C     CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
+C
+C
+C     Input Parameters.
+C     -----------------
+C
+C     P      - Row of values to be interpolated.
+C              Dimension must be at least KO.
+C
+C     KO     - Number of values required.
+C
+C     KI     - Number of values in P on input.
+C
+C     PW     - Working array.
+C              Dimension must be at least (0:KO+2,3).
+C
+C     KCODE  - Interpolation required.
+C              1 , linear.
+C              3 , cubic.
+C
+C     PMSVAL - Value used for missing data indicator.
+C
+C     OMISNG - True if missing values are present in field.
+C
+C     OPERIO - True if input field is periodic.
+C
+C     OVEGGY - True if 'nearest neighbour' processing must be used
+C              for interpolation
+C
+C     Output Parameters.
+C     ------------------
+C
+C     P     - Now contains KO values.
+C     KRET  - Return code
+C             0, OK
+C             Non-zero, error
+C
+C
+C     Method.
+C     -------
+C
+C     Linear or cubic interpolation performed as required.
+C
+C     Comments.
+C     ---------
+C
+C     This is a version of ROWINA which allows for missing data
+C     values and hence for bitmapped fields.
+C
+C
+C     Author.
+C     -------
+C
+C     J.D.Chambers    ECMWF     22.07.94
+C
+C
+C     Modifications.
+C     --------------
+C
+C     J.D.Chambers    ECMWF     13.09.94
+C     Add return code KRET and remove calls to ABORT.
+C
+C     J. Clochard, Meteo France, for ECMWF - January 1998.
+C     Addition of OMISNG and OPERIO arguments.
+C
+C
+C     -----------------------------------------------------------------
+*/
+  /* System generated locals */
+  int pw_dim1, pw_offset, i_1;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  /* Local variables */
+  int jl, ip;
+  double zwt1, zrdi, zpos;
+  double zdo, zwt;
 
-  if (vlistptr->vars[varID].param != param)
+  UNUSED(omisng);
+
+  /* Parameter adjustments */
+  --p;
+  pw_dim1 = ko + 3;
+  pw_offset = pw_dim1;
+  pw -= pw_offset;
+
+  *kret = 0;
+
+  if ( kcode == 1 )
     {
-      vlistptr->vars[varID].param = param;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+      /*    Move input values to work array */
+      for ( jl = 1; jl <= ki; ++jl )
+	pw[jl + pw_dim1] = p[jl];
 
-/*
- at Function  vlistDefVarCode
- at Title     Define the code number of a Variable
+      if ( operio )
+	{
+	  /* Arrange wrap-around value in work array */
+	  pw[ki + 1 + pw_dim1] = p[1];
 
- at Prototype void vlistDefVarCode(int vlistID, int varID, int code)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  code     Code number.
+	  /* Set up constants to be used to figure out weighting for */
+	  /* values in interpolation. */
+	  zrdi = (double) ki;
+	  zdo = 1.0 / (double) ko;
+	}
+      else
+	{
+	  /* Repeat last value, to cope with "implicit truncation" below */
+	  pw[ki + 1 + pw_dim1] = p[ki];
 
- at Description
-The function @func{vlistDefVarCode} defines the code number of a variable.
+	  /* Set up constants to be used to figure out weighting for */
+	  /* values in interpolation. */
+	  zrdi = (double) (ki-1);
+	  zdo = 1.0 / (double) (ko-1);
+ 	}
 
- at EndFunction
-*/
-void vlistDefVarCode(int vlistID, int varID, int code)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      /*    Loop through the output points */
+      for ( jl = 1; jl <= ko; ++jl )
+	{
 
-  vlistCheckVarID(__func__, vlistID, varID);
+	  /* Calculate weight from the start of row */
+	  zpos = (jl - 1) * zdo;
+	  zwt = zpos * zrdi;
 
-  int param = vlistptr->vars[varID].param;
-  int pnum, pcat, pdis;
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  int newParam = cdiEncodeParam(code, pcat, pdis);
-  if (vlistptr->vars[varID].param != newParam)
-    {
-      vlistptr->vars[varID].param = newParam;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+	  /* Get the current array position(minus 1) from the weight - */
+	  /* note the implicit truncation. */
+	  ip = (int) zwt;
+		  
+	  /* Adjust the weight to range (0.0 to 1.0) */
+	  zwt -= ip;
+
+          /* If 'nearest neighbour' processing must be used */
+	  if ( oveggy )
+	    {
+              if ( zwt < 0.5 )
+                p[jl] = pw[ip + 1 + pw_dim1];
+	      else
+		p[jl] = pw[ip + 2 + pw_dim1];
+	    }
+	  else
+	    {
+	      /*    If the left value is missing, use the right value */
+	      if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
+		{
+		  p[jl] = pw[ip + 2 + pw_dim1];
+		}
+	      /*    If the right value is missing, use the left value */
+	      else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
+		{
+		  p[jl] = pw[ip + 1 + pw_dim1];
+		}
+	      /*    If neither missing, interpolate ... */
+	      else
+		{
+		  /*  Interpolate using the weighted values on either side */
+		  /*  of the output point position */
+		  p[jl] = (1.0 - zwt) * pw[ip+1 + pw_dim1] +
+		                  zwt * pw[ip+2 + pw_dim1];
+		}
+	    }
+	}
     }
-}
+  else if ( kcode == 3 )
+    {
+      /*     *******************************    */
+      /*     Section 2.  Cubic interpolation .. */
+      /*     *******************************    */
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          if ( IS_EQUAL(p[jl], msval) )
+	    {
+	      fprintf(stderr," ROWINA3: ");
+	      fprintf(stderr," Cubic interpolation not supported");
+	      fprintf(stderr," for fields containing missing data.\n");
+	      *kret = 1;
+	      goto L900;
+	    }
+          pw[jl + pw_dim1] = p[jl];
+	}
+      pw[pw_dim1] = p[ki];
+      pw[ki + 1 + pw_dim1] = p[1];
+      pw[ki + 2 + pw_dim1] = p[2];
+      i_1 = ki;
+      for ( jl = 1; jl <= i_1; ++jl )
+	{
+          pw[jl + (pw_dim1 << 1)] =
+	        - pw[jl - 1 + pw_dim1] / 3.0 -
+	          pw[jl     + pw_dim1] * 0.5 +
+	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
+          pw[jl + 1 + pw_dim1 * 3] =
+                  pw[jl - 1 + pw_dim1] / 6.0 -
+                  pw[jl     + pw_dim1] +
+                  pw[jl + 1 + pw_dim1] * 0.5 +
+                  pw[jl + 2 + pw_dim1] / 3.0;
+	}
 
+      TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
+		       &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
 
-void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      zrdi = (double) ki;
+      zdo = 1.0 / (double) ko;
+      for ( jl = 1; jl <= ko; ++jl )
+	{
+          zpos = (jl - 1) * zdo;
+          zwt = zpos * zrdi;
+          ip = (int) zwt + 1;
+          zwt = zwt + 1.0 - ip;
+          zwt1 = 1.0 - zwt;
+          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
+                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
+                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
+                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
+	}
 
-  vlistCheckVarID(__func__, vlistID, varID);
+    }
+  else
+    {
+      /*    **************************************    */
+      /*    Section 3.  Invalid interpolation code .. */
+      /*    **************************************    */
+      fprintf(stderr," ROWINA3:");
+      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
+      *kret = 2;
+    }
 
-  *gridID    = vlistptr->vars[varID].gridID;
-  *zaxisID   = vlistptr->vars[varID].zaxisID;
-  *tsteptype = vlistptr->vars[varID].tsteptype;
+L900:
+    return 0;
+} /* rowina3 */
 
-  return;
-}
 
-/*
- at Function  vlistInqVarGrid
- at Title     Get the Grid ID of a Variable
+int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
+			T msval, int *kret, int omisng, int operio, int oveggy)
+{
+  /*
+C**** QU2REG3 - Convert quasi-regular grid data to regular.
+C
+C     Purpose.
+C     --------
+C
+C     Convert quasi-regular grid data to regular,
+C     using either a linear or cubic interpolation.
+C
+C
+C**   Interface.
+C     ----------
+C
+C     CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
+C    X            OVEGGY)
+C
+C
+C     Input Parameters.
+C     -----------------
+C
+C     PFIELD     - Array containing quasi-regular grid data.
+C
+C     KPOINT     - Array containing list of the number of
+C                  points on each latitude (or longitude) of
+C                  the quasi-regular grid.
+C
+C     KLAT       - Number of latitude lines
+C
+C     KLON       - Number of longitude lines
+C
+C     KCODE      - Interpolation required.
+C                  1 , linear - data quasi-regular on latitude lines.
+C                  3 , cubic -  data quasi-regular on latitude lines.
+C                  11, linear - data quasi-regular on longitude lines.
+C                  13, cubic -  data quasi-regular on longitude lines.
+C
+C     PMSVAL     - Value used for missing data indicator.
+C
+C     OMISNG     - True if missing values are present in field.
+C
+C     OPERIO     - True if input field is periodic.
+C
+C     OVEGGY     - True if 'nearest neighbour' processing must be used
+C                  for interpolation
+C
+C
+C     Output Parameters.
+C     ------------------
+C
+C     KRET       - return code
+C                  0 = OK
+C                  non-zero indicates fatal error
+C
+C
+C     Output Parameters.
+C     ------------------
+C
+C     PFIELD     - Array containing regular grid data.
+C
+C
+C     Method.
+C     -------
+C
+C     Data is interpolated and expanded into a temporary array,
+C     which is then copied back into the user's array.
+C     Returns an error code if an invalid interpolation is requested
+C     or field size exceeds array dimensions.
+C
+C     Comments.
+C     ---------
+C
+C     This routine is an adaptation of QU2REG to allow missing data
+C     values, and hence bit mapped fields.
+C
+C
+C     Author.
+C     -------
+C
+C     J.D.Chambers     ECMWF      22.07.94
+C
+C
+C     Modifications.
+C     --------------
+C
+C     J.D.Chambers     ECMWF      13.09.94
+C     Add return code KRET and remove calls to ABORT.
+C
+C     J.D.Chambers     ECMWF        Feb 1997
+C     Allow for 64-bit pointers
+C
+C     J. Clochard, Meteo France, for ECMWF - January 1998.
+C     Addition of OMISNG and OPERIO arguments.
+C     Fix message for longitude number out of bounds, and routine
+C     name in title and formats.
+C
+*/
+   /* System generated locals */
+   int i_1, i_2;
+   int kcode = 1;
 
- at Prototype int vlistInqVarGrid(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
+   /* Local variables */
+   int ilii, ilio, icode;
+   int iregno, iquano, j210, j220, j230, j240, j225;
+   T *ztemp = NULL;
+   T *zline = NULL;
+   T *zwork = NULL;
 
- at Description
-The function @func{vlistInqVarGrid} returns the grid ID of a variable.
+   ztemp = (T*) malloc(klon*klat*sizeof(T));
+   if ( ztemp == NULL ) SysError("No Memory!");
 
- at Result
- at func{vlistInqVarGrid} returns the grid ID of the variable.
+   zline = (T*) malloc(2*klon*sizeof(T));
+   if ( zline == NULL ) SysError("No Memory!");
 
- at EndFunction
-*/
-int vlistInqVarGrid(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+   zwork = (T*) malloc(3*(2*klon+3)*sizeof(T));
+   if ( zwork == NULL ) SysError("No Memory!");
 
-  vlistCheckVarID(__func__, vlistID, varID);
+   /* Parameter adjustments */
+   --pfield;
+   --kpoint;
 
-  return (vlistptr->vars[varID].gridID);
-}
+/* ------------------------------ */
+/* Section 1. Set initial values. */
+/* ------------------------------ */
 
-/*
- at Function  vlistInqVarZaxis
- at Title     Get the Zaxis ID of a Variable
+   *kret = 0;
 
- at Prototype int vlistInqVarZaxis(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
+/* Check input parameters. */
 
- at Description
-The function @func{vlistInqVarZaxis} returns the zaxis ID of a variable.
+   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
+      fprintf(stderr," QU2REG :");
+      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
+      *kret = 1;
+      goto L900;
+   }
 
- at Result
- at func{vlistInqVarZaxis} returns the zaxis ID of the variable.
+/* Set array indices to 0. */
 
- at EndFunction
-*/
-int vlistInqVarZaxis(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+   ilii = 0;
+   ilio = 0;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+/* Establish values of loop parameters. */
 
-  return (vlistptr->vars[varID].zaxisID);
-}
+   if (kcode > 10) {
 
-/*
- at Function  vlistInqVarParam
- at Title     Get the parameter number of a Variable
+/*    Quasi-regular along longitude lines. */
 
- at Prototype int vlistInqVarParam(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
+      iquano = klon;
+      iregno = klat;
+      icode = kcode - 10;
+   } else {
 
- at Description
-The function @func{vlistInqVarParam} returns the parameter number of a variable.
+/*    Quasi-regular along latitude lines. */
 
- at Result
- at func{vlistInqVarParam} returns the parameter number of the variable.
+      iquano = klat;
+      iregno = klon;
+      icode = kcode;
+   }
 
- at EndFunction
-*/
-int vlistInqVarParam(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+/*     -------------------------------------------------------- */
+/**    Section 2. Interpolate field from quasi to regular grid. */
+/*     -------------------------------------------------------- */
 
-  vlistCheckVarID(__func__, vlistID, varID);
+   i_1 = iquano;
+   for (j230 = 1; j230 <= i_1; ++j230) {
 
-  return (vlistptr->vars[varID].param);
-}
+      if (iregno != kpoint[j230]) {
 
-/*
- at Function  vlistInqVarCode
- at Title     Get the Code number of a Variable
+/*       Line contains less values than required,so */
+/*       extract quasi-regular grid values for a line */
 
- at Prototype int vlistInqVarCode(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
+         i_2 = kpoint[j230];
+         for (j210 = 1; j210 <= i_2; ++j210) {
+            ++ilii;
+            zline[j210 - 1] = pfield[ilii];
+         }
 
- at Description
-The function @func{vlistInqVarCode} returns the code number of a variable.
+/*       and interpolate this line. */
 
- at Result
- at func{vlistInqVarCode} returns the code number of the variable.
+         TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
+         if (*kret != 0) goto L900;
 
- at EndFunction
-*/
-int vlistInqVarCode(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+/*       Add regular grid values for this line to the
+         temporary array. */
 
-  vlistCheckVarID(__func__, vlistID, varID);
+         i_2 = iregno;
+         for (j220 = 1; j220 <= i_2; ++j220) {
+            ++ilio;
+            ztemp[ilio - 1] = zline[j220 - 1];
+         }
 
-  int param = vlistptr->vars[varID].param;
-  int pdis, pcat, pnum;
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  int code = pdis == 255 ? pnum : -varID-1;
+      } else {
 
-  if ( code < 0 && vlistptr->vars[varID].tableID != -1 && vlistptr->vars[varID].name != NULL )
-    {
-      tableInqParCode(vlistptr->vars[varID].tableID, vlistptr->vars[varID].name, &code);
-    }
+/*       Line contains the required number of values, so add */
+/*       this line to the temporary array. */
 
-  return (code);
-}
+         i_2 = iregno;
+         for (j225 = 1; j225 <= i_2; ++j225) {
+            ++ilio;
+            ++ilii;
+            ztemp[ilio - 1] = pfield[ilii];
+         }
+      }
+   }
 
+/* Copy temporary array to user array. */
 
-const char *vlistInqVarNamePtr(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+   i_1 = klon * klat;
+   for (j240 = 1; j240 <= i_1; ++j240) {
+      pfield[j240] = ztemp[j240 - 1];
+   }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+/* -------------------------------------------------------- */
+/* Section 9. Return to calling routine. Format statements. */
+/* -------------------------------------------------------- */
 
-  return (vlistptr->vars[varID].name);
-}
+L900:
 
+   free(zwork);
+   free(zline);
+   free(ztemp);
 
-const char *vlistInqVarLongnamePtr(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+   return 0;
+} /* qu2reg3 */
 
-  vlistCheckVarID(__func__, vlistID, varID);
+#endif /* T */
+#include <string.h>
 
-  return (vlistptr->vars[varID].longname);
-}
 
 
-const char *vlistInqVarStdnamePtr(int vlistID, int varID)
+int gribVersion(unsigned char *is, size_t buffersize)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
+  if ( buffersize < 8 )
+    Error("Buffer too small (current size %d)!", (int) buffersize);
 
-  return (vlistptr->vars[varID].stdname);
+  return (GRIB_EDITION(is));
 }
 
-
-const char *vlistInqVarUnitsPtr(int vlistID, int varID)
+static 
+double GET_Real(unsigned char *grib)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int iexp, imant;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  iexp  = GET_UINT1(grib[0]);
+  imant = GET_UINT3(grib[1], grib[2], grib[3]);
 
-  return (vlistptr->vars[varID].units);
+  return (decfp2(iexp, imant));
 }
 
-/*
- at Function  vlistInqVarName
- at Title     Get the name of a Variable
-
- at Prototype void vlistInqVarName(int vlistID, int varID, char *name)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-    @Item  name     Returned variable name. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
-
- at Description
-The function @func{vlistInqVarName} returns the name of a variable.
-
- at Result
- at func{vlistInqVarName} returns the name of the variable to the parameter name if available,
-otherwise the result is an empty string.
-
- at EndFunction
-*/
-void vlistInqVarName(int vlistID, int varID, char *name)
+static 
+int decodeIS(unsigned char *is, int *isec0, int *iret)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
+  int isLen = 0;
+  int grib1offset;
+  int lgrib = FALSE, lbudg = FALSE, ltide = FALSE;
 
-  if ( vlistptr->vars[varID].name == NULL )
+  /*
+    Octets 1 - 4 : The letters G R I B.
+    Four 8 bit fields.
+  */
+  /*
+    Check letters -> GRIB, BUDG or TIDE.
+  */
+  /*
+    Check that 'GRIB' is found where expected.
+  */
+  if ( GRIB_START(is) ) lgrib = TRUE;
+  /*
+    ECMWF pseudo-grib data uses 'BUDG' and 'TIDE'.
+  */
+  if ( BUDG_START(is) ) lbudg = TRUE;
+  if ( TIDE_START(is) ) ltide = TRUE;
+  /*
+    Data is not GRIB or pseudo-grib.
+  */
+  if ( lgrib == FALSE && lbudg == FALSE && ltide == FALSE )
     {
-      int param = vlistptr->vars[varID].param;
-      int pdis, pcat, pnum;
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      if ( pdis == 255 )
-	{
-	  int code = pnum;
-	  int tableID = vlistptr->vars[varID].tableID;
-	  if ( tableInqParName(tableID, code, name) != 0 )
-	    sprintf(name, "var%d", code);
-	}
-      else
-	{
-	  sprintf(name, "param%d.%d.%d", pnum, pcat, pdis);
-	}
+      *iret = 305;
+      gprintf(__func__, "Input data is not GRIB or pseudo-grib.");
+      gprintf(__func__, "Return code = %d", *iret);
     }
-  else
-    strcpy(name, vlistptr->vars[varID].name);
-
-  return;
-}
-
-/*
- at Function  vlistInqVarLongname
- at Title     Get the longname of a Variable
-
- at Prototype void vlistInqVarLongname(int vlistID, int varID, char *longname)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-    @Item  longname Long name of the variable. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
-
- at Description
-The function @func{vlistInqVarLongname} returns the longname of a variable if available,
-otherwise the result is an empty string.
-
- at Result
- at func{vlistInqVaeLongname} returns the longname of the variable to the parameter longname.
-
- at EndFunction
-*/
-void vlistInqVarLongname(int vlistID, int varID, char *longname)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  longname[0] = '\0';
-
-  if ( vlistptr->vars[varID].longname == NULL )
+  if ( lbudg == TRUE || ltide == TRUE )
     {
-      int param = vlistptr->vars[varID].param;
-      int pdis, pcat, pnum;
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      if ( pdis == 255 )
-	{
-	  int code = pnum;
-          int tableID = vlistptr->vars[varID].tableID;
-	  if ( tableInqParLongname(tableID, code, longname) != 0 )
-	    longname[0] = '\0';
-	}
+      *iret = 305;
+      gprintf(__func__, "Pseudo-grib data unsupported.");
+      gprintf(__func__, "Return code = %d", *iret);
     }
-  else
-    strcpy(longname, vlistptr->vars[varID].longname);
 
-  return;
-}
+  /*
+    Octets 5 - 7 : Length of message.
+    One 24 bit field.
+  */
+  ISEC0_GRIB_Len = GRIB1_SECLEN(is);
+  /*
+    Octet 8 : GRIB Edition Number.
+    One 8 bit field.
+  */
+  ISEC0_GRIB_Version = GRIB_EDITION(is);
 
-/*
- at Function  vlistInqVarStdname
- at Title     Get the standard name of a Variable
+  if ( ISEC0_GRIB_Version > 1 )
+    Error("GRIB version %d unsupported!", ISEC0_GRIB_Version);
 
- at Prototype void vlistInqVarStdname(int vlistID, int varID, char *stdname)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-    @Item  stdname  Standard name of the variable. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  grib1offset = ISEC0_GRIB_Version * 4;
 
- at Description
-The function @func{vlistInqVarStdname} returns the standard name of a variable if available,
-otherwise the result is an empty string.
+  isLen = 4 + grib1offset;
 
- at Result
- at func{vlistInqVarName} returns the standard name of the variable to the parameter stdname.
+  return (isLen);
+}
+
+static 
+void decodePDS_ECMWF_local_Extension_1(unsigned char *pds, int *isec1)
+{
+  isec1[36] = GET_UINT1(pds[40]);         /* extension identifier       */
+  isec1[37] = GET_UINT1(pds[41]);         /* Class                      */
+  isec1[38] = GET_UINT1(pds[42]);         /* Type                       */
+  isec1[39] = GET_UINT2(pds[43],pds[44]); /* Stream                     */
+  /* isec1[40] = GET_UINT4(pds[45],pds[46],pds[47],pds[48]); */
+  memcpy((char*) &isec1[40], &pds[45], 4);
+  isec1[41] = GET_UINT1(pds[49]);         /* Forecast number            */
+  isec1[42] = GET_UINT1(pds[50]);         /* Total number of forecasts  */
+}
 
- at EndFunction
-*/
-void vlistInqVarStdname(int vlistID, int varID, char *stdname)
+static 
+void decodePDS_DWD_local_Extension_254(unsigned char *pds, int *isec1)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  long i;
+  int isvn;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+  for ( i = 0; i < 11; i++ ) 
+    { 
+      isec1[37+i] =  GET_UINT1(pds[41+i]);
+    } 
 
-  if ( vlistptr->vars[varID].stdname == NULL )
-    {
-      stdname[0] = '\0';
-    }
-  else
-    strcpy(stdname, vlistptr->vars[varID].stdname);
+  isvn = GET_UINT2(pds[52],pds[53]);
+  
+  isec1[48] =  isvn % 0x8000;              /* DWD experiment identifier            */
+  isec1[49] =  isvn >> 15;                 /* DWD run type (0=main, 2=ass, 3=test) */
 
-  return;
 }
 
-/*
- at Function  vlistInqVarUnits
- at Title     Get the units of a Variable
+static 
+void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
+{
+  long i;
+  int isvn;
 
- at Prototype void vlistInqVarUnits(int vlistID, int varID, char *units)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-    @Item  units    Units of the variable. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
+  for ( i = 0; i < 11; i++ ) 
+    { 
+      isec1[37+i] =  GET_UINT1(pds[41+i]);
+    } 
 
- at Description
-The function @func{vlistInqVarUnits} returns the units of a variable if available,
-otherwise the result is an empty string.
+  isvn = GET_UINT2(pds[52],pds[53]);
+  
+  isec1[48] =  isvn % 0x8000;              /* DWD experiment identifier            */
+  isec1[49] =  isvn >> 15;                 /* DWD run type (0=main, 2=ass, 3=test) */
+  isec1[50] =  GET_UINT1(pds[54]);         /* User id, specified by table          */
+  isec1[51] =  GET_UINT2(pds[55],pds[56]); /* Experiment identifier                */
+  isec1[52] =  GET_UINT2(pds[57],pds[58]); /* Ensemble identification by table     */
+  isec1[53] =  GET_UINT2(pds[59],pds[60]); /* Number of ensemble members           */
+  isec1[54] =  GET_UINT2(pds[61],pds[62]); /* Actual number of ensemble member     */
+  isec1[55] =  GET_UINT1(pds[63]);         /* Model major version number           */
+  isec1[56] =  GET_UINT1(pds[64]);         /* Model minor version number           */
 
- at Result
- at func{vlistInqVarUnits} returns the units of the variable to the parameter units.
+}
 
- at EndFunction
-*/
-void vlistInqVarUnits(int vlistID, int varID, char *units)
+static 
+void decodePDS_MPIM_local_Extension_1(unsigned char *pds, int *isec1)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  isec1[36] = GET_UINT1(pds[40]);         /* extension identifier            */
+  isec1[37] = GET_UINT1(pds[41]);         /* type of ensemble forecast       */
+  isec1[38] = GET_UINT2(pds[42],pds[43]); /* individual ensemble member      */
+  isec1[39] = GET_UINT2(pds[44],pds[45]); /* number of forecasts in ensemble */
+}
 
-  vlistCheckVarID(__func__, vlistID, varID);
+static 
+int decodePDS(unsigned char *pds, int *isec0, int *isec1)
+{
+  int pdsLen;
 
-  units[0] = '\0';
+  pdsLen = PDS_Len;
 
-  if ( vlistptr->vars[varID].units == NULL )
+  ISEC1_CodeTable      = PDS_CodeTable;
+  ISEC1_CenterID       = PDS_CenterID;
+  ISEC1_ModelID        = PDS_ModelID;
+  ISEC1_GridDefinition = PDS_GridDefinition;
+  ISEC1_Sec2Or3Flag    = PDS_Sec2Or3Flag;
+  ISEC1_Parameter      = PDS_Parameter;
+  ISEC1_LevelType      = PDS_LevelType;
+
+  if ( (ISEC1_LevelType !=  20) && 
+       (ISEC1_LevelType != GRIB1_LTYPE_99)        && 
+       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC)  && 
+       (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE)  && 
+       (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT)    && 
+       (ISEC1_LevelType != GRIB1_LTYPE_SIGMA)     && 
+       (ISEC1_LevelType != GRIB1_LTYPE_HYBRID)    && 
+       (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) && 
+       (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) && 
+       (ISEC1_LevelType != 115) && 
+       (ISEC1_LevelType != 117) && 
+       (ISEC1_LevelType != 125) && 
+       (ISEC1_LevelType != 127) && 
+       (ISEC1_LevelType != GRIB1_LTYPE_SEADEPTH)  && 
+       (ISEC1_LevelType != 210) )
     {
-      int param = vlistptr->vars[varID].param;
-      int pdis, pcat, pnum;
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      if ( pdis == 255 )
-	{
-	  int code = pnum;
-	  int tableID = vlistptr->vars[varID].tableID;
-	  if ( tableInqParUnits(tableID, code, units) != 0 )
-	    units[0] = '\0';
-	}
+      ISEC1_Level1 = PDS_Level1;
+      ISEC1_Level2 = PDS_Level2;
     }
   else
-    strcpy(units, vlistptr->vars[varID].units);
-
-  return;
-}
-
-/* used in MPIOM ! */
-int vlistInqVarID(int vlistID, int code)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
     {
-      int param = vlistptr->vars[varID].param;
-      int pdis, pcat, pnum;
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      if ( pnum == code ) return (varID);
+      ISEC1_Level1 = PDS_Level;
+      ISEC1_Level2 = 0;
     }
 
-  return (CDI_UNDEFID);
-}
-
+  /* ISEC1_Year        = PDS_Year; */
+  ISEC1_Month          = PDS_Month;
+  ISEC1_Day            = PDS_Day;
+  ISEC1_Hour           = PDS_Hour;
+  ISEC1_Minute         = PDS_Minute;
+  ISEC1_TimeUnit       = PDS_TimeUnit;
+  ISEC1_TimePeriod1    = PDS_TimePeriod1;
+  ISEC1_TimePeriod2    = PDS_TimePeriod2;
+  ISEC1_TimeRange      = PDS_TimeRange;
+  ISEC1_AvgNum         = PDS_AvgNum;
+  ISEC1_AvgMiss        = PDS_AvgMiss;
 
-int vlistInqVarSize(int vlistID, int varID)
-{
-  vlistCheckVarID(__func__, vlistID, varID);
+  if ( ISEC0_GRIB_Version == 1 )
+    {
+      ISEC1_Year           = PDS_Year;
+      ISEC1_Century        = PDS_Century;
+      ISEC1_SubCenterID    = PDS_Subcenter;
+      ISEC1_DecScaleFactor = PDS_DecimalScale;
+    }
+  else
+    {
+      int year;
+      year                 = GET_UINT1(pds[12]);
+      if ( year <= 100 )
+	{
+	  ISEC1_Year       = year;
+	  ISEC1_Century    = 1;
+	}
+      else
+	{
+	  ISEC1_Year       = year%100;
+	  ISEC1_Century    = 1 + (year-ISEC1_Year)/100;
+	}
+      ISEC1_SubCenterID    = 0;
+      ISEC1_DecScaleFactor = 0;
+    }
 
-  int zaxisID, gridID;
-  int tsteptype;
-  vlistInqVar(vlistID, varID, &gridID, &zaxisID, &tsteptype);
+  if ( ISEC1_Year < 0 )
+    {
+      ISEC1_Year    = -ISEC1_Year;
+      ISEC1_Century = -ISEC1_Century;
+    }
 
-  int nlevs = zaxisInqSize(zaxisID);
+  ISEC1_LocalFLag = 0;
+  if ( pdsLen > 28 )
+    {
+      int localextlen;
+      localextlen = pdsLen-28;
 
-  int gridsize = gridInqSize(gridID);
+      if ( localextlen > 4000 )
+	{
+	  Warning("PDS larger than 4000 bytes not supported!");
+	}
+      else
+	{
+	  ISEC1_LocalFLag = 1;
 
-  int size = gridsize*nlevs;
+	  if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
+	    {
+	      if ( pds[40] == 254 ) 
+		{
+		  decodePDS_DWD_local_Extension_254(pds, isec1);
+		}
+	      else if ( pds[40] == 253 )
+		{ 
+		  decodePDS_DWD_local_Extension_253(pds, isec1);
+		}
+	    }
+	  else if ( (ISEC1_CenterID    == 98 && ISEC1_LocalFLag ==  1) ||
+		    (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag ==  1) ||
+		    (ISEC1_CenterID    ==  7 && ISEC1_SubCenterID == 98) )
+	    {
+	      if ( pds[40] == 1 )
+		decodePDS_ECMWF_local_Extension_1(pds, isec1);
+	    }
+	  else if ( ISEC1_CenterID    == 252 && ISEC1_LocalFLag ==  1 )
+	    {
+	      if ( pds[40] == 1 )
+		decodePDS_MPIM_local_Extension_1(pds, isec1);	      
+	    }
+	  else
+	    {
+	      long i;
+	      for ( i = 0; i < localextlen; i++ )
+		{
+		  isec1[24+i] = pds[28+i];
+		}
+	    }
+	}
+    }
 
-  return (size);
+  return (pdsLen);
 }
 
-/*
- at Function  vlistInqVarDatatype
- at Title     Get the data type of a Variable
 
- at Prototype int vlistInqVarDatatype(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
+void gribPrintSec2_double(int *isec0, int *isec2, double *fsec2) {gribPrintSec2DP(isec0, isec2, fsec2);}
+void gribPrintSec3_double(int *isec0, int *isec3, double *fsec3) {gribPrintSec3DP(isec0, isec3, fsec3);}
+void gribPrintSec4_double(int *isec0, int *isec4, double *fsec4) {gribPrintSec4DP(isec0, isec4, fsec4);}
+void gribPrintSec2_float(int *isec0, int *isec2, float *fsec2) {gribPrintSec2SP(isec0, isec2, fsec2);}
+void gribPrintSec3_float(int *isec0, int *isec3, float *fsec3) {gribPrintSec3SP(isec0, isec3, fsec3);}
+void gribPrintSec4_float(int *isec0, int *isec4, float *fsec4) {gribPrintSec4SP(isec0, isec4, fsec4);}
 
- at Description
-The function @func{vlistInqVarDatatype} returns the data type of a variable.
 
- at Result
- at func{vlistInqVarDatatype} returns an identifier to the data type of the variable.
-The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16}, @func{DATATYPE_PACK24},
- at func{DATATYPE_FLT32}, @func{DATATYPE_FLT64}, @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and 
- at func{DATATYPE_INT32}.
 
- at EndFunction
-*/
-int vlistInqVarDatatype(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
 
-  vlistCheckVarID(__func__, vlistID, varID);
+static 
+void TEMPLATE(decode_array_common,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				     T fmin, T zscale, T * restrict fpdata)
+{
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  unsigned int jmask;
+  long i;
+  unsigned int tbits = 0;
+  int n_bits = NumBits;
+  int t_bits = 0;
+      
+  jmask = (1 << n_bits) - 1;
+  for ( i = 0; i < jlend; i++ )
+    {
+      if (n_bits - t_bits > 8)
+	{
+	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
+	  bits += 2;
+	  t_bits += 16;
+	}
 
-  return (vlistptr->vars[varID].datatype);
+      while ( t_bits < n_bits )
+	{
+	  tbits = (tbits * 256) + *bits++;
+	  t_bits += 8;
+	}
+      t_bits -= n_bits;
+      fpdata[i] = (tbits >> t_bits) & jmask;
+    }
+  /* at least this vectorizes :) */
+  for ( i = 0; i < jlend; i++ )
+    fpdata[i] = fmin + zscale*fpdata[i];
 }
 
+#if !defined(_MASK_AND_SHIFT_)
+#define _MASK_AND_SHIFT_
+static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+#endif
 
-int vlistInqVarNumber(int vlistID, int varID)
+static 
+void TEMPLATE(decode_array_common2,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				      T fmin, T zscale, T * restrict fpdata)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  long i;
+  int n_bits = NumBits;
+  int c_bits, j_bits;
+  double jj;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  /* older unoptimized code, not often used */
+  c_bits = 8;
+  for ( i = 0; i < jlend; i++ )
+    {
+      jj = 0.0;
+      j_bits = n_bits;
+      while (c_bits <= j_bits)
+	{
+	  if (c_bits == 8)
+	    {
+	      jj = jj * 256.0  + (double) (*bits++);
+	      j_bits -= 8;
+	    }
+	  else
+	    {
+	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+	      bits++;
+	      j_bits -= c_bits;
+	      c_bits = 8;
+	    }
+	}
 
-  int number = CDI_REAL;
-  if ( vlistptr->vars[varID].datatype == DATATYPE_CPX32 ||
-       vlistptr->vars[varID].datatype == DATATYPE_CPX64 )
-    number = CDI_COMP;
+      if (j_bits)
+	{
+	  c_bits -= j_bits;
+	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
+	}
+      
+      fpdata[i] = fmin + zscale*jj;
+    }
+} 
 
-  return (number);
-}
+static 
+void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits, 
+			      T fmin, T zscale, T *restrict fpdata)
+{
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_decode, end_decode;
+#endif
 
-/*
- at Function  vlistDefVarDatatype
- at Title     Define the data type of a Variable
+  long i;
+  T dval;
+#if defined (VECTORCODE)
+  GRIBPACK *lgrib = NULL;
 
- at Prototype void vlistDefVarDatatype(int vlistID, int varID, int datatype)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  datatype The data type identifier.
-                    The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16},
-                    @func{DATATYPE_PACK24}, @func{DATATYPE_FLT32}, @func{DATATYPE_FLT64},
-                    @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and @func{DATATYPE_INT32}.
+  if ( numBits%8 == 0 )
+    {
+      long jlenc = jlend * numBits / 8;
+      if ( jlenc > 0 ) 
+	{
+	  lgrib = (GRIBPACK*) malloc(jlenc*sizeof(GRIBPACK));
+	  if ( lgrib == NULL ) SysError("No Memory!");
 
- at Description
-The function @func{vlistDefVarDatatype} defines the data type of a variable.
+	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+	}
+    }
 
- at EndFunction
-*/
-void vlistDefVarDatatype(int vlistID, int varID, int datatype)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)lgrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
+	  	 (int)lgrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  if ( lgrib ) free(lgrib);
 
-  if (vlistptr->vars[varID].datatype != datatype)
+#else
+  if ( numBits ==  0 )
     {
-      vlistptr->vars[varID].datatype = datatype;
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)igrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(6, "unpack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_decode = mach_absolute_time();
+#endif
+      
+      if ( sizeof(T) == sizeof(double) )
+      	{ 
+#if defined _ENABLE_AVX
+	  printf("AVX selected ...\n");
+	  avx_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
+#elif defined _ENABLE_SSE4_1
+	  printf("SSE4 selected ...\n");
+	  sse41_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
+#else
+	  for ( i = 0; i < jlend; i++ )
+	    {
+	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	      fpdata[i] = fmin + zscale * dval;
+	    }
+#endif
+	}
+      else
+	{
+	  for ( i = 0; i < jlend; i++ )
+	    {
+	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	      fpdata[i] = fmin + zscale * dval;
+	    }
+	}
 
-      if ( vlistptr->vars[varID].missvalused == FALSE )
-        switch (datatype)
-          {
-          case DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
-          case DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
-          case DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
-          case DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
-          case DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
-          case DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
-          }
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_decode = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(6);
+#endif
     }
-}
-
-
-void vlistDefVarInstitut(int vlistID, int varID, int instID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].instID != instID)
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
+		 (int)igrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
     {
-      vlistptr->vars[varID].instID = instID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
     }
-}
-
-
-int vlistInqVarInstitut(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].instID);
-}
-
-
-void vlistDefVarModel(int vlistID, int varID, int modelID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].modelID != modelID)
+  else if ( numBits > 25 && numBits < 32 )
     {
-      vlistptr->vars[varID].modelID = modelID;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
     }
-}
-
-
-int vlistInqVarModel(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].modelID);
-}
-
-
-void vlistDefVarTable(int vlistID, int varID, int tableID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  if (vlistptr->vars[varID].tableID != tableID)
+  else
     {
-      vlistptr->vars[varID].tableID = tableID;
-      int tablenum = tableInqNum(tableID);
-
-      int param = vlistptr->vars[varID].param;
-
-      int pnum, pcat, pdis;
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      vlistptr->vars[varID].param = cdiEncodeParam(pnum, tablenum, pdis);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      Error("Unimplemented packing factor %d!", numBits);
     }
+#endif
 }
 
+#endif /* T */
 
-int vlistInqVarTable(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].tableID);
-}
-
-/*
- at Function  vlistDefVarName
- at Title     Define the name of a Variable
-
- at Prototype void vlistDefVarName(int vlistID, int varID, const char *name)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  name     Name of the variable.
-
- at Description
-The function @func{vlistDefVarName} defines the name of a variable.
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
 
- at EndFunction
-*/
-void vlistDefVarName(int vlistID, int varID, const char *name)
+static 
+void TEMPLATE(decode_array_common,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				     T fmin, T zscale, T * restrict fpdata)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  if ( name )
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  unsigned int jmask;
+  long i;
+  unsigned int tbits = 0;
+  int n_bits = NumBits;
+  int t_bits = 0;
+      
+  jmask = (1 << n_bits) - 1;
+  for ( i = 0; i < jlend; i++ )
     {
-      if ( vlistptr->vars[varID].name )
+      if (n_bits - t_bits > 8)
 	{
-	  free(vlistptr->vars[varID].name);
-	  vlistptr->vars[varID].name = NULL;
+	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
+	  bits += 2;
+	  t_bits += 16;
 	}
 
-      vlistptr->vars[varID].name = strdupx(name);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
-
-/*
- at Function  vlistDefVarLongname
- at Title     Define the long name of a Variable
-
- at Prototype void vlistDefVarLongname(int vlistID, int varID, const char *longname)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  longname Long name of the variable.
-
- at Description
-The function @func{vlistDefVarLongname} defines the long name of a variable.
-
- at EndFunction
-*/
-void vlistDefVarLongname(int vlistID, int varID, const char *longname)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  if ( longname )
-    {
-      if ( vlistptr->vars[varID].longname )
+      while ( t_bits < n_bits )
 	{
-	  free(vlistptr->vars[varID].longname);
-	  vlistptr->vars[varID].longname = 0;
+	  tbits = (tbits * 256) + *bits++;
+	  t_bits += 8;
 	}
-
-      vlistptr->vars[varID].longname = strdupx(longname);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      t_bits -= n_bits;
+      fpdata[i] = (tbits >> t_bits) & jmask;
     }
+  /* at least this vectorizes :) */
+  for ( i = 0; i < jlend; i++ )
+    fpdata[i] = fmin + zscale*fpdata[i];
 }
 
-/*
- at Function  vlistDefVarStdname
- at Title     Define the standard name of a Variable
-
- at Prototype void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  stdname  Standard name of the variable.
-
- at Description
-The function @func{vlistDefVarStdname} defines the standard name of a variable.
+#if !defined(_MASK_AND_SHIFT_)
+#define _MASK_AND_SHIFT_
+static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+#endif
 
- at EndFunction
-*/
-void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
+static 
+void TEMPLATE(decode_array_common2,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				      T fmin, T zscale, T * restrict fpdata)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  long i;
+  int n_bits = NumBits;
+  int c_bits, j_bits;
+  double jj;
 
-  if ( stdname )
+  /* older unoptimized code, not often used */
+  c_bits = 8;
+  for ( i = 0; i < jlend; i++ )
     {
-      if ( vlistptr->vars[varID].stdname )
+      jj = 0.0;
+      j_bits = n_bits;
+      while (c_bits <= j_bits)
 	{
-	  free(vlistptr->vars[varID].stdname);
-	  vlistptr->vars[varID].stdname = 0;
+	  if (c_bits == 8)
+	    {
+	      jj = jj * 256.0  + (double) (*bits++);
+	      j_bits -= 8;
+	    }
+	  else
+	    {
+	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+	      bits++;
+	      j_bits -= c_bits;
+	      c_bits = 8;
+	    }
 	}
 
-      vlistptr->vars[varID].stdname = strdupx(stdname);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      if (j_bits)
+	{
+	  c_bits -= j_bits;
+	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
+	}
+      
+      fpdata[i] = fmin + zscale*jj;
     }
-}
-
-/*
- at Function  vlistDefVarUnits
- at Title     Define the units of a Variable
-
- at Prototype void vlistDefVarUnits(int vlistID, int varID, const char *units)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  units    Units of the variable.
-
- at Description
-The function @func{vlistDefVarUnits} defines the units of a variable.
+} 
 
- at EndFunction
-*/
-void vlistDefVarUnits(int vlistID, int varID, const char *units)
+static 
+void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits, 
+			      T fmin, T zscale, T *restrict fpdata)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_decode, end_decode;
+#endif
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  long i;
+  T dval;
+#if defined (VECTORCODE)
+  GRIBPACK *lgrib = NULL;
 
-  if ( units )
+  if ( numBits%8 == 0 )
     {
-      if ( vlistptr->vars[varID].units )
+      long jlenc = jlend * numBits / 8;
+      if ( jlenc > 0 ) 
 	{
-	  free(vlistptr->vars[varID].units);
-	  vlistptr->vars[varID].units = 0;
-	}
+	  lgrib = (GRIBPACK*) malloc(jlenc*sizeof(GRIBPACK));
+	  if ( lgrib == NULL ) SysError("No Memory!");
 
-      vlistptr->vars[varID].units = strdupx(units);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+	}
     }
-}
-
-/*
- at Function  vlistInqVarMissval
- at Title     Get the missing value of a Variable
-
- at Prototype double vlistInqVarMissval(int vlistID, int varID)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-
- at Description
-The function @func{vlistInqVarMissval} returns the missing value of a variable.
-
- at Result
- at func{vlistInqVarMissval} returns the missing value of the variable.
-
- at EndFunction
-*/
-double vlistInqVarMissval(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  return (vlistptr->vars[varID].missval);
-}
-
-/*
- at Function  vlistDefVarMissval
- at Title     Define the missing value of a Variable
-
- at Prototype void vlistDefVarMissval(int vlistID, int varID, double missval)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  missval  Missing value.
-
- at Description
-The function @func{vlistDefVarMissval} defines the missing value of a variable.
-
- at EndFunction
-*/
-void vlistDefVarMissval(int vlistID, int varID, double missval)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  vlistptr->vars[varID].missval = missval;
-  vlistptr->vars[varID].missvalused = TRUE;
-}
-
-/*
- at Function  vlistDefVarExtra
- at Title     Define extra information of a Variable
-
- at Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
-    @Item  varID    Variable identifier.
-    @Item  extra    Extra information.
-
- at Description
-The function @func{vlistDefVarExtra} defines the extra information of a variable.
-
- at EndFunction
-*/
-void vlistDefVarExtra(int vlistID, int varID, const char *extra)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)lgrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
+	  	 (int)lgrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  if ( lgrib ) free(lgrib);
 
-  if ( extra )
+#else
+  if ( numBits ==  0 )
     {
-      if ( vlistptr->vars[varID].extra )
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)igrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(6, "unpack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_decode = mach_absolute_time();
+#endif
+      
+      if ( sizeof(T) == sizeof(double) )
+      	{ 
+#if defined _ENABLE_AVX
+	  printf("AVX selected ...\n");
+	  avx_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
+#elif defined _ENABLE_SSE4_1
+	  printf("SSE4 selected ...\n");
+	  sse41_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
+#else
+	  for ( i = 0; i < jlend; i++ )
+	    {
+	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	      fpdata[i] = fmin + zscale * dval;
+	    }
+#endif
+	}
+      else
 	{
-	  free(vlistptr->vars[varID].extra);
-	  vlistptr->vars[varID].extra = NULL;
+	  for ( i = 0; i < jlend; i++ )
+	    {
+	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	      fpdata[i] = fmin + zscale * dval;
+	    }
 	}
 
-      vlistptr->vars[varID].extra = strdupx(extra);
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_decode = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(6);
+#endif
     }
-}
-
-/*
- at Function  vlistInqVarExtra
- at Title     Get extra information of a Variable
-
- at Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
- at Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
-    @Item  varID    Variable identifier.
-    @Item  extra    Returned variable extra information. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
-
- at Description
-The function @func{vlistInqVarExtra} returns the extra information of a variable.
-
- at Result
- at func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available,
-otherwise the result is an empty string.
-
- at EndFunction
-*/
-void vlistInqVarExtra(int vlistID, int varID, char *extra)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  if ( vlistptr->vars[varID].extra == NULL )
-      sprintf(extra, "-");
-  else
-    strcpy(extra, vlistptr->vars[varID].extra);
-
-  return;
-}
-
-
-int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  if ( validrange != NULL && vlistptr->vars[varID].lvalidrange )
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
+		 (int)igrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
     {
-      validrange[0] = vlistptr->vars[varID].validrange[0];
-      validrange[1] = vlistptr->vars[varID].validrange[1];
+      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
     }
-
-  return (vlistptr->vars[varID].lvalidrange);
-}
-
-
-void vlistDefVarValidrange(int vlistID, int varID, const double *validrange)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  vlistptr->vars[varID].validrange[0] = validrange[0];
-  vlistptr->vars[varID].validrange[1] = validrange[1];
-  vlistptr->vars[varID].lvalidrange = TRUE;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
+#endif
 }
 
+#endif /* T */
 
-double vlistInqVarScalefactor(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
-
-  return (vlistptr->vars[varID].scalefactor);
-}
 
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
 
-double vlistInqVarAddoffset(int vlistID, int varID)
+static 
+int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-
-  vlistCheckVarID(__func__, vlistID, varID);
+  /* int imisng = 0; */
+  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
+  int  locnv = 0, locnl;
+  int  jlenl;
+  long i;
+  int iexp, imant;
+  int ipvpl, ipl;
+  int gdsLen = 0;
+#if defined (VECTORCODE)
+  unsigned char *igrib;
+  GRIBPACK *lgrib = NULL;
+  size_t lGribLen = 0;
+#endif
 
-  return (vlistptr->vars[varID].addoffset);
-}
+  *numGridVals = 0;
 
+  memset(isec2, 0, 22*sizeof(int));
 
-void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  gdsLen = GDS_Len;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  ipvpl = GDS_PVPL;
+  if ( ipvpl == 0 ) ipvpl = 0xFF;
 
-  if ( IS_NOT_EQUAL(vlistptr->vars[varID].scalefactor, scalefactor) )
+  if ( ipvpl != 0xFF )
+    { /* Either vct or reduced grid */
+      if ( GDS_NV != 0 )
+	{ /* we have vct */
+	  VertCoorTab = TRUE;
+	  ipl =  4*GDS_NV + ipvpl - 1;
+	  if ( ipl < gdsLen )
+	    {
+	      ReducedGrid = TRUE;
+	    }
+	}
+      else
+	{
+	  VertCoorTab = FALSE;
+	  ReducedGrid = TRUE;
+	}
+      /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+    }
+ 
+  if ( ISEC0_GRIB_Version == 0 )
     {
-      vlistptr->vars[varID].scalefactor = scalefactor;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      if ((gdsLen - 32) > 0) VertCoorTab = TRUE;
+      else                   VertCoorTab = FALSE;
+    }
+  
+  if ( ReducedGrid )
+    {
+      locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+      jlenl = (gdsLen - locnl)  >> 1;
+      if ( jlenl == GDS_NumLat )
+	{
+	  *numGridVals = 0;
+	  ISEC2_Reduced = TRUE;
+	  for ( i = 0; i < jlenl; i++ )
+	    {
+	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
+	      *numGridVals += ISEC2_RowLon(i);
+	    }
+	}
+      else
+	{
+	  ReducedGrid = FALSE;
+	}
     }
-}
-
 
-void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  ISEC2_GridType = GDS_GridType;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  /*
+     Gaussian grid definition.
+  */
+  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
+       ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
+       ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+    {
+      ISEC2_NumLat    = GDS_NumLat;
+      if ( ! ReducedGrid )
+	{
+	  ISEC2_NumLon = GDS_NumLon;
+	  *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+	}
+      ISEC2_FirstLat  = GDS_FirstLat;
+      ISEC2_FirstLon  = GDS_FirstLon;
+      ISEC2_ResFlag   = GDS_ResFlag;
+      ISEC2_LastLat   = GDS_LastLat;
+      ISEC2_LastLon   = GDS_LastLon;
+      ISEC2_LonIncr   = GDS_LonIncr;
 
-  if ( IS_NOT_EQUAL(vlistptr->vars[varID].addoffset, addoffset))
+      ISEC2_NumPar    = GDS_NumPar;
+      ISEC2_ScanFlag  = GDS_ScanFlag;
+      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+	{
+	  ISEC2_LatSP     = GDS_LatSP;
+	  ISEC2_LonSP     = GDS_LonSP;
+	  FSEC2_RotAngle  = GDS_RotAngle;
+	}
+      /*
+	if ( Lons != Longitudes || Lats != Latitudes )
+	Error("Latitude/Longitude Conflict");
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN     ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
     {
-      vlistptr->vars[varID].addoffset = addoffset;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      /*
+      iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+      */
     }
-}
-
-
-void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].tsteptype != tsteptype)
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON     ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
     {
-      vlistptr->vars[varID].tsteptype = tsteptype;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      /*
+      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
+    {
+      ISEC2_NumLon    = GDS_NumLon;
+      ISEC2_NumLat    = GDS_NumLat;
+      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+      ISEC2_FirstLat  = GDS_FirstLat;
+      ISEC2_FirstLon  = GDS_FirstLon;
+      ISEC2_ResFlag   = GDS_ResFlag;
+      ISEC2_Lambert_Lov   = GDS_Lambert_Lov;
+      ISEC2_Lambert_dx    = GDS_Lambert_dx;
+      ISEC2_Lambert_dy    = GDS_Lambert_dy;
+      ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
+      ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
+      ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
+      ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
+      ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
+      ISEC2_ScanFlag      = GDS_ScanFlag;
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+    {
+      ISEC2_PentaJ  = GDS_PentaJ; /* Truncation */
+      ISEC2_PentaK  = GDS_PentaK;
+      ISEC2_PentaM  = GDS_PentaM;
+      ISEC2_RepType = GDS_RepType;
+      ISEC2_RepMode = GDS_RepMode;
+      *numGridVals  = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
+      isec2[ 6] = 0;
+      isec2[ 7] = 0;
+      isec2[ 8] = 0;
+      isec2[ 9] = 0;
+      isec2[10] = 0;
+      /*
+      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+    {
+      ISEC2_GME_NI2    = GDS_GME_NI2;
+      ISEC2_GME_NI3    = GDS_GME_NI3;
+      ISEC2_GME_ND     = GDS_GME_ND;
+      ISEC2_GME_NI     = GDS_GME_NI;
+      ISEC2_GME_AFlag  = GDS_GME_AFlag;
+      ISEC2_GME_LatPP  = GDS_GME_LatPP;
+      ISEC2_GME_LonPP  = GDS_GME_LonPP;
+      ISEC2_GME_LonMPL = GDS_GME_LonMPL;
+      ISEC2_GME_BFlag  = GDS_GME_BFlag;
+      *numGridVals  = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
+      /*
+      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else
+    {
+      ISEC2_NumLon = GDS_NumLon;
+      ISEC2_NumLat = GDS_NumLat;
+      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+      Message("Gridtype %d unsupported", ISEC2_GridType);
     }
-}
 
+  /*    vertical coordinate parameters for hybrid levels.     */
+  /*    get number of vertical coordinate parameters, if any. */
 
-int vlistInqVarTsteptype(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].tsteptype);
-}
+  ISEC2_NumVCP = 0;
 
+  isec2[17] = 0;
+  isec2[18] = 0;
 
-void vlistDefVarTimave(int vlistID, int varID, int timave)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].timave != timave)
+  if ( VertCoorTab == TRUE )
     {
-      vlistptr->vars[varID].timave = timave;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      if ( ISEC0_GRIB_Version  == 0 )
+	{
+	  locnv = 32;
+	  ISEC2_NumVCP = (gdsLen - 32) >> 2;
+	}
+      else
+	{
+	  locnv = GDS_PVPL - 1;
+	  ISEC2_NumVCP = GDS_NV;
+	}
+#if defined (SX)
+      lGribLen = 4*ISEC2_NumVCP;	      
+      lgrib    = (GRIBPACK*) malloc(lGribLen*sizeof(GRIBPACK));
+
+      igrib = &gds[locnv];
+      if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
+      for ( i = 0; i < ISEC2_NumVCP; i++ )
+	{
+	  iexp   = (lgrib[4*i  ]);
+	  imant  =((lgrib[4*i+1]) << 16) +
+	          ((lgrib[4*i+2]) <<  8) +
+	           (lgrib[4*i+3]);
+	  fsec2[10+i] = POW_2_M24 * imant * pow(16.0, (double)(iexp - 64));
+	}
+
+      free(lgrib);
+#else
+      for ( i = 0; i < ISEC2_NumVCP; i++ )
+	{
+	  iexp   = (gds[locnv+4*i  ]);
+	  imant  =((gds[locnv+4*i+1]) << 16) +
+	          ((gds[locnv+4*i+2]) <<  8) +
+	           (gds[locnv+4*i+3]);
+	  fsec2[10+i] = decfp2(iexp,imant);
+	}
+#endif
     }
-}
 
+  return (gdsLen);
+}
 
-int vlistInqVarTimave(int vlistID, int varID)
+static
+int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
+			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].timave);
-}
+  unsigned char *igrib;
+  int lspherc = FALSE, lcomplex = FALSE;
+  int lcompress;
+  int jup, kup, mup;
+  int locnd;
+  long jlend;
+  long i;
+  int bds_flag, jscale, imiss;
+  int bds_ubits;
+  int ioff = 0;
+  int iexp, imant;
+  int zoff;
+  int bds_head = 11;
+  double zscale = 0.;
+  T fmin = 0.;
+  T *fpdata = fsec4;
+  int bdsLen;
+  extern int CGRIBEX_Fix_ZSE;
 
+  *iret = 0;
+  igrib = bds;
 
-void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].timaccu != timaccu)
-    {
-      vlistptr->vars[varID].timaccu = timaccu;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  memset(isec4, 0, 42*sizeof(int));
 
+  /* get length of binary data block. */
 
-int vlistInqVarTimaccu(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].timaccu);
-}
+  bdsLen = BDS_Len;
+  /*
+    If a very large product, the section 4 length field holds
+    the number of bytes in the product after section 4 upto
+    the end of the padding bytes.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  if ( llarge ) bdsLen = bdsLenIn - bdsLen;
 
+  /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
 
-void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGeneratingProcess)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if (vlistptr->vars[varID].typeOfGeneratingProcess != typeOfGeneratingProcess)
-    {
-      vlistptr->vars[varID].typeOfGeneratingProcess = typeOfGeneratingProcess;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  bds_flag = BDS_Flag;
 
+  /* 0------- grid point           */
+  /* 1------- spherical harmonics  */
 
-int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].typeOfGeneratingProcess);
-}
+  lspherc = bds_flag >> 7;
 
+  if ( lspherc ) isec4[2] = 128;
+  else           isec4[2] = 0;
 
-void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDefinitionTemplate)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* -0------  simple packing */
+  /* -1------ complex packing */
 
-  if (vlistptr->vars[varID].productDefinitionTemplate != productDefinitionTemplate)
-    {
-      vlistptr->vars[varID].productDefinitionTemplate = productDefinitionTemplate;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  lcomplex = (bds_flag >> 6)&1;
 
+  if ( lcomplex ) isec4[3] = 64;
+  else            isec4[3] =  0;
 
-int vlistInqVarProductDefinitionTemplate(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* ---0---- No additional flags */
+  /* ---1---- No additional flags */
 
-  return (vlistptr->vars[varID].productDefinitionTemplate);
-}
+  lcompress = (bds_flag >> 4)&1; /* compress */
 
+  if ( lcompress )
+    { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
+  else
+    { isec4[5] =  0; isec4[6] = 0;     zoff =  0; }
 
-void vlistDestroyVarName(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  if ( vlistptr->vars[varID].name )
-    {
-      free(vlistptr->vars[varID].name);
-      vlistptr->vars[varID].name = NULL;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  /* ----++++ number of unused bits at end of section) */
 
+  bds_ubits = bds_flag & 0xF;
+  
+  /* scale factor (2 bytes) */;
 
-void vlistDestroyVarLongname(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  jscale = BDS_BinScale;
 
-  if ( vlistptr->vars[varID].longname )
-    {
-      free(vlistptr->vars[varID].longname);
-      vlistptr->vars[varID].longname = NULL;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  /* check for missing data indicators. */
 
+  iexp  = bds[ 6];
+  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
 
-void vlistDestroyVarStdname(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
 
-  if ( vlistptr->vars[varID].stdname )
-    {
-      free(vlistptr->vars[varID].stdname);
-      vlistptr->vars[varID].stdname = NULL;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  /* convert reference value and scale factor. */
+
+  if ( ! (dfunc == 'J') )
+    if ( imiss == 0 )
+      {
+	fmin = BDS_RefValue;
+	
+	if ( jscale < 0 )
+	  zscale = 1.0/intpow2(-jscale);
+	else
+	  zscale = intpow2(jscale);
+      }
 
+  /* get number of bits in each data value. */
 
-void vlistDestroyVarUnits(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  ISEC4_NumBits = BDS_NumBits;
 
-  if ( vlistptr->vars[varID].units )
-    {
-      free(vlistptr->vars[varID].units);
-      vlistptr->vars[varID].units = NULL;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  /* octet number of start of packed data */
+  /* calculated from start of block 4 - 1 */
 
+  locnd = zoff + bds_head;
 
-int vlistInqVarMissvalUsed(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].missvalused);
-}
+  /* if data is in spherical harmonic form, distinguish   */
+  /* between simple/complex packing (lcomplex = 0/1)      */
 
+  if ( lspherc )
+    {
+      if ( !lcomplex )
+	{
+	  /*    no unpacked binary data present */
 
-void vlistDefFlag(int vlistID, int varID, int levID, int flag)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  jup = kup = mup = 0;
 
-  levinfo_t li = DEFAULT_LEVINFO(levID);
-  if (vlistptr->vars[varID].levinfo)
-    ;
-  else if (flag != li.flag)
-    cdiVlistCreateVarLevInfo(vlistptr, varID);
-  else
-    return;
+	  /*    octet number of start of packed data */
+	  /*    calculated from start of block 4 - 1 */
 
-  vlistptr->vars[varID].levinfo[levID].flag = flag;
+	  ioff   = 1;
+	  locnd += 4*ioff;  /* RealCoef */
 
-  vlistptr->vars[varID].flag = 0;
+	  /*    get real (0,0) coefficient in grib format and     */
+	  /*    convert to floating point.                        */
 
-  int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
-  for ( int levelID = 0; levelID < nlevs; levelID++ )
-    {
-      if ( vlistptr->vars[varID].levinfo[levelID].flag )
-        {
-          vlistptr->vars[varID].flag = 1;
-          break;
-        }
-    }
+	  if ( dfunc != 'J' )
+	    {
+	      if ( imiss ) *fpdata++ = 0.0;
+	      else         *fpdata++ = BDS_RealCoef;
+	    }
+	}
+      else /* complex packed spherical harmonics */
+	{
+	  isec4[15] = BDS_PackData;
+	  /*    scaling factor */
+	  isec4[16] = BDS_Power;
 
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+	  /*    pentagonal resolution parameters of the */
+	  /*    unpacked section of data field          */
 
+	  jup = bds[zoff+15];
+	  kup = bds[zoff+16];
+	  mup = bds[zoff+17];
 
-int vlistInqFlag(int vlistID, int varID, int levID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  isec4[zoff+17] = jup;
+	  isec4[zoff+18] = kup;
+	  isec4[zoff+19] = mup;
 
-  if (vlistptr->vars[varID].levinfo)
-    return (vlistptr->vars[varID].levinfo[levID].flag);
-  else
-    {
-      levinfo_t li = DEFAULT_LEVINFO(levID);
-      return li.flag;
-    }
-}
+	  /*    unpacked binary data */
 
+	  locnd += 4; /* 2 + power */
+	  locnd += 3; /* j, k, m   */
+	  ioff   = (jup+1)*(jup+2);
 
-int vlistFindVar(int vlistID, int fvarID)
-{
-  int varID;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  if ( dfunc != 'J' )
+	    for ( i = 0; i < ioff; i++ )
+	      {
+		if ( imiss )
+		  *fpdata++ = 0.0;
+		else
+		  {
+		    iexp   = (bds[locnd+4*i  ]);
+		    imant  =((bds[locnd+4*i+1]) << 16) +
+		            ((bds[locnd+4*i+2]) <<  8) +
+		             (bds[locnd+4*i+3]);
 
-  for ( varID = 0; varID < vlistptr->nvars; varID++ )
-    {
-      if ( vlistptr->vars[varID].fvarID == fvarID ) break;
+		    *fpdata++ = decfp2(iexp,imant);
+		  }
+	      }
+	  
+	  locnd += 4*ioff;  /* RealCoef */
+	}
     }
-
-  if ( varID == vlistptr->nvars )
+  else
     {
-      varID = -1;
-      Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
+      if ( lcomplex )
+	{
+	  *iret = 1999;
+	  gprintf(__func__, " Second order packed grids unsupported!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
+	}
     }
 
-  return (varID);
-}
-
-
-int vlistFindLevel(int vlistID, int fvarID, int flevelID)
-{
-  int levelID = -1;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* Decode data values to floating point and store in fsec4.  */
+  /* First calculate the number of data values.                */
+  /* Take into account that spherical harmonics can be packed  */
+  /* simple (lcomplex = 0) or complex (lcomplex = 1)           */
 
-  int varID = vlistFindVar(vlistID, fvarID);
+  jlend = bdsLen - locnd;
 
-  if ( varID != -1 )
+  if ( ISEC4_NumBits == 0 )
     {
-      int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
-      for ( levelID = 0; levelID < nlevs; levelID++ )
+      if ( jlend > 1 )
 	{
-	  if ( vlistptr->vars[varID].levinfo[levelID].flevelID == flevelID ) break;
+	  *iret = 2001;
+	  gprintf(__func__, " Number of bits per data value = 0!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
 	}
 
-      if ( levelID == nlevs )
+      if ( numGridVals == 0 )
 	{
-	  levelID = -1;
-	  Message("levelID not found for fvarID %d and levelID %d in vlistID %d!",
-		  fvarID, flevelID, vlistID);
+	  *iret = 2002;
+	  gprintf(__func__, " Constant field unsupported for this grid type!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
 	}
-    }
 
-  return (levelID);
-}
+      jlend = numGridVals;
+      jlend -= ioff;
+    }
+  else
+    {
+      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+    }
 
+  ISEC4_NumValues        = jlend + ioff;
+  ISEC4_NumNonMissValues = 0;
 
-int vlistMergedVar(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (vlistptr->vars[varID].mvarID);
-}
+  if ( lcompress )
+    {
+      size_t len;
 
+      if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
+	len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
+      else
+        len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
-int vlistMergedLevel(int vlistID, int varID, int levelID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      ISEC4_NumValues = len*8/ISEC4_NumBits;
 
-  if (vlistptr->vars[varID].levinfo)
-    return vlistptr->vars[varID].levinfo[levelID].mlevelID;
-  else
-    {
-      levinfo_t li = DEFAULT_LEVINFO(levelID);
-      return li.mlevelID;
+      if ( lspherc )
+	{
+	  if ( lcomplex )
+	    ISEC4_NumValues += ioff;
+	  else
+	    ISEC4_NumValues++;
+	}
     }
-}
 
+  if ( dfunc == 'J' ) return (bdsLen);
 
-void vlistDefIndex(int vlistID, int varID, int levelID, int index)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* check length of output array. */
+  
+  if ( ISEC4_NumValues > fsec4len )
+    {
+      *iret = 710;
+      gprintf(__func__, " Output array too small. Length = %d", fsec4len);
+      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
+      gprintf(__func__, " Return code =  %d", *iret);
+      return (0);
+    }
 
-  levinfo_t li = DEFAULT_LEVINFO(levelID);
-  if (vlistptr->vars[varID].levinfo)
-    ;
-  else if (index != li.index)
-    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  if ( imiss ) memset((char *)fpdata, 0, jlend*sizeof(T));
   else
-    return;
-  vlistptr->vars[varID].levinfo[levelID].index = index;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+    {
+      igrib += locnd;
 
+      TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+    }
 
-int vlistInqIndex(int vlistID, int varID, int levelID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( lspherc && lcomplex )
+    {
+      int pcStart, pcScale;
+      pcStart = isec4[19];
+      pcScale = isec4[16];
+      TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
+      TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
+    }
 
-  if (vlistptr->vars[varID].levinfo)
-    return (vlistptr->vars[varID].levinfo[levelID].index);
-  else
+  if ( CGRIBEX_Fix_ZSE )  /* Fix ZeroShiftError of simple packed spherical harmonics */
+    if ( lspherc && !lcomplex )
+      {
+        /* 20100705: Fix ZeroShiftError - Edi Kirk */
+	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
+	  {
+	    T zserr = fsec4[1];
+	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
+	  }
+      }
+
+  if ( decscale )
     {
-      levinfo_t li = DEFAULT_LEVINFO(levelID);
-      return li.index;
+      T scale = (T) pow(10.0, (double)-decscale);
+      for ( i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
     }
+
+  return (bdsLen);
 }
 
 
-void vlistChangeVarZaxis(int vlistID, int varID, int zaxisID)
+void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+			     T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
+			     int kleng, int *kword, int dfunc, int *iret)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
+  int gribLen = 0;
+  int gdsIncluded = FALSE;
+  int bmsIncluded = FALSE;
+  int bitmapSize = 0;
+  int imaskSize = 0;
+  int ldebug = FALSE;
+  int llarge = FALSE, l_iorj = FALSE;
+  int lsect2 = FALSE, lsect3 = FALSE;
+  int numGridVals = 0;
+  static int lmissvalinfo = 1;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  UNUSED(kleng);
 
-  int nlevs1 = zaxisInqSize(vlistptr->vars[varID].zaxisID);
-  int nlevs2 = zaxisInqSize(zaxisID);
+  *iret = 0;
 
-  if ( nlevs1 != nlevs2 ) Error("Number of levels must not change!");
+  grsdef();
 
-  int nvars = vlistptr->nvars;
-  int found = 0;
-  int oldZaxisID = vlistptr->vars[varID].zaxisID;
-  for ( int i = 0; i < varID; ++i)
-    found |= (vlistptr->vars[i].zaxisID == oldZaxisID);
-  for ( int i = varID + 1; i < nvars; ++i)
-    found |= (vlistptr->vars[i].zaxisID == oldZaxisID);
+  ISEC2_Reduced = FALSE;
 
-  if (found)
+  /*
+    ----------------------------------------------------------------
+    IS Indicator Section (Section 0)
+    ----------------------------------------------------------------
+  */
+  is = (unsigned char *) &kgrib[0];
+
+  isLen = decodeIS(is, isec0, iret);
+
+  /*
+    If count is negative, have to rescale by factor of -120.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  if ( ISEC0_GRIB_Len < 0 )
     {
-      int nzaxis = vlistptr->nzaxis;
-      for (int i = 0; i < nzaxis; ++i)
-	if (vlistptr->zaxisIDs[i] == oldZaxisID )
-	  vlistptr->zaxisIDs[i] = zaxisID;
+      if ( ldebug )
+	gprintf(__func__, "Special case, negative length multiplied by -120");
+      llarge = TRUE;
+      ISEC0_GRIB_Len *= (-120);
     }
-  else
-    vlistAdd2ZaxisIDs(vlistptr, zaxisID);
+  /*
+    When decoding or calculating length, previous editions
+    of the GRIB code must be taken into account.
 
-  vlistptr->vars[varID].zaxisID = zaxisID;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+    In the table below, covering sections 0 and 1 of the GRIB
+    code, octet numbering is from the beginning of the GRIB
+    message;
+    * indicates that the value is not available in the code edition;
+    R indicates reserved, should be set to 0;
+    Experimental edition is considered as edition -1.
 
+    GRIB code edition -1 has fixed length of 20 octets for
+    section 1, the length not included in the message.
+    GRIB code edition 0 has fixed length of 24 octets for
+    section 1, the length being included in the message.
+    GRIB code edition 1 can have different lengths for section
+    1, the minimum being 28 octets, length being included in
+    the message.
 
-void vlistChangeVarGrid(int vlistID, int varID, int gridID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+                                         Octet numbers for code
+                                                  editions
 
-  vlistCheckVarID(__func__, vlistID, varID);
+                 Contents.                   -1      0      1
+                 ---------                ----------------------
+       Letters GRIB                          1-4    1-4    1-4
+       Total length of GRIB message.          *      *     5-7
+       GRIB code edition number               *      *      8
+       Length of Section 1.                   *     5-7    9-11
+       Reserved octet (R).                    *      8(R)   *
+       Version no. of Code Table 2.           *      *     12
+       Identification of centre.              5      9     13
+       Generating process.                    6     10     14
+       Grid definition .                      7     11     15
+       Flag (Code Table 1).                   8     12     16
+       Indicator of parameter.                9     13     17
+       Indicator of type of level.           10     14     18
+       Height, pressure etc of levels.      11-12  15-16  19-20
+       Year of century.                      13     17     21
+       Month.                                14     18     22
+       Day.                                  15     19     23
+       Hour.                                 16     20     24
+       Minute.                               17     21     25
+       Indicator of unit of time.            18     22     26
+       P1 - Period of time.                  19     23     27
+       P2 - Period of time                  20(R)   24     28
+       or reserved octet (R).
+       Time range indicator.                21(R)   25     29
+       or reserved octet (R).
+       Number included in average.       22-23(R)  26-27  30-31
+       or reserved octet (R).
+       Number missing from average.         24(R)  28(R)   32
+       or reserved octet (R).
+       Century of data.                       *      *     33
+       Designates sub-centre if not 0.        *      *     34
+       Decimal scale factor.                  *      *    35-36
+       Reserved. Set to 0.                    *      *    37-48
+       (Need not be present)
+       For originating centre use only.       *      *    49-nn
+       (Need not be present)
 
-  int nvars = vlistptr->nvars;
-  int index;
-  for ( index = 0; index < nvars; index++ )
-    if ( index != varID )
-      if ( vlistptr->vars[index].gridID == vlistptr->vars[varID].gridID ) break;
+    Identify which GRIB code edition is being decoded.
 
-  if ( index == nvars )
+    In GRIB edition 1, the edition number is in octet 8.
+    In GRIB edition 0, octet 8 is reserved and set to 0.
+    In GRIB edition -1, octet 8 is a flag field and can have a
+    a valid value of 0, 1, 2 or 3.
+
+    However, GRIB edition number 0 has a fixed
+    length of 24, included in the message, for section 1, so
+    if the value extracted from octets 5-7 is 24 and that from
+    octet 8 is 0, it is safe to assume edition 0 of the code.
+
+  */
+  if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
     {
-      for ( index = 0; index < vlistptr->ngrids; index++ )
-	if ( vlistptr->gridIDs[index] == vlistptr->vars[varID].gridID )
-	  vlistptr->gridIDs[index] = gridID;
+      /*
+	Set length of GRIB message to missing data value.
+      */
+      ISEC0_GRIB_Len = 0;
     }
-  else
-    vlistAdd2GridIDs(vlistptr, gridID);
-
-  vlistptr->vars[varID].gridID = gridID;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+  /*
+    If Grib Edition 1 and only length is required, go to section 9.
+  */
+  if ( dfunc == 'L' ) goto LABEL900;
 
+  /*
+    ----------------------------------------------------------------
+    PDS Product Definition Section (Section 1)
+    ----------------------------------------------------------------
+  */ 
+  pds = is + isLen;
 
-void vlistDefVarCompType(int vlistID, int varID, int comptype)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  pdsLen = decodePDS(pds, isec0, isec1);
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  /*
+    ----------------------------------------------------------------
+    GDS Grid Description Section (Section 2)
+    ----------------------------------------------------------------
+  */
+  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
 
-  if (vlistptr->vars[varID].comptype != comptype)
+  if ( gdsIncluded )
     {
-      vlistptr->vars[varID].comptype = comptype;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+      gds = is + isLen + pdsLen;
 
+      gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
+    }
 
-int vlistInqVarCompType(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /*
+    ----------------------------------------------------------------
+    BMS Bit-Map Section Section (Section 3)
+    ----------------------------------------------------------------
+  */ 
+  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  isec3[0] = 0;
+  if ( bmsIncluded )
+    {
+      bms = is + isLen + pdsLen + gdsLen;
 
-  return (vlistptr->vars[varID].comptype);
-}
+      bmsLen = BMS_Len;
+      imaskSize = (bmsLen - 6)<<3;
+      bitmapSize = imaskSize - BMS_UnusedBits;
+      /*
+      fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
+      */
+    }
 
+  /*
+    ----------------------------------------------------------------
+    BDS Binary Data Section (Section 4)
+    ----------------------------------------------------------------
+  */
+  bds = is + isLen + pdsLen + gdsLen + bmsLen;
 
-void vlistDefVarCompLevel(int vlistID, int varID, int complevel)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
+				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
 
-  if (vlistptr->vars[varID].complevel != complevel)
-    {
-      vlistptr->vars[varID].complevel = complevel;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  if ( *iret != 0 ) return;
 
+  ISEC4_NumNonMissValues = ISEC4_NumValues;
 
-int vlistInqVarCompLevel(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( bitmapSize > 0 )
+    {
+      if ( dfunc != 'L' && dfunc != 'J' )
+	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+	  {
+	    lmissvalinfo = 0;
+	    FSEC3_MissVal = GRIB_MISSVAL;
+	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+	  }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+      /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
+      ISEC4_NumValues        = bitmapSize;
 
-  return (vlistptr->vars[varID].complevel);
-}
+      if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
+	{
+	  long i, j;
+	  GRIBPACK *pbitmap;
+	  GRIBPACK bitmap;
+	  GRIBPACK *imask;
 
+	  /*
+	  unsigned char *bitmap;
+	  bitmap = BMS_Bitmap;
+	  j = ISEC4_NumNonMissValues;
+	  for ( i = ISEC4_NumValues-1; i >= 0; i-- )
+	    {
+	      if ( (bitmap[i/8]>>(7-(i&7)))&1 )
+		fsec4[i] = fsec4[--j];
+	      else
+		fsec4[i] = FSEC3_MissVal;
+	    }
+	  */
 
-void  vlistDefVarChunkType(int vlistID, int varID, int chunktype)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  imask = (GRIBPACK*) malloc(imaskSize*sizeof(GRIBPACK));
 
-  vlistCheckVarID(__func__, vlistID, varID);
+#if defined (VECTORCODE)
+	  (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
+	  pbitmap = imask;
+#else
+	  pbitmap = BMS_Bitmap;
+#endif
 
-  if (vlistptr->vars[varID].chunktype != chunktype)
-    {
-      vlistptr->vars[varID].chunktype = chunktype;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+	  for ( i = imaskSize/8-1; i >= 0; i-- )
+	    {
+	      bitmap = pbitmap[i];
+	      imask[i*8+0] = 1 & (bitmap >> 7);
+	      imask[i*8+1] = 1 & (bitmap >> 6);
+	      imask[i*8+2] = 1 & (bitmap >> 5);
+	      imask[i*8+3] = 1 & (bitmap >> 4);
+	      imask[i*8+4] = 1 & (bitmap >> 3);
+	      imask[i*8+5] = 1 & (bitmap >> 2);
+	      imask[i*8+6] = 1 & (bitmap >> 1);
+	      imask[i*8+7] = 1 & (bitmap);
+	    }
 
+	  j = 0;
+	  for ( i = 0; i < ISEC4_NumValues; i++ )
+	    if ( imask[i] ) j++;
 
-int vlistInqVarChunkType(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  if ( ISEC4_NumNonMissValues != j )
+	    {
+	      if ( dfunc != 'J' && ISEC4_NumBits != 0 )
+		Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
+			j, ISEC4_NumNonMissValues);
 
-  vlistCheckVarID(__func__, vlistID, varID);
+	      ISEC4_NumNonMissValues = j;
+	    }
 
-  return (vlistptr->vars[varID].chunktype);
-}
+	  if ( dfunc != 'J' )
+	    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+	      for ( i = ISEC4_NumValues-1; i >= 0; i-- )
+		fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
+	    }
 
-static
-int vlistEncodeXyz(int (*dimorder)[3])
-{
-  return (*dimorder)[0]*100 + (*dimorder)[1]*10 + (*dimorder)[2];
-}
+	  free(imask);
+	}
+    }
 
+  if ( ISEC2_Reduced )
+    {
+      int nlon, nlat;
+      int lsect3, lperio = 1, lveggy;
+      int ilat;
+      int nvalues = 0;
+      int dlon;
 
-static
-void vlistDecodeXyz(int xyz, int (*outDimorder)[3])
-{
-  (*outDimorder)[0] = xyz/100, xyz -= (*outDimorder)[0]*100;
-  (*outDimorder)[1] = xyz/10, xyz -= (*outDimorder)[1]*10;
-  (*outDimorder)[2] = xyz;
-}
+      nlat = ISEC2_NumLat;
+      nlon = ISEC2_RowLonPtr[0];
+      for ( ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
+      for ( ilat = 1; ilat < nlat; ++ilat )
+	if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
 
+      dlon = ISEC2_LastLon-ISEC2_FirstLon;
+      if ( dlon < 0 ) dlon += 360000;
+	  
+      if ( nvalues != ISEC4_NumValues )
+	{
+	  *iret = -801;
+	}
+      //printf("nlat %d  nlon %d \n", nlat, nlon);
+      //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
 
-void  vlistDefVarXYZ(int vlistID, int varID, int xyz)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+      if ( dfunc == 'R' && *iret == -801 )
+	gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
+		ISEC4_NumValues, nvalues);
+      
+      if ( dfunc == 'R' && *iret != -801 )
+	{
+	  ISEC2_Reduced = 0;
+	  ISEC2_NumLon = nlon;
+	  ISEC4_NumValues = nlon*nlat;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+	  lsect3 = bitmapSize > 0;
+	  lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) && 
+	          ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) || 
+	           (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30));
+	
+	  (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
+	      
+	  if ( bitmapSize > 0 )
+	    {
+	      long i;
+	      int j = 0;
+	      
+	      for ( i = 0; i < ISEC4_NumValues; i++ )
+		if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
+		  
+	      ISEC4_NumNonMissValues = j;
+	    }
+	}
+    }
 
-  if ( xyz == 3 ) xyz = 321;
 
-  /* check xyz dimension order */
-  {
-    int dimorder[3];
-    vlistDecodeXyz(xyz, &dimorder);
-    int dimx = 0, dimy = 0, dimz = 0;
-    for ( int id = 0; id < 3; ++id )
-      {
-        switch ( dimorder[id] )
-          {
-            case 1: dimx++; break;
-            case 2: dimy++; break;
-            case 3: dimz++; break;
-            default: dimorder[id] = 0; break;    //Ensure that we assign a valid dimension to this position.
-          }
-     }
-    if ( dimz > 1 || dimy > 1 || dimx > 1 ) xyz = 321; // ZYX
-    else
-      {
-        if ( dimz == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 3; break;}
-        if ( dimy == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 2; break;}
-        if ( dimx == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 1; break;}
-        xyz = vlistEncodeXyz(&dimorder);
-      }
-  }
+  if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
+  esLen = 4;
 
-  assert(xyz == 123 || xyz == 312 || xyz == 231 || xyz == 321 || xyz == 132 || xyz == 213);
+  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
 
-  vlistptr->vars[varID].xyz = xyz;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+  if ( ISEC0_GRIB_Len )
+    if ( ISEC0_GRIB_Len < gribLen )
+      Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
 
+  ISEC0_GRIB_Len = gribLen;
 
-void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3])
-{
-  vlist_t *vlistptr;
+  *kword = gribLen / sizeof(int);
+  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
 
-  vlistptr = vlist_to_pointer(vlistID);
+  /*
+    ----------------------------------------------------------------
+    Section 9 . Abort/return to calling routine.
+    ----------------------------------------------------------------
+  */
+ LABEL900:;
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  if ( ldebug )
+    {
+      gprintf(__func__, "Section 9.");
+      gprintf(__func__, "Output values set -");
 
-  vlistDecodeXyz(vlistptr->vars[varID].xyz, outDimorder);
-}
+      gribPrintSec0(isec0);
+      gribPrintSec1(isec0, isec1);
+      /*
+	Print section 2 if present.
+      */
+      if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
 
+      if ( ! l_iorj )
+	{
+	  /*
+	    Print section 3 if present.
+	  */
+	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
 
-int vlistInqVarXYZ(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
+	  /*
+	    Special print for 2D spectra wave field real values in
+	    section 4
+	  */
+	  if ( (isec1[ 0] ==  140) && 
+	       (isec1[ 1] ==   98) && 
+	       (isec1[23] ==    1) && 
+	       ((isec1[39] == 1045) || (isec1[39] == 1081))  && 
+	       ((isec1[ 5] ==  250) || (isec1[ 5] ==  251)) )
+	    gribPrintSec4Wave(isec4);
+	}
+    }
+}
 
-  vlistCheckVarID(__func__, vlistID, varID);
+#endif /* T */
 
-  return (vlistptr->vars[varID].xyz);
-}
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
 
-/* Ensemble Info Routines */
-void vlistDefVarEnsemble(int vlistID, int varID, int ensID, int ensCount, int forecast_type )
+static 
+int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* int imisng = 0; */
+  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
+  int  locnv = 0, locnl;
+  int  jlenl;
+  long i;
+  int iexp, imant;
+  int ipvpl, ipl;
+  int gdsLen = 0;
+#if defined (VECTORCODE)
+  unsigned char *igrib;
+  GRIBPACK *lgrib = NULL;
+  size_t lGribLen = 0;
+#endif
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  *numGridVals = 0;
 
-  if ( vlistptr->vars[varID].ensdata == NULL )
-    vlistptr->vars[varID].ensdata
-      = (ensinfo_t *)xmalloc( sizeof( ensinfo_t ) );
+  memset(isec2, 0, 22*sizeof(int));
 
-  vlistptr->vars[varID].ensdata->ens_index          = ensID;
-  vlistptr->vars[varID].ensdata->ens_count          = ensCount;
-  vlistptr->vars[varID].ensdata->forecast_init_type = forecast_type;
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-}
+  gdsLen = GDS_Len;
 
+  ipvpl = GDS_PVPL;
+  if ( ipvpl == 0 ) ipvpl = 0xFF;
 
-int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int *forecast_type )
-{
-  int status = 0;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( ipvpl != 0xFF )
+    { /* Either vct or reduced grid */
+      if ( GDS_NV != 0 )
+	{ /* we have vct */
+	  VertCoorTab = TRUE;
+	  ipl =  4*GDS_NV + ipvpl - 1;
+	  if ( ipl < gdsLen )
+	    {
+	      ReducedGrid = TRUE;
+	    }
+	}
+      else
+	{
+	  VertCoorTab = FALSE;
+	  ReducedGrid = TRUE;
+	}
+      /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+    }
+ 
+  if ( ISEC0_GRIB_Version == 0 )
+    {
+      if ((gdsLen - 32) > 0) VertCoorTab = TRUE;
+      else                   VertCoorTab = FALSE;
+    }
+  
+  if ( ReducedGrid )
+    {
+      locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+      jlenl = (gdsLen - locnl)  >> 1;
+      if ( jlenl == GDS_NumLat )
+	{
+	  *numGridVals = 0;
+	  ISEC2_Reduced = TRUE;
+	  for ( i = 0; i < jlenl; i++ )
+	    {
+	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
+	      *numGridVals += ISEC2_RowLon(i);
+	    }
+	}
+      else
+	{
+	  ReducedGrid = FALSE;
+	}
+    }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  ISEC2_GridType = GDS_GridType;
 
-  if ( vlistptr->vars[varID].ensdata )
+  /*
+     Gaussian grid definition.
+  */
+  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
+       ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
+       ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
     {
-      *ensID = vlistptr->vars[varID].ensdata->ens_index;
-      *ensCount = vlistptr->vars[varID].ensdata->ens_count;
-      *forecast_type = vlistptr->vars[varID].ensdata->forecast_init_type;
+      ISEC2_NumLat    = GDS_NumLat;
+      if ( ! ReducedGrid )
+	{
+	  ISEC2_NumLon = GDS_NumLon;
+	  *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+	}
+      ISEC2_FirstLat  = GDS_FirstLat;
+      ISEC2_FirstLon  = GDS_FirstLon;
+      ISEC2_ResFlag   = GDS_ResFlag;
+      ISEC2_LastLat   = GDS_LastLat;
+      ISEC2_LastLon   = GDS_LastLon;
+      ISEC2_LonIncr   = GDS_LonIncr;
 
-      status = 1;
+      ISEC2_NumPar    = GDS_NumPar;
+      ISEC2_ScanFlag  = GDS_ScanFlag;
+      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+	{
+	  ISEC2_LatSP     = GDS_LatSP;
+	  ISEC2_LonSP     = GDS_LonSP;
+	  FSEC2_RotAngle  = GDS_RotAngle;
+	}
+      /*
+	if ( Lons != Longitudes || Lats != Latitudes )
+	Error("Latitude/Longitude Conflict");
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN     ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
+    {
+      /*
+      iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON     ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
+    {
+      /*
+      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
+    {
+      ISEC2_NumLon    = GDS_NumLon;
+      ISEC2_NumLat    = GDS_NumLat;
+      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+      ISEC2_FirstLat  = GDS_FirstLat;
+      ISEC2_FirstLon  = GDS_FirstLon;
+      ISEC2_ResFlag   = GDS_ResFlag;
+      ISEC2_Lambert_Lov   = GDS_Lambert_Lov;
+      ISEC2_Lambert_dx    = GDS_Lambert_dx;
+      ISEC2_Lambert_dy    = GDS_Lambert_dy;
+      ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
+      ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
+      ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
+      ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
+      ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
+      ISEC2_ScanFlag      = GDS_ScanFlag;
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+    {
+      ISEC2_PentaJ  = GDS_PentaJ; /* Truncation */
+      ISEC2_PentaK  = GDS_PentaK;
+      ISEC2_PentaM  = GDS_PentaM;
+      ISEC2_RepType = GDS_RepType;
+      ISEC2_RepMode = GDS_RepMode;
+      *numGridVals  = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
+      isec2[ 6] = 0;
+      isec2[ 7] = 0;
+      isec2[ 8] = 0;
+      isec2[ 9] = 0;
+      isec2[10] = 0;
+      /*
+      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+    {
+      ISEC2_GME_NI2    = GDS_GME_NI2;
+      ISEC2_GME_NI3    = GDS_GME_NI3;
+      ISEC2_GME_ND     = GDS_GME_ND;
+      ISEC2_GME_NI     = GDS_GME_NI;
+      ISEC2_GME_AFlag  = GDS_GME_AFlag;
+      ISEC2_GME_LatPP  = GDS_GME_LatPP;
+      ISEC2_GME_LonPP  = GDS_GME_LonPP;
+      ISEC2_GME_LonMPL = GDS_GME_LonMPL;
+      ISEC2_GME_BFlag  = GDS_GME_BFlag;
+      *numGridVals  = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
+      /*
+      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+      */
+    }
+  else
+    {
+      ISEC2_NumLon = GDS_NumLon;
+      ISEC2_NumLat = GDS_NumLat;
+      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
+      Message("Gridtype %d unsupported", ISEC2_GridType);
     }
 
-  return (status);
-}
-
-/* ---------------------------------- */
-/* Local change: 2013-01-28, FP (DWD) */
-/* ---------------------------------- */
-
-/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
-void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
-{
-#if  defined  (HAVE_LIBGRIB_API)
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  int idx;
+  /*    vertical coordinate parameters for hybrid levels.     */
+  /*    get number of vertical coordinate parameters, if any. */
 
-  if ( !vlistptr->locked )
-    Error("User defined vlist object (vlistID=%d) isn't allowed!\n"
-          "Need a CDI internal vlist object from streamInqVlist(streamID).", vlistID);
+  ISEC2_NumVCP = 0;
 
-  for ( idx=0; idx<vlistptr->vars[varID].opt_grib_int_nentries; idx++)
-    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[idx]) == 0 ) break;
+  isec2[17] = 0;
+  isec2[18] = 0;
 
-  if ( idx < vlistptr->vars[varID].opt_grib_int_nentries )
-    {
-      vlistptr->vars[varID].opt_grib_int_val[idx] = value;
-      vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
-    }
-  else
+  if ( VertCoorTab == TRUE )
     {
-      idx = vlistptr->vars[varID].opt_grib_int_nentries;
-      vlistptr->vars[varID].opt_grib_int_nentries++;
-      if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
-      vlistptr->vars[varID].opt_grib_int_val[idx] = value;
-      vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
-      if ( name )
-        vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
+      if ( ISEC0_GRIB_Version  == 0 )
+	{
+	  locnv = 32;
+	  ISEC2_NumVCP = (gdsLen - 32) >> 2;
+	}
       else
-        Error("Internal error, name undefined!");
-    }
+	{
+	  locnv = GDS_PVPL - 1;
+	  ISEC2_NumVCP = GDS_NV;
+	}
+#if defined (SX)
+      lGribLen = 4*ISEC2_NumVCP;	      
+      lgrib    = (GRIBPACK*) malloc(lGribLen*sizeof(GRIBPACK));
 
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+      igrib = &gds[locnv];
+      if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
+      for ( i = 0; i < ISEC2_NumVCP; i++ )
+	{
+	  iexp   = (lgrib[4*i  ]);
+	  imant  =((lgrib[4*i+1]) << 16) +
+	          ((lgrib[4*i+2]) <<  8) +
+	           (lgrib[4*i+3]);
+	  fsec2[10+i] = POW_2_M24 * imant * pow(16.0, (double)(iexp - 64));
+	}
+
+      free(lgrib);
 #else
-  (void)vlistID;
-  (void)varID;
-  (void)name;
-  (void)value;
+      for ( i = 0; i < ISEC2_NumVCP; i++ )
+	{
+	  iexp   = (gds[locnv+4*i  ]);
+	  imant  =((gds[locnv+4*i+1]) << 16) +
+	          ((gds[locnv+4*i+2]) <<  8) +
+	           (gds[locnv+4*i+3]);
+	  fsec2[10+i] = decfp2(iexp,imant);
+	}
 #endif
+    }
+
+  return (gdsLen);
 }
 
-/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
-void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
+static
+int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
+			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
 {
-#if  defined  (HAVE_LIBGRIB_API)
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  int idx;
+  unsigned char *igrib;
+  int lspherc = FALSE, lcomplex = FALSE;
+  int lcompress;
+  int jup, kup, mup;
+  int locnd;
+  long jlend;
+  long i;
+  int bds_flag, jscale, imiss;
+  int bds_ubits;
+  int ioff = 0;
+  int iexp, imant;
+  int zoff;
+  int bds_head = 11;
+  double zscale = 0.;
+  T fmin = 0.;
+  T *fpdata = fsec4;
+  int bdsLen;
+  extern int CGRIBEX_Fix_ZSE;
 
-  if ( !vlistptr->locked )
-    Error("User defined vlist object (vlistID=%d) isn't allowed!\n"
-          "Need a CDI internal vlist object from streamInqVlist(streamID).", vlistID);
+  *iret = 0;
+  igrib = bds;
 
-  for ( idx=0; idx<vlistptr->vars[varID].opt_grib_dbl_nentries; idx++)
-    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[idx]) == 0 ) break;
+  memset(isec4, 0, 42*sizeof(int));
 
-  if ( idx < vlistptr->vars[varID].opt_grib_dbl_nentries )
-    {
-      vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
-      vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
-    }
-  else
-    {
-      idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
-      vlistptr->vars[varID].opt_grib_dbl_nentries++;
-      if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
-      vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
-      vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
-      if ( name )
-        vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
-      else
-        Error("Internal error, name undefined!");
-    }
+  /* get length of binary data block. */
+
+  bdsLen = BDS_Len;
+  /*
+    If a very large product, the section 4 length field holds
+    the number of bytes in the product after section 4 upto
+    the end of the padding bytes.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  if ( llarge ) bdsLen = bdsLenIn - bdsLen;
 
-  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-#else
-  (void)vlistID;
-  (void)varID;
-  (void)name;
-  (void)value;
-#endif
-}
+  /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
 
-#if  defined  (HAVE_LIBGRIB_API)
-#endif
+  bds_flag = BDS_Flag;
 
+  /* 0------- grid point           */
+  /* 1------- spherical harmonics  */
 
-/* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
-void cdiClearAdditionalKeys()
-{
-#if  defined  (HAVE_LIBGRIB_API)
-  for (int i=0; i<cdiNAdditionalGRIBKeys; i++)  free(cdiAdditionalGRIBKeys[i]);
-  cdiNAdditionalGRIBKeys = 0;
-#endif
-}
+  lspherc = bds_flag >> 7;
 
-/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
-void cdiDefAdditionalKey(const char *name)
-{
-#if  defined  (HAVE_LIBGRIB_API)
-  int idx = cdiNAdditionalGRIBKeys;
-  cdiNAdditionalGRIBKeys++;
-  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many additional keywords!");
-  if ( name )
-    cdiAdditionalGRIBKeys[idx] = strdupx(name);
-  else
-    Error("Internal error!");
-#else
-  (void)name;
-#endif
-}
+  if ( lspherc ) isec4[2] = 128;
+  else           isec4[2] = 0;
 
-/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
-int vlistHasVarKey(int vlistID, int varID, const char* name)
-{
-#if  defined  (HAVE_LIBGRIB_API)
-  /* check if the GRIB key was previously read and is stored */
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* -0------  simple packing */
+  /* -1------ complex packing */
 
-  for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
-    {
-      if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
-	return 1;
-    }
+  lcomplex = (bds_flag >> 6)&1;
 
-  for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
-    {
-      if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
-	return 1;
-    }
-#else
-  (void)vlistID;
-  (void)varID;
-  (void)name;
-#endif
-  return 0;
-}
+  if ( lcomplex ) isec4[3] = 64;
+  else            isec4[3] =  0;
 
-/* vlistInqVarDblKey: raw access to GRIB meta-data */
-double vlistInqVarDblKey(int vlistID, int varID, const char* name)
-{
-  double value = 0;
-#if  defined  (HAVE_LIBGRIB_API)
-  /* check if the GRIB key was previously read and is stored in "opt_grib_dbl_val" */
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* ---0---- No additional flags */
+  /* ---1---- No additional flags */
 
-  for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
-    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
-      return vlistptr->vars[varID].opt_grib_dbl_val[i];
-#else
-  (void)vlistID;
-  (void)varID;
-  (void)name;
-#endif
-  return value;
-}
+  lcompress = (bds_flag >> 4)&1; /* compress */
 
+  if ( lcompress )
+    { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
+  else
+    { isec4[5] =  0; isec4[6] = 0;     zoff =  0; }
 
-/* vlistInqVarIntKey: raw access to GRIB meta-data */
-int vlistInqVarIntKey(int vlistID, int varID, const char* name)
-{
-  long int value = 0;
-#if  defined  (HAVE_LIBGRIB_API)
-  /* check if the GRIB key was previously read and is stored in "opt_grib_int_val" */
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  /* ----++++ number of unused bits at end of section) */
 
-  for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
-    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
-      return vlistptr->vars[varID].opt_grib_int_val[i];
-#else
-  (void)vlistID;
-  (void)varID;
-  (void)name;
-#endif
-  return (int) value;
-}
+  bds_ubits = bds_flag & 0xF;
+  
+  /* scale factor (2 bytes) */;
 
+  jscale = BDS_BinScale;
 
-void vlistDefVarIOrank(int vlistID, int varID, int iorank)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID );
+  /* check for missing data indicators. */
 
-  vlistCheckVarID ( __func__, vlistID, varID );
+  iexp  = bds[ 6];
+  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
 
-  if (vlistptr->vars[varID].iorank != iorank)
-    {
-      vlistptr->vars[varID].iorank = iorank;
-      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-    }
-}
+  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
 
+  /* convert reference value and scale factor. */
 
-int vlistInqVarIOrank(int vlistID, int varID)
-{
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( ! (dfunc == 'J') )
+    if ( imiss == 0 )
+      {
+	fmin = BDS_RefValue;
+	
+	if ( jscale < 0 )
+	  zscale = 1.0/intpow2(-jscale);
+	else
+	  zscale = intpow2(jscale);
+      }
 
-  vlistCheckVarID(__func__, vlistID, varID);
+  /* get number of bits in each data value. */
 
-  return vlistptr->vars[varID].iorank;
-}
+  ISEC4_NumBits = BDS_NumBits;
 
+  /* octet number of start of packed data */
+  /* calculated from start of block 4 - 1 */
 
-int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
-{
-  xassert(a && b
-          && varIDA >= 0 && varIDA < a->nvars
-          && varIDB >= 0 && varIDB < b->nvars);
-  var_t *pva = a->vars + varIDA, *pvb = b->vars + varIDB;
-#define FCMP(f) ((pva->f) != (pvb->f))
-#define FCMPFLT(f) (IS_NOT_EQUAL((pva->f), (pvb->f)))
-#define FCMPSTR(fs) ((pva->fs) != (pvb->fs) && strcmp((pva->fs), (pvb->fs)))
-#define FCMP2(f) (namespaceResHDecode(pva->f).idx       \
-                  != namespaceResHDecode(pvb->f).idx)
-  int diff = FCMP(fvarID) | FCMP(mvarID) | FCMP(flag) | FCMP(param)
-    | FCMP(datatype) | FCMP(tsteptype) | FCMP(timave) | FCMP(timaccu)
-    | FCMP(chunktype) | FCMP(xyz) | FCMP2(gridID) | FCMP2(zaxisID)
-    | FCMP2(instID) | FCMP2(modelID) | FCMP2(tableID) | FCMP(missvalused)
-    | FCMPFLT(missval) | FCMPFLT(addoffset) | FCMPFLT(scalefactor) | FCMPSTR(name)
-    | FCMPSTR(longname) | FCMPSTR(stdname) | FCMPSTR(units) | FCMPSTR(extra)
-    | FCMP(comptype) | FCMP(complevel) | FCMP(lvalidrange)
-    | FCMPFLT(validrange[0]) | FCMPFLT(validrange[1]);
-#undef FCMP
-#undef FCMPFLT
-#undef FCMP2
-  if ((diff |= ((pva->levinfo == NULL) ^ (pvb->levinfo == NULL))))
-    return 1;
-  if (pva->levinfo)
+  locnd = zoff + bds_head;
+
+  /* if data is in spherical harmonic form, distinguish   */
+  /* between simple/complex packing (lcomplex = 0/1)      */
+
+  if ( lspherc )
     {
-      int zaxisID = pva->zaxisID;
-      size_t nlevs = (size_t)zaxisInqSize(zaxisID);
-      diff |= (memcmp(pva->levinfo, pvb->levinfo, sizeof (levinfo_t) * nlevs)
-               != 0);
-      if (diff)
-        return 1;
-    }
-  size_t natts = a->vars[varIDA].atts.nelems;
-  if (natts != b->vars[varIDB].atts.nelems)
-    return 1;
-  for (size_t attID = 0; attID < natts; ++attID)
-    diff |= vlist_att_compare(a, varIDA, b, varIDB, (int)attID);
-  if ((diff |= ((pva->ensdata == NULL) ^ (pvb->ensdata == NULL))))
-    return 1;
-  if (pva->ensdata)
-    diff = (memcmp(pva->ensdata, pvb->ensdata, sizeof (*(pva->ensdata)))) != 0;
-  return diff;
-}
+      if ( !lcomplex )
+	{
+	  /*    no unpacked binary data present */
 
+	  jup = kup = mup = 0;
 
+	  /*    octet number of start of packed data */
+	  /*    calculated from start of block 4 - 1 */
 
-enum {
-  vlistvar_nints = 20,
-  vlistvar_ndbls = 3,
-};
+	  ioff   = 1;
+	  locnd += 4*ioff;  /* RealCoef */
 
-int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
-{
-  var_t *var = p->vars + varID;
-  int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
-    + serializeGetSize(vlistvar_ndbls, DATATYPE_FLT64, context);
-  if (var->name)
-    varsize += serializeGetSize((int)strlen(var->name), DATATYPE_TXT, context);
-  if (var->longname)
-    varsize += serializeGetSize((int)strlen(var->longname), DATATYPE_TXT, context);
-  if (var->stdname)
-    varsize += serializeGetSize((int)strlen(var->stdname), DATATYPE_TXT, context);
-  if (var->units)
-    varsize += serializeGetSize((int)strlen(var->units), DATATYPE_TXT, context);
-  varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
-                              DATATYPE_INT, context);
-  varsize += vlistAttsGetSize(p, varID, context);
-  return varsize;
-}
+	  /*    get real (0,0) coefficient in grib format and     */
+	  /*    convert to floating point.                        */
 
-void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
-                  void *context)
-{
-  double dtempbuf[vlistvar_ndbls];
-  var_t *var = p->vars + varID;
-  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz;
+	  if ( dfunc != 'J' )
+	    {
+	      if ( imiss ) *fpdata++ = 0.0;
+	      else         *fpdata++ = BDS_RealCoef;
+	    }
+	}
+      else /* complex packed spherical harmonics */
+	{
+	  isec4[15] = BDS_PackData;
+	  /*    scaling factor */
+	  isec4[16] = BDS_Power;
 
-  tempbuf[0] = var->flag;
-  tempbuf[1] = var->gridID;
-  tempbuf[2] = var->zaxisID;
-  tempbuf[3] = var->tsteptype;
-  tempbuf[4] = namesz = var->name?(int)strlen(var->name):0;
-  tempbuf[5] = longnamesz = var->longname?(int)strlen(var->longname):0;
-  tempbuf[6] = stdnamesz = var->stdname?(int)strlen(var->stdname):0;
-  tempbuf[7] = unitssz = var->units?(int)strlen(var->units):0;
-  tempbuf[8] = var->datatype;
-  tempbuf[9] = var->param;
-  tempbuf[10] = var->instID;
-  tempbuf[11] = var->modelID;
-  tempbuf[12] = var->tableID;
-  tempbuf[13] = var->timave;
-  tempbuf[14] = var->timaccu;
-  tempbuf[15] = var->missvalused;
-  tempbuf[16] = var->comptype;
-  tempbuf[17] = var->complevel;
-  int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
-  tempbuf[18] = nlevs;
-  tempbuf[19] = var->iorank;
-  dtempbuf[0] = var->missval;
-  dtempbuf[1] = var->scalefactor;
-  dtempbuf[2] = var->addoffset;
-  serializePack(tempbuf, vlistvar_nints, DATATYPE_INT,
-                buf, size, position, context);
-  serializePack(dtempbuf, vlistvar_ndbls, DATATYPE_FLT64,
-                buf, size, position, context);
-  if (namesz)
-    serializePack(var->name, namesz, DATATYPE_TXT, buf, size, position, context);
-  if (longnamesz)
-    serializePack(var->longname, longnamesz, DATATYPE_TXT,
-                  buf, size, position, context);
-  if (stdnamesz)
-    serializePack(var->stdname, stdnamesz, DATATYPE_TXT,
-                  buf, size, position, context);
-  if (unitssz)
-    serializePack(var->units, unitssz, DATATYPE_TXT,
-                  buf, size, position, context);
-  if (nlevs)
-    {
-      int levbuf[nlevs][4];
-      for (int levID = 0; levID < nlevs; ++levID)
-        {
-          levbuf[levID][0] = var->levinfo[levID].flag;
-          levbuf[levID][1] = var->levinfo[levID].index;
-          levbuf[levID][2] = var->levinfo[levID].mlevelID;
-          levbuf[levID][3] = var->levinfo[levID].flevelID;
-        }
-      serializePack(levbuf, nlevs * 4, DATATYPE_INT,
-                    buf, size, position, context);
-    }
-  vlistAttsPack(p, varID, buf, size, position, context);
-}
+	  /*    pentagonal resolution parameters of the */
+	  /*    unpacked section of data field          */
 
-static inline int
-imax(int a, int b)
-{
-  return a>=b?a:b;
-}
+	  jup = bds[zoff+15];
+	  kup = bds[zoff+16];
+	  mup = bds[zoff+17];
 
+	  isec4[zoff+17] = jup;
+	  isec4[zoff+18] = kup;
+	  isec4[zoff+19] = mup;
 
-void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
-		    int originNamespace, void *context)
-{
-  double dtempbuf[vlistvar_ndbls];
-  int tempbuf[vlistvar_nints];
-  char *varname = NULL;
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  serializeUnpack(buf, size, position,
-                  tempbuf, vlistvar_nints, DATATYPE_INT, context);
-  serializeUnpack(buf, size, position,
-                  dtempbuf, vlistvar_ndbls, DATATYPE_FLT64, context);
+	  /*    unpacked binary data */
 
-  int newvar = vlistDefVar ( vlistID,
-			 namespaceAdaptKey ( tempbuf[1], originNamespace ),
-			 namespaceAdaptKey ( tempbuf[2], originNamespace ),
-			 tempbuf[3]);
-  if (tempbuf[4] || tempbuf[5] || tempbuf[6] || tempbuf[7])
-    varname = (char *)xmalloc((size_t)imax(imax(imax(tempbuf[4],tempbuf[5]),
-                                                tempbuf[6]),
-                                           tempbuf[7]) + 1);
-  if (tempbuf[4])
-  {
-    serializeUnpack(buf, size, position,
-                    varname, tempbuf[4], DATATYPE_TXT, context);
-    varname[tempbuf[4]] = '\0';
-    vlistDefVarName(vlistID, newvar, varname);
-  }
-  if (tempbuf[5])
-  {
-    serializeUnpack(buf, size, position,
-                    varname, tempbuf[5], DATATYPE_TXT, context);
-    varname[tempbuf[5]] = '\0';
-    vlistDefVarLongname(vlistID, newvar, varname);
-  }
-  if (tempbuf[6])
-  {
-    serializeUnpack(buf, size, position,
-                    varname, tempbuf[6], DATATYPE_TXT, context);
-    varname[tempbuf[6]] = '\0';
-    vlistDefVarStdname(vlistID, newvar, varname);
-  }
-  if (tempbuf[7])
-  {
-    serializeUnpack(buf, size, position,
-                    varname, tempbuf[7], DATATYPE_TXT, context);
-    varname[tempbuf[7]] = '\0';
-    vlistDefVarUnits(vlistID, newvar, varname);
-  }
-  free(varname);
-  vlistDefVarDatatype(vlistID, newvar, tempbuf[8]);
-  vlistDefVarInstitut ( vlistID, newvar,
-			namespaceAdaptKey ( tempbuf[10], originNamespace ));
-  vlistDefVarModel ( vlistID, newvar,
-		     namespaceAdaptKey ( tempbuf[11], originNamespace ));
-  vlistDefVarTable(vlistID, newvar, tempbuf[12]);
-  /* FIXME: changing the table might change the param code */
-  vlistDefVarParam(vlistID, newvar, tempbuf[9]);
-  vlistDefVarTimave(vlistID, newvar, tempbuf[13]);
-  vlistDefVarTimaccu(vlistID, newvar, tempbuf[14]);
-  if (tempbuf[15])
-    vlistDefVarMissval(vlistID, newvar, dtempbuf[0]);
-  vlistDefVarScalefactor(vlistID, newvar, dtempbuf[1]);
-  vlistDefVarAddoffset(vlistID, newvar, dtempbuf[2]);
-  vlistDefVarCompType(vlistID, newvar, tempbuf[16]);
-  vlistDefVarCompLevel(vlistID, newvar, tempbuf[17]);
-  int nlevs = tempbuf[18];
-  if (nlevs)
+	  locnd += 4; /* 2 + power */
+	  locnd += 3; /* j, k, m   */
+	  ioff   = (jup+1)*(jup+2);
+
+	  if ( dfunc != 'J' )
+	    for ( i = 0; i < ioff; i++ )
+	      {
+		if ( imiss )
+		  *fpdata++ = 0.0;
+		else
+		  {
+		    iexp   = (bds[locnd+4*i  ]);
+		    imant  =((bds[locnd+4*i+1]) << 16) +
+		            ((bds[locnd+4*i+2]) <<  8) +
+		             (bds[locnd+4*i+3]);
+
+		    *fpdata++ = decfp2(iexp,imant);
+		  }
+	      }
+	  
+	  locnd += 4*ioff;  /* RealCoef */
+	}
+    }
+  else
     {
-      int levbuf[nlevs][4];
-      var_t *var = vlistptr->vars + newvar;
-      int i, flagSetLev = 0;
-      cdiVlistCreateVarLevInfo(vlistptr, newvar);
-      serializeUnpack(buf, size, position,
-                      levbuf, nlevs * 4, DATATYPE_INT, context);
-      for (i = 0; i < nlevs; ++i)
-        {
-          vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
-          vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
-          // FIXME: these lack an accessor function
-          var->levinfo[i].mlevelID = levbuf[i][2];
-          var->levinfo[i].flevelID = levbuf[i][3];
-          if (levbuf[i][0] == tempbuf[0])
-            flagSetLev = i;
-        }
-      vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
+      if ( lcomplex )
+	{
+	  *iret = 1999;
+	  gprintf(__func__, " Second order packed grids unsupported!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
+	}
     }
-  vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
-  vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
-}
 
+  /* Decode data values to floating point and store in fsec4.  */
+  /* First calculate the number of data values.                */
+  /* Take into account that spherical harmonics can be packed  */
+  /* simple (lcomplex = 0) or complex (lcomplex = 1)           */
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  jlend = bdsLen - locnd;
 
-#include <stdio.h>
+  if ( ISEC4_NumBits == 0 )
+    {
+      if ( jlend > 1 )
+	{
+	  *iret = 2001;
+	  gprintf(__func__, " Number of bits per data value = 0!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
+	}
 
+      if ( numGridVals == 0 )
+	{
+	  *iret = 2002;
+	  gprintf(__func__, " Constant field unsupported for this grid type!");
+	  gprintf(__func__, " Return code =  %d", *iret);
+	  return (0);
+	}
 
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
+      jlend = numGridVals;
+      jlend -= ioff;
+    }
+  else
+    {
+      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+    }
 
-void basetimeInit(basetime_t *basetime)
-{
-  if ( basetime == NULL )
-    Error("Internal problem! Basetime not allocated.");
+  ISEC4_NumValues        = jlend + ioff;
+  ISEC4_NumNonMissValues = 0;
 
-  basetime->ncvarid       = UNDEFID;
-  basetime->ncdimid       = UNDEFID;
-  basetime->ncvarboundsid = UNDEFID;
-  basetime->leadtimeid    = UNDEFID;
-  basetime->lwrf          = 0;
-  basetime->timevar_cache = NULL;
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  if ( lcompress )
+    {
+      size_t len;
 
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
+      if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
+	len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
+      else
+        len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
+      ISEC4_NumValues = len*8/ISEC4_NumBits;
 
+      if ( lspherc )
+	{
+	  if ( lcomplex )
+	    ISEC4_NumValues += ioff;
+	  else
+	    ISEC4_NumValues++;
+	}
+    }
 
+  if ( dfunc == 'J' ) return (bdsLen);
 
-enum {
-  SRV_HEADER_LEN = 8,
-};
+  /* check length of output array. */
+  
+  if ( ISEC4_NumValues > fsec4len )
+    {
+      *iret = 710;
+      gprintf(__func__, " Output array too small. Length = %d", fsec4len);
+      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
+      gprintf(__func__, " Return code =  %d", *iret);
+      return (0);
+    }
 
+  if ( imiss ) memset((char *)fpdata, 0, jlend*sizeof(T));
+  else
+    {
+      igrib += locnd;
 
-static int initSrvLib      = 0;
-static int srvDefaultHprec = 0;
-static int srvDefaultDprec = 0;
+      TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+    }
 
+  if ( lspherc && lcomplex )
+    {
+      int pcStart, pcScale;
+      pcStart = isec4[19];
+      pcScale = isec4[16];
+      TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
+      TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
+    }
 
-/*
- * A version string.
- */
+  if ( CGRIBEX_Fix_ZSE )  /* Fix ZeroShiftError of simple packed spherical harmonics */
+    if ( lspherc && !lcomplex )
+      {
+        /* 20100705: Fix ZeroShiftError - Edi Kirk */
+	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
+	  {
+	    T zserr = fsec4[1];
+	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
+	  }
+      }
 
-#undef  LIBVERSION
-#define LIBVERSION      1.3.2
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
-static const char srv_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
+  if ( decscale )
+    {
+      T scale = (T) pow(10.0, (double)-decscale);
+      for ( i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
+    }
 
-const char *srvLibraryVersion(void)
-{
-  return (srv_libvers);
+  return (bdsLen);
 }
 
 
-int SRV_Debug = 0;    /* If set to 1, debugging */
+void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+			     T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
+			     int kleng, int *kword, int dfunc, int *iret)
+{
+  UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
+  int gribLen = 0;
+  int gdsIncluded = FALSE;
+  int bmsIncluded = FALSE;
+  int bitmapSize = 0;
+  int imaskSize = 0;
+  int ldebug = FALSE;
+  int llarge = FALSE, l_iorj = FALSE;
+  int lsect2 = FALSE, lsect3 = FALSE;
+  int numGridVals = 0;
+  static int lmissvalinfo = 1;
 
+  UNUSED(kleng);
 
-void srvDebug(int debug)
-{
-  SRV_Debug = debug;
+  *iret = 0;
 
-  if ( SRV_Debug )
-    Message("debug level %d", debug);
-}
+  grsdef();
 
+  ISEC2_Reduced = FALSE;
 
-void srvLibInit()
-{
-  char *envString;
-  char *envName = "SRV_PRECISION";
+  /*
+    ----------------------------------------------------------------
+    IS Indicator Section (Section 0)
+    ----------------------------------------------------------------
+  */
+  is = (unsigned char *) &kgrib[0];
 
+  isLen = decodeIS(is, isec0, iret);
 
-  envString = getenv(envName);
-  if ( envString )
+  /*
+    If count is negative, have to rescale by factor of -120.
+    This is a fixup to get round the restriction on product lengths
+    due to the count being only 24 bits. It is only possible because
+    the (default) rounding for GRIB products is 120 bytes.
+  */
+  if ( ISEC0_GRIB_Len < 0 )
     {
-      int pos;
-      int nrun;
-      if ( strlen(envString) == 2 ) nrun = 1;
-      else                          nrun = 2;
-
-      pos = 0;
-      while ( nrun-- )
-	{
-	  switch ( tolower((int) envString[pos]) )
-	    {
-	    case 'i':
-	      {
-		switch ( (int) envString[pos+1] )
-		  {
-		  case '4': srvDefaultHprec = SINGLE_PRECISION; break;
-		  case '8': srvDefaultHprec = DOUBLE_PRECISION; break;
-		  default:
-		    Message("Invalid digit in %s: %s", envName, envString);
-		  }
-		break;
-	      }
-	    case 'r':
-	      {
-		switch ( (int) envString[pos+1] )
-		  {
-		  case '4': srvDefaultDprec = SINGLE_PRECISION; break;
-		  case '8': srvDefaultDprec = DOUBLE_PRECISION; break;
-		  default:
-		    Message("Invalid digit in %s: %s", envName, envString);
-		  }
-		break;
-	      }
-	    default:
-              {
-                Message("Invalid character in %s: %s", envName, envString);
-                break;
-              }
-            }
-	  pos += 2;
-	}
+      if ( ldebug )
+	gprintf(__func__, "Special case, negative length multiplied by -120");
+      llarge = TRUE;
+      ISEC0_GRIB_Len *= (-120);
     }
+  /*
+    When decoding or calculating length, previous editions
+    of the GRIB code must be taken into account.
 
-  initSrvLib = 1;
-}
+    In the table below, covering sections 0 and 1 of the GRIB
+    code, octet numbering is from the beginning of the GRIB
+    message;
+    * indicates that the value is not available in the code edition;
+    R indicates reserved, should be set to 0;
+    Experimental edition is considered as edition -1.
 
+    GRIB code edition -1 has fixed length of 20 octets for
+    section 1, the length not included in the message.
+    GRIB code edition 0 has fixed length of 24 octets for
+    section 1, the length being included in the message.
+    GRIB code edition 1 can have different lengths for section
+    1, the minimum being 28 octets, length being included in
+    the message.
 
-void srvInit(srvrec_t *srvp)
-{
-  srvp->checked    = 0;
-  srvp->byteswap   = 0;
-  srvp->hprec      = 0;
-  srvp->dprec      = 0;
-  srvp->datasize   = 0;
-  srvp->buffersize = 0;
-  srvp->buffer     = NULL;
-}
+                                         Octet numbers for code
+                                                  editions
 
+                 Contents.                   -1      0      1
+                 ---------                ----------------------
+       Letters GRIB                          1-4    1-4    1-4
+       Total length of GRIB message.          *      *     5-7
+       GRIB code edition number               *      *      8
+       Length of Section 1.                   *     5-7    9-11
+       Reserved octet (R).                    *      8(R)   *
+       Version no. of Code Table 2.           *      *     12
+       Identification of centre.              5      9     13
+       Generating process.                    6     10     14
+       Grid definition .                      7     11     15
+       Flag (Code Table 1).                   8     12     16
+       Indicator of parameter.                9     13     17
+       Indicator of type of level.           10     14     18
+       Height, pressure etc of levels.      11-12  15-16  19-20
+       Year of century.                      13     17     21
+       Month.                                14     18     22
+       Day.                                  15     19     23
+       Hour.                                 16     20     24
+       Minute.                               17     21     25
+       Indicator of unit of time.            18     22     26
+       P1 - Period of time.                  19     23     27
+       P2 - Period of time                  20(R)   24     28
+       or reserved octet (R).
+       Time range indicator.                21(R)   25     29
+       or reserved octet (R).
+       Number included in average.       22-23(R)  26-27  30-31
+       or reserved octet (R).
+       Number missing from average.         24(R)  28(R)   32
+       or reserved octet (R).
+       Century of data.                       *      *     33
+       Designates sub-centre if not 0.        *      *     34
+       Decimal scale factor.                  *      *    35-36
+       Reserved. Set to 0.                    *      *    37-48
+       (Need not be present)
+       For originating centre use only.       *      *    49-nn
+       (Need not be present)
 
-srvrec_t *srvNew(void)
-{
-  srvrec_t *srvp;
+    Identify which GRIB code edition is being decoded.
 
-  if ( ! initSrvLib ) srvLibInit();
+    In GRIB edition 1, the edition number is in octet 8.
+    In GRIB edition 0, octet 8 is reserved and set to 0.
+    In GRIB edition -1, octet 8 is a flag field and can have a
+    a valid value of 0, 1, 2 or 3.
 
-  srvp = (srvrec_t *) malloc(sizeof(srvrec_t));
+    However, GRIB edition number 0 has a fixed
+    length of 24, included in the message, for section 1, so
+    if the value extracted from octets 5-7 is 24 and that from
+    octet 8 is 0, it is safe to assume edition 0 of the code.
 
-  srvInit(srvp);
+  */
+  if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
+    {
+      /*
+	Set length of GRIB message to missing data value.
+      */
+      ISEC0_GRIB_Len = 0;
+    }
+  /*
+    If Grib Edition 1 and only length is required, go to section 9.
+  */
+  if ( dfunc == 'L' ) goto LABEL900;
 
-  return (srvp);
-}
+  /*
+    ----------------------------------------------------------------
+    PDS Product Definition Section (Section 1)
+    ----------------------------------------------------------------
+  */ 
+  pds = is + isLen;
 
+  pdsLen = decodePDS(pds, isec0, isec1);
 
-void srvDelete(srvrec_t *srvp)
-{
-  if ( srvp )
+  /*
+    ----------------------------------------------------------------
+    GDS Grid Description Section (Section 2)
+    ----------------------------------------------------------------
+  */
+  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+
+  if ( gdsIncluded )
     {
-      if ( srvp->buffer ) free(srvp->buffer);
-      free(srvp);
+      gds = is + isLen + pdsLen;
+
+      gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
     }
-}
 
+  /*
+    ----------------------------------------------------------------
+    BMS Bit-Map Section Section (Section 3)
+    ----------------------------------------------------------------
+  */ 
+  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
 
-int srvCheckFiletype(int fileID, int *swap)
-{
-  size_t blocklen = 0;
-  size_t sblocklen = 0;
-  size_t data = 0;
-  size_t dimx = 0, dimy = 0;
-  size_t fact = 0;
-  int found = 0;
-  unsigned char buffer[72], *pbuf;
+  isec3[0] = 0;
+  if ( bmsIncluded )
+    {
+      bms = is + isLen + pdsLen + gdsLen;
 
-  if ( fileRead(fileID, buffer, 4) != 4 ) return (found);
+      bmsLen = BMS_Len;
+      imaskSize = (bmsLen - 6)<<3;
+      bitmapSize = imaskSize - BMS_UnusedBits;
+      /*
+      fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
+      */
+    }
 
-  blocklen  = (size_t) get_UINT32(buffer);
-  sblocklen = (size_t) get_SUINT32(buffer);
+  /*
+    ----------------------------------------------------------------
+    BDS Binary Data Section (Section 4)
+    ----------------------------------------------------------------
+  */
+  bds = is + isLen + pdsLen + gdsLen + bmsLen;
 
-  if ( SRV_Debug )
-    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
 
-  if ( blocklen == 32 )
-    {
-     *swap = 0;
-      fact = blocklen>>3;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
-      pbuf = buffer+4*fact;      dimx = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+5*fact;      dimy = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
-    }
-  else if ( blocklen == 64 )
-    {
-     *swap = 0;
-      fact = blocklen>>3;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
-      pbuf = buffer+4*fact;      dimx = (size_t) get_UINT64(pbuf);
-      pbuf = buffer+5*fact;      dimy = (size_t) get_UINT64(pbuf);
-      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
-    }
-  else if ( sblocklen == 32 )
-    {
-     *swap = 1;
-      fact = sblocklen>>3;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
-      pbuf = buffer+4*fact;       dimx = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+5*fact;       dimy = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
-    }
-  else if ( sblocklen == 64 )
-    {
-     *swap = 1;
-      fact = sblocklen>>3;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
-      pbuf = buffer+4*fact;       dimx = (size_t) get_SUINT64(pbuf);
-      pbuf = buffer+5*fact;       dimy = (size_t) get_SUINT64(pbuf);
-      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
-    }
+  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
+				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
 
-  fileRewind(fileID);
+  if ( *iret != 0 ) return;
 
-  if      ( data && dimx*dimy*fact == data ) found = 1;
-  else if ( data && dimx*dimy*8    == data ) found = 1;
+  ISEC4_NumNonMissValues = ISEC4_NumValues;
 
-  if ( SRV_Debug )
+  if ( bitmapSize > 0 )
     {
-      Message("swap = %d fact = %d", *swap, fact);
-      Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
-    }
+      if ( dfunc != 'L' && dfunc != 'J' )
+	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
+	  {
+	    lmissvalinfo = 0;
+	    FSEC3_MissVal = GRIB_MISSVAL;
+	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
+	  }
 
-  return (found);
-}
+      /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
+      ISEC4_NumValues        = bitmapSize;
 
+      if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
+	{
+	  long i, j;
+	  GRIBPACK *pbitmap;
+	  GRIBPACK bitmap;
+	  GRIBPACK *imask;
 
-int srvInqHeader(srvrec_t *srvp, int *header)
-{
-  size_t i;
+	  /*
+	  unsigned char *bitmap;
+	  bitmap = BMS_Bitmap;
+	  j = ISEC4_NumNonMissValues;
+	  for ( i = ISEC4_NumValues-1; i >= 0; i-- )
+	    {
+	      if ( (bitmap[i/8]>>(7-(i&7)))&1 )
+		fsec4[i] = fsec4[--j];
+	      else
+		fsec4[i] = FSEC3_MissVal;
+	    }
+	  */
 
-  for ( i = 0; i < SRV_HEADER_LEN; i++ )
-    header[i] = srvp->header[i];
-  
-  if ( SRV_Debug )
-    Message("datasize = %lu", srvp->datasize);
+	  imask = (GRIBPACK*) malloc(imaskSize*sizeof(GRIBPACK));
 
-  return (0);
-}
+#if defined (VECTORCODE)
+	  (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
+	  pbitmap = imask;
+#else
+	  pbitmap = BMS_Bitmap;
+#endif
+
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+	  for ( i = imaskSize/8-1; i >= 0; i-- )
+	    {
+	      bitmap = pbitmap[i];
+	      imask[i*8+0] = 1 & (bitmap >> 7);
+	      imask[i*8+1] = 1 & (bitmap >> 6);
+	      imask[i*8+2] = 1 & (bitmap >> 5);
+	      imask[i*8+3] = 1 & (bitmap >> 4);
+	      imask[i*8+4] = 1 & (bitmap >> 3);
+	      imask[i*8+5] = 1 & (bitmap >> 2);
+	      imask[i*8+6] = 1 & (bitmap >> 1);
+	      imask[i*8+7] = 1 & (bitmap);
+	    }
 
+	  j = 0;
+	  for ( i = 0; i < ISEC4_NumValues; i++ )
+	    if ( imask[i] ) j++;
 
-int srvDefHeader(srvrec_t *srvp, const int *header)
-{
-  size_t i;
+	  if ( ISEC4_NumNonMissValues != j )
+	    {
+	      if ( dfunc != 'J' && ISEC4_NumBits != 0 )
+		Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
+			j, ISEC4_NumNonMissValues);
 
-  for ( i = 0; i < SRV_HEADER_LEN; i++ )
-    srvp->header[i] = header[i];
+	      ISEC4_NumNonMissValues = j;
+	    }
 
-  srvp->datasize = (size_t)(header[4] * header[5]);
+	  if ( dfunc != 'J' )
+	    {
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+	      for ( i = ISEC4_NumValues-1; i >= 0; i-- )
+		fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
+	    }
+
+	  free(imask);
+	}
+    }
+
+  if ( ISEC2_Reduced )
+    {
+      int nlon, nlat;
+      int lsect3, lperio = 1, lveggy;
+      int ilat;
+      int nvalues = 0;
+      int dlon;
+
+      nlat = ISEC2_NumLat;
+      nlon = ISEC2_RowLonPtr[0];
+      for ( ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
+      for ( ilat = 1; ilat < nlat; ++ilat )
+	if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+
+      dlon = ISEC2_LastLon-ISEC2_FirstLon;
+      if ( dlon < 0 ) dlon += 360000;
+	  
+      if ( nvalues != ISEC4_NumValues )
+	{
+	  *iret = -801;
+	}
+      //printf("nlat %d  nlon %d \n", nlat, nlon);
+      //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+
+      if ( dfunc == 'R' && *iret == -801 )
+	gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
+		ISEC4_NumValues, nvalues);
+      
+      if ( dfunc == 'R' && *iret != -801 )
+	{
+	  ISEC2_Reduced = 0;
+	  ISEC2_NumLon = nlon;
+	  ISEC4_NumValues = nlon*nlat;
+
+	  lsect3 = bitmapSize > 0;
+	  lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) && 
+	          ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) || 
+	           (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30));
+	
+	  (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
+	      
+	  if ( bitmapSize > 0 )
+	    {
+	      long i;
+	      int j = 0;
+	      
+	      for ( i = 0; i < ISEC4_NumValues; i++ )
+		if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
+		  
+	      ISEC4_NumNonMissValues = j;
+	    }
+	}
+    }
 
-  if ( SRV_Debug )
-    Message("datasize = %lu", srvp->datasize);
 
-  return (0);
-}
+  if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
+  esLen = 4;
 
+  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
 
-int srvInqData(srvrec_t *srvp, int prec, void *data)
-{
-  size_t datasize;
-  size_t i;
-  int ierr = 0;
-  int dprec;
-  void *buffer;
-  int byteswap = srvp->byteswap;
+  if ( ISEC0_GRIB_Len )
+    if ( ISEC0_GRIB_Len < gribLen )
+      Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
 
-  datasize = srvp->datasize;
+  ISEC0_GRIB_Len = gribLen;
 
-  buffer = srvp->buffer;
+  *kword = gribLen / sizeof(int);
+  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
 
-  dprec = srvp->dprec;
+  /*
+    ----------------------------------------------------------------
+    Section 9 . Abort/return to calling routine.
+    ----------------------------------------------------------------
+  */
+ LABEL900:;
 
-  switch ( dprec )
+  if ( ldebug )
     {
-    case SINGLE_PRECISION:
-      {
-	if ( sizeof(FLT32) == 4 )
-	  {
-	    if ( byteswap ) swap4byte(buffer, datasize);
+      gprintf(__func__, "Section 9.");
+      gprintf(__func__, "Output values set -");
 
-	    if ( dprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT32));
-	    else
-	      for (i = 0; i < datasize; i++)
-		((double *) data)[i] = (double) ((float *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT32));
-	  }
-	break;
-      }
-    case DOUBLE_PRECISION:
-	if ( sizeof(FLT64) == 8 )
-	  {
-	    if ( byteswap ) swap8byte(buffer, datasize);
+      gribPrintSec0(isec0);
+      gribPrintSec1(isec0, isec1);
+      /*
+	Print section 2 if present.
+      */
+      if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
 
-	    if ( dprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT64));
-	    else
-	      for (i = 0; i < datasize; i++)
-		((float *) data)[i] = (float) ((double *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT64));
-	  }
-	break;
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
-    }
+      if ( ! l_iorj )
+	{
+	  /*
+	    Print section 3 if present.
+	  */
+	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
 
-  return (ierr);
+	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
+	  /*
+	    Special print for 2D spectra wave field real values in
+	    section 4
+	  */
+	  if ( (isec1[ 0] ==  140) && 
+	       (isec1[ 1] ==   98) && 
+	       (isec1[23] ==    1) && 
+	       ((isec1[39] == 1045) || (isec1[39] == 1081))  && 
+	       ((isec1[ 5] ==  250) || (isec1[ 5] ==  251)) )
+	    gribPrintSec4Wave(isec4);
+	}
+    }
 }
 
+#endif /* T */
 
-int srvInqDataSP(srvrec_t *srvp, float *data)
+/* GRIB block 0 - indicator block */
+static
+void encodeIS(GRIBPACK *lGrib, long *gribLen)
 {
-  return (srvInqData(srvp, SINGLE_PRECISION, (void *) data));
-}
+  long z = *gribLen;
 
+  lGrib[0] = 'G';
+  lGrib[1] = 'R';
+  lGrib[2] = 'I';
+  lGrib[3] = 'B';
 
-int srvInqDataDP(srvrec_t *srvp, double *data)
-{
-  return (srvInqData(srvp, DOUBLE_PRECISION, (void *) data));
-}
+  /* 
+   * lGrib[4]-lGrib[6] contains full length of grib record. 
+   * included before finished CODEGB
+   */
+
+  z = 7;   
+  Put1Byte(1); /* grib version */
+  z = 8;
 
+  *gribLen = z;
+}
 
-int srvDefData(srvrec_t *srvp, int prec, const void *data)
+/* GRIB block 5 - end block */
+static
+void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
 {
-  size_t datasize;
-  size_t blocklen;
-  size_t buffersize;
-  size_t i;
-  int dprec, hprec;
-  int *header;
-  void *buffer;
+  long z = *gribLen;
 
-  if ( srvDefaultDprec ) dprec = srvDefaultDprec;
-  else                   dprec = srvp->dprec;
+  lGrib[z++] = '7';
+  lGrib[z++] = '7';
+  lGrib[z++] = '7';
+  lGrib[z++] = '7';
 
-  if ( ! dprec ) dprec = prec;
+  if ( z > JP23SET )
+    {
+      long itemp;
+      long bdslen = z - 4;
+      /*
+      fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET);
+      exit(1);
+      */
+      /*
+	If a very large product, the section 4 length field holds
+	the number of bytes in the product after section 4 upto
+	the end of the padding bytes.
+	This is a fixup to get round the restriction on product lengths
+	due to the count being only 24 bits. It is only possible because
+	the (default) rounding for GRIB products is 120 bytes.
+      */
+      while ( z%120 ) lGrib[z++] = 0;
 
-  srvp->dprec = dprec;
+      if ( z > JP23SET*120 )
+	{
+	  fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET*120);
+	  exit(1);
+	}
 
-  if ( srvDefaultHprec ) hprec = srvDefaultHprec;
-  else                   hprec = srvp->hprec;
+      itemp = z / (-120);
+      itemp = JP23SET - itemp + 1;
 
-  if ( ! hprec ) hprec = dprec;
+      lGrib[4] = itemp >> 16;
+      lGrib[5] = itemp >>  8;
+      lGrib[6] = itemp;
 
-  srvp->hprec = hprec;
+      bdslen = z - bdslen;
+      lGrib[bdsstart  ] = bdslen >> 16;
+      lGrib[bdsstart+1] = bdslen >>  8;
+      lGrib[bdsstart+2] = bdslen;
+    }
+  else
+    {
+      lGrib[4] = z >> 16;
+      lGrib[5] = z >>  8;
+      lGrib[6] = z;
 
-  header = srvp->header;
+      while ( z%8 ) lGrib[z++] = 0;
+    }
 
-  datasize = (size_t)(header[4] * header[5]);
-  blocklen = datasize * (size_t)dprec;
+  *gribLen = z;
+}
 
-  srvp->datasize = datasize;
+/* GRIB block 1 - product definition block. */
 
-  buffersize = srvp->buffersize;
+#define DWD_extension_253_len 38
+#define DWD_extension_254_len 26
+#define ECMWF_extension_1_len 24
+#define MPIM_extension_1_len  18
 
-  if ( buffersize != blocklen )
-    {
-      buffersize = blocklen;
-      buffer = srvp->buffer;
-      buffer = realloc(buffer, buffersize);
-      srvp->buffer = buffer;
-      srvp->buffersize = buffersize;
-    }
-  else
-    buffer = srvp->buffer;
+static
+long getLocalExtLen(int *isec1)
+{
+  long extlen = 0;
 
-  switch ( dprec )
+  if ( ISEC1_LocalFLag )
     {
-    case SINGLE_PRECISION:
-      {
-	if ( dprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT32));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((float *) buffer)[i] = (float) ((double *) data)[i];
-
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	if ( dprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT64));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((double *) buffer)[i] = (double) ((float *) data)[i];
-
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
+      if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
+	{
+	  if      ( isec1[36] == 254 ) extlen = DWD_extension_254_len;
+	  else if ( isec1[36] == 253 ) extlen = DWD_extension_253_len;
+	}
+      else if ( ISEC1_CenterID == 98 )
+        {
+	  if ( isec1[36] == 1 )   extlen = ECMWF_extension_1_len;
+        }
+      else if ( ISEC1_CenterID == 252 )
+        {
+	  if ( isec1[36] == 1 ) extlen = MPIM_extension_1_len;
+        }
     }
 
-  return (0);
+  return (extlen);
 }
 
-
-int srvDefDataSP(srvrec_t *srvp, const float *data)
+static
+long getPdsLen(int *isec1)
 {
-  return (srvDefData(srvp, SINGLE_PRECISION, (void *) data));
-}
+  long pdslen = 28;
 
+  pdslen += getLocalExtLen(isec1);
 
-int srvDefDataDP(srvrec_t *srvp, const double *data)
-{
-  return (srvDefData(srvp, DOUBLE_PRECISION, (void *) data));
+  return (pdslen);
 }
 
-
-int srvRead(int fileID, srvrec_t *srvp)
+static
+void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
 {
-  size_t datasize;
-  size_t blocklen, blocklen2;
-  size_t i;
-  char tempheader[64];
-  void *buffer;
-  int byteswap;
-  int status;
+  int isvn;
+  long localextlen, i;
+  long z = *zs;
 
-  if ( ! srvp->checked )
+  localextlen = getLocalExtLen(isec1);
+  for ( i = 0; i < localextlen-2; i++ )
     {
-      status = srvCheckFiletype(fileID, &srvp->byteswap);
-      if ( status == 0 ) Error("Not a SERVICE file!");
-      srvp->checked = 1;
+      Put1Byte(isec1[24+i]);
     }
 
-  byteswap = srvp->byteswap;
+  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
+  Put2Byte(isvn);             /* DWD run type (0=main, 2=ass, 3=test) */
 
-  /* read header record */
-  blocklen = binReadF77Block(fileID, byteswap);
+  *zs = z;
+}
 
-  if ( fileEOF(fileID) ) return (-1);
+static
+void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
+{
+  int isvn;
+  long localextlen, i;
+  long z = *zs;
 
-  if ( SRV_Debug )
-    Message("blocklen = %lu", blocklen);
+  localextlen = DWD_extension_254_len;
+  for ( i = 0; i < localextlen-2; i++ )
+    {
+      Put1Byte(isec1[24+i]);
+    }
 
-  size_t hprec = blocklen / SRV_HEADER_LEN;
+  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
+  Put2Byte(isvn);             /* DWD run type (0=main, 2=ass, 3=test) */
+  Put1Byte(isec1[50]);        /* 55 User id, specified by table       */
+  Put2Byte(isec1[51]);        /* 56 Experiment identifier             */
+  Put2Byte(isec1[52]);        /* 58 Ensemble identification by table  */
+  Put2Byte(isec1[53]);        /* 60 Number of ensemble members        */
+  Put2Byte(isec1[54]);        /* 62 Actual number of ensemble member  */
+  Put1Byte(isec1[55]);        /* 64 Model major version number        */ 
+  Put1Byte(isec1[56]);        /* 65 Model minor version number        */ 
+  Put1Byte(0);                /* 66 Blank for even buffer length      */
 
-  srvp->hprec = (int)hprec;
+  *zs = z;
+}
 
-  switch ( hprec )
+static
+void encodePDS_ECMWF_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
+{
+  // int isvn;
+  long localextlen, i;
+  long z = *zs;
+
+  localextlen = getLocalExtLen(isec1);
+  for ( i = 0; i < localextlen-12; i++ )
     {
-    case SINGLE_PRECISION:
-      {
-	binReadInt32(fileID, byteswap, SRV_HEADER_LEN, (INT32 *) tempheader);
+      Put1Byte(isec1[24+i]);
+    }
+                              /* 12 bytes explicitly encoded below:         */
+  Put1Byte(isec1[36]);        /* ECMWF local GRIB use definition identifier */
+                              /*    1=MARS labelling or ensemble fcst. data */
+  Put1Byte(isec1[37]);        /* Class                                      */
+  Put1Byte(isec1[38]);        /* Type                                       */
+  Put2Byte(isec1[39]);        /* Stream                                     */
 
-	for ( i = 0; i < SRV_HEADER_LEN; i++ )
-          srvp->header[i] = (int) ((INT32 *) tempheader)[i];
+  /* Version number or experiment identifier    */
+  Put1Byte(((unsigned char*) &isec1[40])[0]);
+  Put1Byte(((unsigned char*) &isec1[40])[1]);
+  Put1Byte(((unsigned char*) &isec1[40])[2]);
+  Put1Byte(((unsigned char*) &isec1[40])[3]);
 
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	binReadInt64(fileID, byteswap, SRV_HEADER_LEN, (INT64 *) tempheader);
+  Put1Byte(isec1[41]);        /* Ensemble forecast number                   */
+  Put1Byte(isec1[42]);        /* Total number of forecasts in ensemble      */
+  Put1Byte(0);                /* (Spare)                                    */
 
-	for ( i = 0; i < SRV_HEADER_LEN; i++ )
-          srvp->header[i] = (int) ((INT64 *) tempheader)[i];
+  *zs = z;
+}
 
-	break;
-      }
-    default:
-      {
-	Error("Unexpected header precision %d", hprec);
-        break;
-      }
+static
+void encodePDS_MPIM_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
+{
+  // int isvn;
+  long localextlen, i;
+  long z = *zs;
+
+  localextlen = getLocalExtLen(isec1);
+  for ( i = 0; i < localextlen-6; i++ )
+    {
+      Put1Byte(isec1[24+i]);
     }
+                              /* 6 bytes explicitly encoded below:          */
+  Put1Byte(isec1[36]);        /* MPIM local GRIB use definition identifier  */
+                              /*    (extension identifier)                  */
+  Put1Byte(isec1[37]);        /* type of ensemble forecast                  */
+  Put2Byte(isec1[38]);        /* individual ensemble member                 */
+  Put2Byte(isec1[39]);        /* number of forecasts in ensemble            */
 
-  blocklen2 = binReadF77Block(fileID, byteswap);
+  *zs = z;
+}
 
-  if ( blocklen2 != blocklen )
+/* GRIB BLOCK 1 - PRODUCT DESCRIPTION SECTION */
+static
+void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
+{
+  GRIBPACK *lGrib = lpds;
+  long z = 0;
+  int ival, century, year;
+
+  century = ISEC1_Century;
+  year    = ISEC1_Year;
+
+  if ( century < 0 )
     {
-      Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
-      if ( blocklen2 != 0 ) return (-1);
+      century = -century;
+      year    = -year;
     }
 
-  srvp->datasize = (size_t)(srvp->header[4] * srvp->header[5]);
+  Put3Byte(pdsLen);               /*  0 Length of Block 1        */
+  Put1Byte(ISEC1_CodeTable);      /*  3 Local table number       */
+  Put1Byte(ISEC1_CenterID);       /*  4 Identification of centre */
+  Put1Byte(ISEC1_ModelID);        /*  5 Identification of model  */
+  Put1Byte(ISEC1_GridDefinition); /*  6 Grid definition          */
+  Put1Byte(ISEC1_Sec2Or3Flag);    /*  7 Block 2 included         */
+  Put1Byte(ISEC1_Parameter);      /*  8 Parameter Code           */
+  Put1Byte(ISEC1_LevelType);      /*  9 Type of level            */
+  if ( (ISEC1_LevelType !=  20) &&
+       (ISEC1_LevelType != GRIB1_LTYPE_99)         &&
+       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC)   &&
+       (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE)   &&
+       (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT)     &&
+       (ISEC1_LevelType != GRIB1_LTYPE_SIGMA)      &&
+       (ISEC1_LevelType != GRIB1_LTYPE_HYBRID)     &&
+       (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH)  &&
+       (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
+       (ISEC1_LevelType != 115) &&
+       (ISEC1_LevelType != 117) &&
+       (ISEC1_LevelType != 125) &&
+       (ISEC1_LevelType != 127) &&
+       (ISEC1_LevelType != 160) &&
+       (ISEC1_LevelType != 210) )
+    {
+      Put1Byte(ISEC1_Level1);
+      Put1Byte(ISEC1_Level2);
+    }
+  else
+    {
+      Put2Byte(ISEC1_Level1);     /* 10 Level                    */    
+    }
 
-  if ( SRV_Debug )
-    Message("datasize = %lu", srvp->datasize);
+  Put1Int(year);                  /* 12 Year of Century          */
+  Put1Byte(ISEC1_Month);          /* 13 Month                    */
+  Put1Byte(ISEC1_Day);            /* 14 Day                      */
+  Put1Byte(ISEC1_Hour);           /* 15 Hour                     */
+  Put1Byte(ISEC1_Minute);         /* 16 Minute                   */
 
-  blocklen = binReadF77Block(fileID, byteswap);
+  Put1Byte(ISEC1_TimeUnit);       /* 17 Time unit                */
+  if ( ISEC1_TimeRange == 10 )
+    {
+      Put1Byte(ISEC1_TimePeriod1);
+      Put1Byte(ISEC1_TimePeriod2);
+    }
+  else if ( ISEC1_TimeRange == 113 || ISEC1_TimeRange ==   0 )
+    {
+      Put1Byte(ISEC1_TimePeriod1);
+      Put1Byte(0);
+    }
+  else if ( ISEC1_TimeRange ==   5 || ISEC1_TimeRange ==   4 || 
+	    ISEC1_TimeRange ==   3 || ISEC1_TimeRange ==   2 )
+    {
+      Put1Byte(0);
+      Put1Byte(ISEC1_TimePeriod2);
+    }
+  else
+    {
+      Put1Byte(0);
+      Put1Byte(0); 
+    }
+  Put1Byte(ISEC1_TimeRange);      /* 20 Timerange flag           */
+  Put2Byte(ISEC1_AvgNum);         /* 21 Average                  */
 
-  size_t buffersize = srvp->buffersize;
+  Put1Byte(ISEC1_AvgMiss);        /* 23 Missing from averages    */
+  Put1Byte(century);              /* 24 Century                  */
+  Put1Byte(ISEC1_SubCenterID);    /* 25 Subcenter                */
+  Put2Byte(ISEC1_DecScaleFactor); /* 26 Decimal scale factor     */
 
-  if ( buffersize < blocklen )
+  if ( ISEC1_LocalFLag )
     {
-      buffersize = blocklen;
-      buffer = srvp->buffer;
-      buffer = realloc(buffer, buffersize);
-      srvp->buffer = buffer;
-      srvp->buffersize = buffersize;
+      if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
+	{
+	  if      ( isec1[36] == 254 ) encodePDS_DWD_local_Extension_254(lGrib, &z, isec1);
+	  else if ( isec1[36] == 253 ) encodePDS_DWD_local_Extension_253(lGrib, &z, isec1);
+	}
+      else if ( ISEC1_CenterID == 98 )
+	{
+	  if ( isec1[36] == 1 ) encodePDS_ECMWF_local_Extension_1(lGrib, &z, isec1);
+	}
+      else if ( ISEC1_CenterID == 252 )
+	{
+	  if ( isec1[36] == 1 ) encodePDS_MPIM_local_Extension_1(lGrib, &z, isec1);
+	}
+      else
+	{
+	  long i, localextlen;
+	  localextlen = getLocalExtLen(isec1);
+	  for ( i = 0; i < localextlen; i++ )
+	    {
+	      Put1Byte(isec1[24+i]);
+	    }
+	}
     }
-  else
-    buffer = srvp->buffer;
+}
 
-  datasize = srvp->datasize;
+int  BitsPerInt = (int) (sizeof(int) * 8);
 
-  size_t dprec = blocklen / datasize;
 
-  srvp->dprec = (int)dprec;
 
-  if ( dprec != SINGLE_PRECISION && dprec != DOUBLE_PRECISION )
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
+
+static
+void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
+				     const T *data, T zref, T factor, size_t *gz)
+{
+  size_t i, z = *gz;
+  unsigned int ival;
+  int cbits, jbits;
+  unsigned int c;
+  static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+    
+  /* code from gribw routine flist2bitstream */
+
+  cbits = 8;
+  c = 0;
+  for ( i = packStart; i < datasize; i++ )
     {
-      Warning("Unexpected data precision %d", dprec);
-      return (-1);
+      /* note float -> unsigned int .. truncate */
+      ival = (unsigned int) ((data[i] - zref) * factor + 0.5);
+      /*
+	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
+	if ( ival < 0 ) ival = 0;
+      */
+      jbits = numBits;
+      while ( cbits <= jbits ) 
+	{
+	  if ( cbits == 8 )
+	    {
+	      jbits -= 8;
+	      lGrib[z++] = (ival >> jbits) & 0xFF;
+	    }
+	  else
+	    {
+	      jbits -= cbits;
+	      lGrib[z++] = (c << cbits) + ((ival >> jbits) & mask[cbits]);
+	      cbits = 8;
+	      c = 0;
+	    }
+	}
+      /* now jbits < cbits */
+      if ( jbits )
+	{
+	  c = (c << jbits) + (ival & mask[jbits]);
+	  cbits -= jbits;
+	}
     }
+  if ( cbits != 8 ) lGrib[z++] = c << cbits;
 
-  fileRead(fileID, buffer, blocklen);
+  *gz = z;
+}
 
-  blocklen2 = binReadF77Block(fileID, byteswap);
+static
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+				    const T *restrict data, T zref, T factor, size_t *gz)
+{
+  size_t i, z = *gz;
+  uint16_t ui16;
+  T tmp;
 
-  if ( blocklen2 != blocklen )
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+  for ( i = 0; i < datasize; i++ )
     {
-      Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
-      if ( blocklen2 != 0 ) return (-1);
+      tmp = ((data[i] - zref) * factor + 0.5);
+      ui16 = (uint16_t) tmp;
+      lGrib[z  ] = ui16 >>  8;
+      lGrib[z+1] = ui16;
+      z += 2;
     }
 
-  return (0);
+  *gz = z;
 }
 
-
-void srvWrite(int fileID, srvrec_t *srvp)
+static
+void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize, 
+			      GRIBPACK *restrict lGrib,
+			      const T *restrict data, 
+			      T zref, T factor, size_t *gz)
 {
-  size_t datasize;
-  size_t blocklen;
-  size_t i;
-  int dprec, hprec;
-  char tempheader[64];
-  int *header;
-  void *buffer;
-  int byteswap = srvp->byteswap;
-
-  dprec  = srvp->dprec;
-  hprec  = srvp->hprec;
-  header = srvp->header;
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_minmax, end_minmax;
+#endif
 
-  /* write header record */
-  blocklen = SRV_HEADER_LEN * (size_t)hprec;
+  uint32_t ui32;
+  size_t i, z = *gz;
+  T tmp;
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+  data += packStart;
+  datasize -= packStart;
 
-  switch ( hprec )
+  if      ( numBits ==  8 )
     {
-    case SINGLE_PRECISION:
-      {
-	for (i = 0; i < SRV_HEADER_LEN; i++)
-          ((INT32 *) tempheader)[i] = (INT32) header[i];
-
-	binWriteInt32(fileID, byteswap, SRV_HEADER_LEN, (INT32 *) tempheader);
-
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	for (i = 0; i < SRV_HEADER_LEN; i++)
-          ((INT64 *) tempheader)[i] = (INT64) header[i];
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(2, "pack 8 bit base");
+#endif
 
-	binWriteInt64(fileID, byteswap, SRV_HEADER_LEN, (INT64 *) tempheader);
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+	  lGrib[z  ] = (uint16_t) tmp;
+          z++;
+	}
 
-	break;
-      }
-    default:
-      {
-	Error("unexpected header precision %d", hprec);
-        break;
-      }
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(2);
+#endif
     }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(3, "pack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_minmax = mach_absolute_time();
+#endif
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+      if ( sizeof(T) == sizeof(double) )
+      	{
+          grib_encode_array_2byte_double(datasize, lGrib, (const double * restrict) data, zref, factor, &z);
+        }
+      else
+        {
+          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
+        }
 
-  datasize = (size_t)(header[4] * header[5]);
-  blocklen = datasize * (size_t)dprec;
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_minmax = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(3);
+#endif
+    }
+  else if ( numBits == 24 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(4, "pack 24 bit base");
+#endif
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+          ui32 = (uint32_t) tmp;
+          lGrib[z  ] =  ui32 >> 16;
+          lGrib[z+1] =  ui32 >>  8;
+          lGrib[z+2] =  ui32;
+          z += 3;
+	}
 
-  srvp->datasize = datasize;
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(4);
+#endif
+    }
+  else if ( numBits == 32 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(5, "pack 32 bit base");
+#endif
 
-  buffer = srvp->buffer;
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+          ui32 = (uint32_t) tmp;
+          lGrib[z  ] =  ui32 >> 24;
+          lGrib[z+1] =  ui32 >> 16;
+          lGrib[z+2] =  ui32 >>  8;
+          lGrib[z+3] =  ui32;
+          z += 4;
+	}
 
-  switch ( dprec )
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(5);
+#endif
+    }
+  else if ( numBits > 0 && numBits <= 32 )
     {
-    case SINGLE_PRECISION:
-      {
-	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
+      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+    }
+  else if ( numBits == 0 )
+    {
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
     }
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+  *gz = z;
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
-
-
-
-enum {
-  EXT_HEADER_LEN = 4,
-};
 
+static
+void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize, 
+				       GRIBPACK *restrict lGrib,
+				       const T *restrict data, 
+				       T zref, T factor, size_t *gz)
+{
+  U_BYTEORDER;
+  size_t i, j, z = *gz;
+#ifdef _ARCH_PWR6
+#define __UNROLL_DEPTH_2 8
+#else
+#define __UNROLL_DEPTH_2 8
+#endif
+  size_t residual;
+  size_t ofs;
+  T dval[__UNROLL_DEPTH_2];
+  unsigned long ival;
 
-static int initExtLib       = 0;
-static int extDefaultPrec   = 0;
-static int extDefaultNumber = EXT_REAL;
+  data += packStart;
+  datasize -= packStart;
+  residual =  datasize % __UNROLL_DEPTH_2;
+  ofs = datasize - residual;
 
+  // reducing FP operations to single FMA is slowing down on pwr6 ...
 
-/*
- * A version string.
- */
+  if      ( numBits ==  8 )
+    {
+      unsigned char *cgrib = (unsigned char *) (lGrib + z);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(2, "pack 8 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      *cgrib++ =  (unsigned long) dval[j];
+	    }
+	  z += __UNROLL_DEPTH_2;
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  *cgrib++ = (unsigned long) dval[j];
+	}
+      z += residual;
 
-#undef  LIBVERSION
-#define LIBVERSION      1.3.2
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
-static const char ext_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(2);
+#endif
+    }
+  else if ( numBits == 16 )
+    {
+      unsigned short *sgrib = (unsigned short *) (lGrib + z);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(3, "pack 16 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  if ( IS_BIGENDIAN() )
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  *sgrib++ = (unsigned long) dval[j];
+		}
+	      z += 2*__UNROLL_DEPTH_2;
+	    }
+	  else
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  ival = (unsigned long) dval[j];
+		  lGrib[z  ] = ival >>  8;
+		  lGrib[z+1] = ival;
+		  z += 2;
+		}
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      if ( IS_BIGENDIAN() )
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      *sgrib++ = (unsigned long) dval[j];
+	    }
+	  z += 2*residual;
+	}
+      else
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] = ival >>  8;
+	      lGrib[z+1] = ival;
+	      z += 2;
+	    }
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(3);
+#endif
+    }
+  else if ( numBits == 24 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(4, "pack 24 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] =  ival >> 16;
+	      lGrib[z+1] =  ival >>  8;
+	      lGrib[z+2] =  ival;
+	      z += 3;
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  ival = (unsigned long) dval[j];
+	  lGrib[z  ] =  ival >> 16;
+	  lGrib[z+1] =  ival >>  8;
+	  lGrib[z+2] =  ival;
+	  z += 3;
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(4);
+#endif
+    }
+  else if ( numBits == 32 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(5, "pack 32 bit unrolled");
+#endif
+      unsigned int *igrib = (unsigned int *) (lGrib + z);
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  if ( IS_BIGENDIAN() )
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  *igrib = (unsigned long) dval[j];
+		  igrib++;
+		  z += 4;
+		}
+	    }
+	  else
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  ival = (unsigned long) dval[j];
+		  lGrib[z  ] =  ival >> 24;
+		  lGrib[z+1] =  ival >> 16;
+		  lGrib[z+2] =  ival >>  8;
+		  lGrib[z+3] =  ival;
+		  z += 4;
+		}
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      if ( IS_BIGENDIAN() )
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      *igrib = (unsigned long) dval[j];
+	      igrib++;
+	      z += 4;
+	    }
+	}
+      else
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] =  ival >> 24;
+	      lGrib[z+1] =  ival >> 16;
+	      lGrib[z+2] =  ival >>  8;
+	      lGrib[z+3] =  ival;
+	      z += 4;
+	    }
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(5);
+#endif
+    }
+  else if ( numBits > 0 && numBits <= 32 )
+    {
+      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+    }
+  else if ( numBits == 0 )
+    {
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
 
-const char *extLibraryVersion(void)
-{
-  return (ext_libvers);
+  *gz = z;
+#undef __UNROLL_DEPTH_2
 }
 
+#endif /* T */
 
-static int EXT_Debug = 0;    /* If set to 1, debugging */
-
-
-void extDebug(int debug)
-{
-  EXT_Debug = debug;
-
-  if ( EXT_Debug )
-    Message("debug level %d", debug);
-}
-
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
 
-static void extLibInit()
+static
+void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
+				     const T *data, T zref, T factor, size_t *gz)
 {
-  char *envString;
-  char *envName = "EXT_PRECISION";
-
+  size_t i, z = *gz;
+  unsigned int ival;
+  int cbits, jbits;
+  unsigned int c;
+  static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+    
+  /* code from gribw routine flist2bitstream */
 
-  envString = getenv(envName);
-  if ( envString )
+  cbits = 8;
+  c = 0;
+  for ( i = packStart; i < datasize; i++ )
     {
-      int pos = 0;
-
-      if ( strlen(envString) == 2  )
+      /* note float -> unsigned int .. truncate */
+      ival = (unsigned int) ((data[i] - zref) * factor + 0.5);
+      /*
+	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
+	if ( ival < 0 ) ival = 0;
+      */
+      jbits = numBits;
+      while ( cbits <= jbits ) 
 	{
-	  switch ( tolower((int) envString[pos]) )
+	  if ( cbits == 8 )
 	    {
-	    case 'r':
-	      {
-		extDefaultNumber = EXT_REAL;
-		switch ( (int) envString[pos+1] )
-		  {
-		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
-		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
-		  default:
-		    Message("Invalid digit in %s: %s", envName, envString);
-		  }
-		break;
-	      }
-	    case 'c':
-	      {
-		extDefaultNumber = EXT_COMP;
-		switch ( (int) envString[pos+1] )
-		  {
-		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
-		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
-		  default:
-		    Message("Invalid digit in %s: %s", envName, envString);
-		  }
-		break;
-	      }
-	    default:
-              {
-                Message("Invalid character in %s: %s", envName, envString);
-                break;
-              }
-            }
+	      jbits -= 8;
+	      lGrib[z++] = (ival >> jbits) & 0xFF;
+	    }
+	  else
+	    {
+	      jbits -= cbits;
+	      lGrib[z++] = (c << cbits) + ((ival >> jbits) & mask[cbits]);
+	      cbits = 8;
+	      c = 0;
+	    }
+	}
+      /* now jbits < cbits */
+      if ( jbits )
+	{
+	  c = (c << jbits) + (ival & mask[jbits]);
+	  cbits -= jbits;
 	}
     }
+  if ( cbits != 8 ) lGrib[z++] = c << cbits;
 
-  initExtLib = 1;
+  *gz = z;
 }
 
 static
-void extInit(extrec_t *extp)
+void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
+				    const T *restrict data, T zref, T factor, size_t *gz)
 {
-  extp->checked    = 0;
-  extp->byteswap   = 0;
-  extp->prec       = 0;
-  extp->number     = extDefaultNumber;
-  extp->datasize   = 0;
-  extp->buffersize = 0;
-  extp->buffer     = NULL;
-}
+  size_t i, z = *gz;
+  uint16_t ui16;
+  T tmp;
+
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+  for ( i = 0; i < datasize; i++ )
+    {
+      tmp = ((data[i] - zref) * factor + 0.5);
+      ui16 = (uint16_t) tmp;
+      lGrib[z  ] = ui16 >>  8;
+      lGrib[z+1] = ui16;
+      z += 2;
+    }
 
+  *gz = z;
+}
 
-void *extNew(void)
+static
+void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize, 
+			      GRIBPACK *restrict lGrib,
+			      const T *restrict data, 
+			      T zref, T factor, size_t *gz)
 {
-  extrec_t *extp;
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_minmax, end_minmax;
+#endif
 
-  if ( ! initExtLib ) extLibInit();
+  uint32_t ui32;
+  size_t i, z = *gz;
+  T tmp;
 
-  extp = (extrec_t *) malloc(sizeof(extrec_t));
+  data += packStart;
+  datasize -= packStart;
 
-  extInit(extp);
+  if      ( numBits ==  8 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(2, "pack 8 bit base");
+#endif
 
-  return ((void*)extp);
-}
+#if defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+	  lGrib[z  ] = (uint16_t) tmp;
+          z++;
+	}
 
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(2);
+#endif
+    }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(3, "pack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_minmax = mach_absolute_time();
+#endif
 
-void extDelete(void *ext)
-{
-  extrec_t *extp = (extrec_t *) ext;
+      if ( sizeof(T) == sizeof(double) )
+      	{
+          grib_encode_array_2byte_double(datasize, lGrib, (const double * restrict) data, zref, factor, &z);
+        }
+      else
+        {
+          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
+        }
 
-  if ( extp )
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_minmax = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_minmax = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(3);
+#endif
+    }
+  else if ( numBits == 24 )
     {
-      if ( extp->buffer ) free(extp->buffer);
-      free(extp);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(4, "pack 24 bit base");
+#endif
+
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+          ui32 = (uint32_t) tmp;
+          lGrib[z  ] =  ui32 >> 16;
+          lGrib[z+1] =  ui32 >>  8;
+          lGrib[z+2] =  ui32;
+          z += 3;
+	}
+
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(4);
+#endif
     }
-}
+  else if ( numBits == 32 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(5, "pack 32 bit base");
+#endif
+
+#if   defined (CRAY)
+#pragma _CRI ivdep
+#elif defined (SX)
+#pragma vdir nodep
+#elif defined (__uxp__)
+#pragma loop novrec
+#elif defined (__ICC)
+#pragma ivdep
+#endif
+      for ( i = 0; i < datasize; i++ )
+	{
+	  tmp = ((data[i] - zref) * factor + 0.5);
+          ui32 = (uint32_t) tmp;
+          lGrib[z  ] =  ui32 >> 24;
+          lGrib[z+1] =  ui32 >> 16;
+          lGrib[z+2] =  ui32 >>  8;
+          lGrib[z+3] =  ui32;
+          z += 4;
+	}
 
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(5);
+#endif
+    }
+  else if ( numBits > 0 && numBits <= 32 )
+    {
+      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
+    }
+  else if ( numBits == 0 )
+    {
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
 
-int extCheckFiletype(int fileID, int *swap)
+  *gz = z;
+}
+
+static
+void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize, 
+				       GRIBPACK *restrict lGrib,
+				       const T *restrict data, 
+				       T zref, T factor, size_t *gz)
 {
-  size_t blocklen = 0, fact = 0;
-  size_t sblocklen = 0;
-  size_t data =  0;
-  size_t dimxy = 0;
-  int found = 0;
-  unsigned char buffer[40], *pbuf;
+  U_BYTEORDER;
+  size_t i, j, z = *gz;
+#ifdef _ARCH_PWR6
+#define __UNROLL_DEPTH_2 8
+#else
+#define __UNROLL_DEPTH_2 8
+#endif
+  size_t residual;
+  size_t ofs;
+  T dval[__UNROLL_DEPTH_2];
+  unsigned long ival;
 
-  if ( fileRead(fileID, buffer, 4) != 4 ) return (found);
+  data += packStart;
+  datasize -= packStart;
+  residual =  datasize % __UNROLL_DEPTH_2;
+  ofs = datasize - residual;
 
-  blocklen  = (size_t) get_UINT32(buffer);
-  sblocklen = (size_t) get_SUINT32(buffer);
+  // reducing FP operations to single FMA is slowing down on pwr6 ...
 
-  if ( EXT_Debug )
-    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+  if      ( numBits ==  8 )
+    {
+      unsigned char *cgrib = (unsigned char *) (lGrib + z);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(2, "pack 8 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      *cgrib++ =  (unsigned long) dval[j];
+	    }
+	  z += __UNROLL_DEPTH_2;
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  *cgrib++ = (unsigned long) dval[j];
+	}
+      z += residual;
 
-  if ( blocklen == 16 )
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(2);
+#endif
+    }
+  else if ( numBits == 16 )
     {
-     *swap = 0;
-      fact = blocklen/4;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
-      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
+      unsigned short *sgrib = (unsigned short *) (lGrib + z);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(3, "pack 16 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  if ( IS_BIGENDIAN() )
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  *sgrib++ = (unsigned long) dval[j];
+		}
+	      z += 2*__UNROLL_DEPTH_2;
+	    }
+	  else
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  ival = (unsigned long) dval[j];
+		  lGrib[z  ] = ival >>  8;
+		  lGrib[z+1] = ival;
+		  z += 2;
+		}
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      if ( IS_BIGENDIAN() )
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      *sgrib++ = (unsigned long) dval[j];
+	    }
+	  z += 2*residual;
+	}
+      else
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] = ival >>  8;
+	      lGrib[z+1] = ival;
+	      z += 2;
+	    }
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(3);
+#endif
     }
-  else if ( blocklen == 32 )
+  else if ( numBits == 24 )
     {
-     *swap = 0;
-      fact = blocklen/4;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
-      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT64(pbuf);
-      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(4, "pack 24 bit unrolled");
+#endif
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] =  ival >> 16;
+	      lGrib[z+1] =  ival >>  8;
+	      lGrib[z+2] =  ival;
+	      z += 3;
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  ival = (unsigned long) dval[j];
+	  lGrib[z  ] =  ival >> 16;
+	  lGrib[z+1] =  ival >>  8;
+	  lGrib[z+2] =  ival;
+	  z += 3;
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(4);
+#endif
     }
-  else if ( sblocklen == 16 )
+  else if ( numBits == 32 )
     {
-     *swap = 1;
-      fact = sblocklen/4;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
-      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(5, "pack 32 bit unrolled");
+#endif
+      unsigned int *igrib = (unsigned int *) (lGrib + z);
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
+	{
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+	    {
+	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
+	    }
+	  if ( IS_BIGENDIAN() )
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  *igrib = (unsigned long) dval[j];
+		  igrib++;
+		  z += 4;
+		}
+	    }
+	  else
+	    {
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
+		{
+		  ival = (unsigned long) dval[j];
+		  lGrib[z  ] =  ival >> 24;
+		  lGrib[z+1] =  ival >> 16;
+		  lGrib[z+2] =  ival >>  8;
+		  lGrib[z+3] =  ival;
+		  z += 4;
+		}
+	    }
+	}
+      for (j = 0; j < residual; j++) 
+	{
+	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
+	}
+      if ( IS_BIGENDIAN() )
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      *igrib = (unsigned long) dval[j];
+	      igrib++;
+	      z += 4;
+	    }
+	}
+      else
+	{
+	  for (j = 0; j < residual; j++) 
+	    {
+	      ival = (unsigned long) dval[j];
+	      lGrib[z  ] =  ival >> 24;
+	      lGrib[z+1] =  ival >> 16;
+	      lGrib[z+2] =  ival >>  8;
+	      lGrib[z+3] =  ival;
+	      z += 4;
+	    }
+	}
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(5);
+#endif
     }
-  else if ( sblocklen == 32 )
+  else if ( numBits > 0 && numBits <= 32 )
     {
-     *swap = 1;
-      fact = sblocklen/4;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
-      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT64(pbuf);
-      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
+      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
     }
-
-  fileRewind(fileID);
-
-  if      ( data && dimxy*fact   == data ) found = 1;
-  else if ( data && dimxy*fact*2 == data ) found = 1;
-
-  if ( EXT_Debug )
+  else if ( numBits == 0 )
     {
-      Message("swap = %d fact = %d", *swap, fact);
-      Message("dimxy = %lu data = %lu", dimxy, data);
     }
-
-  return (found);
-}
-
-
-int extInqHeader(void *ext, int *header)
-{
-  extrec_t *extp = (extrec_t *) ext;
-  size_t i;
-
-  for ( i = 0; i < EXT_HEADER_LEN; i++ )
-    header[i] = extp->header[i];
-
-  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
-
-  return (0);
-}
-
-
-int extDefHeader(void *ext, const int *header)
-{
-  extrec_t *extp = (extrec_t *) ext;
-  size_t i;
-
-  for ( i = 0; i < EXT_HEADER_LEN; i++ )
-    extp->header[i] = header[i];
-
-  extp->datasize = (size_t)header[3];
-  if ( extp->number == EXT_COMP ) extp->datasize *= 2;
-
-  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
-
-  return (0);
-}
-
-
-static int extInqData(extrec_t *extp, int prec, void *data)
-{
-  size_t datasize;
-  size_t i;
-  int ierr = 0;
-  int rprec;
-  void *buffer;
-  int byteswap = extp->byteswap;
-
-  datasize = extp->datasize;
-  buffer   = extp->buffer;
-  rprec    = extp->prec;
-
-  switch ( rprec )
+  else
     {
-    case SINGLE_PRECISION:
-      {
-	if ( sizeof(FLT32) == 4 )
-	  {
-	    if ( byteswap ) swap4byte(buffer, datasize);
-
-	    if ( rprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT32));
-	    else
-	      for ( i = 0; i < datasize; ++i )
-		((double *) data)[i] = (double) ((float *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT32));
-	  }
-	break;
-      }
-    case DOUBLE_PRECISION:
-	if ( sizeof(FLT64) == 8 )
-	  {
-	    if ( byteswap ) swap8byte(buffer, datasize);
-
-	    if ( rprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT64));
-	    else
-	      for ( i = 0; i < datasize; ++i )
-		((float *) data)[i] = (float) ((double *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT64));
-	  }
-	break;
-    default:
-      {
-	Error("unexpected data precision %d", rprec);
-	break;
-      }
+      Error("Unimplemented packing factor %d!", numBits);
     }
 
-  return (ierr);
-}
-
-
-int extInqDataSP(void *ext, float *data)
-{
-  return (extInqData(ext, SINGLE_PRECISION, (void *) data));
+  *gz = z;
+#undef __UNROLL_DEPTH_2
 }
 
+#endif /* T */
 
-int extInqDataDP(void *ext, double *data)
-{
-  return (extInqData(ext, DOUBLE_PRECISION, (void *) data));
-}
 
+#ifdef T
+#undef T
+#endif
+#define T double
+#ifdef T
 
-int extDefData(void *ext, int prec, const void *data)
+/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
+static
+void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
 {
-  extrec_t *extp = (extrec_t *) ext;
-  size_t datasize;
-  size_t blocklen;
-  size_t buffersize;
-  size_t i;
-  int rprec;
-  int *header;
-  void *buffer;
-
-  if ( extDefaultPrec ) rprec = extDefaultPrec;
-  else                  rprec = extp->prec;
-
-  if ( ! rprec ) rprec = prec;
+  long z = *gribLen;
+  int exponent, mantissa;
+  long i;
+  int ival;
+  int pvoffset = 0xFF;
+  int gdslen = 32;
+  unsigned lonIncr, latIncr;
 
-  extp->prec = rprec;
+  if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
 
-  header = extp->header;
+  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )  gdslen += 10;
 
-  datasize = (size_t)header[3];
-  if ( extp->number == EXT_COMP ) datasize *= 2;
-  blocklen = datasize * (size_t)rprec;
+  if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
 
-  extp->datasize = datasize;
+  if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
 
-  buffersize = extp->buffersize;
+  gdslen += ISEC2_NumVCP * 4;
 
-  if ( buffersize != blocklen )
-    {
-      buffersize = blocklen;
-      buffer = extp->buffer;
-      buffer = realloc(buffer, buffersize);
-      extp->buffer = buffer;
-      extp->buffersize = buffersize;
-    }
-  else
-    buffer = extp->buffer;
+  Put3Byte(gdslen);             /*  0- 2 Length of Block 2 Byte 0 */
+  Put1Byte(ISEC2_NumVCP);       /*  3    NV */
+  Put1Byte(pvoffset);           /*  4    PV */
+  Put1Byte(ISEC2_GridType);     /*  5    LatLon=0 Gauss=4 Spectral=50 */
 
-  switch ( rprec )
+  if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
     {
-    case SINGLE_PRECISION:
-      {
-	if ( rprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT32));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((float *) buffer)[i] = (float) ((double *) data)[i];
-
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	if ( rprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT64));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((double *) buffer)[i] = (double) ((float *) data)[i];
-
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", rprec);
-        break;
-      }
+      Put2Byte(ISEC2_PentaJ);   /*  6- 7 Pentagonal resolution J  */
+      Put2Byte(ISEC2_PentaK);   /*  8- 9 Pentagonal resolution K  */
+      Put2Byte(ISEC2_PentaM);   /* 10-11 Pentagonal resolution M  */
+      Put1Byte(ISEC2_RepType);  /* 12    Representation type      */
+      Put1Byte(ISEC2_RepMode);  /* 13    Representation mode      */
+      PutnZero(18);             /* 14-31 reserved                 */
     }
-
-  return (0);
-}
-
-
-int extDefDataSP(void *ext, const float *data)
-{
-  return (extDefData(ext, SINGLE_PRECISION, (void *) data));
-}
-
-
-int extDefDataDP(void *ext, const double *data)
-{
-  return (extDefData(ext, DOUBLE_PRECISION, (void *) data));
-}
-
-
-int extRead(int fileID, void *ext)
-{
-  extrec_t *extp = (extrec_t *) ext;
-  size_t blocklen, blocklen2;
-  size_t i;
-  void *buffer;
-  int byteswap;
-  int status;
-
-  if ( ! extp->checked )
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
     {
-      status = extCheckFiletype(fileID, &extp->byteswap);
-      if ( status == 0 ) Error("Not a EXTRA file!");
-      extp->checked = 1;
+      Put2Byte(ISEC2_GME_NI2);
+      Put2Byte(ISEC2_GME_NI3);
+      Put3Byte(ISEC2_GME_ND);
+      Put3Byte(ISEC2_GME_NI);
+      Put1Byte(ISEC2_GME_AFlag);
+      Put3Int(ISEC2_GME_LatPP);
+      Put3Int(ISEC2_GME_LonPP);
+      Put3Int(ISEC2_GME_LonMPL);
+      Put1Byte(ISEC2_GME_BFlag);
+      PutnZero(5);
     }
-
-  byteswap = extp->byteswap;
-
-  /* read header record */
-  blocklen = binReadF77Block(fileID, byteswap);
-
-  if ( fileEOF(fileID) ) return (-1);
-
-  if ( EXT_Debug )
-    Message("blocklen = %lu", blocklen);
-
-  size_t hprec = blocklen / EXT_HEADER_LEN;
-
-  extp->prec = (int)hprec;
-
-  switch ( hprec )
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
     {
-    case SINGLE_PRECISION:
-      {
-        INT32 tempheader[4];
-	binReadInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader);
-
-	for ( i = 0; i < EXT_HEADER_LEN; i++ )
-          extp->header[i] = (int)tempheader[i];
-
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-        INT64 tempheader[4];
-	binReadInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader);
-
-	for ( i = 0; i < EXT_HEADER_LEN; i++ )
-          extp->header[i] = (int)tempheader[i];
+      Put2Byte(ISEC2_NumLon);          /*  6- 7 Longitudes               */
 
-	break;
-      }
-    default:
-      {
-	Error("Unexpected header precision %d", hprec);
-        break;
-      }
+      Put2Byte(ISEC2_NumLat);          /*  8- 9 Latitudes                */
+      Put3Int(ISEC2_FirstLat);
+      Put3Int(ISEC2_FirstLon);
+      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
+      Put3Int(ISEC2_Lambert_Lov);      /* 17-19 */
+      Put3Int(ISEC2_Lambert_dx);       /* 20-22 */
+      Put3Int(ISEC2_Lambert_dy);       /* 23-25 */
+      Put1Byte(ISEC2_Lambert_ProjFlag);/* 26    Projection flag          */
+      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
+      Put3Int(ISEC2_Lambert_LatS1);    /* 28-30 */  
+      Put3Int(ISEC2_Lambert_LatS2);    /* 31-33 */
+      Put3Int(ISEC2_Lambert_LatSP);    /* 34-36 */  
+      Put3Int(ISEC2_Lambert_LonSP);    /* 37-39 */
+      PutnZero(2);                     /* 34-41 */
     }
-
-  blocklen2 = binReadF77Block(fileID, byteswap);
-
-  if ( blocklen2 != blocklen )
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
     {
-      Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
-      if ( blocklen2 != 0 ) return (-1);
-    }
-
-  extp->datasize = (size_t)extp->header[3];
+      int numlon;
+      if ( ISEC2_Reduced )
+	numlon = 0xFFFF;
+      else
+	numlon = ISEC2_NumLon;
 
-  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
+      Put2Byte(numlon);                /*  6- 7 Number of Longitudes     */
 
-  blocklen = binReadF77Block(fileID, byteswap);
+      Put2Byte(ISEC2_NumLat);          /*  8- 9 Number of Latitudes      */
+      Put3Int(ISEC2_FirstLat);
+      Put3Int(ISEC2_FirstLon);
+      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
+      Put3Int(ISEC2_LastLat);
+      Put3Int(ISEC2_LastLon);
+      if ( ISEC2_ResFlag == 0 )
+	{
+	  lonIncr = 0xFFFF;
+	  latIncr = 0xFFFF;
+	}
+      else
+	{
+	  lonIncr = ISEC2_LonIncr;
+	  latIncr = ISEC2_LatIncr;
+	}
+      Put2Byte(lonIncr);               /* 23-24 i - direction increment  */
+      if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
+	Put2Byte(ISEC2_NumPar);        /* 25-26 Latitudes Pole->Equator  */
+      else
+	Put2Byte(latIncr);             /* 25-26 j - direction increment  */
 
-  size_t buffersize = (size_t)extp->buffersize;
+      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
+      PutnZero(4);                     /* 28-31 reserved                 */
 
-  if ( buffersize < blocklen )
-    {
-      buffersize = blocklen;
-      buffer = extp->buffer;
-      buffer = realloc(buffer, buffersize);
-      extp->buffer = buffer;
-      extp->buffersize = buffersize;
+      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+	{
+	  Put3Int(ISEC2_LatSP);
+	  Put3Int(ISEC2_LonSP);
+	  Put1Real((double)(FSEC2_RotAngle));
+	}
     }
   else
-    buffer = extp->buffer;
-
-  size_t dprec = blocklen / extp->datasize;
-
-  if ( dprec == hprec )
-    {
-      extp->number = EXT_REAL;
-    }
-  else if ( dprec == 2*hprec )
     {
-      dprec /= 2;
-      extp->datasize *= 2;
-      extp->number = EXT_COMP;
+      Error("Unsupported grid type %d", ISEC2_GridType);
     }
 
-  if ( dprec != SINGLE_PRECISION && dprec != DOUBLE_PRECISION )
+#if defined (SX)
+#pragma vdir novector     /* vectorization gives wrong results on NEC */
+#endif
+  for ( i = 0; i < ISEC2_NumVCP; ++i )
     {
-      Warning("Unexpected data precision %d", dprec);
-      return (-1);
+      Put1Real((double)(fsec2[10+i]));
     }
 
-  fileRead(fileID, buffer, blocklen);
-
-  blocklen2 = binReadF77Block(fileID, byteswap);
-
-  if ( blocklen2 != blocklen )
-    {
-      Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
-      if ( blocklen2 != 0 ) return (-1);
-    }
+  if ( ISEC2_Reduced )
+    for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
 
-  return (0);
+  *gribLen = z;
 }
 
-
-int extWrite(int fileID, void *ext)
+/* GRIB BLOCK 3 - BIT MAP SECTION */
+static
+void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
 {
-  extrec_t *extp = (extrec_t *) ext;
-  size_t datasize;
-  size_t blocklen;
-  size_t i;
-  int rprec, number;
-  char tempheader[32];
-  int *header;
-  void *buffer;
-  int byteswap = extp->byteswap;
-
-
-  rprec  = extp->prec;
-  number = extp->number;
-  header = extp->header;
-
-  /* write header record */
-  blocklen = EXT_HEADER_LEN * (size_t)rprec;
-
-  binWriteF77Block(fileID, byteswap, blocklen);
+  GRIBPACK *bitmap;
+  long bitmapSize;
+  long imaskSize;
+  long i;
+  long bmsLen, bmsUnusedBits;
+  long fsec4size;
+  long z = *gribLen;
+#if defined (VECTORCODE)
+  unsigned int *imask;
+#endif
+  static int lmissvalinfo = 1;
+  /*  unsigned int c, imask; */
 
-  switch ( rprec )
+  if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
     {
-    case SINGLE_PRECISION:
-      {
-	for (i = 0; i < EXT_HEADER_LEN; i++)
-          ((INT32 *) tempheader)[i] = (INT32) header[i];
-
-	binWriteInt32(fileID, byteswap, EXT_HEADER_LEN, (INT32 *) tempheader);
-
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	for (i = 0; i < EXT_HEADER_LEN; i++)
-          ((INT64 *) tempheader)[i] = (INT64) header[i];
-
-	binWriteInt64(fileID, byteswap, EXT_HEADER_LEN, (INT64 *) tempheader);
-
-	break;
-      }
-    default:
-      {
-	Error("unexpected header precision %d", rprec);
-        break;
-      }
+      lmissvalinfo = 0;
+      Message("Missing value = NaN is unsupported!");
     }
 
-  binWriteF77Block(fileID, byteswap, blocklen);
-
-  datasize = (size_t)header[3];
-  if ( number == EXT_COMP ) datasize *= 2;
-  blocklen = datasize * (size_t)rprec;
-
-  binWriteF77Block(fileID, byteswap, blocklen);
+  bitmapSize = ISEC4_NumValues;
+  imaskSize = ((bitmapSize+7)>>3)<<3;
+  bitmap = &lGrib[z+6];
+  fsec4size = 0;
 
-  extp->datasize = datasize;
+#if defined (VECTORCODE)
+  imask = (unsigned int*) malloc(imaskSize*sizeof(unsigned int));
+  memset(imask, 0, imaskSize*sizeof(int));
 
-  buffer = extp->buffer;
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+  for ( i = 0; i < bitmapSize; i++ )
+    {
+      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+	{
+	  data[fsec4size++] = data[i];
+	  imask[i] = 1;
+	}
+    }
 
-  switch ( rprec )
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+  for ( i = 0; i < imaskSize/8; i++ )
     {
-    case SINGLE_PRECISION:
-      {
-	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", rprec);
-        break;
-      }
+      bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
+	          (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
+	          (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
+	          (imask[i*8+6] << 1) | (imask[i*8+7]);
     }
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+  free(imask);
+#else
+  for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
 
-  return (0);
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
+  for ( i = 0; i < bitmapSize; i++ )
+    {
+      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+	{
+	  data[fsec4size++] = data[i];
+	  bitmap[i/8] |= 1<<(7-(i&7));
+	}
+    }
 #endif
 
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
+  bmsLen = imaskSize/8 + 6;
+  bmsUnusedBits = imaskSize - bitmapSize;
 
+  Put3Byte(bmsLen);   /*  0- 2 Length of Block 3 Byte 0 */
+  Put1Byte(bmsUnusedBits);
+  Put2Byte(0);
 
+  *gribLen += bmsLen;
 
-static int initIegLib      = 0;
-static int iegDefaultDprec = 0;
+  *datasize = fsec4size;
+}
 
 
-/*
- * A version string.
- */
+/* GRIB BLOCK 4 - BINARY DATA SECTION */
+static
+int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
+			  long *datstart, long *datsize, int code)
+{
+  /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
+  /* Uwe Schulzweida,  6/05/2003 : Copy result to fpval to prevent integer overflow */
 
-#undef  LIBVERSION
-#define LIBVERSION      1.3.3
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
-static const char ieg_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
+  size_t z = *gribLen;
+  long i, jloop;
+  int numBits;
+  int ival;
+  int blockLength, PackStart = 0, Flag = 0;
+  int binscale = 0;
+  int nbpv;
+  int bds_head = 11;
+  int bds_ext = 0;
+  /* ibits = BitsPerInt; */
+  unsigned int max_nbpv_pow2;
+  int exponent, mantissa;
+  int unused_bits = 0;
+  int lspherc = FALSE, lcomplex = FALSE;
+  int isubset = 0, itemp = 0, itrunc = 0;
+  T factor = 1, fmin, fmax;
+  double zref;
+  double range, rangec;
+  double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
+                                /*        of floating point numbers - needed   */
+		                /*        on some platforms (eg vpp700, linux) */
+  extern const double _pow2tab[158];
+  extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
 
-const char *iegLibraryVersion(void)
-{
-  return (ieg_libvers);
-}
+  if ( isec2 )
+    {
+      /* If section 2 is present, it says if data is spherical harmonic */
 
+      if ( isec2[0] == 50 || isec2[0] == 60 || 
+	   isec2[0] == 70 || isec2[0] == 80 ) lspherc = TRUE;
 
-int IEG_Debug = 0;    /* If set to 1, debugging */
+      if ( lspherc )
+	isec4[2] = 128;
+      else
+	isec4[2] = 0;
+    }
+  else
+    {
+      /* Section 4 says if it's spherical harmonic data.. */
 
+      lspherc = ( isec4[2] == 128 );
+    }
 
+  /* Complex packing supported for spherical harmonics. */
 
-void iegLibInit()
-{
-  char *envString;
-  char *envName = "IEG_PRECISION";
+  lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+             ( lspherc && isec2 && ( isec2[5] == 2 ) );
 
+  /* Check input specification is consistent */
 
-  envString = getenv(envName);
-  if ( envString )
+  if ( lcomplex && isec2 )
     {
-      int pos;
-      int nrun;
-      if ( strlen(envString) == 2 ) nrun = 1;
-      else                          nrun = 2;
-
-      pos = 0;
-      while ( nrun-- )
+      if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
 	{
-	  switch ( tolower((int) envString[pos]) )
-	    {
-	    case 'r':
-	      {
-		switch ( (int) envString[pos+1] )
-		  {
-		  case '4': iegDefaultDprec = SINGLE_PRECISION; break;
-		  case '8': iegDefaultDprec = DOUBLE_PRECISION; break;
-		  default:
-		    Message("Invalid digit in %s: %s", envName, envString);
-		  }
-		break;
-	      }
-	    default:
-              {
-                Message("Invalid character in %s: %s", envName, envString);
-                break;
-              }
-            }
-	  pos += 2;
+	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+	  return (807);
+	}
+      else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
+	{
+	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+	  return (807);
+        }
+      else if ( lcomplex )
+	{
+	  /*
+	    Truncation of full spectrum, which is supposed triangular,
+	    has to be diagnosed. Define also sub-set truncation.
+	  */
+	  isubset = isec4[17];
+	  /* When encoding, use the total number of data. */
+	  itemp   = isec4[0];
+	  itrunc  = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
 	}
     }
 
-  initIegLib = 1;
-}
-
-
-void iegDebug(int debug)
-{
-  IEG_Debug = debug;
-
-  if ( IEG_Debug )
-    Message("debug level %d", debug);
-}
-
-
-void iegInit(iegrec_t *iegp)
-{
-  iegp->checked    = 0;
-  iegp->byteswap   = 0;
-  iegp->dprec      = 0;
-  iegp->refval     = 0;
-  iegp->datasize   = 0;
-  iegp->buffersize = 0;
-  iegp->buffer     = NULL;
-}
-
+  if ( decscale )
+    {
+      T scale = (T) pow(10.0, (double) decscale);
+      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+    }
 
-void iegInitMem(iegrec_t *iegp)
-{
-  memset(iegp->ipdb, 0, sizeof(iegp->ipdb));
-  memset(iegp->igdb, 0, sizeof(iegp->igdb));
-  memset(iegp->vct,  0, sizeof(iegp->vct));
-}
+  if ( lspherc )
+    {
+      if ( lcomplex )
+	{
+	  int jup, ioff;
+	  jup  = isubset;
+	  ioff = (jup+1)*(jup+2);
+	  bds_ext = 4 + 3 + 4*ioff;
+	  PackStart = ioff;
+	  Flag = 192;
+	}
+      else
+	{
+	  bds_ext = 4;
+	  PackStart = 1;
+	  Flag = 128;
+	}
+    }
 
+  *datstart = bds_head + bds_ext;
 
-iegrec_t *iegNew(void)
-{
-  iegrec_t *iegp;
+  nbpv = numBits = ISEC4_NumBits;
 
-  if ( ! initIegLib ) iegLibInit();
+  if ( lspherc && lcomplex )
+    {
+      int pcStart, pcScale;
+      pcStart = isubset;
+      pcScale = isec4[16];
+      TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
+      TEMPLATE(gather_complex,T)(data, pcStart, itrunc, datasize);
+    }
 
-  iegp = (iegrec_t *) malloc(sizeof(iegrec_t));
+  fmin = fmax = data[PackStart];
 
-  iegInit(iegp);
-  iegInitMem(iegp);
+  TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
 
-  return (iegp);
-}
+  zref = (double)fmin;
 
 
-void iegDelete(iegrec_t *iegp)
-{
-  if ( iegp )
+  if ( CGRIBEX_Const && !lspherc )
     {
-      if ( iegp->buffer ) free(iegp->buffer);
-      free(iegp);
+      if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
     }
-}
 
 
-int iegCheckFiletype(int fileID, int *swap)
-{
-  size_t blocklen = 0;
-  size_t sblocklen = 0;
-  size_t data = 0;
-  size_t dimx = 0, dimy = 0;
-  size_t fact = 0;
-  unsigned char buffer[1048], *pbuf;
+  blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
+  if ( (blockLength%2) == 1 ) blockLength++;
 
-  if ( fileRead(fileID, buffer, 4) != 4 ) return (0);
+  unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
 
-  blocklen  = get_UINT32(buffer);
-  sblocklen = get_SUINT32(buffer);
+  Flag += unused_bits;
 
-  if ( IEG_Debug )
-    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
 
-  if ( blocklen == 636 || blocklen == 640 )
+  /*
+    Adjust number of bits per value if full integer length to
+    avoid hitting most significant bit (sign bit).
+  */
+  /* if( nbpv == ibits ) nbpv = nbpv - 1; */
+  /*
+    Calculate the binary scaling factor to spread the range of
+    values over the number of bits per value.
+    Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
+    as a guideline).           
+  */
+  range = fabs(fmax - fmin);
+
+  if ( fabs(fmin) < FLT_MIN ) fmin = 0;
+  /*
+    Have to allow tolerance in comparisons on some platforms
+    (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
+    to avoid clipping ranges which are a power of 2.
+  */
+  if ( range <= jpepsln )
     {
-     *swap = 0;
-      fact = 4;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (0);
-      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
+      binscale = 0;
     }
-  else if ( blocklen == 1040 || blocklen == 1036 )
+  else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
     {
-     *swap = 0;
-      fact = 8;
-      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (0);
-      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
-      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
+      binscale = 0;
     }
-  else if ( sblocklen == 636 || sblocklen == 640 )
+  else if ( fabs(range-1.0) <= jpepsln )
     {
-     *swap = 1;
-      fact = 4;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (0);
-      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
+      binscale = 1 - nbpv;
     }
-  else if ( sblocklen == 1040 || sblocklen == 1036 )
+  else if ( range > 1.0 )
     {
-     *swap = 1;
-      fact = 8;
-      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (0);
-      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
-      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
+      rangec = range + jpepsln;
+      for ( jloop = 1; jloop < 128; jloop++ )
+	{
+	  if ( _pow2tab[jloop] > rangec ) break;
+	}
+      if ( jloop == 128 )
+	{
+	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+	  gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+	  return (707);
+	}
+      else
+	{
+	  binscale = jloop - nbpv;
+	}
     }
-
-  fileRewind(fileID);
-
-  int found = data && (dimx*dimy*fact == data || dimx*dimy*8 == data);
-
-  if ( IEG_Debug )
+  else
     {
-      Message("swap = %d fact = %d", *swap, fact);
-      Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
+      rangec = range - jpepsln;
+      for ( jloop = 1; jloop < 127; jloop++ )
+	{
+	  if ( 1.0/_pow2tab[jloop] < rangec ) break;
+	}
+      if ( jloop == 127 )
+	{
+	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+	  gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+	  return (707);
+	}
+      else
+	{
+	  binscale = 1 - jloop - nbpv;
+	}
     }
 
-  return (found);
-}
-
-
-void iegCopyMeta(iegrec_t *diegp, iegrec_t *siegp)
-{
-  /*  diegp->byteswap = siegp->byteswap; */
-  diegp->dprec    = siegp->dprec;
-  diegp->refval   = siegp->refval;
-
-  memcpy(diegp->ipdb, siegp->ipdb, sizeof(siegp->ipdb));
-  memcpy(diegp->igdb, siegp->igdb, sizeof(siegp->igdb));
-  memcpy(diegp->vct,  siegp->vct,  sizeof(siegp->vct));
-}
-
-
-int iegInqData(iegrec_t *iegp, int prec, void *data)
-{
-  size_t datasize;
-  size_t i;
-  int ierr = 0;
-  int dprec;
-  void *buffer;
-  int byteswap = iegp->byteswap;
+  //max_nbpv_pow2 = (unsigned) (intpow2(nbpv) - 1);
+  max_nbpv_pow2 = (unsigned) ((1ULL << nbpv) - 1);
 
+  if ( binscale != 0 )
+    {
+      if ( binscale < 0 )
+	{
+	  if ( (unsigned)(range*intpow2(-binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+	}
+      else
+	{
+	  if ( (unsigned)(range/intpow2(binscale)+0.5) > max_nbpv_pow2 ) binscale--;
+	}
 
-  datasize = iegp->datasize;
+      if ( binscale < 0 ) factor =     intpow2(-binscale);
+      else                factor = 1.0/intpow2( binscale);
+    }
 
-  buffer = iegp->buffer;
+  ref2ibm(&zref, BitsPerInt);
 
-  dprec = iegp->dprec;
+  Put3Byte(blockLength);      /*  0-2 Length of Block 4        */
+  Put1Byte(Flag);             /*  3   Flag & Unused bits       */
+  if ( binscale < 0 ) binscale = 32768 - binscale;
+  Put2Byte(binscale);         /*  4-5 Scale factor             */
+  Put1Real(zref);             /*  6-9 Reference value          */
+  Put1Byte(nbpv);             /*   10 Packing size             */
 
-  switch ( dprec )
+  if ( lspherc )
     {
-    case SINGLE_PRECISION:
-      {
-	if ( sizeof(FLT32) == 4 )
-	  {
-	    if ( byteswap ) swap4byte(buffer, datasize);
+      if ( lcomplex )
+	{
+	  int jup = isubset;
+	  int ioff = z + bds_ext;
+	  if ( ioff > 0xFFFF ) ioff = 0;
+	  Put2Byte(ioff);
+	  Put2Int(isec4[16]);
+	  Put1Byte(jup);
+	  Put1Byte(jup);
+	  Put1Byte(jup);
+	  for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
+	}
+      else
+	{
+	  Put1Real((double)(data[0]));
+	}
+    }
 
-	    if ( dprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT32));
-	    else
-	      for (i = 0; i < datasize; i++)
-		((double *) data)[i] = (double) ((float *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT32));
-	  }
-	break;
-      }
-    case DOUBLE_PRECISION:
-	if ( sizeof(FLT64) == 8 )
-	  {
-	    if ( byteswap ) swap8byte(buffer, datasize);
+  *datsize  = ((datasize-PackStart)*nbpv + 7)/8;
 
-	    if ( dprec == prec )
-	      memcpy(data, buffer, datasize*sizeof(FLT64));
-	    else
-	      for (i = 0; i < datasize; i++)
-		((float *) data)[i] = (float) ((double *) buffer)[i];
-	  }
-	else
-	  {
-	    Error("not implemented for %d byte float", sizeof(FLT64));
-	  }
-	break;
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
-    }
+#if  defined  (_ARCH_PWR6)
+  TEMPLATE(encode_array_unrolled,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
+#else
+  TEMPLATE(encode_array,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
+#endif
 
-  return (ierr);
-}
+  if ( unused_bits >= 8 ) Put1Byte(0);  /*  Fillbyte                     */
 
+  *gribLen = z;
 
-int iegInqDataSP(iegrec_t *iegp, float *data)
-{
-  return (iegInqData(iegp, SINGLE_PRECISION, (void *) data));
+  return (0);
 }
 
 
-int iegInqDataDP(iegrec_t *iegp, double *data)
+void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+			     T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
+			     int kleng, int *kword, int efunc, int *kret)
 {
-  return (iegInqData(iegp, DOUBLE_PRECISION, (void *) data));
-}
+  long gribLen = 0; /* Counter of GRIB length for output */
+  long isLen, pdsLen;
+  GRIBPACK *lpds;
+  unsigned char *CGrib;
+  long fsec4size = 0;
+  int numBytes;
+  int bmsIncluded;
+  size_t len;
+  GRIBPACK *lGrib;
+  long datstart, datsize, bdsstart;
+  int status = 0;
 
+  UNUSED(isec3);
+  UNUSED(efunc);
 
-int iegDefData(iegrec_t *iegp, int prec, const void *data)
-{
-  size_t datasize;
-  size_t blocklen;
-  size_t buffersize;
-  size_t i;
-  int dprec;
-  void *buffer;
+  grsdef();
 
+  CGrib = (unsigned char *) kgrib;
 
-  if ( iegDefaultDprec ) dprec = iegDefaultDprec;
-  else                   dprec = iegp->dprec;
+  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
 
-  if ( ! dprec ) dprec = prec;
+  /* set max header len */
+  len = 16384;
 
-  iegp->dprec = dprec;
+  /* add data len */
+  numBytes = (ISEC4_NumBits+7)>>3;
 
-  datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
-  blocklen = datasize * (size_t)dprec;
+  len += numBytes*klenp;
 
-  iegp->datasize = datasize;
+  /* add bitmap len */
+  if ( bmsIncluded ) len += (klenp+7)>>3;
 
-  buffersize = iegp->buffersize;
+#if defined (VECTORCODE)
+  lGrib = (GRIBPACK*) malloc(len*sizeof(GRIBPACK));
+  if ( lGrib == NULL ) SysError("No Memory!");
+#else
+  lGrib = CGrib;
+#endif
 
-  if ( buffersize != blocklen )
+  isLen = 8;
+  encodeIS(lGrib, &gribLen);
+  lpds = &lGrib[isLen];
+  pdsLen = getPdsLen(isec1);
+
+  encodePDS(lpds, pdsLen,  isec1);
+  gribLen += pdsLen;
+  /*
+  if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
     {
-      buffersize = blocklen;
-      buffer = iegp->buffer;
-      buffer = realloc(buffer, buffersize);
-      iegp->buffer = buffer;
-      iegp->buffersize = buffersize;
+      static int lwarn_cplx = TRUE;
+
+      if ( lwarn_cplx )
+	Message("Complex packing of spectral data unsupported, using simple packing!");
+
+      isec2[5] = 1;
+      isec4[3] = 0;
+
+      lwarn_cplx = FALSE;
+    }
+  */
+  TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
+  /*
+    ----------------------------------------------------------------
+    BMS Bit-Map Section Section (Section 3)
+    ----------------------------------------------------------------
+  */ 
+  if ( bmsIncluded )
+    {
+      TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
     }
   else
-    buffer = iegp->buffer;
+    {
+      fsec4size = ISEC4_NumValues;
+    }
 
-  switch ( dprec )
+  bdsstart = gribLen;
+  status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
+				 isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
+  if ( status )
     {
-    case SINGLE_PRECISION:
-      {
-	if ( dprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT32));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((float *) buffer)[i] = (float) ((double *) data)[i];
+      *kret = status;
+      return;
+    }
 
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	if ( dprec == prec )
-	  memcpy(buffer, data, datasize*sizeof(FLT64));
-	else
-	  for (i = 0; i < datasize; i++)
-	    ((double *) buffer)[i] = (double) ((float *) data)[i];
+  encodeES(lGrib, &gribLen, bdsstart);
 
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
-    }
+  if ( (size_t) gribLen > kleng*sizeof(int) )
+    Error("kgrib buffer too small! kleng = %d  gribLen = %d", kleng, gribLen);
 
-  return (0);
-}
+#if defined (VECTORCODE)
+  if ( (size_t) gribLen > len )
+    Error("lGrib buffer too small! len = %d  gribLen = %d", len, gribLen);
 
+  (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
 
-int iegDefDataSP(iegrec_t *iegp, const float *data)
-{
-  return (iegDefData(iegp, SINGLE_PRECISION, (void *) data));
-}
+  free(lGrib);
+#endif
 
+  ISEC0_GRIB_Len     = gribLen;
+  ISEC0_GRIB_Version = 1;
 
-int iegDefDataDP(iegrec_t *iegp, const double *data)
-{
-  return (iegDefData(iegp, DOUBLE_PRECISION, (void *) data));
+  *kword = gribLen / sizeof(int);
+  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
+
+  *kret = status;
 }
 
+#endif /* T */
 
-int iegRead(int fileID, iegrec_t *iegp)
+#ifdef T
+#undef T
+#endif
+#define T float
+#ifdef T
+
+/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
+static
+void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
 {
-  size_t datasize;
-  size_t blocklen, blocklen2;
-  size_t i;
-  char tmpbuffer[800], *tmpbuf = tmpbuffer;
-  int dprec = 0;
-  void *buffer;
-  int byteswap;
-  int status;
+  long z = *gribLen;
+  int exponent, mantissa;
+  long i;
+  int ival;
+  int pvoffset = 0xFF;
+  int gdslen = 32;
+  unsigned lonIncr, latIncr;
 
-  if ( ! iegp->checked )
+  if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
+
+  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )  gdslen += 10;
+
+  if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
+
+  if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
+
+  gdslen += ISEC2_NumVCP * 4;
+
+  Put3Byte(gdslen);             /*  0- 2 Length of Block 2 Byte 0 */
+  Put1Byte(ISEC2_NumVCP);       /*  3    NV */
+  Put1Byte(pvoffset);           /*  4    PV */
+  Put1Byte(ISEC2_GridType);     /*  5    LatLon=0 Gauss=4 Spectral=50 */
+
+  if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
     {
-      status = iegCheckFiletype(fileID, &iegp->byteswap);
-      if ( status == 0 ) Error("Not a IEG file!");
-      iegp->checked = 1;
+      Put2Byte(ISEC2_PentaJ);   /*  6- 7 Pentagonal resolution J  */
+      Put2Byte(ISEC2_PentaK);   /*  8- 9 Pentagonal resolution K  */
+      Put2Byte(ISEC2_PentaM);   /* 10-11 Pentagonal resolution M  */
+      Put1Byte(ISEC2_RepType);  /* 12    Representation type      */
+      Put1Byte(ISEC2_RepMode);  /* 13    Representation mode      */
+      PutnZero(18);             /* 14-31 reserved                 */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+    {
+      Put2Byte(ISEC2_GME_NI2);
+      Put2Byte(ISEC2_GME_NI3);
+      Put3Byte(ISEC2_GME_ND);
+      Put3Byte(ISEC2_GME_NI);
+      Put1Byte(ISEC2_GME_AFlag);
+      Put3Int(ISEC2_GME_LatPP);
+      Put3Int(ISEC2_GME_LonPP);
+      Put3Int(ISEC2_GME_LonMPL);
+      Put1Byte(ISEC2_GME_BFlag);
+      PutnZero(5);
     }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
+    {
+      Put2Byte(ISEC2_NumLon);          /*  6- 7 Longitudes               */
 
-  byteswap = iegp->byteswap;
+      Put2Byte(ISEC2_NumLat);          /*  8- 9 Latitudes                */
+      Put3Int(ISEC2_FirstLat);
+      Put3Int(ISEC2_FirstLon);
+      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
+      Put3Int(ISEC2_Lambert_Lov);      /* 17-19 */
+      Put3Int(ISEC2_Lambert_dx);       /* 20-22 */
+      Put3Int(ISEC2_Lambert_dy);       /* 23-25 */
+      Put1Byte(ISEC2_Lambert_ProjFlag);/* 26    Projection flag          */
+      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
+      Put3Int(ISEC2_Lambert_LatS1);    /* 28-30 */  
+      Put3Int(ISEC2_Lambert_LatS2);    /* 31-33 */
+      Put3Int(ISEC2_Lambert_LatSP);    /* 34-36 */  
+      Put3Int(ISEC2_Lambert_LonSP);    /* 37-39 */
+      PutnZero(2);                     /* 34-41 */
+    }
+  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
+	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
+	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+    {
+      int numlon;
+      if ( ISEC2_Reduced )
+	numlon = 0xFFFF;
+      else
+	numlon = ISEC2_NumLon;
 
-  /* read header record */
-  blocklen = binReadF77Block(fileID, byteswap);
+      Put2Byte(numlon);                /*  6- 7 Number of Longitudes     */
 
-  if ( fileEOF(fileID) ) return (-1);
+      Put2Byte(ISEC2_NumLat);          /*  8- 9 Number of Latitudes      */
+      Put3Int(ISEC2_FirstLat);
+      Put3Int(ISEC2_FirstLon);
+      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
+      Put3Int(ISEC2_LastLat);
+      Put3Int(ISEC2_LastLon);
+      if ( ISEC2_ResFlag == 0 )
+	{
+	  lonIncr = 0xFFFF;
+	  latIncr = 0xFFFF;
+	}
+      else
+	{
+	  lonIncr = ISEC2_LonIncr;
+	  latIncr = ISEC2_LatIncr;
+	}
+      Put2Byte(lonIncr);               /* 23-24 i - direction increment  */
+      if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
+	Put2Byte(ISEC2_NumPar);        /* 25-26 Latitudes Pole->Equator  */
+      else
+	Put2Byte(latIncr);             /* 25-26 j - direction increment  */
 
-  if ( IEG_Debug )
-    Message("blocklen = %lu", blocklen);
+      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
+      PutnZero(4);                     /* 28-31 reserved                 */
 
-  if ( blocklen == 636 || blocklen == 640 )
-    dprec = 4;
-  else if ( blocklen == 1040 || blocklen == 1036 )
-    dprec = 8;
+      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+	{
+	  Put3Int(ISEC2_LatSP);
+	  Put3Int(ISEC2_LonSP);
+	  Put1Real((double)(FSEC2_RotAngle));
+	}
+    }
   else
     {
-      Warning("unexpecteted header size %d!", (int) blocklen);
-      return (-1);
+      Error("Unsupported grid type %d", ISEC2_GridType);
     }
 
-  iegp->dprec = dprec;
+#if defined (SX)
+#pragma vdir novector     /* vectorization gives wrong results on NEC */
+#endif
+  for ( i = 0; i < ISEC2_NumVCP; ++i )
+    {
+      Put1Real((double)(fsec2[10+i]));
+    }
 
-  binReadInt32(fileID, byteswap, 37, (INT32 *) tmpbuf);
-  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = (int) ((INT32 *) tmpbuf)[i];
+  if ( ISEC2_Reduced )
+    for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
 
-  binReadInt32(fileID, byteswap, 18, (INT32 *) tmpbuf);
-  for ( i = 0; i < 18; i++ ) iegp->igdb[i] = (int) ((INT32 *) tmpbuf)[i];
+  *gribLen = z;
+}
 
-  if ( blocklen == 636 || blocklen == 1036 )
+/* GRIB BLOCK 3 - BIT MAP SECTION */
+static
+void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
+{
+  GRIBPACK *bitmap;
+  long bitmapSize;
+  long imaskSize;
+  long i;
+  long bmsLen, bmsUnusedBits;
+  long fsec4size;
+  long z = *gribLen;
+#if defined (VECTORCODE)
+  unsigned int *imask;
+#endif
+  static int lmissvalinfo = 1;
+  /*  unsigned int c, imask; */
+
+  if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
     {
-      fileRead(fileID, tmpbuf, 4);
-      if ( byteswap ) swap4byte(tmpbuf, 1);
-      iegp->refval = (double) ((float *) tmpbuf)[0];
+      lmissvalinfo = 0;
+      Message("Missing value = NaN is unsupported!");
     }
-  else
+
+  bitmapSize = ISEC4_NumValues;
+  imaskSize = ((bitmapSize+7)>>3)<<3;
+  bitmap = &lGrib[z+6];
+  fsec4size = 0;
+
+#if defined (VECTORCODE)
+  imask = (unsigned int*) malloc(imaskSize*sizeof(unsigned int));
+  memset(imask, 0, imaskSize*sizeof(int));
+
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+  for ( i = 0; i < bitmapSize; i++ )
     {
-      fileRead(fileID, tmpbuf, 8);
-      if ( byteswap ) swap8byte(tmpbuf, 1);
-      iegp->refval = (double) ((double *) tmpbuf)[0];
+      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+	{
+	  data[fsec4size++] = data[i];
+	  imask[i] = 1;
+	}
     }
 
-  binReadInt32(fileID, byteswap, 3, (INT32 *) tmpbuf);
-  for ( i = 0; i < 3; i++ ) iegp->igdb[18+i] = (int) ((INT32 *) tmpbuf)[i];
-
-  if ( dprec == SINGLE_PRECISION )
+#if defined (CRAY)
+#pragma _CRI ivdep
+#endif
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#ifdef __uxpch__
+#pragma loop novrec
+#endif
+  for ( i = 0; i < imaskSize/8; i++ )
     {
-      fileRead(fileID, tmpbuf, 400);
-      if ( byteswap ) swap4byte(tmpbuf, 100);
-      for ( i = 0; i < 100; i++ )
-	iegp->vct[i] = (double) ((float *) tmpbuf)[i];
+      bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
+	          (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
+	          (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
+	          (imask[i*8+6] << 1) | (imask[i*8+7]);
     }
-  else
+
+  free(imask);
+#else
+  for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
+
+  for ( i = 0; i < bitmapSize; i++ )
     {
-      fileRead(fileID, tmpbuf, 800);
-      if ( byteswap ) swap8byte(tmpbuf, 100);
-      for ( i = 0; i < 100; i++ )
-	iegp->vct[i] = (double) ((double *) tmpbuf)[i];
+      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+	{
+	  data[fsec4size++] = data[i];
+	  bitmap[i/8] |= 1<<(7-(i&7));
+	}
     }
+#endif
 
-  /*
-  fprintf(stderr, "refval %g\n", iegp->refval);
+  bmsLen = imaskSize/8 + 6;
+  bmsUnusedBits = imaskSize - bitmapSize;
 
-  for ( i = 0; i < 100; i++ )
-    fprintf(stderr, "%3d %g\n", i, iegp->vct[i]);
+  Put3Byte(bmsLen);   /*  0- 2 Length of Block 3 Byte 0 */
+  Put1Byte(bmsUnusedBits);
+  Put2Byte(0);
 
-  {
-    int i;
-    for ( i = 0; i < 37; i++ )
-      fprintf(stderr, "pdb: %d %d\n", i, iegp->ipdb[i]);
-    for ( i = 0; i < 22; i++ )
-      fprintf(stderr, "gdb: %d %d\n", i, iegp->igdb[i]);
-  }
-  */
-  blocklen2 = binReadF77Block(fileID, byteswap);
+  *gribLen += bmsLen;
 
-  if ( blocklen2 != blocklen )
+  *datasize = fsec4size;
+}
+
+
+/* GRIB BLOCK 4 - BINARY DATA SECTION */
+static
+int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
+			  long *datstart, long *datsize, int code)
+{
+  /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
+  /* Uwe Schulzweida,  6/05/2003 : Copy result to fpval to prevent integer overflow */
+
+  size_t z = *gribLen;
+  long i, jloop;
+  int numBits;
+  int ival;
+  int blockLength, PackStart = 0, Flag = 0;
+  int binscale = 0;
+  int nbpv;
+  int bds_head = 11;
+  int bds_ext = 0;
+  /* ibits = BitsPerInt; */
+  unsigned int max_nbpv_pow2;
+  int exponent, mantissa;
+  int unused_bits = 0;
+  int lspherc = FALSE, lcomplex = FALSE;
+  int isubset = 0, itemp = 0, itrunc = 0;
+  T factor = 1, fmin, fmax;
+  double zref;
+  double range, rangec;
+  double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
+                                /*        of floating point numbers - needed   */
+		                /*        on some platforms (eg vpp700, linux) */
+  extern const double _pow2tab[158];
+  extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
+
+  if ( isec2 )
     {
-      Warning("header blocklen differ!");
-      return (-1);
+      /* If section 2 is present, it says if data is spherical harmonic */
+
+      if ( isec2[0] == 50 || isec2[0] == 60 || 
+	   isec2[0] == 70 || isec2[0] == 80 ) lspherc = TRUE;
+
+      if ( lspherc )
+	isec4[2] = 128;
+      else
+	isec4[2] = 0;
     }
+  else
+    {
+      /* Section 4 says if it's spherical harmonic data.. */
 
-  iegp->datasize = (size_t)IEG_G_NumLon(iegp->igdb)
-    * (size_t)IEG_G_NumLat(iegp->igdb);
+      lspherc = ( isec4[2] == 128 );
+    }
 
-  if ( IEG_Debug )
-    Message("datasize = %lu", iegp->datasize);
+  /* Complex packing supported for spherical harmonics. */
 
-  blocklen = binReadF77Block(fileID, byteswap);
+  lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+             ( lspherc && isec2 && ( isec2[5] == 2 ) );
 
-  size_t buffersize = iegp->buffersize;
+  /* Check input specification is consistent */
+
+  if ( lcomplex && isec2 )
+    {
+      if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
+	{
+	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+	  return (807);
+	}
+      else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
+	{
+	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
+	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
+	  return (807);
+        }
+      else if ( lcomplex )
+	{
+	  /*
+	    Truncation of full spectrum, which is supposed triangular,
+	    has to be diagnosed. Define also sub-set truncation.
+	  */
+	  isubset = isec4[17];
+	  /* When encoding, use the total number of data. */
+	  itemp   = isec4[0];
+	  itrunc  = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
+	}
+    }
 
-  if ( buffersize < blocklen )
+  if ( decscale )
     {
-      buffersize = blocklen;
-      buffer = iegp->buffer;
-      buffer = realloc(buffer, buffersize);
-      iegp->buffer = buffer;
-      iegp->buffersize = buffersize;
+      T scale = (T) pow(10.0, (double) decscale);
+      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
     }
-  else
-    buffer = iegp->buffer;
-
-  datasize = iegp->datasize;
 
-  if ( dprec != (int) (blocklen/datasize) )
+  if ( lspherc )
     {
-      Warning("data precision differ! (h = %d; d = %d)",
-	      (int) dprec, (int) (blocklen/datasize));
-      return (-1);
+      if ( lcomplex )
+	{
+	  int jup, ioff;
+	  jup  = isubset;
+	  ioff = (jup+1)*(jup+2);
+	  bds_ext = 4 + 3 + 4*ioff;
+	  PackStart = ioff;
+	  Flag = 192;
+	}
+      else
+	{
+	  bds_ext = 4;
+	  PackStart = 1;
+	  Flag = 128;
+	}
     }
 
-  fileRead(fileID, buffer, blocklen);
+  *datstart = bds_head + bds_ext;
 
-  blocklen2 = binReadF77Block(fileID, byteswap);
+  nbpv = numBits = ISEC4_NumBits;
 
-  if ( blocklen2 != blocklen )
+  if ( lspherc && lcomplex )
     {
-      Warning("data blocklen differ!");
-      return (-1);
+      int pcStart, pcScale;
+      pcStart = isubset;
+      pcScale = isec4[16];
+      TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
+      TEMPLATE(gather_complex,T)(data, pcStart, itrunc, datasize);
     }
 
-  return (0);
-}
+  fmin = fmax = data[PackStart];
 
+  TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
 
-int iegWrite(int fileID, iegrec_t *iegp)
-{
-  size_t datasize;
-  size_t blocklen;
-  size_t i;
-  int dprec;
-  float refvalf;
-  double refval;
-  char tmpbuf[800];
-  float fvct[100];
-  void *buffer;
-  int byteswap = iegp->byteswap;
+  zref = (double)fmin;
 
 
-  dprec  = iegp->dprec;
+  if ( CGRIBEX_Const && !lspherc )
+    {
+      if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
+    }
 
-  /* write header record */
-  if ( dprec == SINGLE_PRECISION )
-    blocklen = 636;
-  else
-    blocklen = 1040;
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+  blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
+  if ( (blockLength%2) == 1 ) blockLength++;
 
-  for ( i = 0; i < 37; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->ipdb[i];
-  binWriteInt32(fileID, byteswap, 37, (INT32 *) tmpbuf);
+  unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
 
-  for ( i = 0; i < 18; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->igdb[i];
-  binWriteInt32(fileID, byteswap, 18, (INT32 *) tmpbuf);
+  Flag += unused_bits;
 
-  refval = iegp->refval;
-  refvalf = (float) refval;
-  if ( dprec == SINGLE_PRECISION )
-    binWriteFlt32(fileID, byteswap, 1, (FLT32 *) &refvalf);
-  else
-    binWriteFlt64(fileID, byteswap, 1, (FLT64 *) &refval);
 
-  for ( i = 0; i < 3; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->igdb[18+i];
-  binWriteInt32(fileID, byteswap, 3, (INT32 *) tmpbuf);
+  /*
+    Adjust number of bits per value if full integer length to
+    avoid hitting most significant bit (sign bit).
+  */
+  /* if( nbpv == ibits ) nbpv = nbpv - 1; */
+  /*
+    Calculate the binary scaling factor to spread the range of
+    values over the number of bits per value.
+    Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
+    as a guideline).           
+  */
+  range = fabs(fmax - fmin);
 
-  if ( dprec == SINGLE_PRECISION )
+  if ( fabs(fmin) < FLT_MIN ) fmin = 0;
+  /*
+    Have to allow tolerance in comparisons on some platforms
+    (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
+    to avoid clipping ranges which are a power of 2.
+  */
+  if ( range <= jpepsln )
     {
-      for ( i = 0; i < 100; i++ ) fvct[i] = (float) iegp->vct[i];
-      binWriteFlt32(fileID, byteswap, 100, fvct);
+      binscale = 0;
+    }
+  else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
+    {
+      binscale = 0;
+    }
+  else if ( fabs(range-1.0) <= jpepsln )
+    {
+      binscale = 1 - nbpv;
+    }
+  else if ( range > 1.0 )
+    {
+      rangec = range + jpepsln;
+      for ( jloop = 1; jloop < 128; jloop++ )
+	{
+	  if ( _pow2tab[jloop] > rangec ) break;
+	}
+      if ( jloop == 128 )
+	{
+	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+	  gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+	  return (707);
+	}
+      else
+	{
+	  binscale = jloop - nbpv;
+	}
     }
   else
     {
-      binWriteFlt64(fileID, byteswap, 100, iegp->vct);
+      rangec = range - jpepsln;
+      for ( jloop = 1; jloop < 127; jloop++ )
+	{
+	  if ( 1.0/_pow2tab[jloop] < rangec ) break;
+	}
+      if ( jloop == 127 )
+	{
+	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
+	  gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
+	  return (707);
+	}
+      else
+	{
+	  binscale = 1 - jloop - nbpv;
+	}
     }
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+  //max_nbpv_pow2 = (unsigned) (intpow2(nbpv) - 1);
+  max_nbpv_pow2 = (unsigned) ((1ULL << nbpv) - 1);
 
-  datasize = (size_t)iegp->igdb[4] * (size_t)iegp->igdb[5];
-  blocklen = datasize * (size_t)dprec;
+  if ( binscale != 0 )
+    {
+      if ( binscale < 0 )
+	{
+	  if ( (unsigned)(range*intpow2(-binscale)+0.5) > max_nbpv_pow2 ) binscale++;
+	}
+      else
+	{
+	  if ( (unsigned)(range/intpow2(binscale)+0.5) > max_nbpv_pow2 ) binscale--;
+	}
 
-  binWriteF77Block(fileID, byteswap, blocklen);
+      if ( binscale < 0 ) factor =     intpow2(-binscale);
+      else                factor = 1.0/intpow2( binscale);
+    }
 
-  iegp->datasize = datasize;
+  ref2ibm(&zref, BitsPerInt);
 
-  buffer = iegp->buffer;
+  Put3Byte(blockLength);      /*  0-2 Length of Block 4        */
+  Put1Byte(Flag);             /*  3   Flag & Unused bits       */
+  if ( binscale < 0 ) binscale = 32768 - binscale;
+  Put2Byte(binscale);         /*  4-5 Scale factor             */
+  Put1Real(zref);             /*  6-9 Reference value          */
+  Put1Byte(nbpv);             /*   10 Packing size             */
 
-  switch ( dprec )
+  if ( lspherc )
     {
-    case SINGLE_PRECISION:
-      {
-	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
-	break;
-      }
-    case DOUBLE_PRECISION:
-      {
-	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
-	break;
-      }
-    default:
-      {
-	Error("unexpected data precision %d", dprec);
-        break;
-      }
+      if ( lcomplex )
+	{
+	  int jup = isubset;
+	  int ioff = z + bds_ext;
+	  if ( ioff > 0xFFFF ) ioff = 0;
+	  Put2Byte(ioff);
+	  Put2Int(isec4[16]);
+	  Put1Byte(jup);
+	  Put1Byte(jup);
+	  Put1Byte(jup);
+	  for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
+	}
+      else
+	{
+	  Put1Real((double)(data[0]));
+	}
     }
 
-  binWriteF77Block(fileID, byteswap, blocklen);
-
-  return (0);
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <string.h>
-#include <float.h>  /* FLT_EPSILON */
-#include <limits.h> /* INT_MAX     */
-
-
-#ifndef  RAD2DEG
-#define  RAD2DEG  (180./M_PI)   /* conversion for rad to deg */
-#endif
+  *datsize  = ((datasize-PackStart)*nbpv + 7)/8;
 
-#ifndef  DEG2RAD
-#define  DEG2RAD  (M_PI/180.)   /* conversion for deg to rad */
+#if  defined  (_ARCH_PWR6)
+  TEMPLATE(encode_array_unrolled,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
+#else
+  TEMPLATE(encode_array,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
 #endif
 
+  if ( unused_bits >= 8 ) Put1Byte(0);  /*  Fillbyte                     */
 
-/* the value in the second pair of brackets must match the length of
- * the longest string (including terminating NUL) */
-static const char Grids[][17] = {
-  /*  0 */  "undefined",
-  /*  1 */  "generic",
-  /*  2 */  "gaussian",
-  /*  3 */  "gaussian reduced",
-  /*  4 */  "lonlat",
-  /*  5 */  "spectral",
-  /*  6 */  "fourier",
-  /*  7 */  "gme",
-  /*  8 */  "trajectory",
-  /*  9 */  "unstructured",
-  /* 10 */  "curvilinear",
-  /* 11 */  "lcc",
-  /* 12 */  "lcc2",
-  /* 13 */  "laea",
-  /* 14 */  "sinusoidal",
-  /* 15 */  "projection",
-};
-
-
-static int    gridCompareP    ( void * gridptr1, void * gridptr2 );
-static void   gridDestroyP    ( void * gridptr );
-static void   gridPrintP      ( void * gridptr, FILE * fp );
-static int    gridGetPackSize ( void * gridptr, void *context);
-static void   gridPack        ( void * gridptr, void * buff, int size,
-				int *position, void *context);
-static int    gridTxCode      ( void );
-
-static const resOps gridOps = {
-  gridCompareP,
-  gridDestroyP,
-  gridPrintP,
-  gridGetPackSize,
-  gridPack,
-  gridTxCode
-};
-
-static int  GRID_Debug = 0;   /* If set to 1, debugging */
-
-#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
-
-void grid_init(grid_t *gridptr)
-{
-  gridptr->self         = CDI_UNDEFID;
-  gridptr->type         = CDI_UNDEFID;
-  gridptr->proj         = CDI_UNDEFID;
-  gridptr->mask         = NULL;
-  gridptr->mask_gme     = NULL;
-  gridptr->xvals        = NULL;
-  gridptr->yvals        = NULL;
-  gridptr->area         = NULL;
-  gridptr->xbounds      = NULL;
-  gridptr->ybounds      = NULL;
-  gridptr->rowlon       = NULL;
-  gridptr->nrowlon      = 0;
-  gridptr->xfirst       = 0.0;
-  gridptr->xlast        = 0.0;
-  gridptr->xinc         = 0.0;
-  gridptr->yfirst       = 0.0;
-  gridptr->ylast        = 0.0;
-  gridptr->yinc         = 0.0;
-  gridptr->lcc_originLon = 0.0;
-  gridptr->lcc_originLat = 0.0;
-  gridptr->lcc_lonParY  = 0.0;
-  gridptr->lcc_lat1     = 0.0;
-  gridptr->lcc_lat2     = 0.0;
-  gridptr->lcc_xinc     = 0.0;
-  gridptr->lcc_yinc     = 0.0;
-  gridptr->lcc_projflag = 0;
-  gridptr->lcc_scanflag = 0;
-  gridptr->lcc_defined  = FALSE;
-  gridptr->lcc2_lon_0   = 0.0;
-  gridptr->lcc2_lat_0   = 0.0;
-  gridptr->lcc2_lat_1   = 0.0;
-  gridptr->lcc2_lat_2   = 0.0;
-  gridptr->lcc2_a       = 0.0;
-  gridptr->lcc2_defined = FALSE;
-  gridptr->laea_lon_0   = 0.0;
-  gridptr->laea_lat_0   = 0.0;
-  gridptr->laea_a       = 0.0;
-  gridptr->laea_defined = FALSE;
-  gridptr->trunc        = 0;
-  gridptr->nvertex      = 0;
-  gridptr->nd           = 0;
-  gridptr->ni           = 0;
-  gridptr->ni2          = 0;
-  gridptr->ni3          = 0;
-  gridptr->number       = 0;
-  gridptr->position     = 0;
-  gridptr->reference    = NULL;
-  gridptr->prec         = 0;
-  gridptr->size         = 0;
-  gridptr->xsize        = 0;
-  gridptr->ysize        = 0;
-  gridptr->np           = 0;
-  gridptr->xdef         = 0;
-  gridptr->ydef         = 0;
-  gridptr->isCyclic     = CDI_UNDEFID;
-  gridptr->isRotated    = FALSE;
-  gridptr->xpole        = 0.0;
-  gridptr->ypole        = 0.0;
-  gridptr->angle        = 0.0;
-  gridptr->locked       = FALSE;
-  gridptr->lcomplex     = 0;
-  gridptr->hasdims      = TRUE;
-  gridptr->xname[0]     = 0;
-  gridptr->yname[0]     = 0;
-  gridptr->xlongname[0] = 0;
-  gridptr->ylongname[0] = 0;
-  gridptr->xunits[0]    = 0;
-  gridptr->yunits[0]    = 0;
-  gridptr->xstdname[0]  = 0;
-  gridptr->ystdname[0]  = 0;
-  memset(gridptr->uuid, 0, CDI_UUID_SIZE);
-  gridptr->name         = NULL;
-}
-
-
-void grid_free(grid_t *gridptr)
-{
-  if ( gridptr->mask      ) free(gridptr->mask);
-  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
-  if ( gridptr->xvals     ) free(gridptr->xvals);
-  if ( gridptr->yvals     ) free(gridptr->yvals);
-  if ( gridptr->area      ) free(gridptr->area);
-  if ( gridptr->xbounds   ) free(gridptr->xbounds);
-  if ( gridptr->ybounds   ) free(gridptr->ybounds);
-  if ( gridptr->rowlon    ) free(gridptr->rowlon);
-  if ( gridptr->reference ) free(gridptr->reference);
-  if ( gridptr->name      ) free(gridptr->name);
+  *gribLen = z;
 
-  grid_init(gridptr);
+  return (0);
 }
 
-static grid_t *
-gridNewEntry(cdiResH resH)
-{
-  grid_t *gridptr = (grid_t*) xmalloc(sizeof(grid_t));
-  grid_init(gridptr);
-  if (resH == CDI_UNDEFID)
-    gridptr->self = reshPut(gridptr, &gridOps);
-  else
-    {
-      gridptr->self = resH;
-      reshReplace(resH, gridptr, &gridOps);
-    }
-  return gridptr;
-}
 
-static
-void gridInit (void)
+void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
+			     T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
+			     int kleng, int *kword, int efunc, int *kret)
 {
-  static int gridInitialized = 0;
-  char *env;
-
-  if ( gridInitialized ) return;
-
-  gridInitialized = 1;
-
-  env = getenv("GRID_DEBUG");
-  if ( env ) GRID_Debug = atoi(env);
-}
+  long gribLen = 0; /* Counter of GRIB length for output */
+  long isLen, pdsLen;
+  GRIBPACK *lpds;
+  unsigned char *CGrib;
+  long fsec4size = 0;
+  int numBytes;
+  int bmsIncluded;
+  size_t len;
+  GRIBPACK *lGrib;
+  long datstart, datsize, bdsstart;
+  int status = 0;
 
-static
-void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
-{
-  int gridID2;
+  UNUSED(isec3);
+  UNUSED(efunc);
 
-  gridID2 = gridptr2->self;
-  memcpy(gridptr2, gridptr1, sizeof(grid_t));
-  gridptr2->self = gridID2;
-}
+  grsdef();
 
-int gridSize(void)
-{
-  return reshCountType ( &gridOps );
-}
+  CGrib = (unsigned char *) kgrib;
 
-// used also in CDO
-void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
-{
-  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
-    {
-      if ( xfirst >= xlast )
-        {
-          while ( xfirst >= xlast ) xlast += 360;
-          xinc = (xlast-xfirst)/(xsize);
-        }
-      else
-        {
-          xinc = (xlast-xfirst)/(xsize-1);
-        }
-    }
+  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
 
-  for ( int i = 0; i < xsize; ++i )
-    xvals[i] = xfirst + i*xinc;
-}
+  /* set max header len */
+  len = 16384;
 
-static
-void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
-{
-  double *restrict yw = (double *)xmalloc((size_t)ysize * sizeof(double));
-  gaussaw(yvals, yw, (size_t)ysize);
-  free(yw);
-  for (int i = 0; i < ysize; i++ )
-    yvals[i] = asin(yvals[i])/M_PI*180.0;
+  /* add data len */
+  numBytes = (ISEC4_NumBits+7)>>3;
 
-  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
-    {
-      int yhsize = ysize/2;
-      for (int i = 0; i < yhsize; i++ )
-        {
-          double ytmp = yvals[i];
-          yvals[i] = yvals[ysize-i-1];
-          yvals[ysize-i-1] = ytmp;
-        }
-    }
-}
+  len += numBytes*klenp;
 
-// used also in CDO
-void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
-{
-  const double deleps = 0.002;
+  /* add bitmap len */
+  if ( bmsIncluded ) len += (klenp+7)>>3;
 
-  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      if ( ysize > 2 )
-	{
-	  calc_gaussgrid(yvals, ysize, yfirst, ylast);
+#if defined (VECTORCODE)
+  lGrib = (GRIBPACK*) malloc(len*sizeof(GRIBPACK));
+  if ( lGrib == NULL ) SysError("No Memory!");
+#else
+  lGrib = CGrib;
+#endif
 
-	  if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
-	    if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
-	      {
-		double yinc = fabs(ylast-yfirst)/(ysize-1);
-		double *restrict ytmp = NULL;
-		int nstart, lfound = 0;
-		int ny = (int) (180./yinc + 0.5);
-		ny -= ny%2;
-		/* printf("%g %g %g %g %g %d\n", ylast, yfirst, ylast-yfirst,yinc, 180/yinc, ny); */
-		if ( ny > ysize && ny < 4096 )
-		  {
-		    ytmp = (double *)xmalloc((size_t)ny * sizeof (double));
-		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
-                    int i;
-		    for ( i = 0; i < (ny-ysize); i++ )
-		      if ( fabs(ytmp[i] - yfirst) < deleps ) break;
+  isLen = 8;
+  encodeIS(lGrib, &gribLen);
+  lpds = &lGrib[isLen];
+  pdsLen = getPdsLen(isec1);
 
-		    nstart = i;
+  encodePDS(lpds, pdsLen,  isec1);
+  gribLen += pdsLen;
+  /*
+  if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
+    {
+      static int lwarn_cplx = TRUE;
 
-		    lfound = (nstart+ysize-1) < ny
-                      && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
-		  }
+      if ( lwarn_cplx )
+	Message("Complex packing of spectral data unsupported, using simple packing!");
 
-		if ( lfound )
-		  {
-		    for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
-		  }
-		else
-		  {
-		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
-		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
-		    yvals[0] = yfirst;
-		    yvals[ysize-1] = ylast;
-		  }
+      isec2[5] = 1;
+      isec4[3] = 0;
 
-		if ( ytmp ) free(ytmp);
-	      }
-	}
-      else
-        {
-          yvals[0] = yfirst;
-          yvals[ysize-1] = ylast;
-        }
+      lwarn_cplx = FALSE;
+    }
+  */
+  TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
+  /*
+    ----------------------------------------------------------------
+    BMS Bit-Map Section Section (Section 3)
+    ----------------------------------------------------------------
+  */ 
+  if ( bmsIncluded )
+    {
+      TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
     }
-  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
   else
     {
-      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
-        {
-          if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
+      fsec4size = ISEC4_NumValues;
+    }
 
-          if ( yfirst > ylast )
-            yinc = (yfirst-ylast)/(ysize-1);
-          else if ( yfirst < ylast )
-            yinc = (ylast-yfirst)/(ysize-1);
-          else
-            {
-              if ( ysize%2 != 0 )
-                {
-                  yinc = 180.0/(ysize-1);
-                  yfirst = -90;
-                }
-              else
-                {
-                  yinc = 180.0/ysize;
-                  yfirst = -90 + yinc/2;
-                }
-            }
-        }
+  bdsstart = gribLen;
+  status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
+				 isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
+  if ( status )
+    {
+      *kret = status;
+      return;
+    }
 
-      if ( yfirst > ylast && yinc > 0 ) yinc = -yinc;
+  encodeES(lGrib, &gribLen, bdsstart);
 
-      for (int i = 0; i < ysize; i++ )
-        yvals[i] = yfirst + i*yinc;
-    }
-  /*
-    else
-    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
-  */
-}
+  if ( (size_t) gribLen > kleng*sizeof(int) )
+    Error("kgrib buffer too small! kleng = %d  gribLen = %d", kleng, gribLen);
 
-/*
- at Function  gridCreate
- at Title     Create a horizontal Grid
+#if defined (VECTORCODE)
+  if ( (size_t) gribLen > len )
+    Error("lGrib buffer too small! len = %d  gribLen = %d", len, gribLen);
 
- at Prototype int gridCreate(int gridtype, int size)
- at Parameter
-    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
-                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
-                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
-                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
-    @Item  size      Number of gridpoints.
+  (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
 
- at Description
-The function @func{gridCreate} creates a horizontal Grid.
+  free(lGrib);
+#endif
 
- at Result
- at func{gridCreate} returns an identifier to the Grid.
+  ISEC0_GRIB_Len     = gribLen;
+  ISEC0_GRIB_Version = 1;
 
- at Example
-Here is an example using @func{gridCreate} to create a regular lon/lat Grid:
+  *kword = gribLen / sizeof(int);
+  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
 
- at Source
-   ...
-#define  nlon  12
-#define  nlat   6
-   ...
-double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
-double lats[nlat] = {-75, -45, -15, 15, 45, 75};
-int gridID;
-   ...
-gridID = gridCreate(GRID_LONLAT, nlon*nlat);
-gridDefXsize(gridID, nlon);
-gridDefYsize(gridID, nlat);
-gridDefXvals(gridID, lons);
-gridDefYvals(gridID, lats);
-   ...
- at EndSource
- at EndFunction
-*/
-int gridCreate(int gridtype, int size)
+  *kret = status;
+}
+
+#endif /* T */
+
+void encode_dummy(void)
 {
-  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
+  (void) encode_array_unrolled_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
+  (void) encode_array_unrolled_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
+}
+static const char grb_libvers[] = "1.7.2" " of ""Apr 22 2015"" ""13:44:04";
+const char *
+cgribexLibraryVersion(void)
+{
+  return (grb_libvers);
+}
 
-  if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic pop
+#endif
 
-  gridInit();
+#ifdef HAVE_CONFIG_H
+#endif
 
-  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
-  if ( ! gridptr ) Error("No memory");
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#ifdef WORDS_BIGENDIAN
+#include <limits.h>
+#endif
 
-  int gridID = gridptr->self;
 
-  if ( CDI_Debug ) Message("gridID: %d", gridID);
+static const uint32_t crctab[] = {
+  0x00000000,
+  0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
+  0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
+  0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
+  0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
+  0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
+  0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
+  0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
+  0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
+  0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
+  0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
+  0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
+  0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
+  0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
+  0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
+  0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
+  0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
+  0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
+  0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
+  0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
+  0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
+  0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
+  0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
+  0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
+  0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
+  0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
+  0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
+  0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
+  0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
+  0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
+  0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
+  0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
+  0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
+  0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
+  0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
 
-  gridptr->type = gridtype;
-  gridptr->size = size;
 
-  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
-  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
-  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
+uint32_t
+memcrc(const unsigned char *b, size_t n)
+{
+/*  Input arguments:
+ *  const char*   b == byte sequence to checksum
+ *  size_t        n == length of sequence
+ */
 
-  switch (gridtype)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_GAUSSIAN_REDUCED:
-    case GRID_CURVILINEAR:
-    case GRID_TRAJECTORY:
-      {
-        if ( gridtype == GRID_TRAJECTORY )
-          {
-            gridDefXname(gridID, "tlon");
-            gridDefYname(gridID, "tlat");
-          }
-        else
-          {
-            gridDefXname(gridID, "lon");
-            gridDefYname(gridID, "lat");
-          }
-        gridDefXlongname(gridID, "longitude");
-        gridDefYlongname(gridID, "latitude");
 
-        /*
-        if ( gridtype == GRID_CURVILINEAR )
-          {
-            strcpy(gridptr->xstdname, "grid_longitude");
-            strcpy(gridptr->ystdname, "grid_latitude");
-            gridDefXunits(gridID, "degrees");
-            gridDefYunits(gridID, "degrees");
-          }
-        else
-        */
-          {
-            strcpy(gridptr->xstdname, "longitude");
-            strcpy(gridptr->ystdname, "latitude");
-            gridDefXunits(gridID, "degrees_east");
-            gridDefYunits(gridID, "degrees_north");
-          }
+  uint32_t s = 0;
 
-        break;
-      }
-    case GRID_GME:
-    case GRID_UNSTRUCTURED:
-      {
-        gridDefXname(gridID, "lon");
-        gridDefYname(gridID, "lat");
-        strcpy(gridptr->xstdname, "longitude");
-        strcpy(gridptr->ystdname, "latitude");
-        gridDefXunits(gridID, "degrees_east");
-        gridDefYunits(gridID, "degrees_north");
-        break;
-      }
-    case GRID_GENERIC:
-      {
-        gridDefXname(gridID, "x");
-        gridDefYname(gridID, "y");
-        /*
-        strcpy(gridptr->xstdname, "grid_longitude");
-        strcpy(gridptr->ystdname, "grid_latitude");
-        gridDefXunits(gridID, "degrees");
-        gridDefYunits(gridID, "degrees");
-        */
-        break;
-      }
-    case GRID_LCC2:
-    case GRID_SINUSOIDAL:
-    case GRID_LAEA:
-      {
-        gridDefXname(gridID, "x");
-        gridDefYname(gridID, "y");
-        strcpy(gridptr->xstdname, "projection_x_coordinate");
-        strcpy(gridptr->ystdname, "projection_y_coordinate");
-        gridDefXunits(gridID, "m");
-        gridDefYunits(gridID, "m");
-        break;
-      }
-    }
+  memcrc_r(&s, b, n);
 
-  return (gridID);
+  /* Extend with the length of the string. */
+  while (n != 0) {
+    register uint32_t c = n & 0377;
+    n >>= 8;
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+
+  return ~s;
 }
 
-static
-void gridDestroyKernel( grid_t * gridptr )
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
 {
-  int id;
-
-  xassert ( gridptr );
+/*  Input arguments:
+ *  const char*   b == byte sequence to checksum
+ *  size_t        n == length of sequence
+ */
 
-  id = gridptr->self;
 
-  if ( gridptr->mask      ) free(gridptr->mask);
-  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
-  if ( gridptr->xvals     ) free(gridptr->xvals);
-  if ( gridptr->yvals     ) free(gridptr->yvals);
-  if ( gridptr->area      ) free(gridptr->area);
-  if ( gridptr->xbounds   ) free(gridptr->xbounds);
-  if ( gridptr->ybounds   ) free(gridptr->ybounds);
-  if ( gridptr->rowlon    ) free(gridptr->rowlon);
-  if ( gridptr->reference ) free(gridptr->reference);
+  register uint32_t c, s = *state;
+  register size_t n = block_len;
+  register const unsigned char *b = block;
 
-  free ( gridptr );
+  for (; n > 0; --n) {
+    c = (uint32_t)(*b++);
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
 
-  reshRemove ( id, &gridOps );
+  *state = s;
 }
 
-/*
- at Function  gridDestroy
- at Title     Destroy a horizontal Grid
+#define SWAP_CSUM(BITWIDTH,BYTEWIDTH,NACC)                              \
+  do {                                                                  \
+    register const uint##BITWIDTH##_t *b = (uint##BITWIDTH##_t *)elems; \
+    for (size_t i = 0; i < num_elems; ++i) {                            \
+      for(size_t aofs = NACC; aofs > 0; --aofs) {                       \
+        uint##BITWIDTH##_t accum = b[i + aofs - 1];                     \
+        for (size_t j = 0; j < BYTEWIDTH; ++j) {                        \
+          uint32_t c = (uint32_t)(accum & UCHAR_MAX);                   \
+          s = (s << 8) ^ crctab[(s >> 24) ^ c];                         \
+          accum >>= 8;                                                  \
+        }                                                               \
+      }                                                                 \
+    }                                                                   \
+  } while (0)
 
- at Prototype void gridDestroy(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
 
- at EndFunction
-*/
-void gridDestroy(int gridID)
+
+/**
+ *  Does endian-swapping prior to checksumming in case platform is big-endian
+ *
+ *  @param elems points to first first element with alignment elem_size
+ *  @param num_elems number of elements to process
+ *  @param elem_size size of each element in bytes
+ */
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+#ifdef WORDS_BIGENDIAN
+  register uint32_t s = *state;
 
-  gridDestroyKernel ( gridptr );
+  switch (elem_size)
+  {
+  case 1:
+    memcrc_r(state, elems, num_elems * elem_size);
+    return;
+  case 2:
+    SWAP_CSUM(16,2,1);
+    break;
+  case 4:
+    SWAP_CSUM(32,4,1);
+    break;
+  case 8:
+    SWAP_CSUM(64,8,1);
+    break;
+  case 16:
+    SWAP_CSUM(64,8,2);
+    break;
+  }
+  *state = s;
+#else
+  memcrc_r(state, elems, num_elems * elem_size);
+#endif
 }
 
-void gridDestroyP ( void * gridptr )
+
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size)
 {
-  gridDestroyKernel (( grid_t * ) gridptr );
+  register uint32_t c, s = *state;
+  register uint64_t n = (uint64_t)total_size;
+
+  /* Extend with the length of the string. */
+  while (n != 0) {
+    c = n & 0377;
+    n >>= 8;
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+  return ~s;
 }
 
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if  defined(HAVE_CONFIG_H)
+#endif
 
-const char *gridNamePtr(int gridtype)
-{
-  const char *name;
-  int size = (int) (sizeof(Grids)/sizeof(char *));
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <errno.h>
 
-  name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
 
-  return (name);
-}
+#if !defined(HAVE_CONFIG_H) && !defined(HAVE_MALLOC_H) && defined(SX)
+#  define  HAVE_MALLOC_H
+#endif
 
+#if  defined(HAVE_MALLOC_H)
+#  include <malloc.h>
+#endif
 
-void gridName(int gridtype, char *gridname)
-{
-  strcpy(gridname, gridNamePtr(gridtype));
-}
+//There is no point in avoiding to include our own header, it is likely to be included before this file in the backed cdilib.c.
+//As such, we may as well always include it and let the compiler check our function signatures.
 
-/*
- at Function  gridDefXname
- at Title     Define the name of a X-axis
+//However, we need to avoid clobbering our own `malloc()` calls, so we ensure that our own malloc calls cannot be interpreted as macro calls.
+#define protected_realloc (realloc)
+#define protected_calloc (calloc)
+#define protected_malloc (malloc)
+#define protected_free (free)
 
- at Prototype void gridDefXname(int gridID, const char *name)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the X-axis.
 
- at Description
-The function @func{gridDefXname} defines the name of a X-axis.
+#define  MALLOC_FUNC   0
+#define  CALLOC_FUNC   1
+#define  REALLOC_FUNC  2
+#define  FREE_FUNC     3
 
- at EndFunction
-*/
-void gridDefXname(int gridID, const char *xname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#undef   UNDEFID
+#define  UNDEFID  -1
 
-  if ( xname )
-    {
-      strncpy(gridptr->xname, xname, CDI_MAX_NAME);
-      gridptr->xname[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
+#define  MAXNAME  32   /* Min = 8, for  "unknown" ! */
+
+int dmemory_ExitOnError = 0;
+
+typedef struct
+{
+  void     *ptr;
+  int       item;
+  size_t    size;
+  size_t    nobj;
+  int       mtype;
+  int       line;
+  char      file[MAXNAME];
+  char      caller[MAXNAME];
 }
+MemTable_t;
 
-/*
- at Function  gridDefXlongname
- at Title     Define the longname of a X-axis
+static MemTable_t *memTable;
+static size_t  memTableSize  = 0;
+static long    memAccess     = 0;
 
- at Prototype void gridDefXlongname(int gridID, const char *longname)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the X-axis.
+static size_t  MemObjs       = 0;
+static size_t  MaxMemObjs    = 0;
+static size_t  MemUsed       = 0;
+static size_t  MaxMemUsed    = 0;
 
- at Description
-The function @func{gridDefXlongname} defines the longname of a X-axis.
+static int     MEM_Debug     = 0;   /* If set to 1, debugging */
 
- at EndFunction
-*/
-void gridDefXlongname(int gridID, const char *xlongname)
+void memDebug(int debug)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-  if ( xlongname )
-    {
-      strncpy(gridptr->xlongname, xlongname, CDI_MAX_NAME);
-      gridptr->xlongname[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
+  MEM_Debug = debug;
 }
 
-/*
- at Function  gridDefXunits
- at Title     Define the units of a X-axis
+static
+void memInternalProblem(const char *caller, const char *fmt, ...)
+{
+  va_list args;
 
- at Prototype void gridDefXunits(int gridID, const char *units)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the X-axis.
+  va_start(args, fmt);
 
- at Description
-The function @func{gridDefXunits} defines the units of a X-axis.
+  printf("\n");
+   fprintf(stderr, "Internal problem (%s) : ", caller);
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
 
- at EndFunction
-*/
-void gridDefXunits(int gridID, const char *xunits)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  va_end(args);
 
-  if ( xunits )
-    {
-      strncpy(gridptr->xunits, xunits, CDI_MAX_NAME);
-      gridptr->xunits[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
+  exit(EXIT_FAILURE);
 }
 
-/*
- at Function  gridDefYname
- at Title     Define the name of a Y-axis
+static
+void memError(const char *caller, const char *file, int line, size_t size)
+{
+  printf("\n");
+  fprintf(stderr, "Error (%s) : Allocation of %zu bytes failed. [ line %d file %s ]\n",
+	  caller, size, line, file);
 
- at Prototype void gridDefYname(int gridID, const char *name)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the Y-axis.
+  if ( errno ) perror("System error message ");
 
- at Description
-The function @func{gridDefYname} defines the name of a Y-axis.
+  exit(EXIT_FAILURE);
+}
 
- at EndFunction
-*/
-void gridDefYname(int gridID, const char *yname)
+static
+void memListPrintEntry(int mtype, int item, size_t size, void *ptr,
+		       const char *caller, const char *file, int line)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  if ( yname )
+  switch (mtype)
     {
-      strncpy(gridptr->yname, yname, CDI_MAX_NAME);
-      gridptr->yname[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    case MALLOC_FUNC:
+      fprintf(stderr, "[%-7s ", "Malloc");
+      break;
+    case CALLOC_FUNC:
+      fprintf(stderr, "[%-7s ", "Calloc");
+      break;
+    case REALLOC_FUNC:
+      fprintf(stderr, "[%-7s ", "Realloc");
+      break;
+    case FREE_FUNC:
+      fprintf(stderr, "[%-7s ", "Free");
+      break;
     }
+
+   fprintf(stderr, "memory item %3d ", item);
+   fprintf(stderr, "(%6zu byte) ", size);
+   fprintf(stderr, "at %p", ptr);
+   if ( file != NULL )
+     {
+       fprintf(stderr, " line %4d", line);
+       fprintf(stderr, " file %s", file);
+     }
+   if ( caller != NULL )
+     fprintf(stderr, " (%s)", caller);
+   fprintf(stderr, "]\n");
 }
 
-/*
- at Function  gridDefYlongname
- at Title     Define the longname of a Y-axis
+static
+void memListPrintTable(void)
+{
+  int item, item1, item2 = 0;
 
- at Prototype void gridDefYlongname(int gridID, const char *longname)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the Y-axis.
+  if ( MemObjs ) fprintf(stderr, "\nMemory table:\n");
 
- at Description
-The function @func{gridDefYlongname} defines the longname of a Y-axis.
+  /* find maximum item */
+  for (size_t memID = 0; memID < memTableSize; memID++)
+    if ( memTable[memID].item != UNDEFID )
+      if ( memTable[memID].item > item2 ) item2 = memTable[memID].item;
 
- at EndFunction
-*/
-void gridDefYlongname(int gridID, const char *ylongname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  /* find minimum item */
+  item1 = item2;
+  for (size_t memID = 0; memID < memTableSize; memID++)
+    if ( memTable[memID].item != UNDEFID )
+      if ( memTable[memID].item < item1 ) item1 = memTable[memID].item;
 
-  if ( ylongname )
+  for ( item = item1; item <= item2; item++ )
+    for (size_t memID = 0; memID < memTableSize; memID++)
+      {
+	if ( memTable[memID].item == item )
+	  memListPrintEntry(memTable[memID].mtype, memTable[memID].item,
+			    memTable[memID].size*memTable[memID].nobj,
+			    memTable[memID].ptr, memTable[memID].caller,
+			    memTable[memID].file, memTable[memID].line);
+      }
+
+  if ( MemObjs )
     {
-      strncpy(gridptr->ylongname, ylongname, CDI_MAX_NAME);
-      gridptr->ylongname[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      fprintf(stderr, "  Memory access             : %6u\n", (unsigned) memAccess);
+      fprintf(stderr, "  Maximum objects           : %6zu\n", memTableSize);
+      fprintf(stderr, "  Objects used              : %6u\n", (unsigned) MaxMemObjs);
+      fprintf(stderr, "  Objects in use            : %6u\n", (unsigned) MemObjs);
+      fprintf(stderr, "  Memory allocated          : ");
+      if (MemUsed > 1024*1024*1024)
+	fprintf(stderr, " %5d GB\n",   (int) (MemUsed/(1024*1024*1024)));
+      else if (MemUsed > 1024*1024)
+	fprintf(stderr, " %5d MB\n",   (int) (MemUsed/(1024*1024)));
+      else if (MemUsed > 1024)
+	fprintf(stderr, " %5d KB\n",   (int) (MemUsed/(1024)));
+      else
+	fprintf(stderr, " %5d Byte\n", (int)  MemUsed);
+    }
+
+  if ( MaxMemUsed )
+    {
+      fprintf(stderr, "  Maximum memory allocated  : ");
+      if (MaxMemUsed > 1024*1024*1024)
+	fprintf(stderr, " %5d GB\n",   (int) (MaxMemUsed/(1024*1024*1024)));
+      else if (MaxMemUsed > 1024*1024)
+	fprintf(stderr, " %5d MB\n",   (int) (MaxMemUsed/(1024*1024)));
+      else if (MaxMemUsed > 1024)
+	fprintf(stderr, " %5d KB\n",   (int) (MaxMemUsed/(1024)));
+      else
+	fprintf(stderr, " %5d Byte\n", (int)  MaxMemUsed);
     }
 }
 
-/*
- at Function  gridDefYunits
- at Title     Define the units of a Y-axis
+static
+void memGetDebugLevel(void)
+{
+  char *debugLevel;
 
- at Prototype void gridDefYunits(int gridID, const char *units)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the Y-axis.
+  debugLevel = getenv("MEMORY_DEBUG");
 
- at Description
-The function @func{gridDefYunits} defines the units of a Y-axis.
+  if ( debugLevel )
+    {
+      if ( isdigit((int) debugLevel[0]) )
+	MEM_Debug = atoi(debugLevel);
 
- at EndFunction
-*/
-void gridDefYunits(int gridID, const char *yunits)
+      if ( MEM_Debug )
+	atexit(memListPrintTable);
+    }
+}
+
+static
+void memInit(void)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  static int initDebugLevel = 0;
 
-  if ( yunits )
+  if ( ! initDebugLevel )
     {
-      strncpy(gridptr->yunits, yunits, CDI_MAX_NAME);
-      gridptr->yunits[CDI_MAX_NAME - 1] = 0;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      memGetDebugLevel();
+      initDebugLevel = 1;
     }
 }
 
-/*
- at Function  gridInqXname
- at Title     Get the name of a X-axis
+static
+int memListDeleteEntry(void *ptr, size_t *size)
+{
+  int item = UNDEFID;
+  size_t memID;
 
- at Prototype void gridInqXname(int gridID, char *name)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  name     Name of the X-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  for (memID = 0; memID < memTableSize; memID++ )
+    {
+      if ( memTable[memID].item == UNDEFID ) continue;
+      if ( memTable[memID].ptr == ptr ) break;
+    }
 
- at Description
-The function @func{gridInqXname} returns the name of a X-axis.
+  if ( memID != memTableSize )
+    {
+      MemObjs--;
+      MemUsed -= memTable[memID].size * memTable[memID].nobj;
+      *size = memTable[memID].size * memTable[memID].nobj;
+       item = memTable[memID].item;
+       memTable[memID].item   = UNDEFID;
+    }
 
- at Result
- at func{gridInqXname} returns the name of the X-axis to the parameter name.
+  return (item);
+}
 
- at EndFunction
-*/
-void gridInqXname(int gridID, char *xname)
+static
+void memTableInitEntry(size_t memID)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( memID >= memTableSize )
+    memInternalProblem(__func__, "memID %d undefined!", memID);
 
-  strcpy(xname, gridptr->xname);
+  memTable[memID].ptr    = NULL;
+  memTable[memID].item   = UNDEFID;
+  memTable[memID].size   = 0;
+  memTable[memID].nobj   = 0;
+  memTable[memID].mtype  = UNDEFID;
+  memTable[memID].line   = UNDEFID;
 }
 
-/*
- at Function  gridInqXlongname
- at Title     Get the longname of a X-axis
+static
+int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
+		    const char *caller, const char *file, int line)
+{
+  static int item = 0;
+  size_t memSize = 0;
+  size_t memID = 0;
 
- at Prototype void gridInqXlongname(int gridID, char *longname)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  longname Longname of the X-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  /*
+    Look for a free slot in memTable.
+    (Create the table the first time through).
+  */
+  if ( memTableSize == 0 )
+    {
+      memTableSize = 8;
+      memSize  = memTableSize * sizeof(MemTable_t);
+      memTable = (MemTable_t *) protected_malloc(memSize);
+      if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
 
- at Description
-The function @func{gridInqXlongname} returns the longname of a X-axis.
+      for(size_t i = 0; i < memTableSize; i++)
+	memTableInitEntry(i);
+    }
+  else
+    {
+      while( memID < memTableSize )
+	{
+	  if ( memTable[memID].item == UNDEFID ) break;
+	  memID++;
+	}
+    }
+  /*
+    If the table overflows, double its size.
+  */
+  if ( memID == memTableSize )
+    {
+      memTableSize = 2*memTableSize;
+      memSize  = memTableSize*sizeof(MemTable_t);
+      memTable = (MemTable_t*) protected_realloc(memTable, memSize);
+      if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
 
- at Result
- at func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
+      for (size_t i = memID; i < memTableSize; i++)
+	memTableInitEntry(i);
+    }
 
- at EndFunction
-*/
-void gridInqXlongname(int gridID, char *xlongname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  memTable[memID].item  = item;
+  memTable[memID].ptr   = ptr;
+  memTable[memID].size  = size;
+  memTable[memID].nobj  = nobj;
+  memTable[memID].mtype = mtype;
+  memTable[memID].line  = line;
 
-  strcpy(xlongname, gridptr->xlongname);
-}
+  if ( file )
+    {
+      size_t len = strlen(file);
+      if ( len > MAXNAME-1 ) len = MAXNAME-1;
 
-/*
- at Function  gridInqXunits
- at Title     Get the units of a X-axis
+      (void) memcpy(memTable[memID].file, file, len);
+      memTable[memID].file[len] = '\0';
+    }
+  else
+    {
+      (void) strcpy(memTable[memID].file, "unknown");
+    }
 
- at Prototype void gridInqXunits(int gridID, char *units)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  units    Units of the X-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  if ( caller )
+    {
+      size_t len = strlen(caller);
+      if ( len > MAXNAME-1 ) len = MAXNAME-1;
 
- at Description
-The function @func{gridInqXunits} returns the units of a X-axis.
+      (void) memcpy(memTable[memID].caller, caller, len);
+      memTable[memID].caller[len] = '\0';
+    }
+  else
+    {
+      (void) strcpy(memTable[memID].caller, "unknown");
+    }
 
- at Result
- at func{gridInqXunits} returns the units of the X-axis to the parameter units.
+  MaxMemObjs++;
+  MemObjs++;
+  MemUsed += size*nobj;
+  if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
 
- at EndFunction
-*/
-void gridInqXunits(int gridID, char *xunits)
+  return (item++);
+}
+
+static
+int memListChangeEntry(void *ptrold, void *ptr, size_t size,
+		       const char *caller, const char *file, int line)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  int item = UNDEFID;
+  size_t memID = 0;
+  size_t sizeold;
 
-  strcpy(xunits, gridptr->xunits);
-}
+  while( memID < memTableSize )
+    {
+      if ( memTable[memID].item != UNDEFID )
+	if ( memTable[memID].ptr == ptrold ) break;
+      memID++;
+    }
+
+  if ( memID == memTableSize )
+    {
+      if ( ptrold != NULL )
+	memInternalProblem(__func__, "Item at %p not found.", ptrold);
+    }
+  else
+    {
+      item = memTable[memID].item;
 
+      sizeold = memTable[memID].size*memTable[memID].nobj;
 
-void gridInqXstdname(int gridID, char *xstdname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      memTable[memID].ptr   = ptr;
+      memTable[memID].size  = size;
+      memTable[memID].nobj  = 1;
+      memTable[memID].mtype = REALLOC_FUNC;
+      memTable[memID].line  = line;
 
-  strcpy(xstdname, gridptr->xstdname);
-}
+      if ( file )
+	{
+	  size_t len = strlen(file);
+	  if ( len > MAXNAME-1 ) len = MAXNAME-1;
 
-/*
- at Function  gridInqYname
- at Title     Get the name of a Y-axis
+	  (void) memcpy(memTable[memID].file, file, len);
+	  memTable[memID].file[len] = '\0';
+	}
+      else
+	{
+	  (void) strcpy(memTable[memID].file, "unknown");
+	}
 
- at Prototype void gridInqYname(int gridID, char *name)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  name     Name of the Y-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+      if ( caller )
+	{
+	  size_t len = strlen(caller);
+	  if ( len > MAXNAME-1 ) len = MAXNAME-1;
 
- at Description
-The function @func{gridInqYname} returns the name of a Y-axis.
+	  (void) memcpy(memTable[memID].caller, caller, len);
+	  memTable[memID].caller[len] = '\0';
+	}
+      else
+	{
+	  (void) strcpy(memTable[memID].caller, "unknown");
+	}
 
- at Result
- at func{gridInqYname} returns the name of the Y-axis to the parameter name.
+      MemUsed -= sizeold;
+      MemUsed += size;
+      if ( MemUsed > MaxMemUsed ) MaxMemUsed = MemUsed;
+    }
 
- at EndFunction
-*/
-void gridInqYname(int gridID, char *yname)
+  return (item);
+}
+
+
+void *Calloc(const char *caller, const char *file, int line, size_t nobjs, size_t size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  void *ptr = NULL;
+  int item = UNDEFID;
 
-  strcpy(yname, gridptr->yname);
-}
+  memInit();
 
-/*
- at Function  gridInqYlongname
- at Title     Get the longname of a Y-axis
+  if ( nobjs*size > 0 )
+    {
+      ptr = protected_calloc(nobjs, size);
 
- at Prototype void gridInqXlongname(int gridID, char *longname)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  longname Longname of the Y-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+      if ( MEM_Debug )
+	{
+	  memAccess++;
 
- at Description
-The function @func{gridInqYlongname} returns the longname of a Y-axis.
+	  if ( ptr ) item = memListNewEntry(CALLOC_FUNC, ptr, size, nobjs, caller, file, line);
 
- at Result
- at func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
+	  memListPrintEntry(CALLOC_FUNC, item, size*nobjs, ptr, caller, file, line);
+	}
 
- at EndFunction
-*/
-void gridInqYlongname(int gridID, char *ylongname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( ptr == NULL && dmemory_ExitOnError )
+	memError(caller, file, line, size*nobjs);
+    }
+  else
+    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
 
-  strcpy(ylongname, gridptr->ylongname);
+  return(ptr);
 }
 
-/*
- at Function  gridInqYunits
- at Title     Get the units of a Y-axis
 
- at Prototype void gridInqYunits(int gridID, char *units)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  units    Units of the Y-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+void *Malloc(const char *caller, const char *file, int line, size_t size)
+{
+  void *ptr = NULL;
+  int item = UNDEFID;
 
- at Description
-The function @func{gridInqYunits} returns the units of a Y-axis.
+  memInit();
 
- at Result
- at func{gridInqYunits} returns the units of the Y-axis to the parameter units.
+  if ( size > 0 )
+    {
+      ptr = protected_malloc(size);
 
- at EndFunction
-*/
-void gridInqYunits(int gridID, char *yunits)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( MEM_Debug )
+	{
+	  memAccess++;
 
-  strcpy(yunits, gridptr->yunits);
-}
+	  if ( ptr ) item = memListNewEntry(MALLOC_FUNC, ptr, size, 1, caller, file, line);
 
-void gridInqYstdname(int gridID, char *ystdname)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+	  memListPrintEntry(MALLOC_FUNC, item, size, ptr, caller, file, line);
+	}
 
-  strcpy(ystdname, gridptr->ystdname);
+      if ( ptr == NULL && dmemory_ExitOnError )
+	memError(caller, file, line, size);
+    }
+  else
+    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
+
+  return (ptr);
 }
 
-/*
- at Function  gridInqType
- at Title     Get the type of a Grid
 
- at Prototype int gridInqType(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+void *Realloc(const char *caller, const char *file, int line, void *ptrold, size_t size)
+{
+  void *ptr = NULL;
+  int item = UNDEFID;
 
- at Description
-The function @func{gridInqType} returns the type of a Grid.
+  memInit();
 
- at Result
- at func{gridInqType} returns the type of the grid,
-one of the set of predefined CDI grid types.
-The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
- at func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
- at func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
+  if ( size > 0 )
+    {
+      ptr = protected_realloc(ptrold, size);
 
- at EndFunction
-*/
-int gridInqType(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( MEM_Debug )
+	{
+	  memAccess++;
 
-  return (gridptr->type);
-}
+	  if ( ptr )
+	    {
+	      item = memListChangeEntry(ptrold, ptr, size, caller, file, line);
 
+	      if ( item == UNDEFID ) item = memListNewEntry(REALLOC_FUNC, ptr, size, 1, caller, file, line);
+	    }
 
-/*
- at Function  gridInqSize
- at Title     Get the size of a Grid
+	  memListPrintEntry(REALLOC_FUNC, item, size, ptr, caller, file, line);
+	}
 
- at Prototype int gridInqSize(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+      if ( ptr == NULL && dmemory_ExitOnError )
+	memError(caller, file, line, size);
+    }
+  else
+    fprintf(stderr, "Warning (%s) : Allocation of 0 bytes! [ line %d file %s ]\n", caller, line, file);
 
- at Description
-The function @func{gridInqSize} returns the size of a Grid.
+  return (ptr);
+}
 
- at Result
- at func{gridInqSize} returns the number of grid points of a Grid.
 
- at EndFunction
-*/
-int gridInqSize(int gridID)
+void Free(const char *caller, const char *file, int line, void *ptr)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  int item;
+  size_t size;
 
-  int size = gridptr->size;
+  memInit();
 
-  if ( ! size )
+  if ( MEM_Debug )
     {
-      int xsize, ysize;
-
-      xsize = gridptr->xsize;
-      ysize = gridptr->ysize;
-
-      if ( ysize )
-        size = xsize *ysize;
+      if ( (item = memListDeleteEntry(ptr, &size)) >= 0 )
+	{
+	  memListPrintEntry(FREE_FUNC, item, size, ptr, caller, file, line);
+	}
       else
-        size = xsize;
-
-      gridptr->size = size;
+	{
+	  if ( ptr )
+	    fprintf(stderr, "%s info: memory entry at %p not found. [line %4d file %s (%s)]\n",
+		    __func__, ptr, line, file, caller);
+	}
     }
 
-  return (size);
+  protected_free(ptr);
 }
 
-static
-int nsp2trunc(int nsp)
+void *cdiXmalloc(size_t size, const char *filename, const char *functionname,
+                 int line)
 {
-  /*  nsp = (trunc+1)*(trunc+1)              */
-  /*      => trunc^2 + 3*trunc - (x-2) = 0   */
-  /*                                         */
-  /*  with:  y^2 + p*y + q = 0               */
-  /*         y = -p/2 +- sqrt((p/2)^2 - q)   */
-  /*         p = 3 and q = - (x-2)           */
-  int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
-  return (trunc);
+  void *value = protected_malloc(size);
+  if (size == 0 || value != NULL) ; else
+    cdiAbort(filename, functionname, line, "malloc failed: %s", strerror(errno));
+  return value;
 }
 
+void *cdiXcalloc(size_t nmemb, size_t size, const char *filename,
+                 const char *functionname, int line)
+{
+  void *value = protected_calloc(nmemb, size);
+  if (size == 0 || value != NULL) ; else
+    cdiAbort(filename, functionname, line, "calloc failed: %s", strerror(errno) );
+  return value;
+}
 
-int gridInqTrunc(int gridID)
+void *cdiXrealloc(void *p, size_t size, const char *functionname,
+                  const char *filename, int line)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  void *value = protected_realloc(p, size);
+  if (size == 0 || value != NULL) ; else
+    cdiAbort(filename, functionname, line, "realloc failed: %s", strerror(errno));
+  return value;
+}
 
-  if ( gridptr->trunc == 0 )
+size_t memTotal(void)
+{
+  size_t memtotal = 0;
+#if  defined  (HAVE_MALLINFO)
+  struct mallinfo meminfo = mallinfo();
+  if ( MEM_Debug )
     {
-      if ( gridptr->type == GRID_SPECTRAL )
-        gridptr->trunc = nsp2trunc(gridptr->size);
-      /*
-      else if      ( gridptr->type == GRID_GAUSSIAN )
-        gridptr->trunc = nlat2trunc(gridptr->ysize);
-      */
+      fprintf(stderr, "arena      %8zu (non-mmapped space allocated from system)\n", (size_t)meminfo.arena);
+      fprintf(stderr, "ordblks    %8zu (number of free chunks)\n", (size_t)meminfo.ordblks);
+      fprintf(stderr, "smblks     %8zu (number of fastbin blocks)\n", (size_t) meminfo.smblks);
+      fprintf(stderr, "hblks      %8zu (number of mmapped regions)\n", (size_t) meminfo.hblks);
+      fprintf(stderr, "hblkhd     %8zu (space in mmapped regions)\n", (size_t) meminfo.hblkhd);
+      fprintf(stderr, "usmblks    %8zu (maximum total allocated space)\n", (size_t) meminfo.usmblks);
+      fprintf(stderr, "fsmblks    %8zu (maximum total allocated space)\n", (size_t) meminfo.fsmblks);
+      fprintf(stderr, "uordblks   %8zu (total allocated space)\n", (size_t) meminfo.uordblks);
+      fprintf(stderr, "fordblks   %8zu (total free space)\n", (size_t) meminfo.fordblks);
+      fprintf(stderr, "Memory in use:   %8zu bytes\n", (size_t) meminfo.usmblks + (size_t)meminfo.uordblks);
+      fprintf(stderr, "Total heap size: %8zu bytes\n", (size_t) meminfo.arena);
+
+      /* malloc_stats(); */
     }
+  memtotal = (size_t)meminfo.arena;
+#endif
 
-  return (gridptr->trunc);
+  return (memtotal);
 }
 
 
-void gridDefTrunc(int gridID, int trunc)
+void memExitOnError(void)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  if (gridptr->trunc != trunc)
-    {
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-      gridptr->trunc = trunc;
-    }
+  dmemory_ExitOnError = 1;
 }
-
 /*
- at Function  gridDefXsize
- at Title     Define the number of values of a X-axis
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
- at Prototype void gridDefXsize(int gridID, int xsize)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  xsize    Number of values of a X-axis.
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
 
- at Description
-The function @func{gridDefXsize} defines the number of values of a X-axis.
+#if !defined (NAMESPACE_H)
+#endif
 
- at EndFunction
-*/
-void gridDefXsize(int gridID, int xsize)
+int _ExitOnError   = 1;	/* If set to 1, exit on error       */
+int _Verbose = 1;	/* If set to 1, errors are reported */
+int _Debug   = 0;       /* If set to 1, debugging           */
+
+
+void SysError_(const char *caller, const char *fmt, ...)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  va_list args;
 
-  if ( xsize > gridInqSize(gridID) )
-    Error("xsize %d is greater then gridsize %d", xsize, gridInqSize(gridID));
+  va_start(args, fmt);
 
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridInqSize(gridID) )
-    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridInqSize(gridID));
+  printf("\n");
+   fprintf(stderr, "Error (%s) : ", caller);
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
 
-  if (gridptr->xsize != xsize)
-    {
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-      gridptr->xsize = xsize;
-    }
+  va_end(args);
 
-  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
-    {
-      long gridsize = gridptr->xsize*gridptr->ysize;
-      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
-        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
-    }
-}
+  if ( errno )
+    perror("System error message ");
 
-/*
- at Function
- at Title
+  exit(EXIT_FAILURE);
+}
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-void gridDefPrec(int gridID, int prec)
+void Error_(const char *caller, const char *fmt, ...)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  va_list args;
 
-  if (gridptr->prec != prec)
-    {
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-      gridptr->prec = prec;
-    }
-}
+  va_start(args, fmt);
 
-/*
- at Function
- at Title
+  printf("\n");
+   fprintf(stderr, "Error (%s) : ", caller);
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  va_end(args);
 
- at EndFunction
-*/
-int gridInqPrec(int gridID)
+  if ( _ExitOnError ) exit(EXIT_FAILURE);
+}
+
+typedef void (*cdiAbortCFunc)(const char * caller, const char * filename,
+                              const char *functionname, int line,
+                              const char * errorString, va_list ap)
+#ifdef __GNUC__
+  __attribute__((noreturn))
+#endif
+;
+
+void cdiAbortC(const char * caller, const char * filename,
+               const char *functionname, int line,
+               const char * errorString, ... )
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  va_list ap;
+  va_start(ap, errorString);
+  cdiAbortCFunc cdiAbortC_p
+    = (cdiAbortCFunc)namespaceSwitchGet(NSSWITCH_ABORT).func;
+  cdiAbortC_p(caller, filename, functionname, line, errorString, ap);
+  va_end(ap);
+}
 
-  return (gridptr->prec);
+void
+cdiAbortC_serial(const char *caller, const char *filename,
+                 const char *functionname, int line,
+                 const char *errorString, va_list ap)
+{
+  fprintf(stderr, "ERROR, %s, %s, line %d%s%s\nerrorString: \"",
+          functionname, filename, line, caller?", called from ":"",
+          caller?caller:"");
+  vfprintf(stderr, errorString, ap);
+  fputs("\"\n", stderr);
+  exit(EXIT_FAILURE);
 }
 
-/*
- at Function  gridInqXsize
- at Title     Get the number of values of a X-axis
+typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
+                               va_list ap);
 
- at Prototype int gridInqXsize(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+void Warning_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
 
- at Description
-The function @func{gridInqXsize} returns the number of values of a X-axis.
+  va_start(args, fmt);
 
- at Result
- at func{gridInqXsize} returns the number of values of a X-axis.
+  if ( _Verbose )
+    {
+      cdiWarningFunc cdiWarning_p
+        = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
+      cdiWarning_p(caller, fmt, args);
+    }
 
- at EndFunction
-*/
-int gridInqXsize(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  va_end(args);
+}
 
-  return (gridptr->xsize);
+void cdiWarning(const char *caller, const char *fmt, va_list ap)
+{
+  fprintf(stderr, "Warning (%s) : ", caller);
+  vfprintf(stderr, fmt, ap);
+  fputc('\n', stderr);
 }
 
-/*
- at Function  gridDefYsize
- at Title     Define the number of values of a Y-axis
 
- at Prototype void gridDefYsize(int gridID, int ysize)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  ysize    Number of values of a Y-axis.
+void Message_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
 
- at Description
-The function @func{gridDefYsize} defines the number of values of a Y-axis.
+  va_start(args, fmt);
 
- at EndFunction
-*/
-void gridDefYsize(int gridID, int ysize)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+   fprintf(stdout, "%-18s : ", caller);
+  vfprintf(stdout, fmt, args);
+   fprintf(stdout, "\n");
 
-  if ( ysize > gridInqSize(gridID) )
-    Error("ysize %d is greater then gridsize %d", ysize, gridInqSize(gridID));
+  va_end(args);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef STREAM_FCOMMON_H
+#define STREAM_FCOMMON_H
 
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridInqSize(gridID) )
-    Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridInqSize(gridID));
+#ifndef  _CDI_INT_H
+#endif
 
-  if (gridptr->ysize != ysize)
-    {
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-      gridptr->ysize = ysize;
-    }
+enum {
+  SINGLE_PRECISION = 4,
+  DOUBLE_PRECISION = 8,
+};
 
-  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
-    {
-      long gridsize = gridptr->xsize*gridptr->ysize;
-      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
-        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
-    }
-}
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
+                       const char *container_name);
 
+#endif
 /*
- at Function  gridInqYsize
- at Title     Get the number of values of a Y-axis
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
- at Prototype int gridInqYsize(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
 
- at Description
-The function @func{gridInqYsize} returns the number of values of a Y-axis.
 
- at Result
- at func{gridInqYsize} returns the number of values of a Y-axis.
 
- at EndFunction
-*/
-int gridInqYsize(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
 
-  return (gridptr->ysize);
-}
+enum {
+  EXT_HEADER_LEN = 4,
+};
+
+
+static int initExtLib       = 0;
+static int extDefaultPrec   = 0;
+static int extDefaultNumber = EXT_REAL;
+
 
 /*
- at Function  gridDefNP
- at Title     Define the number of parallels between a pole and the equator
+ * A version string.
+ */
 
- at Prototype void gridDefNP(int gridID, int np)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  np       Number of parallels between a pole and the equator.
+#undef  LIBVERSION
+#define LIBVERSION      1.3.2
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
+static const char ext_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
 
- at Description
-The function @func{gridDefNP} defines the number of parallels between a pole and the equator
-of a Gaussian grid.
+const char *extLibraryVersion(void)
+{
+  return (ext_libvers);
+}
 
- at EndFunction
-*/
-void gridDefNP(int gridID, int np)
+
+static int EXT_Debug = 0;    /* If set to 1, debugging */
+
+
+void extDebug(int debug)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  EXT_Debug = debug;
 
-  if (gridptr->np != np)
-    {
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-      gridptr->np = np;
-    }
+  if ( EXT_Debug )
+    Message("debug level %d", debug);
 }
 
-/*
- at Function  gridInqNP
- at Title     Get the number of parallels between a pole and the equator
 
- at Prototype int gridInqNP(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+static void extLibInit()
+{
+  char *envString;
+  char *envName = "EXT_PRECISION";
 
- at Description
-The function @func{gridInqNP} returns the number of parallels between a pole and the equator
-of a Gaussian grid.
 
- at Result
- at func{gridInqNP} returns the number of parallels between a pole and the equator.
+  envString = getenv(envName);
+  if ( envString )
+    {
+      int pos = 0;
 
- at EndFunction
-*/
-int gridInqNP(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( strlen(envString) == 2  )
+	{
+	  switch ( tolower((int) envString[pos]) )
+	    {
+	    case 'r':
+	      {
+		extDefaultNumber = EXT_REAL;
+		switch ( (int) envString[pos+1] )
+		  {
+		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
+		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
+		  default:
+		    Message("Invalid digit in %s: %s", envName, envString);
+		  }
+		break;
+	      }
+	    case 'c':
+	      {
+		extDefaultNumber = EXT_COMP;
+		switch ( (int) envString[pos+1] )
+		  {
+		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
+		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
+		  default:
+		    Message("Invalid digit in %s: %s", envName, envString);
+		  }
+		break;
+	      }
+	    default:
+              {
+                Message("Invalid character in %s: %s", envName, envString);
+                break;
+              }
+            }
+	}
+    }
 
-  return (gridptr->np);
+  initExtLib = 1;
 }
 
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
-    @Item  Grid identifier
-
- at EndFunction
-*/
-void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
+static
+void extInit(extrec_t *extp)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  gridptr->rowlon = (int *)xmalloc((size_t)nrowlon * sizeof(int));
-  gridptr->nrowlon = nrowlon;
-  memcpy(gridptr->rowlon, rowlon, (size_t)nrowlon * sizeof(int));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+  extp->checked    = 0;
+  extp->byteswap   = 0;
+  extp->prec       = 0;
+  extp->number     = extDefaultNumber;
+  extp->datasize   = 0;
+  extp->buffersize = 0;
+  extp->buffer     = NULL;
 }
 
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-void gridInqRowlon(int gridID, int *rowlon)
+void *extNew(void)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  if ( gridptr->rowlon == 0 )  Error("undefined pointer!");
-
-  memcpy(rowlon, gridptr->rowlon, (size_t)gridptr->nrowlon * sizeof(int));
-}
+  extrec_t *extp;
 
+  if ( ! initExtLib ) extLibInit();
 
-int gridInqMask(int gridID, int *mask)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  extp = (extrec_t *) malloc(sizeof(extrec_t));
 
-  long size = gridptr->size;
+  extInit(extp);
 
-  if ( CDI_Debug && size == 0 )
-    Warning("Size undefined for gridID = %d", gridID);
+  return ((void*)extp);
+}
 
-  if (mask && gridptr->mask)
-    for (long i = 0; i < size; ++i)
-      mask[i] = (int)gridptr->mask[i];
 
-  if ( gridptr->mask == NULL ) size = 0;
+void extDelete(void *ext)
+{
+  extrec_t *extp = (extrec_t *) ext;
 
-  return (int)size;
+  if ( extp )
+    {
+      if ( extp->buffer ) free(extp->buffer);
+      free(extp);
+    }
 }
 
 
-void gridDefMask(int gridID, const int *mask)
+int extCheckFiletype(int fileID, int *swap)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t blocklen = 0, fact = 0;
+  size_t sblocklen = 0;
+  size_t data =  0;
+  size_t dimxy = 0;
+  int found = 0;
+  unsigned char buffer[40], *pbuf;
 
-  long size = gridptr->size;
+  if ( fileRead(fileID, buffer, 4) != 4 ) return (found);
 
-  if ( size == 0 )
-    Error("Size undefined for gridID = %d", gridID);
+  blocklen  = (size_t) get_UINT32(buffer);
+  sblocklen = (size_t) get_SUINT32(buffer);
 
-  if ( mask == NULL )
+  if ( EXT_Debug )
+    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
+
+  if ( blocklen == 16 )
     {
-      if ( gridptr->mask )
-	{
-	  free(gridptr->mask);
-	  gridptr->mask = NULL;
-	}
+     *swap = 0;
+      fact = blocklen/4;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
+      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
     }
-  else
+  else if ( blocklen == 32 )
     {
-      if ( gridptr->mask == NULL )
-	gridptr->mask = (mask_t *)xmalloc((size_t)size*sizeof(mask_t));
-      else if ( CDI_Debug )
-	Warning("grid mask already defined!");
+     *swap = 0;
+      fact = blocklen/4;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
+      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT64(pbuf);
+      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
+    }
+  else if ( sblocklen == 16 )
+    {
+     *swap = 1;
+      fact = sblocklen/4;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
+      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
+    }
+  else if ( sblocklen == 32 )
+    {
+     *swap = 1;
+      fact = sblocklen/4;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
+      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT64(pbuf);
+      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
+    }
 
-      for (long i = 0; i < size; ++i )
-	gridptr->mask[i] = (mask_t)(mask[i] != 0);
+  fileRewind(fileID);
+
+  if      ( data && dimxy*fact   == data ) found = 1;
+  else if ( data && dimxy*fact*2 == data ) found = 1;
+
+  if ( EXT_Debug )
+    {
+      Message("swap = %d fact = %d", *swap, fact);
+      Message("dimxy = %lu data = %lu", dimxy, data);
     }
+
+  return (found);
 }
 
 
-int gridInqMaskGME(int gridID, int *mask)
+int extInqHeader(void *ext, int *header)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  long size = gridptr->size;
-
-  if ( CDI_Debug && size == 0 )
-    Warning("Size undefined for gridID = %d", gridID);
+  extrec_t *extp = (extrec_t *) ext;
+  size_t i;
 
-  if ( mask && gridptr->mask_gme )
-    for (long i = 0; i < size; ++i)
-      mask[i] = (int)gridptr->mask_gme[i];
+  for ( i = 0; i < EXT_HEADER_LEN; i++ )
+    header[i] = extp->header[i];
 
-  if ( gridptr->mask_gme == NULL ) size = 0;
+  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
 
-  return (int)size;
+  return (0);
 }
 
 
-void gridDefMaskGME(int gridID, const int *mask)
+int extDefHeader(void *ext, const int *header)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  extrec_t *extp = (extrec_t *) ext;
+  size_t i;
 
-  long size = gridptr->size;
+  for ( i = 0; i < EXT_HEADER_LEN; i++ )
+    extp->header[i] = header[i];
 
-  if ( size == 0 )
-    Error("Size undefined for gridID = %d", gridID);
+  extp->datasize = (size_t)header[3];
+  if ( extp->number == EXT_COMP ) extp->datasize *= 2;
 
-  if ( gridptr->mask_gme == NULL )
-    gridptr->mask_gme = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
-  else if ( CDI_Debug )
-    Warning("mask already defined!");
+  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
 
-  for (long i = 0; i < size; ++i)
-    gridptr->mask_gme[i] = (mask_t)(mask[i] != 0);
+  return (0);
 }
 
-/*
- at Function  gridInqXvals
- at Title     Get all values of a X-axis
-
- at Prototype int gridInqXvals(int gridID, double *xvals)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  xvals    Pointer to the location into which the X-values are read.
-                    The caller must allocate space for the returned values.
-
- at Description
-The function @func{gridInqXvals} returns all values of the X-axis.
-
- at Result
-Upon successful completion @func{gridInqXvals} returns the number of values and
-the values are stored in @func{xvals}.
-Otherwise, 0 is returned and @func{xvals} is empty.
 
- at EndFunction
-*/
-int gridInqXvals(int gridID, double *xvals)
+static int extInqData(extrec_t *extp, int prec, void *data)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t datasize;
+  size_t i;
+  int ierr = 0;
+  int rprec;
+  void *buffer;
+  int byteswap = extp->byteswap;
 
-  long size;
-  if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
-    size = gridptr->size;
-  else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
-    size = 2;
-  else
-    size = gridptr->xsize;
+  datasize = extp->datasize;
+  buffer   = extp->buffer;
+  rprec    = extp->prec;
 
-  if ( CDI_Debug && size == 0 )
-    Warning("size undefined for gridID = %d", gridID);
+  switch ( rprec )
+    {
+    case SINGLE_PRECISION:
+      {
+	if ( sizeof(FLT32) == 4 )
+	  {
+	    if ( byteswap ) swap4byte(buffer, datasize);
 
-  if ( size && xvals && gridptr->xvals )
-    memcpy(xvals, gridptr->xvals, (size_t)size * sizeof (double));
+	    if ( rprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT32));
+	    else
+	      for ( i = 0; i < datasize; ++i )
+		((double *) data)[i] = (double) ((float *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT32));
+	  }
+	break;
+      }
+    case DOUBLE_PRECISION:
+	if ( sizeof(FLT64) == 8 )
+	  {
+	    if ( byteswap ) swap8byte(buffer, datasize);
 
-  if ( gridptr->xvals == NULL ) size = 0;
+	    if ( rprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT64));
+	    else
+	      for ( i = 0; i < datasize; ++i )
+		((float *) data)[i] = (float) ((double *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT64));
+	  }
+	break;
+    default:
+      {
+	Error("unexpected data precision %d", rprec);
+	break;
+      }
+    }
 
-  return (int)size;
+  return (ierr);
 }
 
-/*
- at Function  gridDefXvals
- at Title     Define the values of a X-axis
 
- at Prototype void gridDefXvals(int gridID, const double *xvals)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  xvals    X-values of the grid.
+int extInqDataSP(void *ext, float *data)
+{
+  return (extInqData(ext, SINGLE_PRECISION, (void *) data));
+}
 
- at Description
-The function @func{gridDefXvals} defines all values of the X-axis.
 
- at EndFunction
-*/
-void gridDefXvals(int gridID, const double *xvals)
+int extInqDataDP(void *ext, double *data)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  int gridtype;
-  long size;
+  return (extInqData(ext, DOUBLE_PRECISION, (void *) data));
+}
 
-  gridtype = gridptr->type;
 
-  if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
-    size = gridptr->size;
-  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    size = 2;
-  else
-    size = gridptr->xsize;
+int extDefData(void *ext, int prec, const void *data)
+{
+  extrec_t *extp = (extrec_t *) ext;
+  size_t datasize;
+  size_t blocklen;
+  size_t buffersize;
+  size_t i;
+  int rprec;
+  int *header;
+  void *buffer;
 
-  if ( size == 0 )
-    Error("Size undefined for gridID = %d", gridID);
+  if ( extDefaultPrec ) rprec = extDefaultPrec;
+  else                  rprec = extp->prec;
 
-  if (gridptr->xvals && CDI_Debug)
-    Warning("values already defined!");
-  gridptr->xvals = (double *)xrealloc(gridptr->xvals,
-                                      (size_t)size * sizeof(double));
-  memcpy(gridptr->xvals, xvals, (size_t)size * sizeof (double));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-}
+  if ( ! rprec ) rprec = prec;
 
-/*
- at Function  gridInqYvals
- at Title     Get all values of a Y-axis
+  extp->prec = rprec;
 
- at Prototype int gridInqYvals(int gridID, double *yvals)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  yvals    Pointer to the location into which the Y-values are read.
-                    The caller must allocate space for the returned values.
+  header = extp->header;
 
- at Description
-The function @func{gridInqYvals} returns all values of the Y-axis.
+  datasize = (size_t)header[3];
+  if ( extp->number == EXT_COMP ) datasize *= 2;
+  blocklen = datasize * (size_t)rprec;
 
- at Result
-Upon successful completion @func{gridInqYvals} returns the number of values and
-the values are stored in @func{yvals}.
-Otherwise, 0 is returned and @func{yvals} is empty.
+  extp->datasize = datasize;
 
- at EndFunction
-*/
-int gridInqYvals(int gridID, double *yvals)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  buffersize = extp->buffersize;
 
-  int gridtype = gridptr->type;
-  long size
-    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
-    ? gridptr->size : gridptr->ysize;
+  if ( buffersize != blocklen )
+    {
+      buffersize = blocklen;
+      buffer = extp->buffer;
+      buffer = realloc(buffer, buffersize);
+      extp->buffer = buffer;
+      extp->buffersize = buffersize;
+    }
+  else
+    buffer = extp->buffer;
 
-  if ( CDI_Debug && size == 0 )
-    Warning("size undefined for gridID = %d!", gridID);
+  switch ( rprec )
+    {
+    case SINGLE_PRECISION:
+      {
+	if ( rprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT32));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((float *) buffer)[i] = (float) ((double *) data)[i];
 
-  if ( size && yvals && gridptr->yvals )
-    memcpy(yvals, gridptr->yvals, (size_t)size * sizeof (double));
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	if ( rprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT64));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((double *) buffer)[i] = (double) ((float *) data)[i];
 
-  if ( gridptr->yvals == NULL ) size = 0;
+	break;
+      }
+    default:
+      {
+	Error("unexpected data precision %d", rprec);
+        break;
+      }
+    }
 
-  return (int)size;
+  return (0);
 }
 
-/*
- at Function  gridDefYvals
- at Title     Define the values of a Y-axis
-
- at Prototype void gridDefYvals(int gridID, const double *yvals)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  yvals    Y-values of the grid.
-
- at Description
-The function @func{gridDefYvals} defines all values of the Y-axis.
 
- at EndFunction
-*/
-void gridDefYvals(int gridID, const double *yvals)
+int extDefDataSP(void *ext, const float *data)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  int gridtype = gridptr->type;
-  long size
-    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
-    ? gridptr->size : gridptr->ysize;
-
-  if ( size == 0 )
-    Error("Size undefined for gridID = %d!", gridID);
+  return (extDefData(ext, SINGLE_PRECISION, (void *) data));
+}
 
-  if (gridptr->yvals && CDI_Debug)
-    Warning("Values already defined!");
 
-  gridptr->yvals = (double *)xrealloc(gridptr->yvals, (size_t)size * sizeof (double));
-  memcpy(gridptr->yvals, yvals, (size_t)size * sizeof (double));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+int extDefDataDP(void *ext, const double *data)
+{
+  return (extDefData(ext, DOUBLE_PRECISION, (void *) data));
 }
 
 
-double gridInqXval(int gridID, int index)
+int extRead(int fileID, void *ext)
 {
-  double xval = 0;
-  grid_t *gridptr = gridID2Ptr(gridID);
+  extrec_t *extp = (extrec_t *) ext;
+  size_t blocklen, blocklen2;
+  size_t i;
+  void *buffer;
+  int byteswap;
+  int status;
 
-  if ( gridptr->xvals )
-    xval = gridptr->xvals[index];
+  if ( ! extp->checked )
+    {
+      status = extCheckFiletype(fileID, &extp->byteswap);
+      if ( status == 0 ) Error("Not a EXTRA file!");
+      extp->checked = 1;
+    }
 
-  return (xval);
-}
+  byteswap = extp->byteswap;
 
-/*
- at Function
- at Title
+  /* read header record */
+  blocklen = binReadF77Block(fileID, byteswap);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  if ( fileEOF(fileID) ) return (-1);
 
- at EndFunction
-*/
-double gridInqYval(int gridID, int index)
-{
-  double yval = 0;
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( EXT_Debug )
+    Message("blocklen = %lu", blocklen);
 
-  if ( gridptr->yvals )
-    yval = gridptr->yvals[index];
+  size_t hprec = blocklen / EXT_HEADER_LEN;
 
-  return (yval);
-}
+  extp->prec = (int)hprec;
 
-/*
- at Function
- at Title
+  switch ( hprec )
+    {
+    case SINGLE_PRECISION:
+      {
+        INT32 tempheader[4];
+	binReadInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+	for ( i = 0; i < EXT_HEADER_LEN; i++ )
+          extp->header[i] = (int)tempheader[i];
 
- at EndFunction
-*/
-double gridInqXinc(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+        INT64 tempheader[4];
+	binReadInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader);
 
-  double xinc = gridptr->xinc;
+	for ( i = 0; i < EXT_HEADER_LEN; i++ )
+          extp->header[i] = (int)tempheader[i];
+
+	break;
+      }
+    default:
+      {
+	Error("Unexpected header precision %d", hprec);
+        break;
+      }
+    }
+
+  blocklen2 = binReadF77Block(fileID, byteswap);
 
-  if ( (! (fabs(xinc) > 0)) && gridptr->xvals )
+  if ( blocklen2 != blocklen )
     {
-      int xsize = gridptr->xsize;
-      if ( xsize > 1 )
-        {
-          double *xvals = gridptr->xvals;
-          xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
-          int i;
-          for (i = 2; i < xsize; i++ )
-            if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc ) break;
-
-          if ( i < xsize ) xinc = 0;
-        }
+      Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+      if ( blocklen2 != 0 ) return (-1);
     }
 
-  return (xinc);
-}
+  extp->datasize = (size_t)extp->header[3];
 
-/*
- at Function
- at Title
+  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  blocklen = binReadF77Block(fileID, byteswap);
 
- at EndFunction
-*/
-double gridInqYinc(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t buffersize = (size_t)extp->buffersize;
 
-  double yinc = gridptr->yinc;
+  if ( buffersize < blocklen )
+    {
+      buffersize = blocklen;
+      buffer = extp->buffer;
+      buffer = realloc(buffer, buffersize);
+      extp->buffer = buffer;
+      extp->buffersize = buffersize;
+    }
+  else
+    buffer = extp->buffer;
 
-  if ( (! (fabs(yinc) > 0)) && gridptr->yvals )
+  size_t dprec = blocklen / extp->datasize;
+
+  if ( dprec == hprec )
     {
-      int ysize;
-      double *yvals;
+      extp->number = EXT_REAL;
+    }
+  else if ( dprec == 2*hprec )
+    {
+      dprec /= 2;
+      extp->datasize *= 2;
+      extp->number = EXT_COMP;
+    }
 
-      ysize = gridptr->ysize;
-      yvals = gridptr->yvals;
+  if ( dprec != SINGLE_PRECISION && dprec != DOUBLE_PRECISION )
+    {
+      Warning("Unexpected data precision %d", dprec);
+      return (-1);
+    }
 
-      if ( ysize > 1 )
-        {
-          yinc = fabs(yvals[1] - yvals[0]);
-          int i;
-          for ( i = 2; i < ysize; i++ )
-            if ( fabs(fabs(yvals[i] - yvals[i-1]) - yinc) > (yinc/1000) ) break;
+  fileRead(fileID, buffer, blocklen);
 
-          if ( i < ysize ) yinc = 0;
-          else             yinc = yvals[1] - yvals[0];
-        }
+  blocklen2 = binReadF77Block(fileID, byteswap);
+
+  if ( blocklen2 != blocklen )
+    {
+      Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+      if ( blocklen2 != 0 ) return (-1);
     }
 
-  return (yinc);
+  return (0);
 }
 
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-double gridInqXpole(int gridID)
+int extWrite(int fileID, void *ext)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  return (gridptr->xpole);
-}
+  extrec_t *extp = (extrec_t *) ext;
+  size_t datasize;
+  size_t blocklen;
+  size_t i;
+  int rprec, number;
+  char tempheader[32];
+  int *header;
+  void *buffer;
+  int byteswap = extp->byteswap;
 
-/*
- at Function
- at Title
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  rprec  = extp->prec;
+  number = extp->number;
+  header = extp->header;
 
- at EndFunction
-*/
-void gridDefXpole(int gridID, double xpole)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  /* write header record */
+  blocklen = EXT_HEADER_LEN * (size_t)rprec;
 
-  if ( memcmp(gridptr->xstdname, "grid", 4) != 0 )
-    strcpy(gridptr->xstdname, "grid_longitude");
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->xpole, xpole) )
+  switch ( rprec )
     {
-      gridptr->isRotated = TRUE;
-      gridptr->xpole = xpole;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
-}
+    case SINGLE_PRECISION:
+      {
+	for (i = 0; i < EXT_HEADER_LEN; i++)
+          ((INT32 *) tempheader)[i] = (INT32) header[i];
 
-/*
- at Function
- at Title
+	binWriteInt32(fileID, byteswap, EXT_HEADER_LEN, (INT32 *) tempheader);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	for (i = 0; i < EXT_HEADER_LEN; i++)
+          ((INT64 *) tempheader)[i] = (INT64) header[i];
 
- at EndFunction
-*/
-double gridInqYpole(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+	binWriteInt64(fileID, byteswap, EXT_HEADER_LEN, (INT64 *) tempheader);
 
-  return (gridptr->ypole);
-}
+	break;
+      }
+    default:
+      {
+	Error("unexpected header precision %d", rprec);
+        break;
+      }
+    }
 
-/*
- at Function
- at Title
+  binWriteF77Block(fileID, byteswap, blocklen);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  datasize = (size_t)header[3];
+  if ( number == EXT_COMP ) datasize *= 2;
+  blocklen = datasize * (size_t)rprec;
 
- at EndFunction
-*/
-void gridDefYpole(int gridID, double ypole)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  if ( memcmp(gridptr->ystdname, "grid", 4) != 0 )
-    strcpy(gridptr->ystdname, "grid_latitude");
+  extp->datasize = datasize;
 
-  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->ypole, ypole) )
+  buffer = extp->buffer;
+
+  switch ( rprec )
     {
-      gridptr->isRotated = TRUE;
-      gridptr->ypole = ypole;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    case SINGLE_PRECISION:
+      {
+	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
+	break;
+      }
+    default:
+      {
+	Error("unexpected data precision %d", rprec);
+        break;
+      }
     }
-}
 
-/*
- at Function
- at Title
+  binWriteF77Block(fileID, byteswap, blocklen);
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+  return (0);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
- at EndFunction
-*/
-double gridInqAngle(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>  // gettimeofday()
 
-  return (gridptr->angle);
-}
 
-/*
- at Function
- at Title
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+#if ! defined (O_BINARY)
+#define O_BINARY 0
+#endif
 
- at EndFunction
+#ifndef strdupx
+#ifndef strdup
+char *strdup(const char *s);
+#endif
+#define strdupx  strdup
+/*
+#define strdupx(s)                                \
+({                                                \
+   const char *__old = (s);                       \
+   size_t __len = strlen(__old) + 1;              \
+   char *__new = (char *) malloc(__len);          \
+   (char *) memcpy(__new, __old, __len);          \
+})
 */
-void gridDefAngle(int gridID, double angle)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#endif
 
-  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->angle, angle) )
-    {
-      gridptr->isRotated = TRUE;
-      gridptr->angle = angle;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
-}
 
-/*
- at Function
- at Title
+#if defined (HAVE_MMAP)
+#  include <sys/mman.h> /* mmap() is defined in this header */
+#endif
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-int gridInqGMEnd(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#if ! defined   (FALSE)
+#  define  FALSE  0
+#endif
 
-  return (gridptr->nd);
-}
+#if ! defined   (TRUE)
+#  define  TRUE   1
+#endif
 
-/*
- at Function
- at Title
+/* #define  MAX_FILES  FOPEN_MAX */
+#define  MAX_FILES  4096
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+static int _file_max = MAX_FILES;
 
- at EndFunction
-*/
-void gridDefGMEnd(int gridID, int nd)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+static void file_initialize(void);
 
-  if (gridptr->nd != nd)
-    {
-      gridptr->nd = nd;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
-}
+static int _file_init = FALSE;
 
-/*
- at Function
- at Title
+#if  defined  (HAVE_LIBPTHREAD)
+#include <pthread.h>
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+static pthread_once_t  _file_init_thread = PTHREAD_ONCE_INIT;
+static pthread_mutex_t _file_mutex;
 
- at EndFunction
-*/
-int gridInqGMEni(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#  define FILE_LOCK()         pthread_mutex_lock(&_file_mutex)
+#  define FILE_UNLOCK()       pthread_mutex_unlock(&_file_mutex)
+#  define FILE_INIT()        \
+   if ( _file_init == FALSE ) pthread_once(&_file_init_thread, file_initialize)
 
-  return (gridptr->ni);
-}
+#else
 
-/*
- at Function
- at Title
+#  define FILE_LOCK()
+#  define FILE_UNLOCK()
+#  define FILE_INIT()        \
+   if ( _file_init == FALSE ) file_initialize()
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+#endif
 
- at EndFunction
-*/
-void gridDefGMEni(int gridID, int ni)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if (gridptr->ni != ni)
-    {
-      gridptr->ni = ni;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
+typedef struct
+{
+  int        self;
+  int        flag;           /* access and error flag         */
+  int        eof;            /* end of file flag              */
+  int        fd;             /* file descriptor used for read */
+  FILE      *fp;             /* FILE pointer used for write   */
+  int        mode;           /* file access mode              */
+  char      *name;           /* file name                     */
+  off_t      size;           /* file size                     */
+  off_t      position;       /* file position                 */
+  long       access;         /* file access                   */
+  off_t      byteTrans;      /*                               */
+  size_t     blockSize;      /* file block size               */
+  int        type;           /* file type ( 1:open 2:fopen )  */
+  int        bufferType;     /* buffer type ( 1:std 2:mmap )  */
+  size_t     bufferSize;     /* file buffer size              */
+  size_t     mappedSize;     /* mmap buffer size              */
+  char      *buffer;         /* file buffer                   */
+  long       bufferNumFill;  /* number of buffer fill         */
+  char      *bufferPtr;      /* file buffer pointer           */
+  off_t      bufferPos;
+  off_t      bufferStart;
+  off_t      bufferEnd;
+  size_t     bufferCnt;
+  double     time_in_sec;
 }
+bfile_t;
 
-/*
- at Function
- at Title
-
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-int gridInqGMEni2(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+enum F_I_L_E_Flags
+  {
+    FILE_READ  =  01,
+    FILE_WRITE =  02,
+    FILE_UNBUF =  04,
+    FILE_EOF   = 010,
+    FILE_ERROR = 020
+  };
 
-  return (gridptr->ni2);
-}
 
-/*
- at Function
- at Title
+static int FileInfo  = FALSE;
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-void gridDefGMEni2(int gridID, int ni2)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#if ! defined (MIN_BUF_SIZE)
+#  define  MIN_BUF_SIZE  131072L
+#endif
 
-  if (gridptr->ni2 != ni2)
-    {
-      gridptr->ni2 = ni2;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
-}
 
-/*
- at Function
- at Title
+static size_t FileBufferSizeMin = MIN_BUF_SIZE;
+static long   FileBufferSizeEnv = -1;
+static int    FileBufferTypeEnv =  0;
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
+static int    FileTypeRead  = FILE_TYPE_OPEN;
+static int    FileTypeWrite = FILE_TYPE_FOPEN;
+static int    FileFlagWrite = 0;
 
- at EndFunction
-*/
-int gridInqGMEni3(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+static int    FILE_Debug = 0;   /* If set to 1, debugging */
 
-  return (gridptr->ni3);
-}
 
-void gridDefGMEni3(int gridID, int ni3)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+static void file_table_print(void);
 
-  if (gridptr->ni3 != ni3)
-    {
-      gridptr->ni3 = ni3;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-    }
-}
+/*
+ * A version string.
+ */
+#undef   LIBVERSION
+#define  LIBVERSION      1.8.2
+#define  XSTRING(x)	 #x
+#define  STRING(x) 	 XSTRING(x)
+const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
 
 /*
- at Function
- at Title
+  21/05/2004  1.3.2 set min I/O Buffersize to 128k
+  31/05/2005  1.4.0 replace fileTable by _fileList
+  26/08/2005  1.4.1 fileClose with return value
+                    checks for all fileptr
+  01/09/2005  1.5.0 thread safe version
+  06/11/2005  1.5.1 add filePtrEOF, filePtr, filePtrGetc
+  03/02/2006  1.5.2 ansi C: define getpagesize and strdupx
+  27/12/2007  1.6.0 add FILE_TYPE_FOPEN
+  24/03/2008  1.6.1 add O_BINARY if available
+                    remove default HAVE_MMAP
+                    use HAVE_STRUCT_STAT_ST_BLKSIZE
+  22/08/2010  1.7.0 refactor
+  11/11/2010  1.7.1 update for changed interface of error.h
+  02/02/2012  1.8.0 cleanup
+  16/11/2012  1.8.1 added support for unbuffered write
+  27/06/2013  1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
+ */
 
- at Prototype
- at Parameter
-    @Item  Grid identifier
 
- at EndFunction
-*/
-void gridChangeType(int gridID, int gridtype)
+typedef struct _filePtrToIdx {
+  int idx;
+  bfile_t *ptr;
+  struct _filePtrToIdx *next;
+} filePtrToIdx;
+
+
+static filePtrToIdx *_fileList  = NULL;
+static filePtrToIdx *_fileAvail = NULL;
+
+static
+void file_list_new(void)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  assert(_fileList == NULL);
 
-  if ( CDI_Debug )
-    Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
+  _fileList = (filePtrToIdx *)xmalloc((size_t)_file_max * sizeof (filePtrToIdx));
+}
 
-  if (gridptr->type != gridtype)
+static
+void file_list_delete(void)
+{
+  if ( _fileList )
     {
-      gridptr->type = gridtype;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      free(_fileList);
+      _fileList = NULL;
     }
 }
 
 static
-void grid_check_cyclic(grid_t *gridptr)
+void file_init_pointer(void)
 {
-  int xsize, ysize;
-  long i1, i2, in, j, k1, k2, nc;
-  double xinc, x0;
-  const double *xvals, *xbounds;
-
-  gridptr->isCyclic = FALSE;
-
-  xsize = gridptr->xsize;
-  ysize = gridptr->ysize;
-  xvals = gridptr->xvals;
-  xbounds = gridptr->xbounds;
+  int  i;
 
-  if ( gridptr->type == GRID_GAUSSIAN || gridptr->type == GRID_LONLAT )
+  for ( i = 0; i < _file_max; i++ )
     {
-      if ( xvals && xsize > 1 )
-        {
-          xinc = xvals[1] - xvals[0];
-          if ( IS_EQUAL(xinc, 0) ) xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
-
-          x0 = 2*xvals[xsize-1]-xvals[xsize-2]-360;
-
-          if ( IS_NOT_EQUAL(xvals[0], xvals[xsize-1]) )
-            if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
-        }
+      _fileList[i].next = _fileList + i + 1;
+      _fileList[i].idx  = i;
+      _fileList[i].ptr  = 0;
     }
-  else if ( gridptr->type == GRID_CURVILINEAR )
-    {
-      if ( xvals && xsize > 1 )
-        {
-          double val1, val2, valn;
-
-          nc = 0;
-          gridptr->isCyclic = FALSE;
-          for ( j = 0; j < ysize; ++j )
-            {
-              i1 = j*xsize;
-              i2 = j*xsize+1;
-              in = j*xsize+(xsize-1);
-              val1 = xvals[i1];
-              val2 = xvals[i2];
-              valn = xvals[in];
-
-              xinc = fabs(val2-val1);
-
-	      if ( val1 <    1 && valn > 300 ) val1 += 360;
-	      if ( valn <    1 && val1 > 300 ) valn += 360;
-	      if ( val1 < -179 && valn > 120 ) val1 += 360;
-	      if ( valn < -179 && val1 > 120 ) valn += 360;
-              if ( fabs(valn-val1) > 180 ) val1 += 360;
-
-              if ( valn > val1 ) x0 = valn - xinc;
-              else               x0 = valn + xinc;
-
-              if ( fabs(x0-val1) < 0.5*xinc ) nc++;
-            }
-
-          if ( nc > 0.5*ysize ) gridptr->isCyclic = TRUE;
-        }
-
-      if ( xbounds && xsize > 1 )
-	{
-	  double val1, val2;
-
-	  gridptr->isCyclic = TRUE;
-	  for ( j = 0; j < ysize; ++j )
-	    {
-	      i1 = j*xsize*4;
-	      i2 = j*xsize*4+(xsize-1)*4;
-	      nc = 0;
-	      for ( k1 = 0; k1 < 4; ++k1 )
-		{
-		  val1 = xbounds[i1+k1];
-		  for ( k2 = 0; k2 < 4; ++k2 )
-		    {
-		      val2 = xbounds[i2+k2];
-
-		      if ( val1 <    1 && val2 > 300 ) val1 += 360;
-		      if ( val2 <    1 && val1 > 300 ) val2 += 360;
-		      if ( val1 < -179 && val2 > 120 ) val1 += 360;
-		      if ( val2 < -179 && val1 > 120 ) val2 += 360;
-                      if ( fabs(val2-val1) > 180 ) val1 += 360;
 
-		      if ( fabs(val1-val2) < 0.001 )
-			{
-			  nc++;
-			  break;
-			}
-		    }
-		}
+  _fileList[_file_max-1].next = 0;
 
-	      if ( nc < 1 )
-		{
-		  gridptr->isCyclic = FALSE;
-		  break;
-		}
-	    }
-	}
-    }
+  _fileAvail = _fileList;
 }
 
-
-int gridIsCircular(int gridID)
+static
+bfile_t *file_to_pointer(int idx)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  bfile_t *fileptr = NULL;
 
-  if ( gridptr->isCyclic == CDI_UNDEFID ) grid_check_cyclic(gridptr);
+  FILE_INIT();
 
-  return ( gridptr->isCyclic );
-}
+  if ( idx >= 0 && idx < _file_max )
+    {
+      FILE_LOCK();
 
+      fileptr = _fileList[idx].ptr;
 
-int gridIsRotated(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      FILE_UNLOCK();
+    }
+  else
+    Error("file index %d undefined!", idx);
 
-  return ( gridptr->isRotated );
+  return (fileptr);
 }
 
+/* Create an index from a pointer */
 static
-int compareXYvals(int gridID, long xsize, long ysize, double *xvals0, double *yvals0)
+int file_from_pointer(bfile_t *ptr)
 {
-  long i;
-  int differ = 0;
+  int      idx = -1;
+  filePtrToIdx *newptr;
 
-  if ( !differ && xsize == gridInqXvals(gridID, NULL) )
+  if ( ptr )
     {
-      double *xvals = (double *)xmalloc((size_t)xsize * sizeof (double));
+      FILE_LOCK();
 
-      gridInqXvals(gridID, xvals);
+      if ( _fileAvail )
+	{
+	  newptr       = _fileAvail;
+	  _fileAvail   = _fileAvail->next;
+	  newptr->next = 0;
+	  idx	       = newptr->idx;
+	  newptr->ptr  = ptr;
 
-      for ( i = 0; i < xsize; ++i )
-	if ( fabs(xvals0[i] - xvals[i]) > 1.e-10 )
-	  {
-	    differ = 1;
-	    break;
-	  }
+	  if ( FILE_Debug )
+	    Message("Pointer %p has idx %d from file list", ptr, idx);
+	}
+      else
+	Warning("Too many open files (limit is %d)!", _file_max);
 
-      free(xvals);
+      FILE_UNLOCK();
     }
+  else
+    Error("Internal problem (pointer %p undefined)", ptr);
 
-  if ( !differ && ysize == gridInqYvals(gridID, NULL) )
-    {
-      double *yvals = (double *)xmalloc((size_t)ysize * sizeof (double));
+  return (idx);
+}
 
-      gridInqYvals(gridID, yvals);
+static
+void file_init_entry(bfile_t *fileptr)
+{
+  fileptr->self          = file_from_pointer(fileptr);
 
-      for ( i = 0; i < ysize; ++i )
-	if ( fabs(yvals0[i] - yvals[i]) > 1.e-10 )
-	  {
-	    differ = 1;
-	    break;
-	  }
+  fileptr->flag          = 0;
+  fileptr->fd            = -1;
+  fileptr->fp            = NULL;
+  fileptr->mode          = 0;
+  fileptr->size          = 0;
+  fileptr->name          = NULL;
+  fileptr->access        = 0;
+  fileptr->position      = 0;
+  fileptr->byteTrans     = 0;
+  fileptr->type          = 0;
+  fileptr->bufferType    = 0;
+  fileptr->bufferSize    = 0;
+  fileptr->mappedSize    = 0;
+  fileptr->buffer        = NULL;
+  fileptr->bufferNumFill = 0;
+  fileptr->bufferStart   = 0;
+  fileptr->bufferEnd     = -1;
+  fileptr->bufferPos     = 0;
+  fileptr->bufferCnt     = 0;
+  fileptr->bufferPtr     = NULL;
+  fileptr->time_in_sec   = 0.0;
+}
 
-      free(yvals);
-    }
+static
+bfile_t *file_new_entry(void)
+{
+  bfile_t *fileptr;
 
-  return (differ);
+  fileptr = (bfile_t *) malloc(sizeof(bfile_t));
+
+  if ( fileptr ) file_init_entry(fileptr);
+
+  return (fileptr);
 }
 
 static
-int compareXYvals2(int gridID, int gridsize, double *xvals, double *yvals)
+void file_delete_entry(bfile_t *fileptr)
 {
-  int differ = 0;
+  int idx;
 
-  if ( !differ && ((xvals == NULL && gridInqXvalsPtr(gridID) != NULL) || (xvals != NULL && gridInqXvalsPtr(gridID) == NULL)) ) differ = 1;
-  if ( !differ && ((yvals == NULL && gridInqYvalsPtr(gridID) != NULL) || (yvals != NULL && gridInqYvalsPtr(gridID) == NULL)) ) differ = 1;
+  idx = fileptr->self;
 
-  if ( !differ && xvals && gridInqXvalsPtr(gridID) )
-    {
-      if ( fabs(xvals[0] - gridInqXval(gridID, 0)) > 1.e-9 ||
-	   fabs(xvals[gridsize-1] - gridInqXval(gridID, gridsize-1)) > 1.e-9 )
-	differ = 1;
-    }
+  FILE_LOCK();
 
-  if ( !differ && yvals && gridInqYvalsPtr(gridID) )
-    {
-      if ( fabs(yvals[0] - gridInqYval(gridID, 0)) > 1.e-9 ||
-	   fabs(yvals[gridsize-1] - gridInqYval(gridID, gridsize-1)) > 1.e-9 )
-	differ = 1;
-    }
+  free(fileptr);
 
-  return (differ);
+  _fileList[idx].next = _fileAvail;
+  _fileList[idx].ptr  = 0;
+  _fileAvail   	      = &_fileList[idx];
+
+  FILE_UNLOCK();
+
+  if ( FILE_Debug )
+    Message("Removed idx %d from file list", idx);
 }
 
 
-int gridCompare(int gridID, const grid_t *grid)
+const char *fileLibraryVersion(void)
 {
-  int differ = 1;
+  return (file_libvers);
+}
 
-  if ( grid->type == gridInqType(gridID) || grid->type == GRID_GENERIC )
-    {
-      if ( grid->size == gridInqSize(gridID) )
-	{
-	  differ = 0;
-	  if ( grid->type == GRID_LONLAT )
-	    {
-	      /*
-	      printf("gridID      %d\n", gridID);
-	      printf("grid.xdef   %d\n", grid->xdef);
-	      printf("grid.ydef   %d\n", grid->ydef);
-	      printf("grid.xsize  %d\n", grid->xsize);
-	      printf("grid.ysize  %d\n", grid->ysize);
-	      printf("grid.xfirst %f\n", grid->xfirst);
-	      printf("grid.yfirst %f\n", grid->yfirst);
-	      printf("grid.xfirst %f\n", gridInqXval(gridID, 0));
-	      printf("grid.yfirst %f\n", gridInqYval(gridID, 0));
-	      printf("grid.xinc   %f\n", grid->xinc);
-	      printf("grid.yinc   %f\n", grid->yinc);
-	      printf("grid.xinc   %f\n", gridInqXinc(gridID));
-	      printf("grid.yinc   %f\n", gridInqYinc(gridID));
-	      */
-	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
-		{
-		  if ( grid->xdef == 2 && grid->ydef == 2 )
-		    {
-		      if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
-			   ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0) && IS_EQUAL(grid->yinc, 0)) &&
-			   IS_NOT_EQUAL(grid->xfirst, grid->xlast) && IS_NOT_EQUAL(grid->yfirst, grid->ylast) )
-			{
-			  if ( IS_NOT_EQUAL(grid->xfirst, gridInqXval(gridID, 0)) ||
-			       IS_NOT_EQUAL(grid->yfirst, gridInqYval(gridID, 0)))
-			    {
-			      differ = 1;
-			    }
-			  if ( !differ && fabs(grid->xinc) > 0 &&
-			       fabs(fabs(grid->xinc) - fabs(gridInqXinc(gridID))) > fabs(grid->xinc/1000))
-			    {
-			      differ = 1;
-			    }
-			  if ( !differ && fabs(grid->yinc) > 0 &&
-			       fabs(fabs(grid->yinc) - fabs(gridInqYinc(gridID))) > fabs(grid->yinc/1000))
-			    {
-			      differ = 1;
-			    }
-			}
-		    }
-		  else
-		    {
-		      if ( grid->xvals && grid->yvals )
-			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
-		    }
-		}
-	      else
-		differ = 1;
-	    }
-	  else if ( grid->type == GRID_GENERIC )
-	    {
-	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
-		{
-		  if ( grid->xdef == 1 && grid->ydef == 1 )
-		    {
-		      if ( grid->xvals && grid->yvals )
-			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
-		    }
-		}
-	      else if ( (grid->ysize == 0 || grid->ysize == 1) &&
-			grid->xsize == gridInqXsize(gridID)*gridInqYsize(gridID) )
-		{
-		}
-	      else
-		differ = 1;
-	    }
-	  else if ( grid->type == GRID_GAUSSIAN )
-	    {
-	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
-		{
-		  if ( grid->xdef == 2 && grid->ydef == 2 )
-		    {
-		      if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
-			   ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0)) )
-			if ( fabs(grid->xfirst - gridInqXval(gridID, 0)) > 0.0015 ||
-			     fabs(grid->yfirst - gridInqYval(gridID, 0)) > 0.0015 ||
-			     (fabs(grid->xinc)>0 && fabs(fabs(grid->xinc) - fabs(gridInqXinc(gridID))) > fabs(grid->xinc/1000)) )
-			  {
-			    differ = 1;
-			  }
-		    }
-		  else
-		    {
-		      if ( grid->xvals && grid->yvals )
-			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
-		    }
-		}
-	      else
-		differ = 1;
-	    }
-	  else if ( grid->type == GRID_CURVILINEAR )
-	    {
-	      /*
-	      printf("gridID      %d\n", gridID);
-	      printf("grid.xsize  %d\n", grid->xsize);
-	      printf("grid.ysize  %d\n", grid->ysize);
-	      printf("grid.xfirst %f\n", grid->xvals[0]);
-	      printf("grid.yfirst %f\n", grid->yvals[0]);
-	      printf("grid xfirst %f\n", gridInqXval(gridID, 0));
-	      printf("grid yfirst %f\n", gridInqYval(gridID, 0));
-	      printf("grid.xlast  %f\n", grid->xvals[grid->size-1]);
-	      printf("grid.ylast  %f\n", grid->yvals[grid->size-1]);
-	      printf("grid xlast  %f\n", gridInqXval(gridID, grid->size-1));
-	      printf("grid ylast  %f\n", gridInqYval(gridID, grid->size-1));
-	      printf("grid.nv     %d\n", grid->nvertex);
-	      printf("grid nv     %d\n", gridInqNvertex(gridID));
-	      */
-	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
-		differ = compareXYvals2(gridID, grid->size, grid->xvals, grid->yvals);
-	    }
-	  else if ( grid->type == GRID_UNSTRUCTURED )
-	    {
-              unsigned char uuidOfHGrid[CDI_UUID_SIZE];
-              gridInqUUID(gridID, uuidOfHGrid);
 
-              if ( !differ && memcmp(uuidOfHGrid, grid->uuid, CDI_UUID_SIZE) != 0 ) differ = 1;
+#ifndef POSIXIO_DEFAULT_PAGESIZE
+#define POSIXIO_DEFAULT_PAGESIZE 4096
+#endif
 
-              if ( !differ && grid->nvertex != gridInqNvertex(gridID) ) differ = 1;
+static
+int pagesize(void)
+{
+#if defined(_SC_PAGESIZE)
+  return ((int) sysconf(_SC_PAGESIZE));
+#else
+  return ((int) POSIXIO_DEFAULT_PAGESIZE);
+#endif
+}
 
-              if ( !differ && grid->number != gridInqNumber(gridID) ) differ = 1;
-              if ( !differ && grid->position != gridInqPosition(gridID) ) differ = 1;
+static
+double file_time()
+{
+  double tseconds = 0.0;
+  struct timeval mytime;
+  gettimeofday(&mytime, NULL);
+  tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
+  return (tseconds);
+}
 
-              if ( !differ && grid->nvertex != gridInqNvertex(gridID) ) differ = 1;
-              if ( !differ && grid->number != gridInqNumber(gridID) ) differ = 1;
-              if ( !differ && grid->number > 0 && grid->position != gridInqPosition(gridID) ) differ = 1;
-	      if ( !differ )
-		differ = compareXYvals2(gridID, grid->size, grid->xvals, grid->yvals);
-	    }
-	}
-    }
+void fileDebug(int debug)
+{
+  FILE_Debug = debug;
 
-  return (differ);
+  if ( FILE_Debug )
+    Message("Debug level %d", debug);
 }
 
 
-int gridCompareP ( void * gridptr1, void * gridptr2 )
+void *filePtr(int fileID)
 {
-  grid_t * g1 = ( grid_t * ) gridptr1;
-  grid_t * g2 = ( grid_t * ) gridptr2;
-  enum { equal = 0,
-         differ = -1 };
-  int i, size;
+  bfile_t *fileptr;
 
-  xassert ( g1 );
-  xassert ( g2 );
+  fileptr = file_to_pointer(fileID);
 
-  if ( g1->type          != g2->type         ) return differ;
-  if ( g1->prec          != g2->prec         ) return differ;
-  if ( g1->lcc_projflag  != g2->lcc_projflag ) return differ;
-  if ( g1->lcc_scanflag  != g2->lcc_scanflag ) return differ;
-  if ( g1->lcc_defined   != g2->lcc_defined  ) return differ;
-  if ( g1->lcc2_defined  != g2->lcc2_defined ) return differ;
-  if ( g1->laea_defined  != g2->laea_defined ) return differ;
-  if ( g1->isCyclic      != g2->isCyclic     ) return differ;
-  if ( g1->isRotated     != g2->isRotated    ) return differ;
-  if ( g1->xdef          != g2->xdef         ) return differ;
-  if ( g1->ydef          != g2->ydef         ) return differ;
-  if ( g1->nd            != g2->nd           ) return differ;
-  if ( g1->ni            != g2->ni           ) return differ;
-  if ( g1->ni2           != g2->ni2          ) return differ;
-  if ( g1->ni3           != g2->ni3          ) return differ;
-  if ( g1->number        != g2->number       ) return differ;
-  if ( g1->position      != g2->position     ) return differ;
-  if ( g1->trunc         != g2->trunc        ) return differ;
-  if ( g1->nvertex       != g2->nvertex      ) return differ;
-  if ( g1->nrowlon       != g2->nrowlon      ) return differ;
-  if ( g1->size          != g2->size         ) return differ;
-  if ( g1->xsize         != g2->xsize        ) return differ;
-  if ( g1->ysize         != g2->ysize        ) return differ;
-  if ( g1->locked        != g2->locked       ) return differ;
-  if ( g1->lcomplex      != g2->lcomplex     ) return differ;
+  return (fileptr);
+}
 
-  if ( g1->rowlon )
+static
+void file_pointer_info(const char *caller, int fileID)
+{
+  if ( FILE_Debug )
     {
-      for ( i = 0; i < g1->nrowlon; i++ )
-	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ;
+      fprintf(stdout, "%-18s : ", caller);
+      fprintf(stdout, "The fileID %d underlying pointer is not valid!", fileID);
+      fprintf(stdout, "\n");
     }
-  else if ( g2->rowlon )
-    return differ;
-
-  if ( IS_NOT_EQUAL(g1->xfirst        , g2->xfirst)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->yfirst	      , g2->yfirst)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->xlast         , g2->xlast)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->ylast         , g2->ylast)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->xinc	      , g2->xinc)          ) return differ;
-  if ( IS_NOT_EQUAL(g1->yinc	      , g2->yinc)          ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_originLon , g2->lcc_originLon) ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_originLat , g2->lcc_originLat) ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_lonParY   , g2->lcc_lonParY)   ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_lat1      , g2->lcc_lat1)      ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_lat2      , g2->lcc_lat2)      ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_xinc      , g2->lcc_xinc)      ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc_yinc      , g2->lcc_yinc)      ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc2_lon_0    , g2->lcc2_lon_0)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc2_lat_0    , g2->lcc2_lat_0)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc2_lat_1    , g2->lcc2_lat_1)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc2_lat_2    , g2->lcc2_lat_2)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->lcc2_a        , g2->lcc2_a)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->laea_lon_0    , g2->laea_lon_0)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->laea_lat_0    , g2->laea_lat_0)    ) return differ;
-  if ( IS_NOT_EQUAL(g1->laea_a        , g2->laea_a)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->xpole         , g2->xpole)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->ypole         , g2->ypole)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->angle         , g2->angle)         ) return differ;
-
-  if ( g1->xvals )
-    {
-      if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
-	size = g1->size;
-      else
-	size = g1->xsize;
-      xassert ( size );
+}
 
-      if ( !g2->xvals ) return differ;
 
-      for ( i = 0; i < size; i++ )
-	if ( IS_NOT_EQUAL(g1->xvals[i], g2->xvals[i]) ) return differ;
-    }
-  else if ( g2->xvals )
-    return differ;
+int fileSetBufferType(int fileID, int type)
+{
+  int ret = 0;
+  bfile_t *fileptr;
 
-  if ( g1->yvals )
+  fileptr = file_to_pointer(fileID);
+
+  if ( fileptr )
     {
-      if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
-	size = g1->size;
-      else
-	size = g1->ysize;
-      xassert ( size );
+      switch (type)
+	{
+	case FILE_BUFTYPE_STD:
+	case FILE_BUFTYPE_MMAP:
+	  fileptr->bufferType = type;
+	  break;
+	default:
+	  Error("File type %d not implemented!", type);
+	}
+    }
 
-      if ( !g2->yvals ) return differ;
+#if ! defined (HAVE_MMAP)
+  if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
+#endif
 
-      for ( i = 0; i < size; i++ )
-        if ( IS_NOT_EQUAL(g1->yvals[i], g2->yvals[i]) ) return differ;
-    }
-  else if ( g2->yvals )
-    return differ;
+  return (ret);
+}
 
-  if ( g1->area )
-    {
-      xassert ( g1->size );
 
-      if ( !g2->area ) return differ;
+int fileGetBufferType(int fileID)
+{
+  bfile_t *fileptr;
+  int bufferType = 0;
 
-      for ( i = 0; i < g1->size; i++ )
-	if ( IS_NOT_EQUAL(g1->area[i], g2->area[i]) ) return differ;
-    }
-  else if ( g2->area )
-    return differ;
+  fileptr = file_to_pointer(fileID);
 
-  if ( g1->xbounds )
-    {
-      xassert ( g1->nvertex );
-      if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
-	size = g1->nvertex * g1->size;
-      else
-	size = g1->nvertex * g1->xsize;
-      xassert ( size );
+  if ( fileptr ) bufferType = fileptr->bufferType;
 
-      if ( !g2->xbounds ) return differ;
+  return (bufferType);
+}
 
-      for ( i = 0; i < size; i++ )
-	if ( IS_NOT_EQUAL(g1->xbounds[i], g2->xbounds[i]) ) return differ;
-    }
-  else if ( g2->xbounds )
-    return differ;
 
-  if ( g1->ybounds )
-    {
-      xassert ( g1->nvertex );
-      if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
-	size = g1->nvertex * g1->size;
-      else
-	size = g1->nvertex * g1->ysize;
-      xassert ( size );
+int fileFlush(int fileID)
+{
+  bfile_t *fileptr;
+  int retval = 0;
 
-      if ( !g2->ybounds ) return differ;
+  fileptr = file_to_pointer(fileID);
 
-      for ( i = 0; i < size; i++ )
-	if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
-    }
-  else if ( g2->ybounds )
-    return differ;
+  if ( fileptr ) retval = fflush(fileptr->fp);
 
-  if (strcmp(g1->xname, g2->xname)) return differ;
-  if (strcmp(g1->yname, g2->yname)) return differ;
-  if (strcmp(g1->xlongname, g2->xlongname)) return differ;
-  if (strcmp(g1->ylongname, g2->ylongname)) return differ;
-  if (strcmp(g1->xstdname, g2->xstdname)) return differ;
-  if (strcmp(g1->ystdname, g2->ystdname)) return differ;
-  if (strcmp(g1->xunits, g2->xunits)) return differ;
-  if (strcmp(g1->yunits, g2->yunits)) return differ;
+  return (retval);
+}
 
-  if ( g1->reference )
-    {
-      if ( !g2->reference ) return differ;
-      if ( strcmp(g1->reference, g2->reference) ) return differ;
-    }
-  else if ( g2->reference )
-    return differ;
 
-  if ( g1->mask )
-    {
-      xassert ( g1->size );
-      if ( !g2->mask ) return differ;
-      if ( memcmp ( g1->mask, g2->mask, (size_t)g1->size * sizeof(mask_t)) ) return differ;
-    }
-  else if ( g2->mask )
-    return differ;
+void fileClearerr(int fileID)
+{
+  bfile_t *fileptr;
 
-  if ( g1->mask_gme )
+  fileptr = file_to_pointer(fileID);
+
+  if ( fileptr )
     {
-      xassert ( g1->size );
-      if ( !g2->mask_gme ) return differ;
-      if ( memcmp ( g1->mask_gme, g2->mask_gme, (size_t)g1->size * sizeof(mask_t)) ) return differ;
+      if ( fileptr->mode != 'r' )
+	clearerr(fileptr->fp);
     }
-  else if ( g2->mask_gme )
-    return differ;
-
-  if (memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE))
-    return differ;
-
-  return equal;
 }
 
 
-int gridGenerate(const grid_t *grid)
+int filePtrEOF(void *vfileptr)
 {
-  int gridID = gridCreate(grid->type, grid->size);
+  bfile_t *fileptr = (bfile_t *) vfileptr;
+  int retval = 0;
 
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
 
-  gridDefPrec(gridID, grid->prec);
+  return (retval);
+}
 
-  switch (grid->type)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_UNSTRUCTURED:
-    case GRID_CURVILINEAR:
-    case GRID_GENERIC:
-    case GRID_LCC:
-    case GRID_LCC2:
-    case GRID_SINUSOIDAL:
-    case GRID_LAEA:
-    case GRID_PROJECTION:
-      {
-	if ( grid->xsize > 0 ) gridDefXsize(gridID, grid->xsize);
-	if ( grid->ysize > 0 ) gridDefYsize(gridID, grid->ysize);
 
-        if ( grid->type == GRID_GAUSSIAN ) gridDefNP(gridID, grid->np);
+int fileEOF(int fileID)
+{
+  bfile_t *fileptr;
+  int retval = 0;
 
-	if ( grid->nvertex > 0 )
-	  gridDefNvertex(gridID, grid->nvertex);
+  fileptr = file_to_pointer(fileID);
 
-	if ( grid->xdef == 1 )
-	  {
-	    gridDefXvals(gridID, grid->xvals);
-	    if ( grid->xbounds )
-	      gridDefXbounds(gridID, grid->xbounds);
-	  }
-	else if ( grid->xdef == 2 )
-	  {
-	    double *xvals
-              = (double *)xmalloc((size_t)grid->xsize * sizeof (double));
-	    gridGenXvals(grid->xsize, grid->xfirst, grid->xlast, grid->xinc, xvals);
-	    gridDefXvals(gridID, xvals);
-	    free(xvals);
-	    /*
-	    gridDefXinc(gridID, grid->xinc);
-	    */
-	  }
+  if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
 
-	if ( grid->ydef == 1 )
-	  {
-	    gridDefYvals(gridID, grid->yvals);
-	    if ( grid->ybounds && grid->nvertex )
-	      gridDefYbounds(gridID, grid->ybounds);
-	  }
-	else if ( grid->ydef == 2 )
-	  {
-	    double *yvals
-              = (double *)xmalloc((size_t)grid->ysize * sizeof (double));
-	    gridGenYvals(grid->type, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
-	    gridDefYvals(gridID, yvals);
-	    free(yvals);
-	    /*
-	    gridDefYinc(gridID, grid->yinc);
-	    */
-	  }
+  return (retval);
+}
 
-	if ( grid->isRotated )
-	  {
-	    gridDefXname(gridID, "rlon");
-	    gridDefYname(gridID, "rlat");
-	    gridDefXlongname(gridID, "longitude in rotated pole grid");
-	    gridDefYlongname(gridID, "latitude in rotated pole grid");
-	    strcpy(gridptr->xstdname, "grid_longitude");
-	    strcpy(gridptr->ystdname, "grid_latitude");
-	    gridDefXunits(gridID, "degrees");
-	    gridDefYunits(gridID, "degrees");
 
-	    gridDefXpole(gridID, grid->xpole);
-	    gridDefYpole(gridID, grid->ypole);
-	    gridDefAngle(gridID, grid->angle);
-	  }
+int fileError(int fileID)
+{
+  bfile_t *fileptr;
+  int retval = 0;
 
-	if ( grid->area )
-	  {
-	    gridDefArea(gridID, grid->area);
-	  }
+  fileptr = file_to_pointer(fileID);
 
-	if ( grid->type == GRID_LAEA )
-	  gridDefLaea(gridID, grid->laea_a, grid->laea_lon_0, grid->laea_lat_0);
+  if ( fileptr ) retval = (fileptr->flag & FILE_ERROR) != 0;
 
-	if ( grid->type == GRID_LCC2 )
-	  gridDefLcc2(gridID, grid->lcc2_a, grid->lcc2_lon_0, grid->lcc2_lat_0, grid->lcc2_lat_1, grid->lcc2_lat_2);
+  return (retval);
+}
 
-	if ( grid->type == GRID_LCC )
-	  gridDefLCC(gridID, grid->lcc_originLon, grid->lcc_originLat, grid->lcc_lonParY,
-		     grid->lcc_lat1, grid->lcc_lat2, grid->lcc_xinc, grid->lcc_yinc,
-		     grid->lcc_projflag, grid->lcc_scanflag);
 
-	if ( grid->type == GRID_UNSTRUCTURED )
-          {
-            int number = grid->number;
-            int position = grid->position;
-            if ( position < 0 ) position = 0;
-            if ( number > 0 )
-              {
-                gridDefNumber(gridID, number);
-                gridDefPosition(gridID, position);
-              }
-            gridDefUUID(gridID, grid->uuid);
-            if ( grid->reference ) gridDefReference(gridID, grid->reference);
-          }
+void fileRewind(int fileID)
+{
+  fileSetPos(fileID, (off_t) 0, SEEK_SET);
+  fileClearerr(fileID);
+}
 
-	if ( grid->type == GRID_PROJECTION )
-	  {
-	    gridptr->name = strdup(grid->name);
-	  }
 
-	break;
-      }
-    case GRID_GAUSSIAN_REDUCED:
-      {
-	gridDefNP(gridID, grid->np);
-	gridDefYsize(gridID, grid->ysize);
-	gridDefRowlon(gridID, grid->ysize, grid->rowlon);
+off_t fileGetPos(int fileID)
+{
+  off_t filepos = 0;
+  bfile_t *fileptr;
 
-        if ( grid->xdef == 2 )
-          {
-            double xvals[2];
-            xvals[0] = grid->xfirst;
-            xvals[1] = grid->xlast;
-            gridDefXvals(gridID, xvals);
-          }
+  fileptr = file_to_pointer(fileID);
 
-	if ( grid->ydef == 1 )
-	  {
-	    gridDefYvals(gridID, grid->yvals);
-	    if ( grid->ybounds && grid->nvertex )
-	      gridDefYbounds(gridID, grid->ybounds);
-	  }
-	else if ( grid->ydef == 2 )
-	  {
-	    double *yvals
-              = (double *)xmalloc((size_t)grid->ysize * sizeof (double));
-	    gridGenYvals(grid->type, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
-	    gridDefYvals(gridID, yvals);
-	    free(yvals);
-	    /*
-	    gridDefYinc(gridID, grid->yinc);
-	    */
-	  }
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-        gridDefTrunc(gridID, grid->trunc);
-        if ( grid->lcomplex ) gridDefComplexPacking(gridID, 1);
-        break;
-      }
-    case GRID_FOURIER:
-      {
-	gridDefTrunc(gridID, grid->trunc);
-	break;
-      }
-    case GRID_GME:
-      {
-        gridDefGMEnd(gridID, grid->nd);
-        gridDefGMEni(gridID, grid->ni);
-        gridDefGMEni2(gridID, grid->ni2);
-        gridDefGMEni3(gridID, grid->ni3);
-        break;
-      }
-      /*
-    case GRID_GENERIC:
-      {
-        if ( grid->xsize > 0 && grid->ysize > 0 )
-          {
-            gridDefXsize(gridID, grid->xsize);
-            gridDefYsize(gridID, grid->ysize);
-            if ( grid->xvals ) gridDefXvals(gridID, grid->xvals);
-            if ( grid->yvals ) gridDefYvals(gridID, grid->yvals);
-          }
-        break;
-      }
-      */
-    case GRID_TRAJECTORY:
-      {
-        gridDefXsize(gridID, 1);
-        gridDefYsize(gridID, 1);
-        break;
-      }
-    default:
-      {
-	Error("Gridtype %s unsupported!", gridNamePtr(grid->type));
-	break;
-      }
+  if ( fileptr )
+    {
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	filepos = fileptr->position;
+      else
+	filepos = ftell(fileptr->fp);
     }
 
-  if ( grid->xname[0]     ) gridDefXname(gridID, grid->xname);
-  if ( grid->xlongname[0] ) gridDefXlongname(gridID, grid->xlongname);
-  if ( grid->xunits[0]    ) gridDefXunits(gridID, grid->xunits);
-  if ( grid->yname[0]     ) gridDefYname(gridID, grid->yname);
-  if ( grid->ylongname[0] ) gridDefYlongname(gridID, grid->ylongname);
-  if ( grid->yunits[0]    ) gridDefYunits(gridID, grid->yunits);
+  if ( FILE_Debug ) Message("Position %ld", filepos);
 
-  return (gridID);
+  return (filepos);
 }
 
-/*
- at Function  gridDuplicate
- at Title     Duplicate a horizontal Grid
-
- at Prototype int gridDuplicate(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
- at Description
-The function @func{gridDuplicate} duplicates a horizontal Grid.
+int fileSetPos(int fileID, off_t offset, int whence)
+{
+  int status = 0;
+  bfile_t *fileptr;
 
- at Result
- at func{gridDuplicate} returns an identifier to the duplicated Grid.
+  fileptr = file_to_pointer(fileID);
 
- at EndFunction
-*/
-int gridDuplicate(int gridID)
-{
-  grid_t *gridptr = reshGetVal(gridID, &gridOps);
+  if ( FILE_Debug ) Message("Offset %8ld  Whence %3d", (long) offset, whence);
 
-  int gridtype = gridInqType(gridID);
-  int gridsize = gridInqSize(gridID);
+  if ( fileptr == 0 )
+    {
+      file_pointer_info(__func__, fileID);
+      return (1);
+    }
 
-  int gridIDnew = gridCreate(gridtype, gridsize);
-  grid_t *gridptrnew = reshGetVal(gridIDnew, &gridOps);
+  switch (whence)
+    {
+    case SEEK_SET:
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	{
+	  off_t position = offset;
+	  fileptr->position = position;
+	  if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
+	    {
+	      if ( fileptr->bufferType == FILE_BUFTYPE_STD )
+		fileptr->bufferPos = position;
+	      else
+		fileptr->bufferPos = position - position % pagesize();
 
-  grid_copy(gridptrnew, gridptr);
+	      fileptr->bufferCnt = 0;
+	      fileptr->bufferPtr = NULL;
+	    }
+	  else
+	    {
+	      if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
+		{
+		  if ( FILE_Debug )
+		    Message("Reset buffer pos from %ld to %ld",
+			    fileptr->bufferPos, fileptr->bufferEnd + 1);
 
-  strcpy(gridptrnew->xname, gridptr->xname);
-  strcpy(gridptrnew->yname, gridptr->yname);
-  strcpy(gridptrnew->xlongname, gridptr->xlongname);
-  strcpy(gridptrnew->ylongname, gridptr->ylongname);
-  strcpy(gridptrnew->xunits, gridptr->xunits);
-  strcpy(gridptrnew->yunits, gridptr->yunits);
-  strcpy(gridptrnew->xstdname, gridptr->xstdname);
-  strcpy(gridptrnew->ystdname, gridptr->ystdname);
+		  fileptr->bufferPos = fileptr->bufferEnd + 1;
+		}
+	      fileptr->bufferCnt = (size_t)(fileptr->bufferEnd - position) + 1;
+	      fileptr->bufferPtr = fileptr->buffer + position - fileptr->bufferStart;
+	    }
+	}
+      else
+	{
+	  status = fseek(fileptr->fp, offset, whence);
+	}
+      break;
+    case SEEK_CUR:
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	{
+	  fileptr->position += offset;
+	  off_t position = fileptr->position;
+	  if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
+	    {
+	      if ( fileptr->bufferType == FILE_BUFTYPE_STD )
+		fileptr->bufferPos = position;
+	      else
+		fileptr->bufferPos = position - position % pagesize();
 
-  if (gridptr->reference)
-    gridptrnew->reference = strdupx(gridptr->reference);
+	      fileptr->bufferCnt = 0;
+	      fileptr->bufferPtr = NULL;
+	    }
+	  else
+	    {
+	      if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
+		{
+		  if ( FILE_Debug )
+		    Message("Reset buffer pos from %ld to %ld",
+			    fileptr->bufferPos, fileptr->bufferEnd + 1);
 
-  size_t nrowlon = (size_t)gridptr->nrowlon;
-  int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
-  if ( nrowlon )
-    {
-      gridptrnew->rowlon = (int *)xmalloc(nrowlon * sizeof (int));
-      memcpy(gridptrnew->rowlon, gridptr->rowlon, nrowlon * sizeof(int));
+		  fileptr->bufferPos = fileptr->bufferEnd + 1;
+		}
+	      fileptr->bufferCnt -= (size_t)offset;
+	      fileptr->bufferPtr += offset;
+	    }
+	}
+      else
+	{
+	  status = fseek(fileptr->fp, offset, whence);
+	}
+      break;
+    default:
+      Error("Whence = %d not implemented", whence);
     }
 
-  if ( gridptr->xvals != NULL )
+  if ( fileptr->position < fileptr->size )
+    if ( (fileptr->flag & FILE_EOF) != 0 )
+      fileptr->flag -= FILE_EOF;
+
+  return (status);
+}
+
+static
+void file_table_print(void)
+{
+  int fileID;
+  int lprintHeader = 1;
+  bfile_t *fileptr;
+
+  for ( fileID = 0; fileID < _file_max; fileID++ )
     {
-      size_t size  = (size_t)(irregular ? gridsize : gridptr->xsize);
+      fileptr = file_to_pointer(fileID);
+
+      if ( fileptr )
+	{
+	  if ( lprintHeader )
+	    {
+	      fprintf(stderr, "\nFile table:\n");
+	      fprintf(stderr, "+-----+---------+");
+	      fprintf(stderr, "----------------------------------------------------+\n");
+	      fprintf(stderr, "|  ID |  Mode   |");
+	      fprintf(stderr, "  Name                                              |\n");
+	      fprintf(stderr, "+-----+---------+");
+	      fprintf(stderr, "----------------------------------------------------+\n");
+	      lprintHeader = 0;
+	    }
+
+	  fprintf(stderr, "| %3d | ", fileID);
+
+	  switch ( fileptr->mode )
+	    {
+	    case 'r':
+	      fprintf(stderr, "read   ");
+	      break;
+	    case 'w':
+	      fprintf(stderr, "write  ");
+	      break;
+	    case 'a':
+	      fprintf(stderr, "append ");
+	      break;
+	    default:
+	      fprintf(stderr, "unknown");
+	    }
 
-      gridptrnew->xvals = (double *)xmalloc(size * sizeof (double));
-      memcpy(gridptrnew->xvals, gridptr->xvals, size * sizeof (double));
+          fprintf(stderr, " | %-51s|\n", fileptr->name);
+	}
     }
 
-  if ( gridptr->yvals != NULL )
+  if ( lprintHeader == 0 )
     {
-      size_t size  = (size_t)(irregular ? gridsize : gridptr->ysize);
-
-      gridptrnew->yvals = xmalloc(size * sizeof (double));
-      memcpy(gridptrnew->yvals, gridptr->yvals, size * sizeof (double));
+      fprintf(stderr, "+-----+---------+");
+      fprintf(stderr, "----------------------------------------------------+\n");
     }
+}
 
-  if ( gridptr->xbounds != NULL )
-    {
-      size_t size  = (size_t)(irregular ? gridsize : gridptr->xsize)
-        * (size_t)gridptr->nvertex;
-
-      gridptrnew->xbounds = xmalloc(size * sizeof (double));
-      memcpy(gridptrnew->xbounds, gridptr->xbounds, size * sizeof (double));
-    }
 
-  if ( gridptr->ybounds != NULL )
-    {
-      size_t size = (size_t)(irregular ? gridsize : gridptr->ysize)
-        * (size_t)gridptr->nvertex;
+char *fileInqName(int fileID)
+{
+  bfile_t *fileptr;
+  char *name = NULL;
 
-      gridptrnew->ybounds = xmalloc(size * sizeof (double));
-      memcpy(gridptrnew->ybounds, gridptr->ybounds, size * sizeof (double));
-    }
+  fileptr = file_to_pointer(fileID);
 
-  if ( gridptr->area != NULL )
-    {
-      size_t size = (size_t)gridsize;
+  if ( fileptr ) name = fileptr->name;
 
-      gridptrnew->area = xmalloc(size * sizeof (double));
-      memcpy(gridptrnew->area, gridptr->area, size * sizeof (double));
-    }
+  return (name);
+}
 
-  if ( gridptr->mask != NULL )
-    {
-      size_t size = (size_t)gridsize;
 
-      gridptrnew->mask = xmalloc(size * sizeof(mask_t));
-      memcpy(gridptrnew->mask, gridptr->mask, size * sizeof (mask_t));
-    }
+int fileInqMode(int fileID)
+{
+  bfile_t *fileptr;
+  int mode = 0;
 
-  if ( gridptr->mask_gme != NULL )
-    {
-      size_t size = (size_t)gridsize;
+  fileptr = file_to_pointer(fileID);
 
-      gridptrnew->mask_gme = xmalloc(size * sizeof (mask_t));
-      memcpy(gridptrnew->mask_gme, gridptr->mask_gme, size * sizeof(mask_t));
-    }
+  if ( fileptr ) mode = fileptr->mode;
 
-  return (gridIDnew);
+  return (mode);
 }
 
-
-void gridCompress(int gridID)
+static
+long file_getenv(const char *envName)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  char *envString;
+  long envValue = -1;
+  long fact = 1;
 
-  int gridtype = gridInqType(gridID);
-  if ( gridtype == GRID_UNSTRUCTURED )
+  envString = getenv(envName);
+
+  if ( envString )
     {
-      if ( gridptr->mask_gme != NULL )
-	{
-          size_t gridsize = (size_t)gridInqSize(gridID);
-	  size_t nv = (size_t)gridptr->nvertex;
+      int loop;
 
-	  size_t j = 0;
-          double *area = gridptr->area,
-            *xvals = gridptr->xvals,
-            *yvals = gridptr->yvals,
-            *xbounds = gridptr->xbounds,
-            *ybounds = gridptr->ybounds;
-          mask_t *mask_gme = gridptr->mask_gme;
-	  for (size_t i = 0; i < gridsize; i++ )
+      for ( loop = 0; loop < (int) strlen(envString); loop++ )
+	{
+	  if ( ! isdigit((int) envString[loop]) )
 	    {
-	      if (mask_gme[i])
+	      switch ( tolower((int) envString[loop]) )
 		{
-		  if (xvals) xvals[j] = xvals[i];
-		  if (yvals) yvals[j] = yvals[i];
-		  if (area) area[j]  = area[i];
-		  if (xbounds != NULL)
-		    for (size_t iv = 0; iv < nv; iv++)
-		      xbounds[j * nv + iv] = xbounds[i * nv + iv];
-		  if (ybounds != NULL)
-		    for (size_t iv = 0; iv < nv; iv++)
-		      ybounds[j * nv + iv] = ybounds[i * nv + iv];
-
-		  j++;
+		case 'k':  fact =       1024;  break;
+		case 'm':  fact =    1048576;  break;
+		case 'g':  fact = 1073741824;  break;
+		default:
+		  fact = 0;
+		  Message("Invalid number string in %s: %s", envName, envString);
+		  Warning("%s must comprise only digits [0-9].",envName);
 		}
+	      break;
 	    }
+	}
 
-	  /* fprintf(stderr, "grid compress %d %d %d\n", i, j, gridsize); */
-	  gridsize = j;
-	  gridptr->size  = (int)gridsize;
-	  gridptr->xsize = (int)gridsize;
-	  gridptr->ysize = (int)gridsize;
+      if ( fact ) envValue = fact*atol(envString);
 
-	  if ( gridptr->xvals )
-	    gridptr->xvals = (double *)xrealloc(gridptr->xvals, gridsize*sizeof(double));
+      if ( FILE_Debug ) Message("Set %s to %ld", envName, envValue);
+    }
 
-	  if ( gridptr->yvals )
-	    gridptr->yvals = (double *)xrealloc(gridptr->yvals, gridsize*sizeof(double));
+  return (envValue);
+}
 
-	  if ( gridptr->area )
-	    gridptr->area  = (double *)xrealloc(gridptr->area, gridsize*sizeof(double));
+static
+void file_initialize(void)
+{
+  long value;
+  char *envString;
 
-	  if ( gridptr->xbounds )
-	    gridptr->xbounds = (double *)xrealloc(gridptr->xbounds, nv*gridsize*sizeof(double));
+#if  defined  (HAVE_LIBPTHREAD)
+  /* initialize global API mutex lock */
+  pthread_mutex_init(&_file_mutex, NULL);
+#endif
 
-	  if ( gridptr->ybounds )
-	    gridptr->ybounds = (double *)xrealloc(gridptr->ybounds, nv*gridsize*sizeof(double));
+  value = file_getenv("FILE_DEBUG");
+  if ( value >= 0 ) FILE_Debug = (int) value;
 
-	  free(gridptr->mask_gme);
-	  gridptr->mask_gme = NULL;
-          reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+  value = file_getenv("FILE_MAX");
+  if ( value >= 0 ) _file_max = (int) value;
+
+  if ( FILE_Debug )
+    Message("FILE_MAX = %d", _file_max);
+
+  FileInfo  = (int) file_getenv("FILE_INFO");
+
+  value  = file_getenv("FILE_BUFSIZE");
+  if ( value >= 0 ) FileBufferSizeEnv = value;
+  else
+    {
+      value  = file_getenv("GRIB_API_IO_BUFFER_SIZE");
+      if ( value >= 0 ) FileBufferSizeEnv = value;
+    }
+
+  value = file_getenv("FILE_TYPE_READ");
+  if ( value > 0 )
+    {
+      switch (value)
+	{
+	case FILE_TYPE_OPEN:
+	case FILE_TYPE_FOPEN:
+	  FileTypeRead = (int)value;
+	  break;
+	default:
+	  Warning("File type %d not implemented!", value);
 	}
     }
-  else
-    Warning("Unsupported grid type: %s", gridNamePtr(gridtype));
-}
 
+  value = file_getenv("FILE_TYPE_WRITE");
+  if ( value > 0 )
+    {
+      switch (value)
+	{
+	case FILE_TYPE_OPEN:
+	case FILE_TYPE_FOPEN:
+	  FileTypeWrite = (int)value;
+	  break;
+	default:
+	  Warning("File type %d not implemented!", value);
+	}
+    }
 
-void gridDefArea(int gridID, const double *area)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+#if defined (O_NONBLOCK)
+  FileFlagWrite = O_NONBLOCK;
+#endif
+  envString = getenv("FILE_FLAG_WRITE");
+  if ( envString )
+    {
+#if defined (O_NONBLOCK)
+      if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
+#endif
+    }
 
-  size_t size = (size_t)gridptr->size;
+  value = file_getenv("FILE_BUFTYPE");
+#if ! defined (HAVE_MMAP)
+  if ( value == FILE_BUFTYPE_MMAP )
+    {
+      Warning("MMAP not available!");
+      value = 0;
+    }
+#endif
+  if ( value > 0 )
+    {
+      switch (value)
+	{
+	case FILE_BUFTYPE_STD:
+	case FILE_BUFTYPE_MMAP:
+	  FileBufferTypeEnv = (int)value;
+	  break;
+	default:
+	  Warning("File buffer type %d not implemented!", value);
+	}
+    }
 
-  if ( size == 0 )
-    Error("size undefined for gridID = %d", gridID);
+  file_list_new();
+  atexit(file_list_delete);
 
-  if ( gridptr->area == NULL )
-    gridptr->area = (double *)xmalloc(size*sizeof(double));
-  else if ( CDI_Debug )
-    Warning("values already defined!");
+  FILE_LOCK();
 
-  memcpy(gridptr->area, area, size * sizeof(double));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-}
+  file_init_pointer();
 
+  FILE_UNLOCK();
 
-void gridInqArea(int gridID, double *area)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( FILE_Debug ) atexit(file_table_print);
 
-  if (gridptr->area)
-    memcpy(area, gridptr->area, (size_t)gridptr->size * sizeof (double));
+  _file_init = TRUE;
 }
 
-
-int gridHasArea(int gridID)
+static
+void file_set_buffer(bfile_t *fileptr)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t buffersize = 0;
 
-  int hasArea = (gridptr->area != NULL);
+  if ( fileptr->mode == 'r' )
+    {
+      if ( FileBufferTypeEnv )
+	fileptr->bufferType = FileBufferTypeEnv;
+      else if ( fileptr->bufferType == 0 )
+	fileptr->bufferType = FILE_BUFTYPE_STD;
 
-  return (hasArea);
-}
+      if ( FileBufferSizeEnv >= 0 )
+	buffersize = (size_t) FileBufferSizeEnv;
+      else if ( fileptr->bufferSize > 0 )
+	buffersize = fileptr->bufferSize;
+      else
+	{
+	  buffersize = fileptr->blockSize * 4;
+	  if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
+	}
 
+      if ( (size_t) fileptr->size < buffersize )
+	buffersize = (size_t) fileptr->size;
 
-const double *gridInqAreaPtr(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
+	{
+	  size_t blocksize = (size_t) pagesize();
+	  size_t minblocksize = 4 * blocksize;
+	  buffersize = buffersize - buffersize % minblocksize;
 
-  return (gridptr->area);
-}
+	  if ( buffersize < (size_t) fileptr->size && buffersize < minblocksize )
+	    buffersize = minblocksize;
+	}
 
+      if ( buffersize == 0 ) buffersize = 1;
+    }
+  else
+    {
+      fileptr->bufferType = FILE_BUFTYPE_STD;
 
-void gridDefNvertex(int gridID, int nvertex)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+      if ( FileBufferSizeEnv >= 0 )
+	buffersize = (size_t) FileBufferSizeEnv;
+      else if ( fileptr->bufferSize > 0 )
+	buffersize = fileptr->bufferSize;
+      else
+	{
+	  buffersize = fileptr->blockSize * 4;
+	  if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
+	}
+    }
 
-  if (gridptr->nvertex != nvertex)
+  if ( fileptr->bufferType == FILE_BUFTYPE_STD || fileptr->type == FILE_TYPE_FOPEN )
     {
-      gridptr->nvertex = nvertex;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      if ( buffersize > 0 )
+        {
+          fileptr->buffer = (char *) malloc(buffersize);
+          if ( fileptr->buffer == NULL )
+            SysError("Allocation of file buffer failed!");
+        }
     }
-}
 
+  if ( fileptr->type == FILE_TYPE_FOPEN )
+    if ( setvbuf(fileptr->fp, fileptr->buffer, fileptr->buffer ? _IOFBF : _IONBF, buffersize) )
+      SysError("setvbuf failed!");
 
-int gridInqNvertex(int gridID)
+  fileptr->bufferSize = buffersize;
+}
+
+static
+int file_fill_buffer(bfile_t *fileptr)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  ssize_t nread;
+  int fd;
+  long offset = 0;
+  off_t retseek;
 
-  return (gridptr->nvertex);
-}
+  if ( FILE_Debug )
+    Message("file ptr = %p  Cnt = %ld", fileptr, fileptr->bufferCnt);
 
-/*
- at Function  gridDefXbounds
- at Title     Define the bounds of a X-axis
+  if ( (fileptr->flag & FILE_EOF) != 0 ) return (EOF);
 
- at Prototype void gridDefXbounds(int gridID, const double *xbounds)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  xbounds  X-bounds of the grid.
+  if ( fileptr->buffer == NULL ) file_set_buffer(fileptr);
 
- at Description
-The function @func{gridDefXbounds} defines all bounds of the X-axis.
+  if ( fileptr->bufferSize == 0 ) return (EOF);
 
- at EndFunction
-*/
-void gridDefXbounds(int gridID, const double *xbounds)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  fd = fileptr->fd;
 
-  size_t nvertex = (size_t)gridptr->nvertex;
-  if ( nvertex == 0 )
+#if defined (HAVE_MMAP)
+  if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
     {
-      Warning("nvertex undefined for gridID = %d. Cannot define bounds!", gridID);
-      return;
-    }
-
-  int irregular = gridptr->type == GRID_CURVILINEAR
-    || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex
-    * (size_t)(irregular ? gridptr->size : gridptr->xsize);
-  if ( size == 0 )
-    Error("size undefined for gridID = %d", gridID);
+      if ( fileptr->bufferPos >= fileptr->size )
+	{
+	  nread = 0;
+	}
+      else
+	{
+          xassert(fileptr->bufferSize <= SSIZE_MAX);
+	  nread = (ssize_t)fileptr->bufferSize;
+	  if ( (nread + fileptr->bufferPos) > fileptr->size )
+	    nread = fileptr->size - fileptr->bufferPos;
 
-  if (gridptr->xbounds == NULL)
-    gridptr->xbounds = xmalloc(size * sizeof (double));
-  else if ( CDI_Debug )
-    Warning("values already defined!");
+	  if ( fileptr->buffer )
+	    {
+              int ret;
+	      ret = munmap(fileptr->buffer, fileptr->mappedSize);
+	      if ( ret == -1 ) SysError("munmap error for read %s", fileptr->name);
+	      fileptr->buffer = NULL;
+	    }
 
-  memcpy(gridptr->xbounds, xbounds, size * sizeof (double));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-}
+	  fileptr->mappedSize = (size_t)nread;
 
-/*
- at Function  gridInqXbounds
- at Title     Get the bounds of a X-axis
+	  fileptr->buffer = (char*) mmap(NULL, (size_t) nread, PROT_READ, MAP_PRIVATE, fd, fileptr->bufferPos);
 
- at Prototype int gridInqXbounds(int gridID, double *xbounds)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  xbounds  Pointer to the location into which the X-bounds are read.
-                    The caller must allocate space for the returned values.
+	  if ( fileptr->buffer == MAP_FAILED ) SysError("mmap error for read %s", fileptr->name);
 
- at Description
-The function @func{gridInqXbounds} returns the bounds of the X-axis.
+	  offset = fileptr->position - fileptr->bufferPos;
+	}
+    }
+  else
+#endif
+    {
+      retseek = lseek(fileptr->fd, fileptr->bufferPos, SEEK_SET);
+      if ( retseek == (off_t)-1 )
+	SysError("lseek error at pos %ld file %s", (long) fileptr->bufferPos, fileptr->name);
 
- at Result
-Upon successful completion @func{gridInqXbounds} returns the number of bounds and
-the bounds are stored in @func{xbounds}.
-Otherwise, 0 is returned and @func{xbounds} is empty.
+      nread = read(fd, fileptr->buffer, fileptr->bufferSize);
+    }
 
- at EndFunction
-*/
-int gridInqXbounds(int gridID, double *xbounds)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( nread <= 0 )
+    {
+      if ( nread == 0 )
+	fileptr->flag |= FILE_EOF;
+      else
+	fileptr->flag |= FILE_ERROR;
 
-  size_t nvertex = (size_t)gridptr->nvertex;
+      fileptr->bufferCnt = 0;
+      return (EOF);
+    }
 
-  int irregular = gridptr->type == GRID_CURVILINEAR
-    || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->xsize);
+  fileptr->bufferPtr = fileptr->buffer;
+  fileptr->bufferCnt = (size_t)nread;
 
-  if ( size && xbounds && gridptr->xbounds )
-    memcpy(xbounds, gridptr->xbounds, size * sizeof (double));
+  fileptr->bufferStart = fileptr->bufferPos;
+  fileptr->bufferPos  += nread;
+  fileptr->bufferEnd   = fileptr->bufferPos - 1;
 
-  if ( gridptr->xbounds == NULL ) size = 0;
+  if ( FILE_Debug )
+    {
+      Message("fileID = %d  Val     = %d",  fileptr->self, (int) fileptr->buffer[0]);
+      Message("fileID = %d  Start   = %ld", fileptr->self, fileptr->bufferStart);
+      Message("fileID = %d  End     = %ld", fileptr->self, fileptr->bufferEnd);
+      Message("fileID = %d  nread   = %ld", fileptr->self, nread);
+      Message("fileID = %d  offset  = %ld", fileptr->self, offset);
+      Message("fileID = %d  Pos     = %ld", fileptr->self, fileptr->bufferPos);
+      Message("fileID = %d  postion = %ld", fileptr->self, fileptr->position);
+    }
 
-  return ((int)size);
-}
+  if ( offset > 0 )
+    {
+      if ( offset > nread )
+	Error("Internal problem with buffer handling. nread = %d offset = %d", nread, offset);
 
+      fileptr->bufferPtr += offset;
+      fileptr->bufferCnt -= (size_t)offset;
+    }
 
-const double *gridInqXboundsPtr(int gridID)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  fileptr->bufferNumFill++;
 
-  return (gridptr->xbounds);
+  return ((unsigned char) *fileptr->bufferPtr);
 }
 
-/*
- at Function  gridDefYbounds
- at Title     Define the bounds of a Y-axis
-
- at Prototype void gridDefYbounds(int gridID, const double *ybounds)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  ybounds  Y-bounds of the grid.
-
- at Description
-The function @func{gridDefYbounds} defines all bounds of the Y-axis.
-
- at EndFunction
-*/
-void gridDefYbounds(int gridID, const double *ybounds)
+static
+void file_copy_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  size_t nvertex = (size_t)gridptr->nvertex;
-  if ( nvertex == 0 )
-    {
-      Warning("nvertex undefined for gridID = %d. Cannot define bounds!", gridID);
-      return;
-    }
+  if ( FILE_Debug )
+    Message("size = %ld  Cnt = %ld", size, fileptr->bufferCnt);
 
-  int irregular = gridptr->type == GRID_CURVILINEAR
-    || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
+  if ( fileptr->bufferCnt < size )
+    Error("Buffer too small. bufferCnt = %d", fileptr->bufferCnt);
 
-  if ( size == 0 )
-    Error("size undefined for gridID = %d", gridID);
+  if ( size == 1 )
+    {
+      ((char *)ptr)[0] = fileptr->bufferPtr[0];
 
-  if ( gridptr->ybounds == NULL )
-    gridptr->ybounds = xmalloc(size * sizeof (double));
-  else if ( CDI_Debug )
-    Warning("values already defined!");
+      fileptr->bufferPtr++;
+      fileptr->bufferCnt--;
+    }
+  else
+    {
+      memcpy(ptr, fileptr->bufferPtr, size);
 
-  memcpy(gridptr->ybounds, ybounds, size * sizeof (double));
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      fileptr->bufferPtr += size;
+      fileptr->bufferCnt -= size;
+    }
 }
 
-/*
- at Function  gridInqYbounds
- at Title     Get the bounds of a Y-axis
+static
+size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
+{
+  size_t nread, rsize;
+  size_t offset = 0;
 
- at Prototype int gridInqYbounds(int gridID, double *ybounds)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  ybounds  Pointer to the location into which the Y-bounds are read.
-                    The caller must allocate space for the returned values.
+  if ( FILE_Debug )
+    Message("size = %ld  Cnt = %ld", size, (long) fileptr->bufferCnt);
 
- at Description
-The function @func{gridInqYbounds} returns the bounds of the Y-axis.
+  if ( ((long)fileptr->bufferCnt) < 0L )
+    Error("Internal problem. bufferCnt = %ld", (long) fileptr->bufferCnt);
 
- at Result
-Upon successful completion @func{gridInqYbounds} returns the number of bounds and
-the bounds are stored in @func{ybounds}.
-Otherwise, 0 is returned and @func{ybounds} is empty.
+  rsize = size;
 
- at EndFunction
-*/
-int gridInqYbounds(int gridID, double *ybounds)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  while ( fileptr->bufferCnt < rsize )
+    {
+      nread = fileptr->bufferCnt;
+      /*
+      fprintf(stderr, "rsize = %d nread = %d\n", (int) rsize, (int) nread);
+      */
+      if ( nread > (size_t) 0 )
+	file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
+      offset += nread;
+      if ( nread < rsize )
+	rsize -= nread;
+      else
+	rsize = 0;
 
-  size_t nvertex = (size_t)gridptr->nvertex;
+      if ( file_fill_buffer(fileptr) == EOF ) break;
+    }
 
-  int irregular = gridptr->type == GRID_CURVILINEAR
-    || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
+  nread = size - offset;
 
-  if ( size && ybounds && gridptr->ybounds )
-    memcpy(ybounds, gridptr->ybounds, size * sizeof (double));
+  if ( fileptr->bufferCnt < nread ) nread = fileptr->bufferCnt;
 
-  if ( gridptr->ybounds == NULL ) size = 0;
+  if ( nread > (unsigned) 0 )
+    file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
 
-  return ((int)size);
+  return (nread+offset);
 }
 
 
-const double *gridInqYboundsPtr(int gridID)
+void fileSetBufferSize(int fileID, long buffersize)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  return (gridptr->ybounds);
+  bfile_t *fileptr = file_to_pointer(fileID);
+  xassert(buffersize >= 0);
+  if ( fileptr ) fileptr->bufferSize = (size_t)buffersize;
 }
 
+/*
+ *   Open a file. Returns file ID, or -1 on error
+ */
+int fileOpen(const char *filename, const char *mode)
+{
+  int (*myFileOpen)(const char *filename, const char *mode)
+    = (int (*)(const char *, const char *))
+    namespaceSwitchGet(NSSWITCH_FILE_OPEN).func;
+  return myFileOpen(filename, mode);
+}
 
-void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
+int fileOpen_serial(const char *filename, const char *mode)
 {
-  int type;
-  int gridsize, xsize, ysize, xdim, ydim;
-  int trunc;
-  int nbyte0, nbyte;
-  int i;
-  int nvertex, iv;
-  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
-  int gridID = gridptr->self;
-  const double *area    = gridInqAreaPtr(gridID);
-  const double *xvals   = gridInqXvalsPtr(gridID);
-  const double *yvals   = gridInqYvalsPtr(gridID);
-  const double *xbounds = gridInqXboundsPtr(gridID);
-  const double *ybounds = gridInqYboundsPtr(gridID);
+  FILE *fp = NULL;    /* file pointer    (used for write) */
+  int fd = -1;        /* file descriptor (used for read)  */
+  int fileID = FILE_UNDEFID;
+  int fmode = 0;
+  struct stat filestat;
+  bfile_t *fileptr = NULL;
 
-  type     = gridInqType(gridID);
-  trunc    = gridInqTrunc(gridID);
-  gridsize = gridInqSize(gridID);
-  xsize    = gridInqXsize(gridID);
-  ysize    = gridInqYsize(gridID);
-  nvertex  = gridInqNvertex(gridID);
+  FILE_INIT();
 
-  nbyte0 = 0;
-  fprintf(fp, "#\n");
-  fprintf(fp, "# gridID %d\n", gridID);
-  fprintf(fp, "#\n");
-  fprintf(fp, "gridtype  = %s\n", gridNamePtr(type));
-  fprintf(fp, "gridsize  = %d\n", gridsize);
+  fmode = tolower((int) mode[0]);
 
-  if ( type != GRID_GME )
+  switch ( fmode )
     {
-      if ( xvals )
-        {
-          if ( gridptr->xname[0]     )     fprintf(fp, "xname     = %s\n", gridptr->xname);
-          if ( gridptr->xlongname[0] )     fprintf(fp, "xlongname = %s\n", gridptr->xlongname);
-          if ( gridptr->xunits[0]    )     fprintf(fp, "xunits    = %s\n", gridptr->xunits);
-        }
-      if ( yvals )
-        {
-          if ( gridptr->yname[0]     )     fprintf(fp, "yname     = %s\n", gridptr->yname);
-          if ( gridptr->ylongname[0] )     fprintf(fp, "ylongname = %s\n", gridptr->ylongname);
-          if ( gridptr->yunits[0]    )     fprintf(fp, "yunits    = %s\n", gridptr->yunits);
-        }
-      if ( type == GRID_UNSTRUCTURED && nvertex > 0 ) fprintf(fp, "nvertex   = %d\n", nvertex);
+    case 'r':
+      if ( FileTypeRead == FILE_TYPE_FOPEN )
+	fp = fopen(filename, "rb");
+      else
+	fd =  open(filename, O_RDONLY | O_BINARY);
+      break;
+    case 'x':  fp = fopen(filename, "rb");      break;
+    case 'w':
+      if ( FileTypeWrite == FILE_TYPE_FOPEN )
+        fp = fopen(filename, "wb");
+      else
+	fd =  open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
+      break;
+    case 'a':  fp = fopen(filename, "ab");      break;
+    default:   Error("Mode %c unexpected!", fmode);
     }
 
-  switch (type)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_GAUSSIAN_REDUCED:
-    case GRID_GENERIC:
-    case GRID_LCC2:
-    case GRID_SINUSOIDAL:
-    case GRID_LAEA:
-    case GRID_CURVILINEAR:
-    case GRID_UNSTRUCTURED:
-      {
-        if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np        = %d\n", gridptr->np);
-
-	if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
-	  {
-	    xdim = gridsize;
-	    ydim = gridsize;
-	  }
-        else if ( type == GRID_GAUSSIAN_REDUCED )
-          {
-	    xdim = 2;
-	    ydim = ysize;
-          }
-	else
-	  {
-	    xdim = xsize;
-	    ydim = ysize;
-	  }
+  if ( FILE_Debug )
+    if ( fp == NULL && fd == -1 )
+      Message("Open failed on %s mode %c errno %d", filename, fmode, errno);
 
-	if ( type != GRID_UNSTRUCTURED )
-	  {
-	    if ( xsize > 0 ) fprintf(fp, "xsize     = %d\n", xsize);
-	    if ( ysize > 0 ) fprintf(fp, "ysize     = %d\n", ysize);
-	  }
+  if ( fp )
+    {
+      if ( stat(filename, &filestat) != 0 ) return (fileID);
 
-	if ( type == GRID_UNSTRUCTURED )
-          {
-            int number = gridInqNumber(gridID);
-            int position = gridInqPosition(gridID);
-            // const unsigned char *d;
-            if ( number > 0 )
-              {
-                fprintf(fp, "number    = %d\n", number);
-                if ( position >= 0 ) fprintf(fp, "position  = %d\n", position);
-              }
-            /*
-              gridInqUUID(gridID, uuidOfHGrid);
-              d = (unsigned char *) &uuidOfHGrid;
-              fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
-              d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
-              d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
-            */
-            if ( gridInqReference(gridID, NULL) )
-              {
-                char reference_link[8192];
-                gridInqReference(gridID, reference_link);
-                fprintf(fp, "uri       = %s\n", reference_link);
-              }
-          }
+      fileptr = file_new_entry();
+      if ( fileptr )
+	{
+	  fileID = fileptr->self;
+	  fileptr->fp = fp;
+	}
+    }
+  else if ( fd >= 0 )
+    {
+      if ( fstat(fd, &filestat) != 0 ) return (fileID);
 
-	if ( type == GRID_LAEA )
-	  {
-	    double a = 0, lon_0 = 0, lat_0 = 0;
-	    gridInqLaea(gridID, &a, &lon_0, &lat_0);
-	    fprintf(fp, "a         = %g\n", a);
-	    fprintf(fp, "lon_0     = %g\n", lon_0);
-	    fprintf(fp, "lat_0     = %g\n", lat_0);
-	  }
+      fileptr = file_new_entry();
+      if ( fileptr )
+	{
+	  fileID = fileptr->self;
+	  fileptr->fd = fd;
+	}
+    }
 
-	if ( type == GRID_LCC2 )
-	  {
-	    double a = 0, lon_0 = 0, lat_0 = 0, lat_1 = 0, lat_2 = 0;
-	    gridInqLcc2(gridID, &a, &lon_0, &lat_0, &lat_1, &lat_2);
-	    fprintf(fp, "a         = %g\n", a);
-	    fprintf(fp, "lon_0     = %g\n", lon_0);
-	    fprintf(fp, "lat_0     = %g\n", lat_0);
-	    fprintf(fp, "lat_1     = %g\n", lat_1);
-	    fprintf(fp, "lat_2     = %g\n", lat_2);
-	  }
+  if ( fileID >= 0 )
+    {
+      fileptr->mode = fmode;
+      fileptr->name = strdupx(filename);
 
-	if ( gridptr->isRotated )
-	  {
-	    if ( xsize > 0 ) fprintf(fp, "xnpole    = %g\n", gridptr->xpole);
-	    if ( ysize > 0 ) fprintf(fp, "ynpole    = %g\n", gridptr->ypole);
-	    if ( gridptr->angle > 0 ) fprintf(fp, "angle     = %g\n", gridptr->angle);
- 	  }
+#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
+      fileptr->blockSize = (size_t) filestat.st_blksize;
+#else
+      fileptr->blockSize = (size_t) 4096;
+#endif
 
-	if ( xvals )
-	  {
-	    double xfirst = 0.0, xinc = 0.0;
+      if ( fmode == 'r' )
+        fileptr->type = FileTypeRead;
+      else if ( fmode == 'w' )
+        fileptr->type = FileTypeWrite;
+      else
+	fileptr->type = FILE_TYPE_FOPEN;
 
-	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN ||
-		 type == GRID_GENERIC    || type == GRID_LCC2     ||
-                 type == GRID_SINUSOIDAL || type == GRID_LAEA )
-	      {
-		xfirst = gridInqXval(gridID, 0);
-		xinc   = gridInqXinc(gridID);
-	      }
+      if ( fmode == 'r' ) fileptr->size = filestat.st_size;
 
-	    if ( IS_NOT_EQUAL(xinc, 0) && opt )
-	      {
-	  	fprintf(fp, "xfirst    = %g\n", xfirst);
-		fprintf(fp, "xinc      = %g\n", xinc);
-	      }
-	    else
-	      {
-		nbyte0 = fprintf(fp, "xvals     = ");
-		nbyte = nbyte0;
-		for ( i = 0; i < xdim; i++ )
-		  {
-		    if ( nbyte > 80 )
-		      {
-			fprintf(fp, "\n");
-			fprintf(fp, "%*s", nbyte0, "");
-			nbyte = nbyte0;
-		      }
-		    nbyte += fprintf(fp, "%.9g ", xvals[i]);
-		  }
-		fprintf(fp, "\n");
-	      }
-	  }
+      if ( fileptr->type == FILE_TYPE_FOPEN ) file_set_buffer(fileptr);
 
-	if ( xbounds )
-	  {
-	    nbyte0 = fprintf(fp, "xbounds   = ");
-	    for ( i = 0; i < xdim; i++ )
-	      {
-		if ( i ) fprintf(fp, "%*s", nbyte0, "");
+      if ( FILE_Debug )
+	Message("File %s opened with ID %d", filename, fileID);
+    }
 
-		for ( iv = 0; iv < nvertex; iv++ )
-		  fprintf(fp, "%.9g ", xbounds[i*nvertex+iv]);
-		fprintf(fp, "\n");
-	      }
-	  }
+  return (fileID);
+}
 
-	if ( yvals )
-	  {
-	    double yfirst = 0.0, yinc = 0.0;
+/*
+ *   Close a file.
+ */
+int fileClose(int fileID)
+{
+  int (*myFileClose)(int fileID)
+    = (int (*)(int))namespaceSwitchGet(NSSWITCH_FILE_CLOSE).func;
+  return myFileClose(fileID);
+}
 
-	    if ( type == GRID_LONLAT || type == GRID_GENERIC || type == GRID_LCC2 ||
-		 type == GRID_SINUSOIDAL || type == GRID_LAEA )
-	      {
-		yfirst = gridInqYval(gridID, 0);
-		yinc   = gridInqYinc(gridID);
-	      }
+int fileClose_serial(int fileID)
+{
+  char *name;
+  int ret;
+  char *fbtname[] = {"unknown", "standard", "mmap"};
+  char *ftname[] = {"unknown", "open", "fopen"};
+  bfile_t *fileptr = file_to_pointer(fileID);
+  double rout = 0;
 
-	    if ( IS_NOT_EQUAL(yinc, 0) && opt )
-	      {
-	  	fprintf(fp, "yfirst    = %g\n", yfirst);
-		fprintf(fp, "yinc      = %g\n", yinc);
-	      }
-	    else
-	      {
-		nbyte0 = fprintf(fp, "yvals     = ");
-		nbyte = nbyte0;
-		for ( i = 0; i < ydim; i++ )
-		  {
-		    if ( nbyte > 80 )
-		      {
-			fprintf(fp, "\n");
-			fprintf(fp, "%*s", nbyte0, "");
-			nbyte = nbyte0;
-		      }
-		    nbyte += fprintf(fp, "%.9g ", yvals[i]);
-		  }
-		fprintf(fp, "\n");
-	      }
-	  }
+  if ( fileptr == NULL )
+    {
+      file_pointer_info(__func__, fileID);
+      return (1);
+    }
 
-	if ( ybounds )
-	  {
-	    nbyte0 = fprintf(fp, "ybounds   = ");
-	    for ( i = 0; i < ydim; i++ )
-	      {
-		if ( i ) fprintf(fp, "%*s", nbyte0, "");
+  name = fileptr->name;
 
-		for ( iv = 0; iv < nvertex; iv++ )
-		  fprintf(fp, "%.9g ", ybounds[i*nvertex+iv]);
-		fprintf(fp, "\n");
-	      }
-	  }
+  if ( FILE_Debug )
+    Message("fileID = %d  filename = %s", fileID, name);
 
-	if ( area )
-	  {
-	    nbyte0 = fprintf(fp, "area      = ");
-	    nbyte  = nbyte0;
-	    for ( i = 0; i < gridsize; i++ )
-	      {
-		if ( nbyte > 80 )
-		  {
-		    fprintf(fp, "\n");
-		    fprintf(fp, "%*s", nbyte0, "");
-		    nbyte = nbyte0;
-		  }
-		nbyte += fprintf(fp, "%.9g ", area[i]);
-	      }
-	    fprintf(fp, "\n");
-	  }
+  if ( FileInfo > 0 )
+    {
+      fprintf(stderr, "____________________________________________\n");
+      fprintf(stderr, " file ID          : %d\n",  fileID);
+      fprintf(stderr, " file name        : %s\n",  fileptr->name);
+      fprintf(stderr, " file type        : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
 
-        if ( type == GRID_GAUSSIAN_REDUCED )
-          {
-            int *rowlon;
-            nbyte0 = fprintf(fp, "rowlon    = ");
-            nbyte  = nbyte0;
-            rowlon = (int *)xmalloc((size_t)ysize*sizeof(int));
-            gridInqRowlon(gridID, rowlon);
-            for ( i = 0; i < ysize; i++ )
-              {
-                if ( nbyte > 80 )
-                  {
-                    fprintf(fp, "\n");
-                    fprintf(fp, "%*s", nbyte0, "");
-                    nbyte = nbyte0;
-                  }
-                nbyte += fprintf(fp, "%d ", rowlon[i]);
-              }
-            fprintf(fp, "\n");
-            free(rowlon);
-          }
+      if ( fileptr->type == FILE_TYPE_FOPEN )
+	fprintf(stderr, " file pointer     : %p\n",  (void *) fileptr->fp);
+      else
+        {
+          fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
+          fprintf(stderr, " file flag        : %d\n", FileFlagWrite);
+        }
+      fprintf(stderr, " file mode        : %c\n",  fileptr->mode);
 
-	break;
-      }
-    case GRID_LCC:
-      {
-	double originLon = 0, originLat = 0, lonParY = 0, lat1 = 0, lat2 = 0, xincm = 0, yincm = 0;
-	int projflag = 0, scanflag = 0;
-	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
-		   &projflag, &scanflag);
+      if ( sizeof(off_t) > sizeof(long) )
+	{
+#if defined (_WIN32)
+	  fprintf(stderr, " file size        : %I64d\n", (long long) fileptr->size);
+	  if ( fileptr->type == FILE_TYPE_OPEN )
+	    fprintf(stderr, " file position    : %I64d\n", (long long) fileptr->position);
+	  fprintf(stderr, " bytes transfered : %I64d\n", (long long) fileptr->byteTrans);
+#else
+	  fprintf(stderr, " file size        : %lld\n", (long long) fileptr->size);
+	  if ( fileptr->type == FILE_TYPE_OPEN )
+	    fprintf(stderr, " file position    : %lld\n", (long long) fileptr->position);
+	  fprintf(stderr, " bytes transfered : %lld\n", (long long) fileptr->byteTrans);
+#endif
+	}
+      else
+	{
+	  fprintf(stderr, " file size        : %ld\n", (long) fileptr->size);
+	  if ( fileptr->type == FILE_TYPE_OPEN )
+	    fprintf(stderr, " file position    : %ld\n", (long) fileptr->position);
+	  fprintf(stderr, " bytes transfered : %ld\n", (long) fileptr->byteTrans);
+	}
 
-	fprintf(fp, "xsize     = %d\n", xsize);
-	fprintf(fp, "ysize     = %d\n", ysize);
+      if ( fileptr->time_in_sec > 0 )
+        {
+          rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
+        }
 
-	fprintf(fp, "originLon = %g\n", originLon);
-	fprintf(fp, "originLat = %g\n", originLat);
-	fprintf(fp, "lonParY   = %g\n", lonParY);
-	fprintf(fp, "lat1      = %g\n", lat1);
-	fprintf(fp, "lat2      = %g\n", lat2);
-	fprintf(fp, "xinc      = %g\n", xincm);
-	fprintf(fp, "yinc      = %g\n", yincm);
-	if ( (projflag & 128) == 0 )
-	  fprintf(fp, "projection = northpole\n");
-	else
-	  fprintf(fp, "projection = southpole\n");
+      fprintf(stderr, " wall time [s]    : %.2f\n", fileptr->time_in_sec);
+      fprintf(stderr, " data rate [MB/s] : %.1f\n", rout);
 
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-        fprintf(fp, "truncation = %d\n", trunc);
-        fprintf(fp, "complexpacking = %d\n", gridptr->lcomplex );
-        break;
-      }
-    case GRID_FOURIER:
-      {
-	fprintf(fp, "truncation = %d\n", trunc);
-	break;
-      }
-    case GRID_GME:
-      {
-        fprintf(fp, "ni        = %d\n", gridptr->ni );
-        break;
-      }
-   default:
-      {
-	fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
-        break;
-      }
+      fprintf(stderr, " file access      : %ld\n", fileptr->access);
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	{
+	  fprintf(stderr, " buffer type      : %d (%s)\n", fileptr->bufferType, fbtname[fileptr->bufferType]);
+	  fprintf(stderr, " num buffer fill  : %ld\n", fileptr->bufferNumFill);
+	}
+      fprintf(stderr, " buffer size      : %lu\n", (unsigned long) fileptr->bufferSize);
+      fprintf(stderr, " block size       : %lu\n", (unsigned long) fileptr->blockSize);
+      fprintf(stderr, " page size        : %d\n",  pagesize());
+      fprintf(stderr, "--------------------------------------------\n");
     }
 
-  gridInqUUID(gridID, uuidOfHGrid);
-  if ( !cdiUUIDIsNull(uuidOfHGrid) )
+  if ( fileptr->type == FILE_TYPE_FOPEN )
     {
-      char uuidOfHGridStr[37];
-      uuid2str(uuidOfHGrid, uuidOfHGridStr);
-      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
-        fprintf(fp, "uuid      = %s\n", uuidOfHGridStr);
+      ret = fclose(fileptr->fp);
+      if ( ret == EOF )
+	SysError("EOF returned for close of %s!", name);
     }
-
-  if ( gridptr->mask )
+  else
     {
-      nbyte0 = fprintf(fp, "mask      = ");
-      nbyte  = nbyte0;
-      for ( i = 0; i < gridsize; i++ )
-        {
-          if ( nbyte > 80 )
-            {
-              fprintf(fp, "\n");
-              fprintf(fp, "%*s", nbyte0, "");
-              nbyte = nbyte0;
-            }
-          nbyte += fprintf(fp, "%d ", (int) gridptr->mask[i]);
-        }
-      fprintf(fp, "\n");
+#if defined (HAVE_MMAP)
+      if ( fileptr->buffer && fileptr->mappedSize )
+	{
+	  ret = munmap(fileptr->buffer, fileptr->mappedSize);
+	  if ( ret == -1 ) SysError("munmap error for close %s", fileptr->name);
+	  fileptr->buffer = NULL;
+	}
+#endif
+      ret = close(fileptr->fd);
+      if ( ret == -1 )
+	SysError("EOF returned for close of %s!", name);
     }
-}
 
-void gridPrint ( int gridID, int opt )
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( fileptr->name )    free((void*) fileptr->name);
+  if ( fileptr->buffer )  free((void*) fileptr->buffer);
 
-  gridPrintKernel ( gridptr, opt, stdout );
-}
+  file_delete_entry(fileptr);
 
+  return (0);
+}
 
 
-void gridPrintP ( void * voidptr, FILE * fp )
+int filePtrGetc(void *vfileptr)
 {
-  grid_t * gridptr = ( grid_t * ) voidptr;
-  int nbyte0, nbyte, i;
-
-  xassert ( gridptr );
+  int ivalue = EOF;
+  int fillret = 0;
+  bfile_t *fileptr = (bfile_t *) vfileptr;
 
-  gridPrintKernel ( gridptr , 0, fp );
+  if ( fileptr )
+    {
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	{
+	  if ( fileptr->bufferCnt == 0 ) fillret = file_fill_buffer(fileptr);
 
-  fprintf ( fp, "precision = %d\n", gridptr->prec);
-  fprintf ( fp, "nd        = %d\n", gridptr->nd );
-  fprintf ( fp, "ni        = %d\n", gridptr->ni );
-  fprintf ( fp, "ni2       = %d\n", gridptr->ni2 );
-  fprintf ( fp, "ni3       = %d\n", gridptr->ni3 ); 
-  fprintf ( fp, "number    = %d\n", gridptr->number );
-  fprintf ( fp, "position  = %d\n", gridptr->position );
-  fprintf ( fp, "trunc     = %d\n", gridptr->trunc );
-  fprintf ( fp, "lcomplex  = %d\n", gridptr->lcomplex );
-  fprintf ( fp, "nrowlon   = %d\n", gridptr->nrowlon );
+	  if ( fillret >= 0 )
+	    {
+	      ivalue = (unsigned char) *fileptr->bufferPtr++;
+	      fileptr->bufferCnt--;
+	      fileptr->position++;
 
-  if ( gridptr->rowlon )
-    {
-      nbyte0 = fprintf(fp, "rowlon    = ");
-      nbyte  = nbyte0;
-      for ( i = 0; i < gridptr->nrowlon; i++ )
-        {
-          if ( nbyte > 80 )
-            {
-              fprintf(fp, "\n");
-              fprintf(fp, "%*s", nbyte0, "");
-              nbyte = nbyte0;
-            }
-          nbyte += fprintf(fp, "%d ", gridptr->rowlon[i]);
-        }
-      fprintf(fp, "\n");
+	      fileptr->byteTrans++;
+	      fileptr->access++;
+	    }
+	}
+      else
+	{
+	  ivalue = fgetc(fileptr->fp);
+	  if ( ivalue >= 0 )
+	    {
+	      fileptr->byteTrans++;
+	      fileptr->access++;
+	    }
+	  else
+	    fileptr->flag |= FILE_EOF;
+	}
     }
 
-  if ( gridptr->mask_gme )
-    {
-      nbyte0 = fprintf(fp, "mask_gme  = ");
-      nbyte  = nbyte0;
-      for ( i = 0; i < gridptr->size; i++ )
-        {
-          if ( nbyte > 80 )
-            {
-              fprintf(fp, "\n");
-              fprintf(fp, "%*s", nbyte0, "");
-              nbyte = nbyte0;
-            }
-          nbyte += fprintf(fp, "%d ", (int) gridptr->mask_gme[i]);
-        }
-      fprintf(fp, "\n");
-    }
+  return (ivalue);
 }
 
 
-const double *gridInqXvalsPtr(int gridID)
+int fileGetc(int fileID)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  int ivalue;
+  bfile_t *fileptr;
 
-  return ( gridptr->xvals );
+  fileptr = file_to_pointer(fileID);
+
+  ivalue = filePtrGetc((void *)fileptr);
+
+  return (ivalue);
 }
 
 
-const double *gridInqYvalsPtr(int gridID)
+size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t nread = 0;
+  bfile_t *fileptr = (bfile_t *) vfileptr;
 
-  return ( gridptr->yvals );
-}
+  if ( fileptr )
+    {
+      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+	nread = file_read_from_buffer(fileptr, ptr, size);
+      else
+	{
+	  nread = fread(ptr, 1, size, fileptr->fp);
+	  if ( nread != size )
+	    {
+	      if ( nread == 0 )
+		fileptr->flag |= FILE_EOF;
+	      else
+		fileptr->flag |= FILE_ERROR;
+	    }
+	}
 
-/*
- at Function  gridDefLCC
- at Title     Define the parameter of a Lambert Conformal Conic grid
+      fileptr->position  += (off_t)nread;
+      fileptr->byteTrans += (off_t)nread;
+      fileptr->access++;
+    }
 
- at Prototype void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag)
- at Parameter
-    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  originLon Longitude of the first grid point.
-    @Item  originLat Latitude of the first grid point.
-    @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
-    @Item  lat1      First latitude from the pole at which the secant cone cuts the sphere.
-    @Item  lat2      Second latitude at which the secant cone cuts the sphere.
-    @Item  xinc      X-direction grid lenght in meter.
-    @Item  yinc      Y-direction grid lenght in meter.
-    @Item  projflag  Projection centre flag.
-    @Item  scanflag  Scanning mode flag.
+  if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
 
- at Description
-The function @func{gridDefLCC} defines the parameter of a Lambert Conformal Conic grid.
+  return (nread);
+}
 
- at EndFunction
-*/
-void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
-                double lat1, double lat2, double xinc, double yinc,
-                int projflag, int scanflag)
+
+size_t fileRead(int fileID, void *restrict ptr, size_t size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t nread = 0;
+  bfile_t *fileptr;
 
-  if ( gridptr->type != GRID_LCC )
-    Warning("Definition of LCC grid for %s grid not allowed!",
-	    gridNamePtr(gridptr->type));
-  else
+  fileptr = file_to_pointer(fileID);
+
+  if ( fileptr )
     {
-      gridptr->lcc_originLon = originLon;
-      gridptr->lcc_originLat = originLat;
-      gridptr->lcc_lonParY   = lonParY;
-      gridptr->lcc_lat1      = lat1;
-      gridptr->lcc_lat2      = lat2;
-      gridptr->lcc_xinc      = xinc;
-      gridptr->lcc_yinc      = yinc;
-      gridptr->lcc_projflag  = projflag;
-      gridptr->lcc_scanflag  = scanflag;
-      gridptr->lcc_defined   = TRUE;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      double t_begin = 0.0;
+
+      if ( FileInfo ) t_begin = file_time();
+
+      if ( fileptr->type == FILE_TYPE_OPEN )
+	nread = file_read_from_buffer(fileptr, ptr, size);
+      else
+	{
+	  nread = fread(ptr, 1, size, fileptr->fp);
+	  if ( nread != size )
+	    {
+	      if ( nread == 0 )
+		fileptr->flag |= FILE_EOF;
+	      else
+		fileptr->flag |= FILE_ERROR;
+	    }
+	}
+
+      if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
+
+      fileptr->position  += (off_t)nread;
+      fileptr->byteTrans += (off_t)nread;
+      fileptr->access++;
     }
-}
 
-/*
- at Function  gridInqLCC
- at Title     Get the parameter of a Lambert Conformal Conic grid
+  if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
 
- at Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
- at Parameter
-    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  originLon Longitude of the first grid point.
-    @Item  originLat Latitude of the first grid point.
-    @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
-    @Item  lat1      First latitude from the pole at which the secant cone cuts the sphere.
-    @Item  lat2      Second latitude at which the secant cone cuts the sphere.
-    @Item  xinc      X-direction grid lenght in meter.
-    @Item  yinc      Y-direction grid lenght in meter.
-    @Item  projflag  Projection centre flag.
-    @Item  scanflag  Scanning mode flag.
- 
- at Description
-The function @func{gridInqLCC} returns the parameter of a Lambert Conformal Conic grid.
+  return (nread);
+}
 
- at EndFunction
-*/
-void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY,
-                double *lat1, double *lat2, double *xinc, double *yinc,
-                int *projflag, int *scanflag)
+
+size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  size_t nwrite = 0;
+  bfile_t *fileptr;
 
-  if ( gridptr->type != GRID_LCC )
-    Warning("Inquire of LCC grid definition for %s grid not allowed!",
-	    gridNamePtr(gridptr->type));
-  else
+  fileptr = file_to_pointer(fileID);
+
+  if ( fileptr )
     {
-      if ( gridptr->lcc_defined )
+      double t_begin = 0.0;
+
+      /* if ( fileptr->buffer == NULL ) file_set_buffer(fileptr); */
+
+      if ( FileInfo ) t_begin = file_time();
+
+      if ( fileptr->type == FILE_TYPE_FOPEN )
+        nwrite = fwrite(ptr, 1, size, fileptr->fp);
+      else
         {
-          *originLon = gridptr->lcc_originLon;
-          *originLat = gridptr->lcc_originLat;
-          *lonParY   = gridptr->lcc_lonParY;
-          *lat1      = gridptr->lcc_lat1;
-          *lat2      = gridptr->lcc_lat2;
-          *xinc      = gridptr->lcc_xinc;
-          *yinc      = gridptr->lcc_yinc;
-          *projflag  = gridptr->lcc_projflag;
-          *scanflag  = gridptr->lcc_scanflag;
+          ssize_t temp = write(fileptr->fd, ptr, size);
+          if (temp == -1)
+            {
+              perror("error writing to file");
+              nwrite = 0;
+            }
+          else
+            nwrite = (size_t)temp;
         }
-      else
-	Warning("Lambert Conformal grid undefined (gridID = %d)", gridID);
+
+      if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
+
+      fileptr->position  += (off_t)nwrite;
+      fileptr->byteTrans += (off_t)nwrite;
+      fileptr->access++;
     }
+
+  return (nwrite);
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+#include <stdlib.h>
 
-void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2)
+
+#ifndef  M_PI
+#define  M_PI        3.14159265358979323846  /* pi */
+#endif
+
+#ifndef  M_SQRT2
+#define  M_SQRT2     1.41421356237309504880
+#endif
+
+
+static
+void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag, 
+            double *pw, double *pdxn, double *pxmod)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  double zdlk;
+  double zdlldn;
+  double zdlx;
+  double zdlmod;
+  double zdlxn;
 
-  if ( gridptr->type != GRID_LCC2 )
-    Warning("Definition of LCC2 grid for %s grid not allowed!",
-	    gridNamePtr(gridptr->type));
-  else
+  size_t ik, jn;
+
+  /* 1.0 Newton iteration step */
+
+  zdlx = pdx;
+  zdlk = 0.0;
+  if (kodd == 0) 
     {
-      gridptr->lcc2_a       = earth_radius;
-      gridptr->lcc2_lon_0   = lon_0;
-      gridptr->lcc2_lat_0   = lat_0;
-      gridptr->lcc2_lat_1   = lat_1;
-      gridptr->lcc2_lat_2   = lat_2;
-      gridptr->lcc2_defined = TRUE;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      zdlk = 0.5*pfn[0];
     }
-}
-
+  zdlxn  = 0.0;
+  zdlldn = 0.0;
 
-void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0, double *lat_1, double *lat_2)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  ik = 1;
 
-  if ( gridptr->type != GRID_LCC2 )
-    Warning("Inquire of LCC2 grid definition for %s grid not allowed!",
-	    gridNamePtr(gridptr->type));
-  else
+  if (kflag == 0) 
     {
-      if ( gridptr->lcc2_defined )
-        {
-          *earth_radius = gridptr->lcc2_a;
-          *lon_0        = gridptr->lcc2_lon_0;
-          *lat_0        = gridptr->lcc2_lat_0;
-          *lat_1        = gridptr->lcc2_lat_1;
-          *lat_2        = gridptr->lcc2_lat_2;
-        }
-      else
-        Warning("LCC2 grid undefined (gridID = %d)", gridID);
+      for(size_t jn = 2-kodd; jn <= kn; jn += 2) 
+	{
+	  /* normalised ordinary Legendre polynomial == \overbar{p_n}^0 */
+	  zdlk   = zdlk + pfn[ik]*cos((double)(jn)*zdlx);
+	  /* normalised derivative == d/d\theta(\overbar{p_n}^0) */
+	  zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
+	  ik++;
+	}
+      /* Newton method */
+      zdlmod = -(zdlk/zdlldn);
+      zdlxn = zdlx + zdlmod;
+      *pdxn = zdlxn;
+      *pxmod = zdlmod;
     }
-}
 
-void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  /* 2.0 Compute weights */
 
-  if ( gridptr->type != GRID_LAEA )
-    Warning("Definition of LAEA grid for %s grid not allowed!",
-            gridNamePtr(gridptr->type));
-  else
+  if (kflag == 1) 
     {
-      gridptr->laea_a       = earth_radius;
-      gridptr->laea_lon_0   = lon_0;
-      gridptr->laea_lat_0   = lat_0;
-      gridptr->laea_defined = TRUE;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      for(jn = 2-kodd; jn <= kn; jn += 2) 
+	{
+	  /* normalised derivative */
+	  zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
+	  ik++;
+	}
+      *pw = (double)(2*kn+1)/(zdlldn*zdlldn);
     }
-}
 
+  return;
+}
 
-void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
+static
+void gawl(double *pfn, double *pl, double *pw, size_t kn)
 {
-  grid_t* gridptr = gridID2Ptr(gridID);
+  double pmod = 0;
+  int iflag;
+  int itemax;
+  double zw = 0;
+  double zdlx;
+  double zdlxn = 0;
 
-  if ( gridptr->type != GRID_LAEA )
-    Warning("Inquire of LAEA grid definition for %s grid not allowed!",
-            gridNamePtr(gridptr->type));
-  else
+  /* 1.0 Initizialization */
+
+  iflag  =  0;
+  itemax = 20;
+
+  size_t iodd   = (kn % 2);
+
+  zdlx   =  *pl;
+
+  /* 2.0 Newton iteration */
+
+  for (int jter = 1; jter <= itemax+1; jter++)
     {
-      if ( gridptr->laea_defined )
-        {
-          *earth_radius = gridptr->laea_a;
-          *lon_0        = gridptr->laea_lon_0;
-          *lat_0        = gridptr->laea_lat_0;
-        }
-      else
-        Warning("LAEA grid undefined (gridID = %d)", gridID);
+      cpledn(kn, iodd, pfn, zdlx, iflag, &zw, &zdlxn, &pmod);
+      zdlx = zdlxn;
+      if (iflag == 1) break;
+      if (fabs(pmod) <= DBL_EPSILON*1000.0) iflag = 1;
     }
-}
 
+  *pl = zdlxn;
+  *pw = zw;
 
-void gridDefComplexPacking(int gridID, int lcomplex)
+  return;
+}
+
+static
+void gauaw(size_t kn, double *restrict pl, double *restrict pw)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+  /*
+   * 1.0 Initialize Fourier coefficients for ordinary Legendre polynomials
+   *
+   * Belousov, Swarztrauber, and ECHAM use zfn(0,0) = sqrt(2)
+   * IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 (zfn(0,0) = 2.0)
+   */
+  double *zfn, *zfnlat;
 
+  double z, zfnn;
 
-  if (gridptr->lcomplex != lcomplex)
+  zfn    = (double *) malloc((kn+1) * (kn+1) * sizeof(double));
+  zfnlat = (double *) malloc((kn/2+1+1)*sizeof(double));
+
+  zfn[0] = M_SQRT2;
+  for (size_t jn = 1; jn <= kn; jn++)
     {
-      gridptr->lcomplex = lcomplex;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      zfnn = zfn[0];
+      for (size_t jgl = 1; jgl <= jn; jgl++)
+	{
+	  zfnn *= sqrt(1.0-0.25/((double)(jgl*jgl))); 
+	}
+
+      zfn[jn*(kn+1)+jn] = zfnn;
+
+      size_t iodd = jn % 2;
+      for (size_t jgl = 2; jgl <= jn-iodd; jgl += 2) 
+	{
+	  zfn[jn*(kn+1)+jn-jgl] = zfn[jn*(kn+1)+jn-jgl+2]
+	    *((double)((jgl-1)*(2*jn-jgl+2)))/((double)(jgl*(2*jn-jgl+1)));
+	}
     }
-}
 
 
-int gridInqComplexPacking(int gridID)
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
+  /* 2.0 Gaussian latitudes and weights */
+
+  size_t iodd = kn % 2;
+  size_t ik = iodd;
+  for (size_t jgl = iodd; jgl <= kn; jgl += 2)
+    {
+      zfnlat[ik] = zfn[kn*(kn+1)+jgl];
+      ik++;
+    } 
+
+  /*
+   * 2.1 Find first approximation of the roots of the
+   *     Legendre polynomial of degree kn.
+   */
+
+  size_t ins2 = kn/2+(kn % 2);
+
+  for (size_t jgl = 1; jgl <= ins2; jgl++) 
+    {
+      z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2)); 
+      pl[jgl-1] = z+1.0/(tan(z)*((double)(8*kn*kn)));
+    }
 
-  return (gridptr->lcomplex);
-}
+  /* 2.2 Computes roots and weights for transformed theta */
 
+  for (size_t jgl = ins2; jgl >= 1 ; jgl--) 
+    {
+      size_t jglm1 = jgl-1;
+      gawl(zfnlat, &(pl[jglm1]), &(pw[jglm1]), kn);
+    }
 
-void gridDefHasDims(int gridID, int hasdims)
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
+  /* convert to physical latitude */
 
-  if (gridptr->hasdims != hasdims)
+  for (size_t jgl = 0; jgl < ins2; jgl++) 
     {
-      gridptr->hasdims = hasdims;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      pl[jgl] = cos(pl[jgl]);
     }
-}
 
+  for (size_t jgl = 1; jgl <= kn/2; jgl++) 
+    {
+      size_t jglm1 = jgl-1;
+      size_t isym =  kn-jgl;
+      pl[isym] =  -pl[jglm1];
+      pw[isym] =  pw[jglm1];
+    }
 
-int gridInqHasDims(int gridID)
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
+  free(zfnlat);
+  free(zfn);
 
-  return (gridptr->hasdims);
+  return;
 }
 
-/*
- at Function  gridDefNumber
- at Title     Define the reference number for an unstructured grid
+#if 0
+static
+void gauaw_old(double *pa, double *pw, int nlat)
+{
+  /*
+   * Compute Gaussian latitudes.  On return pa contains the
+   * sine of the latitudes starting closest to the north pole and going
+   * toward the south
+   *
+   */
 
- at Prototype void gridDefNumber(int gridID, const int number)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  number   Reference number for an unstructured grid.
+  const int itemax = 20;
 
- at Description
-The function @func{gridDefNumber} defines the reference number for an unstructured grid.
+  int isym, iter, ins2, jn, j;
+  double za, zw, zan;
+  double z, zk, zkm1, zkm2, zx, zxn, zldn, zmod;
 
- at EndFunction
-*/
-void gridDefNumber(int gridID, const int number)
-{
-  grid_t *gridptr = gridID2Ptr(gridID);
+  /*
+   * Perform the Newton loop
+   * Find 0 of Legendre polynomial with Newton loop
+   */
 
-  if (gridptr->number != number)
+  ins2 = nlat/2 + nlat%2;
+
+  for ( j = 0; j < ins2; j++ )
     {
-      gridptr->number = number;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      z = (double) (4*(j+1)-1)*M_PI / (double) (4*nlat+2);
+      pa[j] = cos(z + 1.0/(tan(z)*(double)(8*nlat*nlat)));
     }
-}
-
-/*
- at Function  gridInqNumber
- at Title     Get the reference number to an unstructured grid
 
- at Prototype int gridInqNumber(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+  for ( j = 0; j < ins2; j++ )
+    {
 
- at Description
-The function @func{gridInqNumber} returns the reference number to an unstructured grid.
+      za = pa[j];
 
- at Result
- at func{gridInqNumber} returns the reference number to an unstructured grid.
- at EndFunction
-*/
-int gridInqNumber(int gridID)
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
+      iter = 0;
+      do
+	{
+	  iter++;
+	  zk = 0.0;
 
-  return (gridptr->number);
-}
+	  /* Newton iteration step */
 
-/*
- at Function  gridDefPosition
- at Title     Define the position of grid in the reference file
+	  zkm2 = 1.0;
+	  zkm1 = za;
+	  zx = za;
+	  for ( jn = 2; jn <= nlat; jn++ )
+	    {
+	      zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double)(jn);
+	      zkm2 = zkm1;
+	      zkm1 = zk;
+	    }
+	  zkm1 = zkm2;
+	  zldn = ((double) (nlat)*(zkm1-zx*zk)) / (1.-zx*zx);
+	  zmod = -zk/zldn;
+	  zxn = zx+zmod;
+	  zan = zxn;
 
- at Prototype void gridDefPosition(int gridID, const int position)
- at Parameter
-    @Item  gridID     Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  position   Position of grid in the reference file.
+	  /* computes weight */
 
- at Description
-The function @func{gridDefPosition} defines the position of grid in the reference file.
+	  zkm2 = 1.0;
+	  zkm1 = zxn;
+	  zx = zxn;
+	  for ( jn = 2; jn <= nlat; jn++ )
+	    {
+	      zk = ((double) (2*jn-1)*zx*zkm1-(double)(jn-1)*zkm2) / (double) (jn);
+	      zkm2 = zkm1;
+	      zkm1 = zk;
+	    }
+	  zkm1 = zkm2;
+	  zw = (1.0-zx*zx) / ((double) (nlat*nlat)*zkm1*zkm1);
+	  za = zan;
+	}
+      while ( iter <= itemax && fabs(zmod) >= DBL_EPSILON );
 
- at EndFunction
-*/
-void gridDefPosition(int gridID, int position)
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
+      pa[j] = zan;
+      pw[j] = 2.0*zw;
+    }
 
-  if (gridptr->position != position)
+#if defined (SX)
+#pragma vdir nodep
+#endif
+  for (j = 0; j < nlat/2; j++)
     {
-      gridptr->position = position;
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      isym = nlat-(j+1);
+      pa[isym] = -pa[j];
+      pw[isym] =  pw[j];
     }
-}
-
-/*
- at Function  gridInqPosition
- at Title     Get the position of grid in the reference file
-
- at Prototype int gridInqPosition(int gridID)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
- at Description
-The function @func{gridInqPosition} returns the position of grid in the reference file.
+  return;
+}
+#endif
 
- at Result
- at func{gridInqPosition} returns the position of grid in the reference file.
- at EndFunction
-*/
-int gridInqPosition(int gridID)
+void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
-
-  return (gridptr->position);
+  //gauaw_old(pa, pw, nlat);
+  gauaw(nlat, pa, pw);
 }
 
 /*
- at Function  gridDefReference
- at Title     Define the reference URI for an unstructured grid
-
- at Prototype void gridDefReference(int gridID, const char *reference)
- at Parameter
-    @Item  gridID      Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  reference   Reference URI for an unstructured grid.
-
- at Description
-The function @func{gridDefReference} defines the reference URI for an unstructured grid.
+#define NGL  48
 
- at EndFunction
-*/
-void gridDefReference(int gridID, const char *reference)
+int main (int rgc, char *argv[])
 {
-  grid_t* gridptr = gridID2Ptr(gridID);
+  int ngl = NGL;
+  double plo[NGL], pwo[NGL];
+  double pl[NGL], pw[NGL];
 
-  if ( reference )
-    {
-      if ( gridptr->reference )
-        {
-          free(gridptr->reference);
-          gridptr->reference = NULL;
-        }
+  int i;
 
-      gridptr->reference = strdupx(reference);
-      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+  gauaw(ngl, pl, pw);
+  gauaw_old(plo, pwo, ngl);
+  for (i = 0; i < ngl; i++)
+    {
+      pl[i]  = asin(pl[i])/M_PI*180.0;
+      plo[i] = asin(plo[i])/M_PI*180.0;
     }
-}
-
-/*
- at Function  gridInqReference
- at Title     Get the reference URI to an unstructured grid
-
- at Prototype char *gridInqReference(int gridID, char *reference)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-
- at Description
-The function @func{gridInqReference} returns the reference URI to an unstructured grid.
-
- at Result
- at func{gridInqReference} returns the reference URI to an unstructured grid.
- at EndFunction
-*/
-int gridInqReference(int gridID, char *reference)
-{
-  int len = 0;
-  grid_t* gridptr = gridID2Ptr(gridID);
 
-  if ( gridptr->reference && reference )
+  for (i = 0; i < ngl; i++)
     {
-      strcpy(reference, gridptr->reference);
+      fprintf(stderr, "%4d%25.18f%25.18f%25.18f%25.18f\n", i+1, pl[i], pw[i], pl[i]-plo[i], pw[i]-pwo[i]);
     }
 
-  return (len);
+  return 0;
 }
-
+*/
 /*
- at Function  gridDefUUID
- at Title     Define the UUID for an unstructured grid
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
- at Prototype void gridDefUUID(int gridID, const char *uuid)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  uuid     UUID for an unstructured grid.
+#if  defined  (HAVE_LIBGRIB_API)
+#  include <grib_api.h>
+#endif
 
- at Description
-The function @func{gridDefUUID} defines the UUID for an unstructured grid.
+#include <stdio.h>
 
- at EndFunction
-*/
-void gridDefUUID(int gridID, const unsigned char uuid[CDI_UUID_SIZE])
-{
-  grid_t* gridptr = gridID2Ptr(gridID);
 
-  memcpy(gridptr->uuid, uuid, CDI_UUID_SIZE);
-  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
-}
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
 
-/*
- at Function  gridInqUUID
- at Title     Get the UUID to an unstructured grid
+static char gribapi_libvers[64] = "";
+#if  defined  (HAVE_LIBGRIB_API)
+static int gribapi_libvers_init;
+#endif
 
- at Prototype void gridInqUUID(int gridID, char *uuid)
- at Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
- at Description
-The function @func{gridInqUUID} returns the UUID to an unstructured grid.
+void gribapiLibraryVersion(int* major_version, int* minor_version, int* revision_version)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  long version = grib_get_api_version();
+  (*major_version)    = version/10000;
+  (*minor_version)    = (version-(*major_version)*10000)/100;
+  (*revision_version) = (version-(*major_version)*10000-(*minor_version)*100);
+#else
+  (*major_version)    = 0;
+  (*minor_version)    = 0;
+  (*revision_version) = 0;
+#endif
+}
 
- at Result
- at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
- at EndFunction
-*/
-void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
+const char *gribapiLibraryVersionString(void)
 {
-  grid_t *gridptr = gridID2Ptr(gridID);
+#if  defined  (HAVE_LIBGRIB_API)
+  if (!gribapi_libvers_init)
+    {
+      int major_version, minor_version, revision_version;
 
-  memcpy(uuid, gridptr->uuid, CDI_UUID_SIZE);
-}
+      gribapiLibraryVersion(&major_version, &minor_version, &revision_version);
 
+      sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version);
+      gribapi_libvers_init = 1;
+    }
+#endif
 
-void gridGetIndexList ( int ngrids, int * gridIndexList )
-{
-  reshGetResHListOfType ( ngrids, gridIndexList, &gridOps );
+  return (gribapi_libvers);
 }
 
 
-static int
-gridTxCode ()
+void gribContainersNew(stream_t * streamptr)
 {
-  return GRID;
-}
-
-enum { gridNint    = 27,
-       gridNdouble = 24,
-       gridHasMaskFlag = 1 << 0,
-       gridHasGMEMaskFlag = 1 << 1,
-       gridHasXValsFlag = 1 << 2,
-       gridHasYValsFlag = 1 << 3,
-       gridHasAreaFlag = 1 << 4,
-       gridHasXBoundsFlag = 1 << 5,
-       gridHasYBoundsFlag = 1 << 6,
-       gridHasReferenceFlag = 1 << 7,
-       gridHasRowLonFlag = 1 << 8,
-       gridHasUUIDFlag = 1 << 9,
-};
+  int editionNumber = 2;
 
+  if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
+  (void)editionNumber;
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( streamptr->filetype == FILETYPE_GRB )
+    {
+    }
+  else
+#endif
+    {
+      int nvars = streamptr->nvars;
 
-static int gridGetComponentFlags(const grid_t * gridP)
-{
-  int flags = (gridHasMaskFlag & (int)((unsigned)(gridP->mask == NULL) - 1U))
-    | (gridHasGMEMaskFlag & (int)((unsigned)(gridP->mask_gme == NULL) - 1U))
-    | (gridHasXValsFlag & (int)((unsigned)(gridP->xvals == NULL) - 1U))
-    | (gridHasYValsFlag & (int)((unsigned)(gridP->yvals == NULL) - 1U))
-    | (gridHasAreaFlag & (int)((unsigned)(gridP->area == NULL) - 1U))
-    | (gridHasXBoundsFlag & (int)((unsigned)(gridP->xbounds == NULL) - 1U))
-    | (gridHasYBoundsFlag & (int)((unsigned)(gridP->ybounds == NULL) - 1U))
-    | (gridHasReferenceFlag & (int)((unsigned)(gridP->reference == NULL) - 1U))
-    | (gridHasRowLonFlag & (int)((unsigned)(gridP->rowlon == NULL) - 1U))
-    | (gridHasUUIDFlag & (int)((unsigned)cdiUUIDIsNull(gridP->uuid) - 1U));
-  return flags;
-}
+#if defined (GRIBCONTAINER2D)
+      gribContainer_t **gribContainers;
+      gribContainers = (gribContainer_t **) malloc(nvars*sizeof(gribContainer_t *));
 
+      for ( int varID = 0; varID < nvars; ++varID )
+        {
+          int nlevs = streamptr->vars[varID].nlevs;
+          gribContainers[varID] = (gribContainer_t *) malloc(nlevs*sizeof(gribContainer_t));
 
-#define GRID_STR_SERIALIZE { gridP->xname, gridP->yname, \
-    gridP->xlongname, gridP->ylongname, \
-    gridP->xstdname, gridP->ystdname, \
-    gridP->xunits, gridP->yunits }
+          for ( int levelID = 0; levelID < nlevs; ++levelID )
+            {
+              gribContainers[varID][levelID].gribHandle = gribHandleNew(editionNumber);
+              gribContainers[varID][levelID].init = FALSE;
+            }
+	}
 
-static int
-gridGetPackSize(void * voidP, void *context)
-{
-  grid_t * gridP = ( grid_t * ) voidP;
-  int packBuffSize = 0, count;
+      streamptr->gribContainers = (void **) gribContainers;
+#else
+      gribContainer_t *gribContainers
+        = (gribContainer_t *)xmalloc((size_t)nvars*sizeof(gribContainer_t));
 
-  packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_UINT32, context);
+      for ( int varID = 0; varID < nvars; ++varID )
+        {
+          gribContainers[varID].gribHandle = gribHandleNew(editionNumber);
+          gribContainers[varID].init = FALSE;
+	}
 
-  if (gridP->rowlon)
-    {
-      xassert(gridP->nrowlon);
-      packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
-        + serializeGetSize( 1, DATATYPE_UINT32, context);
+      streamptr->gribContainers = (void *) gribContainers;
+#endif
     }
+}
 
-  packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
 
-  if (gridP->xvals)
+void gribContainersDelete(stream_t * streamptr)
+{
+  if ( streamptr->gribContainers )
     {
-      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
-	count = gridP->size;
-      else
-	count = gridP->xsize;
-      xassert(count);
-      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+      int nvars = streamptr->nvars;
 
-  if (gridP->yvals)
-    {
-      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
-	count = gridP->size;
-      else
-	count = gridP->ysize;
-      xassert(count);
-      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+#if defined (GRIBCONTAINER2D)
+      gribContainer_t **gribContainers = (gribContainer_t **) streamptr->gribContainers;
 
-  if (gridP->area)
-    {
-      xassert(gridP->size);
-      packBuffSize +=
-        serializeGetSize(gridP->size, DATATYPE_FLT64, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+      for ( int varID = 0; varID < nvars; ++varID )
+	{
+          int nlevs = streamptr->vars[varID].nlevs;
+          for ( int levelID = 0; levelID < nlevs; ++levelID )
+            {
+              gribHandleDelete(gribContainers[varID][levelID].gribHandle);
+            }
+          free(gribContainers[varID]);
+	}
+#else
+      gribContainer_t *gribContainers = (gribContainer_t *) streamptr->gribContainers;
 
-  if (gridP->xbounds)
-    {
-      xassert(gridP->nvertex);
-      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
-	count = gridP->size;
-      else
-	count = gridP->xsize;
-      xassert(count);
-      packBuffSize
-        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
-            + serializeGetSize(1, DATATYPE_UINT32, context));
+      for ( int varID = 0; varID < nvars; ++varID )
+	{
+          gribHandleDelete(gribContainers[varID].gribHandle);
+	}
+#endif
+
+      free(gribContainers);
+
+      streamptr->gribContainers = NULL;
     }
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _GRID_H
+#define _GRID_H
+
+#ifndef RESOURCE_HANDLE_H
+#endif
+
+typedef unsigned char mask_t;
+
+typedef struct {
+  int     self;
+  int     type;                   /* grid type                      */
+  int     prec;                   /* grid precision                 */
+  int     proj;                   /* grid projection                */
+  mask_t *mask;
+  mask_t *mask_gme;
+  double *xvals;
+  double *yvals;
+  double *area;
+  double *xbounds;
+  double *ybounds;
+  double  xfirst, yfirst;
+  double  xlast, ylast;
+  double  xinc, yinc;
+  double  lcc_originLon;          /* Lambert Conformal Conic        */
+  double  lcc_originLat;
+  double  lcc_lonParY;
+  double  lcc_lat1;
+  double  lcc_lat2;
+  double  lcc_xinc;
+  double  lcc_yinc;
+  int     lcc_projflag;
+  int     lcc_scanflag;
+  int     lcc_defined;
+  double  lcc2_lon_0;             /* Lambert Conformal Conic 2      */
+  double  lcc2_lat_0;
+  double  lcc2_lat_1;
+  double  lcc2_lat_2;
+  double  lcc2_a;
+  int     lcc2_defined;
+  double  laea_lon_0;             /* Lambert Azimuthal Equal Area   */
+  double  laea_lat_0;
+  double  laea_a;
+  int     laea_defined;
+  double  xpole, ypole, angle;    /* rotated north pole             */
+  int     isCyclic;               /* TRUE for global cyclic grids   */
+  int     isRotated;              /* TRUE for rotated grids         */
+  int     xdef;                   /* 0: undefined 1:xvals 2:x0+xinc */
+  int     ydef;                   /* 0: undefined 1:yvals 2:y0+yinc */
+  int     nd, ni, ni2, ni3;       /* parameter for GRID_GME         */
+  int     number, position;       /* parameter for GRID_REFERENCE   */
+  char   *reference;
+  unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference        */
+  int     trunc;                  /* parameter for GRID_SPECTEAL    */
+  int     nvertex;
+  int    *rowlon;
+  int     nrowlon;
+  int     size;
+  int     xsize;                  /* number of values along X */
+  int     ysize;                  /* number of values along Y */
+  int     np;                     /* number of parallels between a pole and the equator */
+  int     locked;
+  int     lcomplex;
+  int     hasdims;
+  char    xname[CDI_MAX_NAME];
+  char    yname[CDI_MAX_NAME];
+  char    xlongname[CDI_MAX_NAME];
+  char    ylongname[CDI_MAX_NAME];
+  char    xstdname[CDI_MAX_NAME];
+  char    ystdname[CDI_MAX_NAME];
+  char    xunits[CDI_MAX_NAME];
+  char    yunits[CDI_MAX_NAME];
+  char   *name;
+}
+grid_t;
 
-  if (gridP->ybounds)
-    {
-      xassert(gridP->nvertex);
-      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
-	count = gridP->size;
-      else
-	count = gridP->ysize;
-      xassert(count);
-      packBuffSize
-        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
-            + serializeGetSize(1, DATATYPE_UINT32, context));
-    }
 
-  {
-    const char *strTab[] = GRID_STR_SERIALIZE;
-    int numStr = (int)(sizeof (strTab) / sizeof (strTab[0]));
-    packBuffSize
-      += serializeStrTabGetPackSize(strTab, numStr, context);
-  }
+void grid_init(grid_t *gridptr);
+void grid_free(grid_t *gridptr);
 
-  if (gridP->reference)
-    {
-      size_t len = strlen(gridP->reference);
-      packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
-        + serializeGetSize((int)len + 1, DATATYPE_TXT, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+unsigned cdiGridCount(void);
 
-  if (gridP->mask)
-    {
-      xassert(gridP->size);
-      packBuffSize
-        += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+const double *gridInqXvalsPtr(int gridID);
+const double *gridInqYvalsPtr(int gridID);
 
-  if (gridP->mask_gme)
-    {
-      xassert(gridP->size);
-      packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
-    }
+const double *gridInqXboundsPtr(int gridID);
+const double *gridInqYboundsPtr(int gridID);
+const double *gridInqAreaPtr(int gridID);
 
-  if (!cdiUUIDIsNull(gridP->uuid))
-    packBuffSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+int gridCompare(int gridID, const grid_t *grid);
+int gridGenerate(const grid_t *grid);
 
-  return packBuffSize;
-}
+void cdiGridGetIndexList(unsigned, int * );
 
 void
 gridUnpack(char * unpackBuffer, int unpackBufferSize,
            int * unpackBufferPos, int originNamespace, void *context,
-           int force_id)
-{
-  grid_t * gridP;
-  uint32_t d;
-  int memberMask, size;
+           int force_id);
 
-  gridInit();
+extern const resOps gridOps;
 
-  {
-    int intBuffer[gridNint];
-    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    intBuffer, gridNint, DATATYPE_INT, context);
-    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, DATATYPE_UINT32, context);
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+#define INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
 
-    xassert(cdiCheckSum(DATATYPE_INT, gridNint, intBuffer) == d);
-    int targetID = namespaceAdaptKey(intBuffer[0], originNamespace);
-    gridP = gridNewEntry(force_id?targetID:CDI_UNDEFID);
+#ifdef HAVE_LIBGRIB_API
 
-    xassert(!force_id || targetID == gridP->self);
 
-    gridP->type          =   intBuffer[1];
-    gridP->prec          =   intBuffer[2];
-    gridP->lcc_projflag  =   intBuffer[3];
-    gridP->lcc_scanflag  =   intBuffer[4];
-    gridP->lcc_defined   =   intBuffer[5];
-    gridP->lcc2_defined  =   intBuffer[6];
-    gridP->laea_defined  =   intBuffer[7];
-    gridP->isCyclic      =   intBuffer[8];
-    gridP->isRotated     =   intBuffer[9];
-    gridP->xdef          =   intBuffer[10];
-    gridP->ydef          =   intBuffer[11];
-    gridP->nd            =   intBuffer[12];
-    gridP->ni            =   intBuffer[13];
-    gridP->ni2           =   intBuffer[14];
-    gridP->ni3           =   intBuffer[15];
-    gridP->number        =   intBuffer[16];
-    gridP->position      =   intBuffer[17];
-    gridP->trunc         =   intBuffer[18];
-    gridP->nvertex       =   intBuffer[19];
-    gridP->nrowlon       =   intBuffer[20];
-    gridP->size          =   intBuffer[21];
-    gridP->xsize         =   intBuffer[22];
-    gridP->ysize         =   intBuffer[23];
-    gridP->locked        =   intBuffer[24];
-    gridP->lcomplex      =   intBuffer[25];
-    memberMask           =   intBuffer[26];
-  }
+#include <grib_api.h>
 
-  if (memberMask & gridHasRowLonFlag)
-    {
-      xassert(gridP->nrowlon);
-      gridP->rowlon = (int *)xmalloc((size_t)gridP->nrowlon * sizeof (int));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
-    }
+#include <stdbool.h>
 
-  {
-    double doubleBuffer[gridNdouble];
-    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
-    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, DATATYPE_UINT32, context);
-    xassert(d == cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer));
+char* gribCopyString(grib_handle* gribHandle, const char* key);
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue);
 
-    gridP->xfirst = doubleBuffer[0];
-    gridP->yfirst = doubleBuffer[1];
-    gridP->xlast = doubleBuffer[2];
-    gridP->ylast = doubleBuffer[3];
-    gridP->xinc = doubleBuffer[4];
-    gridP->yinc = doubleBuffer[5];
-    gridP->lcc_originLon = doubleBuffer[6];
-    gridP->lcc_originLat = doubleBuffer[7];
-    gridP->lcc_lonParY = doubleBuffer[8];
-    gridP->lcc_lat1 = doubleBuffer[9];
-    gridP->lcc_lat2 = doubleBuffer[10];
-    gridP->lcc_xinc = doubleBuffer[11];
-    gridP->lcc_yinc = doubleBuffer[12];
-    gridP->lcc2_lon_0 = doubleBuffer[13];
-    gridP->lcc2_lat_0 = doubleBuffer[14];
-    gridP->lcc2_lat_1 = doubleBuffer[15];
-    gridP->lcc2_lat_2 = doubleBuffer[16];
-    gridP->lcc2_a = doubleBuffer[17];
-    gridP->laea_lon_0 = doubleBuffer[18];
-    gridP->laea_lat_0 = doubleBuffer[19];
-    gridP->laea_a = doubleBuffer[20];
-    gridP->xpole = doubleBuffer[21];
-    gridP->ypole = doubleBuffer[22];
-    gridP->angle = doubleBuffer[23];
-  }
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue);
+long gribGetLong(grib_handle* gh, const char* key);
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue);
 
-  int irregular = gridP->type == GRID_UNSTRUCTURED
-    || gridP->type == GRID_CURVILINEAR;
-  if (memberMask & gridHasXValsFlag)
-    {
-      size = irregular ? gridP->size : gridP->xsize;
+double gribGetDouble(grib_handle* gh, const char* key);
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue);
 
-      gridP->xvals = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->xvals, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
-    }
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key);
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array);       //The caller is responsible to ensure a sufficiently large buffer.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array);   //The caller is responsible to ensure a sufficiently large buffer.
 
-  if (memberMask & gridHasYValsFlag)
-    {
-      size = irregular ? gridP->size : gridP->ysize;
+long gribEditionNumber(grib_handle* gh);
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime);     //For statistical fields, setting getEndTime produces the time of the end of the integration period, otherwise the time of the start of the integration period is returned. Returns NULL if getEndTime is set and the field does not have an integration period.
+int gribapiTimeIsFC(grib_handle *gh);
+int gribapiGetTsteptype(grib_handle *gh);
+int gribGetDatatype(grib_handle* gribHandle);
+int gribapiGetParam(grib_handle *gh);
+int gribapiGetGridType(grib_handle *gh);
+void gribapiGetGrid(grib_handle *gh, grid_t *grid);
 
-      gridP->yvals = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->yvals, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
-    }
+#endif
 
-  if (memberMask & gridHasAreaFlag)
-    {
-      size = gridP->size;
-      xassert(size);
-      gridP->area = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->area, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
-    }
+#endif
+#ifndef INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
+#define INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
 
-  if (memberMask & gridHasXBoundsFlag)
-    {
-      size = gridP->nvertex * (irregular ? gridP->size : gridP->xsize);
-      xassert(size);
+char* myStrDup(const char* string);      //This exactly implements the standardized behavior of strdup().
 
-      gridP->xbounds = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->xbounds, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
-    }
+char* myAsprintf(char* format, ...) __attribute__((format(printf, 1, 2)));       //This implementation differs from standard asprintf() function in the way the resulting string pointer is returned.
 
-  if (memberMask & gridHasYBoundsFlag)
-    {
-      size = gridP->nvertex * (irregular ? gridP->size : gridP->ysize);
-      xassert(size);
+#endif
+#if defined (HAVE_CONFIG_H)
+#endif
 
-      gridP->ybounds = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-			  gridP->ybounds, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
-    }
+static int dummy;
 
-  {
-    char *strTab[] = GRID_STR_SERIALIZE;
-    int numStr = sizeof (strTab) / sizeof (strTab[0]);
-    serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                          strTab, numStr, context);
-  }
+#ifdef HAVE_LIBGRIB_API
 
-  if (memberMask & gridHasReferenceFlag)
-    {
-      int referenceSize;
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &referenceSize, 1, DATATYPE_INT, context);
-      gridP->reference = (char *)xmalloc((size_t)referenceSize);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->reference, referenceSize, DATATYPE_TXT, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
-    }
 
-  if (memberMask & gridHasMaskFlag)
-    {
-      xassert((size = gridP->size));
-      gridP->mask = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->mask, gridP->size, DATATYPE_UCHAR, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
-    }
 
-  if (memberMask & gridHasGMEMaskFlag)
-    {
-      xassert((size = gridP->size));
-      gridP->mask_gme = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
-    }
-  if (memberMask & gridHasUUIDFlag)
-    {
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
-    }
+#include <assert.h>
+#include <time.h>
+
+#define FAIL_ON_GRIB_ERROR(function, gribHandle, key, ...) do\
+{\
+  int errorCode = function(gribHandle, key, __VA_ARGS__);\
+  if(errorCode)\
+    {\
+      fprintf(stderr, "%s:%d: Error in function `%s`: `%s` returned error code %d for key \"%s\"", __FILE__, __LINE__, __func__, #function, errorCode, key);\
+      exit(errorCode);\
+    }\
+} while(0)
+
+//A simple wrapper for grib_get_string() that returns a newly allocated string.
+char* gribCopyString(grib_handle* gribHandle, const char* key)
+{
+  size_t length;
+  if(grib_get_length(gribHandle, key, &length)) return NULL;
+  char* result = xmalloc(length);
+  if(!grib_get_string(gribHandle, key, result, &length)) return result;
+  free(result);
+  return NULL;
 }
 
+//A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
+//Returns true if the key exists and the value is equal to the given string.
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue)
+{
+  size_t expectedLength = strlen(expectedValue) + 1, length;
+  if(grib_get_length(gribHandle, key, &length)) return false;
+  if(length != expectedLength) return false;
+  char value[length];
+  if(grib_get_string(gribHandle, key, value, &length)) return false;
+  return !strcmp(value, expectedValue);
+}
 
-static void
-gridPack(void * voidP, void * packBuffer, int packBufferSize,
-         int * packBufferPos, void *context)
+//A simple wrapper for grib_get_long() for the usecase that the result is only compared to a given constant value.
+//Returns true if the key exists and the value is equal to the given one.
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue)
 {
-  grid_t   * gridP = ( grid_t * )   voidP;
-  int size;
-  uint32_t d;
-  int memberMask;
+  long value;
+  if(grib_get_long(gribHandle, key, &value)) return false;
+  return value == expectedValue;
+}
 
-  {
-    int intBuffer[gridNint];
+//A simple wrapper for grib_get_long() for the usecase that failure to fetch the value is fatal.
+long gribGetLong(grib_handle* gh, const char* key)
+{
+  long result;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, key, &result);
+  return result;
+}
 
-    intBuffer[0]  = gridP->self;
-    intBuffer[1]  = gridP->type;
-    intBuffer[2]  = gridP->prec;
-    intBuffer[3]  = gridP->lcc_projflag;
-    intBuffer[4]  = gridP->lcc_scanflag;
-    intBuffer[5]  = gridP->lcc_defined;
-    intBuffer[6]  = gridP->lcc2_defined;
-    intBuffer[7]  = gridP->laea_defined;
-    intBuffer[8]  = gridP->isCyclic;
-    intBuffer[9]  = gridP->isRotated;
-    intBuffer[10] = gridP->xdef;
-    intBuffer[11] = gridP->ydef;
-    intBuffer[12] = gridP->nd;
-    intBuffer[13] = gridP->ni;
-    intBuffer[14] = gridP->ni2;
-    intBuffer[15] = gridP->ni3;
-    intBuffer[16] = gridP->number;
-    intBuffer[17] = gridP->position;
-    intBuffer[18] = gridP->trunc;
-    intBuffer[19] = gridP->nvertex;
-    intBuffer[20] = gridP->nrowlon;
-    intBuffer[21] = gridP->size;
-    intBuffer[22] = gridP->xsize;
-    intBuffer[23] = gridP->ysize;
-    intBuffer[24] = gridP->locked;
-    intBuffer[25] = gridP->lcomplex;
-    intBuffer[26] = memberMask = gridGetComponentFlags(gridP);
+//A simple wrapper for grib_get_long() for the usecase that a default value is used in the case that the operation fails.
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
+{
+  long result;
+  if(grib_get_long(gribHandle, key, &result)) return defaultValue;
+  if(result == GRIB_MISSING_LONG) return defaultValue;
+  return result;
+}
 
-    serializePack(intBuffer, gridNint, DATATYPE_INT,
-                  packBuffer, packBufferSize, packBufferPos, context);
-    d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
-    serializePack(&d, 1, DATATYPE_UINT32,
-                  packBuffer, packBufferSize, packBufferPos, context);
-  }
+//A simple wrapper for grib_get_double() for the usecase that failure to fetch the value is fatal.
+double gribGetDouble(grib_handle* gh, const char* key)
+{
+  double result;
+  FAIL_ON_GRIB_ERROR(grib_get_double, gh, key, &result);
+  return result;
+}
 
-  if (memberMask & gridHasRowLonFlag)
-    {
-      size = gridP->nrowlon;
-      xassert(size > 0);
-      serializePack(gridP->rowlon, size, DATATYPE_INT,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+//A sample wrapper for grib_get_double() for the usecase that a default value is used in the case that the operation fails.
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
+{
+  double result;
+  if(grib_get_double(gribHandle, key, &result)) return defaultValue;
+  if(IS_EQUAL(result, GRIB_MISSING_DOUBLE)) return defaultValue;
+  return result;
+}
 
-  {
-    double doubleBuffer[gridNdouble];
+//A simple wrapper for grib_get_size() for the usecase that failure to fetch the value is fatal.
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key)
+{
+  size_t result;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gribHandle, key, &result);
+  return result;
+}
 
-    doubleBuffer[0]  = gridP->xfirst;
-    doubleBuffer[1]  = gridP->yfirst;
-    doubleBuffer[2]  = gridP->xlast;
-    doubleBuffer[3]  = gridP->ylast;
-    doubleBuffer[4]  = gridP->xinc;
-    doubleBuffer[5]  = gridP->yinc;
-    doubleBuffer[6]  = gridP->lcc_originLon;
-    doubleBuffer[7]  = gridP->lcc_originLat;
-    doubleBuffer[8]  = gridP->lcc_lonParY;
-    doubleBuffer[9]  = gridP->lcc_lat1;
-    doubleBuffer[10] = gridP->lcc_lat2;
-    doubleBuffer[11] = gridP->lcc_xinc;
-    doubleBuffer[12] = gridP->lcc_yinc;
-    doubleBuffer[13] = gridP->lcc2_lon_0;
-    doubleBuffer[14] = gridP->lcc2_lat_0;
-    doubleBuffer[15] = gridP->lcc2_lat_1;
-    doubleBuffer[16] = gridP->lcc2_lat_2;
-    doubleBuffer[17] = gridP->lcc2_a;
-    doubleBuffer[18] = gridP->laea_lon_0;
-    doubleBuffer[19] = gridP->laea_lat_0;
-    doubleBuffer[20] = gridP->laea_a;
-    doubleBuffer[21] = gridP->xpole;
-    doubleBuffer[22] = gridP->ypole;
-    doubleBuffer[23] = gridP->angle;
+//A simple wrapper for grib_get_double_array() for the usecase that failure to fetch the data is fatal.
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_double_array, gribHandle, key, array, &valueCount);
+}
 
-    serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
-                  packBuffer, packBufferSize, packBufferPos, context);
-    d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
-    serializePack(&d, 1, DATATYPE_UINT32,
-                  packBuffer, packBufferSize, packBufferPos, context);
-  }
+//A simple wrapper for grib_get_long_array() for the usecase that failure to fetch the data is fatal.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_long_array, gribHandle, key, array, &valueCount);
+}
 
-  if (memberMask & gridHasXValsFlag)
-    {
-      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
-	size = gridP->size;
-      else
-	size = gridP->xsize;
-      xassert(size);
 
-      serializePack(gridP->xvals, size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xvals);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+//We need the edition number so frequently, that it's convenient to give it its own function.
+long gribEditionNumber(grib_handle* gh)
+{
+  return gribGetLong(gh, "editionNumber");
+}
 
-  if (memberMask & gridHasYValsFlag)
+//This return value of this should be passed to a call to resetTz(), it is a malloc'ed string with the content of the TZ environment variable before the call (or NULL if that was not set).
+static char* setUtc()
+{
+  char* temp = getenv("TZ"), *result = NULL;
+  if(temp) result = myStrDup(temp);
+  setenv("TZ", "UTC", 1);
+  return result;
+}
+
+//Undoes the effect of setUtc(), pass to it the return value of the corresponding setUtc() call, it will free the string.
+static void resetTz(char* savedTz)
+{
+  if(savedTz)
     {
-      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR )
-	size = gridP->size;
-      else
-	size = gridP->ysize;
-      xassert(size);
-      serializePack(gridP->yvals, size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, size, gridP->yvals);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
+      setenv("TZ", savedTz, 1);
+      free(savedTz);
     }
-
-  if (memberMask & gridHasAreaFlag)
+  else
     {
-      xassert(gridP->size);
-
-      serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
+      unsetenv("TZ");
     }
+}
 
-  if (memberMask & gridHasXBoundsFlag)
-    {
-      xassert ( gridP->nvertex );
-      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
-	size = gridP->nvertex * gridP->size;
-      else
-	size = gridP->nvertex * gridP->xsize;
-      xassert ( size );
+//This function uses the system functions to normalize the date representation according to the gregorian calendar.
+//Returns zero on success.
+static int normalizeDays(struct tm* me)
+{
+  char* savedTz = setUtc();     //Ensure that mktime() does not interprete the date according to our local time zone.
 
-      serializePack(gridP->xbounds, size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+  int result = mktime(me) == (time_t)-1;        //This does all the heavy lifting.
 
-  if (memberMask & gridHasYBoundsFlag)
-    {
-      xassert(gridP->nvertex);
-      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
-	size = gridP->nvertex * gridP->size;
-      else
-	size = gridP->nvertex * gridP->ysize;
-      xassert ( size );
+  resetTz(savedTz);
+  return result;
+}
 
-      serializePack(gridP->ybounds, size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+//Returns zero on success.
+static int addSecondsToDate(struct tm* me, long long amount)
+{
+  //It is irrelevant here whether days are zero or one based, the correction would have be undone again so that it is effectless.
+  long long seconds = ((me->tm_mday*24ll + me->tm_hour)*60 + me->tm_min)*60 + me->tm_sec;    //The portion of the date that uses fixed increments.
+  seconds += amount;
+  me->tm_mday = seconds/24/60/60;
+  seconds -= me->tm_mday*24*60*60;
+  me->tm_hour = seconds/60/60;
+  seconds -= me->tm_hour*60*60;
+  me->tm_min = seconds/60;
+  seconds -= me->tm_min*60;
+  me->tm_sec = seconds;
+  return normalizeDays(me);
+}
 
-  {
-    const char *strTab[] = GRID_STR_SERIALIZE;
-    int numStr = sizeof (strTab) / sizeof (strTab[0]);
-    serializeStrTabPack(strTab, numStr,
-                        packBuffer, packBufferSize, packBufferPos, context);
-  }
+static void addMonthsToDate(struct tm* me, long long amount)
+{
+  long long months = me->tm_year*12ll + me->tm_mon;
+  months += amount;
+  me->tm_year = months/12;
+  months -= me->tm_year*12;
+  me->tm_mon = months;
+}
 
-  if (memberMask & gridHasReferenceFlag)
+//unit is a value according to code table 4.4 of the GRIB2 specification, returns non-zero on error
+static int addToDate(struct tm* me, long long amount, long unit)
+{
+  switch(unit)
     {
-      size = (int)strlen(gridP->reference) + 1;
-      serializePack(&size, 1, DATATYPE_INT,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      serializePack(gridP->reference, size, DATATYPE_TXT,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+      case 0: return addSecondsToDate(me,       60*amount);   // minute
+      case 1: return addSecondsToDate(me,    60*60*amount);   // hour
+      case 2: return addSecondsToDate(me, 24*60*60*amount);   // day
 
-  if (memberMask & gridHasMaskFlag)
-    {
-      xassert((size = gridP->size));
-      serializePack(gridP->mask, size, DATATYPE_UCHAR,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+      case 3: addMonthsToDate(me,        amount); return 0;   // month
+      case 4: addMonthsToDate(me,     12*amount); return 0;   // year
+      case 5: addMonthsToDate(me,  10*12*amount); return 0;   // decade
+      case 6: addMonthsToDate(me,  30*12*amount); return 0;   // normal
+      case 7: addMonthsToDate(me, 100*12*amount); return 0;   // century
 
-  if (memberMask & gridHasGMEMaskFlag)
-    {
-      xassert((size = gridP->size));
+      case 10: return addSecondsToDate(me,  3*60*60*amount);  // eighth of a day
+      case 11: return addSecondsToDate(me,  6*60*60*amount);  // quarter day
+      case 12: return addSecondsToDate(me, 12*60*60*amount);  // half day
+      case 13: return addSecondsToDate(me,          amount);  // second
 
-      serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
+      default: return 1;        //reserved, unknown, or missing
     }
+}
 
-  if (memberMask & gridHasUUIDFlag)
-    serializePack(gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
-                  packBuffer, packBufferSize, packBufferPos, context);
+static char* makeDateString(struct tm* me)
+{
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec);
 }
 
-#undef GRID_STR_SERIALIZE
+//FIXME: This ignores any calendar definition that might be present.
+//XXX: Identification templates are not implemented in grib_api-1.12.3, so even if I implemented the other calendars now, it wouldn't be possible to use them.
+static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecastTime, bool* outHaveTimeRange)
+{
+  switch(gribGetLong(gh, "productDefinitionTemplateNumber"))
+    {
+      case 20: case 30: case 31: case 254: case 311: case 2000:
+        *outHaveForecastTime = false, *outHaveTimeRange = false;
+        return 0;
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 60: case 1000: case 1002: case 1100: case 40033:
+        *outHaveForecastTime = true, *outHaveTimeRange = false;
+        return 0;
 
-#include <string.h>
-#include <math.h>
-#include <float.h>
+      case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 34: case 42: case 43: case 46: case 47: case 61: case 91: case 1001: case 1101: case 40034:
+        *outHaveForecastTime = true, *outHaveTimeRange = true;
+        return 0;
 
+      default:
+        return 1;
+    }
+}
 
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime)
+{
+  //Get the parts of the reference date.
+  struct tm date = {
+      .tm_mon = gribGetLong(gh, "month") - 1,   //months are zero based in struct tm and one based in GRIB
+      .tm_mday = gribGetLong(gh, "day"),
+      .tm_hour = gribGetLong(gh, "hour"),
+      .tm_min = gribGetLong(gh, "minute")
+  };
+  if(gribEditionNumber(gh) == 1)
+    {
+      date.tm_year = gribGetLong(gh, "yearOfCentury");  //years are -1900 based both in struct tm and GRIB1
+    }
+  else
+    {
+      date.tm_year = gribGetLong(gh, "year") - 1900;   //years are -1900 based in struct tm and zero based in GRIB2
+      date.tm_sec = gribGetLong(gh, "second");
 
-#define  LevelUp    1
-#define  LevelDown  2
+      //Determine whether we have a forecast time and a time range.
+      bool haveForecastTime, haveTimeRange;
+      if(getAvailabilityOfRelativeTimes(gh, &haveForecastTime, &haveTimeRange)) return NULL;
+      if(getEndTime && !haveTimeRange) return NULL;     //tell the caller that the requested time does not exist
 
+      //If we have relative times, apply them to the date
+      if(haveForecastTime)
+        {
+          long offset = gribGetLongDefault(gh, "forecastTime", 0);  //if(stepUnits == indicatorOfUnitOfTimeRange) assert(startStep == forecastTime)
+          long offsetUnit = gribGetLongDefault(gh, "indicatorOfUnitOfTimeRange", 255);
+          if(addToDate(&date, offset, offsetUnit)) return NULL;
+          if(getEndTime)
+            {
+              assert(haveTimeRange);
+              long range = gribGetLongDefault(gh, "lengthOfTimeRange", 0);       //if(stepUnits == indicatorOfUnitForTimeRange) assert(endStep == startStep + lengthOfTimeRange)
+              long rangeUnit = gribGetLongDefault(gh, "indicatorOfUnitForTimeRange", 255);
+              if(addToDate(&date, range, rangeUnit)) return NULL;
+            }
+        }
+    }
 
-static const struct {
-  unsigned char positive;   // 1: up;  2: down
-  char *name;
-  char *longname;
-  char *stdname;
-  char *units;
+  //Bake the date into a string.
+  return makeDateString(&date);
 }
-ZaxistypeEntry[] = {
-  { /*  0 */ 0, "sfc",               "surface",                "",               ""},
-  { /*  1 */ 0, "lev",               "generic",                "",               "level"},
-  { /*  2 */ 2, "lev",               "hybrid",                 "",               "level"},
-  { /*  3 */ 2, "lev",               "hybrid_half",            "",               "level"},
-  { /*  4 */ 2, "lev",               "pressure",               "air_pressure",   "Pa"},
-  { /*  5 */ 1, "height",            "height",                 "height",         "m"},
-  { /*  6 */ 2, "depth",             "depth_below_sea",        "depth",          "m"},
-  { /*  7 */ 2, "depth",             "depth_below_land",       "",               "cm"},
-  { /*  8 */ 0, "lev",               "isentropic",             "",               "K"},
-  { /*  9 */ 0, "lev",               "trajectory",             "",               ""},
-  { /* 10 */ 1, "alt",               "altitude",               "",               "m"},
-  { /* 11 */ 0, "lev",               "sigma",                  "",               "level"},
-  { /* 12 */ 0, "lev",               "meansea",                "",               "level"},
-  { /* 13 */ 0, "toa",               "top_of_atmosphere",      "",               ""},
-  { /* 14 */ 0, "seabottom",         "sea_bottom",             "",               ""},
-  { /* 15 */ 0, "atmosphere",        "atmosphere",             "",               ""},
-  { /* 16 */ 0, "cloudbase",         "cloud_base",             "",               ""},
-  { /* 17 */ 0, "cloudtop",          "cloud_top",              "",               ""},
-  { /* 18 */ 0, "isotherm0",         "isotherm_zero",          "",               ""},
-  { /* 19 */ 0, "snow",              "snow",                   "",               ""},
-  { /* 20 */ 0, "lakebottom",        "lake_bottom",            "",               ""},
-  { /* 21 */ 0, "sedimentbottom",    "sediment_bottom",        "",               ""},
-  { /* 22 */ 0, "sedimentbottomta",  "sediment_bottom_ta",     "",               ""},
-  { /* 23 */ 0, "sedimentbottomtw",  "sediment_bottom_tw",     "",               ""},
-  { /* 24 */ 0, "mixlayer",          "mix_layer",              "",               ""},
-  { /* 25 */ 0, "height",            "generalized height",     "height",         ""},
-};
-
-enum {
-  CDI_NumZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]),
-};
 
+int gribapiTimeIsFC(grib_handle *gh)
+{
+  if(gribEditionNumber(gh) <= 1) return true;
 
-typedef struct {
-  unsigned char positive;
-  char     name[CDI_MAX_NAME];
-  char     longname[CDI_MAX_NAME];
-  char     stdname[CDI_MAX_NAME];
-  char     units[CDI_MAX_NAME];
-  double  *vals;
-  double  *lbounds;
-  double  *ubounds;
-  double  *weights;
-  int      self;
-  int      prec;
-  int      type;
-  int      ltype;    /* GRIB level type */
-  int      ltype2;
-  int      size;
-  int      direction;
-  int      vctsize;
-  double  *vct;
-  int      number;   /* Reference number to a generalized Z-axis */
-  int      nhlev;
-  unsigned char uuid[CDI_UUID_SIZE];
+  long sigofrtime;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
+  return sigofrtime != 3;
 }
-zaxis_t;
 
-static int zaxisCompareP(zaxis_t *z1, zaxis_t *z2);
-static void   zaxisDestroyP    ( void * zaxisptr );
-static void   zaxisPrintP      ( void * zaxisptr, FILE * fp );
-static int    zaxisGetPackSize ( void * zaxisptr, void *context);
-static void   zaxisPack        ( void * zaxisptr, void * buffer, int size, int *pos, void *context);
-static int    zaxisTxCode      ( void );
+//Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
+int gribapiGetTsteptype(grib_handle *gh)
+{
+  int tsteptype = TSTEP_INSTANT;
+  static bool lprint = true;
 
-static const resOps zaxisOps = {
-  (int (*)(void *, void *))zaxisCompareP,
-  zaxisDestroyP,
-  zaxisPrintP,
-  zaxisGetPackSize,
-  zaxisPack,
-  zaxisTxCode
-};
+  if ( gribapiTimeIsFC(gh) )
+    {
+      int status;
+      size_t len = 256;
+      char stepType[256];
 
-static int  ZAXIS_Debug = 0;   /* If set to 1, debugging */
+      status = grib_get_string(gh, "stepType", stepType, &len);
+      if ( status == 0 && len > 1 && len < 256 )
+        {
+          if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
+          else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
+          else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
+          else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
+          else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
+          else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
+          else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
+          else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
+          else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
+          else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
+          else if ( lprint )
+            {
+              Message("Time stepType %s unsupported, set to instant!", stepType);
+              lprint = false;
+            }
 
-static
-void zaxisDefaultValue(zaxis_t *zaxisptr)
-{
-  zaxisptr->self        = CDI_UNDEFID;
-  zaxisptr->name[0]     = 0;
-  zaxisptr->longname[0] = 0;
-  zaxisptr->stdname[0]  = 0;
-  zaxisptr->units[0]    = 0;
-  zaxisptr->vals        = NULL;
-  zaxisptr->ubounds     = NULL;
-  zaxisptr->lbounds     = NULL;
-  zaxisptr->weights     = NULL;
-  zaxisptr->type        = CDI_UNDEFID;
-  zaxisptr->ltype       = 0;
-  zaxisptr->ltype2      = -1;
-  zaxisptr->positive    = 0;
-  zaxisptr->direction   = 0;
-  zaxisptr->prec        = 0;
-  zaxisptr->size        = 0;
-  zaxisptr->vctsize     = 0;
-  zaxisptr->vct         = NULL;
-  zaxisptr->number      = 0;
-  zaxisptr->nhlev       = 0;
-  memset(zaxisptr->uuid, 0, CDI_UUID_SIZE);
-}
+          // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
+        }
+    }
 
+  return (tsteptype);
+}
 
-static
-zaxis_t *zaxisNewEntry(int id)
+int gribGetDatatype(grib_handle* gribHandle)
 {
-  zaxis_t *zaxisptr = (zaxis_t *)xmalloc(sizeof(zaxis_t));
-
-  zaxisDefaultValue ( zaxisptr );
-
-  if (id == CDI_UNDEFID)
-    zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
+  int datatype;
+  if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
+    {
+      datatype = gribCheckLong(gribHandle, "precision", 1) ? DATATYPE_FLT32 : DATATYPE_FLT64;
+    }
   else
     {
-      zaxisptr->self = id;
-      reshReplace(id, zaxisptr, &zaxisOps);
+      long bitsPerValue;
+      datatype = (!grib_get_long(gribHandle, "bitsPerValue", &bitsPerValue) && bitsPerValue > 0 && bitsPerValue <= 32) ? (int)bitsPerValue : DATATYPE_PACK;
     }
+  return datatype;
+}
 
-  return (zaxisptr);
+int gribapiGetParam(grib_handle *gh)
+{
+  long pdis, pcat, pnum;
+  if ( gribEditionNumber(gh) <= 1 )
+    {
+      pdis = 255;
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "table2Version", &pcat);
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "indicatorOfParameter", &pnum);
+    }
+  else
+    {
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "discipline", &pdis);
+      if(grib_get_long(gh, "parameterCategory", &pcat)) pcat = 0;
+      if(grib_get_long(gh, "parameterNumber", &pnum)) pnum = 0;
+    }
+  return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
 }
 
-static
-void zaxisInit(void)
+int gribapiGetGridType(grib_handle *gh)
 {
-  static int zaxisInitialized = 0;
-  char *env;
+  int gridtype = GRID_GENERIC;
+  switch (gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1))
+    {
+      case  GRIB2_GTYPE_LATLON:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GENERIC : GRID_LONLAT;
+        break;
 
-  if ( zaxisInitialized ) return;
+      case  GRIB2_GTYPE_GAUSSIAN:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN;
+        break;
 
-  zaxisInitialized = 1;
+      case GRIB2_GTYPE_LATLON_ROT:   gridtype = GRID_LONLAT; break;
+      case GRIB2_GTYPE_LCC:          gridtype = GRID_LCC; break;
+      case GRIB2_GTYPE_SPECTRAL:     gridtype = GRID_SPECTRAL; break;
+      case GRIB2_GTYPE_GME:          gridtype = GRID_GME; break;
+      case GRIB2_GTYPE_UNSTRUCTURED: gridtype = GRID_UNSTRUCTURED; break;
+    }
 
-  env = getenv("ZAXIS_DEBUG");
-  if ( env ) ZAXIS_Debug = atoi(env);
+  return gridtype;
 }
 
 static
-void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
+int gribapiGetIsRotated(grib_handle *gh)
 {
-  int zaxisID2 = zaxisptr2->self;
-  memcpy(zaxisptr2, zaxisptr1, sizeof(zaxis_t));
-  zaxisptr2->self = zaxisID2;
+  return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
 }
 
-int zaxisSize(void)
+//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
+void gribapiGetGrid(grib_handle *gh, grid_t *grid)
 {
-  return reshCountType ( &zaxisOps );
-}
+  long editionNumber = gribEditionNumber(gh);
+  int gridtype = gribapiGetGridType(gh);
+  /*
+  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
+    {
+      gridtype = GRID_GAUSSIAN;
+      ISEC2_NumLon = 2*ISEC2_NumLat;
+      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
+    }
+  */
+  memset(grid, 0, sizeof(grid_t));
 
-static int
-zaxisCreate_(int zaxistype, int size, int id)
-{
-  zaxis_t *zaxisptr = zaxisNewEntry(id);
+  size_t datasize;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
+  long numberOfPoints;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
 
-  xassert(size >= 0);
-  zaxisptr->type = zaxistype;
-  zaxisptr->size = size;
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+      {
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlon = (int)lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
 
-  if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0 )
-    Error("Internal problem! zaxistype > CDI_MaxZaxistype");
+        if ( gridtype == GRID_GAUSSIAN )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+            grid->np = (int)lpar;
+          }
 
-  int zaxisID = zaxisptr->self;
-  zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
-  zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
-  zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
 
-  if ( *ZaxistypeEntry[zaxistype].stdname )
-    strcpy(zaxisptr->stdname, ZaxistypeEntry[zaxistype].stdname);
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
+        grid->xinc  = 0;
+        grid->yinc  = 0;
+        grid->xdef  = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+        if ( gridtype == GRID_LONLAT )
+          FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->yinc);
+
+        if ( grid->xinc < -999 || grid->xinc > 999 ) grid->xinc = 0;
+        if ( grid->yinc < -999 || grid->yinc > 999 ) grid->yinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
 
-  zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
 
-  double *vals = zaxisptr->vals
-    = (double *)xmalloc((size_t)size * sizeof(double));
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_GAUSSIAN_REDUCED:
+      {
+        size_t dummy;
+        long *pl;
 
-  for ( int ilev = 0; ilev < size; ilev++ )
-    vals[ilev] = 0.0;
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        grid->np = (int)lpar;
 
-  return zaxisID;
-}
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
 
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size   = (int)numberOfPoints;
 
-/*
- at Function  zaxisCreate
- at Title     Create a vertical Z-axis
+        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
+        pl          = (long *) malloc((size_t)nlat * sizeof (long));
+        dummy       = (size_t)nlat;
+        FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
+        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
+        for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
+        free(pl);
+
+        grid->ysize  = nlat;
+        grid->xinc   = 0;
+        grid->yinc   = 0;
+        grid->xdef   = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+
+        if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
 
- at Prototype int zaxisCreate(int zaxistype, int size)
- at Parameter
-    @Item  zaxistype  The type of the Z-axis, one of the set of predefined CDI Z-axis types.
-                      The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
-                      @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
-                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
-                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
-                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
-                      @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
-                      @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
-                      @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
-    @Item  size       Number of levels.
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
 
- at Description
-The function @func{zaxisCreate} creates a vertical Z-axis.
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef  = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_LCC:
+      {
+        int nlon, nlat;
+        long lpar;
 
- at Result
- at func{zaxisCreate} returns an identifier to the Z-axis.
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
+        nlon = lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
+        nlat = lpar;
 
- at Example
-Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
 
- at Source
-   ...
-#define  nlev    5
-   ...
-double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
-int zaxisID;
-   ...
-zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev);
-zaxisDefLevels(zaxisID, levs);
-   ...
- at EndSource
- at EndFunction
-*/
-int zaxisCreate(int zaxistype, int size)
-{
-  if ( CDI_Debug )
-    Message("zaxistype: %d size: %d ", zaxistype, size);
+        grid->size  = numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
 
-  zaxisInit ();
-  return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &grid->lcc_xinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &grid->lcc_yinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "LoVInDegrees", &grid->lcc_lonParY);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin1InDegrees", &grid->lcc_lat1);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin2InDegrees", &grid->lcc_lat2);
+
+        if ( editionNumber <= 1 )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "projectionCenterFlag", &lpar);
+            grid->lcc_projflag  = (int) lpar;
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "scanningMode", &lpar);
+            grid->lcc_scanflag  = (int) lpar;
+          }
+
+        grid->xdef   = 0;
+        grid->ydef   = 0;
+
+        break;
+      }
+    case GRID_SPECTRAL:
+      {
+        size_t len = 256;
+        char typeOfPacking[256];
+        FAIL_ON_GRIB_ERROR(grib_get_string, gh, "packingType", typeOfPacking, &len);
+        grid->lcomplex = 0;
+        if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
+
+        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
+        grid->size  = (int)datasize;
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        grid->trunc = (int)lpar;
+
+        break;
+      }
+    case GRID_GME:
+      {
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        long lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
+
+        break;
+      }
+    case GRID_UNSTRUCTURED:
+      {
+        unsigned char uuid[CDI_UUID_SIZE];
+        /*
+        char reference_link[8192];
+        size_t len = sizeof(reference_link);
+        reference_link[0] = 0;
+        */
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+            grid->size  = (int)numberOfPoints;
+        long lpar;
+        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+          {
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            grid->number   = (int)lpar;
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
+              grid->position = (int)lpar;
+            /*
+            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+              {
+                if ( strncmp(reference_link, "file://", 7) == 0 )
+                  grid->reference = strdupx(reference_link);
+              }
+            */
+            size_t len = (size_t)CDI_UUID_SIZE;
+            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
+              {
+                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
+              }
+          }
+        break;
+      }
+    case GRID_GENERIC:
+      {
+        int nlon = 0, nlat = 0;
+        long lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+
+        if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
+          {
+            grid->xsize = nlon;
+            grid->ysize = nlat;
+          }
+        else
+          {
+            grid->xsize = 0;
+            grid->ysize = 0;
+          }
+
+        break;
+      }
+    default:
+      {
+        Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+        break;
+      }
+    }
+
+  grid->isRotated = FALSE;
+  if ( gribapiGetIsRotated(gh) )
+    {
+      grid->isRotated = TRUE;
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "angleOfRotation", &grid->angle);
+      /* change from south to north pole */
+      grid->ypole = -grid->ypole;
+      grid->xpole =  grid->xpole - 180;
+    }
+
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  grid->type  = gridtype;
 }
+#endif
+#ifndef _GAUSSGRID_H
+#define _GAUSSGRID_H
 
+void   gaussaw(double *restrict pa, double *restrict pw, size_t nlat);
 
-static void zaxisDestroyKernel( zaxis_t * zaxisptr )
-{
-  int id;
+#endif  /* _GAUSSGRID_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef RESOURCE_UNPACK_H
+#define RESOURCE_UNPACK_H
 
-  xassert ( zaxisptr );
+#ifdef HAVE_CONFIG_H
+#endif
 
-  id = zaxisptr->self;
+enum
+{ GRID      = 1,
+  ZAXIS     = 2,
+  TAXIS     = 3,
+  INSTITUTE = 4,
+  MODEL     = 5,
+  STREAM    = 6,
+  VLIST     = 7,
+  RESH_DELETE,
+  START     = 55555555,
+  END       = 99999999
+};
 
-  if ( zaxisptr->vals )    free ( zaxisptr->vals );
-  if ( zaxisptr->lbounds ) free ( zaxisptr->lbounds );
-  if ( zaxisptr->ubounds ) free ( zaxisptr->ubounds );
-  if ( zaxisptr->weights ) free ( zaxisptr->weights );
-  if ( zaxisptr->vct )     free ( zaxisptr->vct );
+void reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
+                         void *context);
+
+#endif
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <string.h>
+#include <float.h>  /* FLT_EPSILON */
+#include <limits.h> /* INT_MAX     */
+
+
+#ifndef  RAD2DEG
+#define  RAD2DEG  (180./M_PI)   /* conversion for rad to deg */
+#endif
+
+#ifndef  DEG2RAD
+#define  DEG2RAD  (M_PI/180.)   /* conversion for deg to rad */
+#endif
+
+
+/* the value in the second pair of brackets must match the length of
+ * the longest string (including terminating NUL) */
+static const char Grids[][17] = {
+  /*  0 */  "undefined",
+  /*  1 */  "generic",
+  /*  2 */  "gaussian",
+  /*  3 */  "gaussian reduced",
+  /*  4 */  "lonlat",
+  /*  5 */  "spectral",
+  /*  6 */  "fourier",
+  /*  7 */  "gme",
+  /*  8 */  "trajectory",
+  /*  9 */  "unstructured",
+  /* 10 */  "curvilinear",
+  /* 11 */  "lcc",
+  /* 12 */  "lcc2",
+  /* 13 */  "laea",
+  /* 14 */  "sinusoidal",
+  /* 15 */  "projection",
+};
 
-  free ( zaxisptr );
 
-  reshRemove ( id, &zaxisOps );
-}
+static int    gridCompareP    ( void * gridptr1, void * gridptr2 );
+static void   gridDestroyP    ( void * gridptr );
+static void   gridPrintP      ( void * gridptr, FILE * fp );
+static int    gridGetPackSize ( void * gridptr, void *context);
+static void   gridPack        ( void * gridptr, void * buff, int size,
+				int *position, void *context);
+static int    gridTxCode      ( void );
 
-/*
- at Function  zaxisDestroy
- at Title     Destroy a vertical Z-axis
+const resOps gridOps = {
+  gridCompareP,
+  gridDestroyP,
+  gridPrintP,
+  gridGetPackSize,
+  gridPack,
+  gridTxCode
+};
 
- at Prototype void zaxisDestroy(int zaxisID)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+static int  GRID_Debug = 0;   /* If set to 1, debugging */
 
- at EndFunction
-*/
-void zaxisDestroy(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
 
-  zaxisDestroyKernel ( zaxisptr );
+void grid_init(grid_t *gridptr)
+{
+  gridptr->self         = CDI_UNDEFID;
+  gridptr->type         = CDI_UNDEFID;
+  gridptr->proj         = CDI_UNDEFID;
+  gridptr->mask         = NULL;
+  gridptr->mask_gme     = NULL;
+  gridptr->xvals        = NULL;
+  gridptr->yvals        = NULL;
+  gridptr->area         = NULL;
+  gridptr->xbounds      = NULL;
+  gridptr->ybounds      = NULL;
+  gridptr->rowlon       = NULL;
+  gridptr->nrowlon      = 0;
+  gridptr->xfirst       = 0.0;
+  gridptr->xlast        = 0.0;
+  gridptr->xinc         = 0.0;
+  gridptr->yfirst       = 0.0;
+  gridptr->ylast        = 0.0;
+  gridptr->yinc         = 0.0;
+  gridptr->lcc_originLon = 0.0;
+  gridptr->lcc_originLat = 0.0;
+  gridptr->lcc_lonParY  = 0.0;
+  gridptr->lcc_lat1     = 0.0;
+  gridptr->lcc_lat2     = 0.0;
+  gridptr->lcc_xinc     = 0.0;
+  gridptr->lcc_yinc     = 0.0;
+  gridptr->lcc_projflag = 0;
+  gridptr->lcc_scanflag = 0;
+  gridptr->lcc_defined  = FALSE;
+  gridptr->lcc2_lon_0   = 0.0;
+  gridptr->lcc2_lat_0   = 0.0;
+  gridptr->lcc2_lat_1   = 0.0;
+  gridptr->lcc2_lat_2   = 0.0;
+  gridptr->lcc2_a       = 0.0;
+  gridptr->lcc2_defined = FALSE;
+  gridptr->laea_lon_0   = 0.0;
+  gridptr->laea_lat_0   = 0.0;
+  gridptr->laea_a       = 0.0;
+  gridptr->laea_defined = FALSE;
+  gridptr->trunc        = 0;
+  gridptr->nvertex      = 0;
+  gridptr->nd           = 0;
+  gridptr->ni           = 0;
+  gridptr->ni2          = 0;
+  gridptr->ni3          = 0;
+  gridptr->number       = 0;
+  gridptr->position     = 0;
+  gridptr->reference    = NULL;
+  gridptr->prec         = 0;
+  gridptr->size         = 0;
+  gridptr->xsize        = 0;
+  gridptr->ysize        = 0;
+  gridptr->np           = 0;
+  gridptr->xdef         = 0;
+  gridptr->ydef         = 0;
+  gridptr->isCyclic     = CDI_UNDEFID;
+  gridptr->isRotated    = FALSE;
+  gridptr->xpole        = 0.0;
+  gridptr->ypole        = 0.0;
+  gridptr->angle        = 0.0;
+  gridptr->locked       = FALSE;
+  gridptr->lcomplex     = 0;
+  gridptr->hasdims      = TRUE;
+  gridptr->xname[0]     = 0;
+  gridptr->yname[0]     = 0;
+  gridptr->xlongname[0] = 0;
+  gridptr->ylongname[0] = 0;
+  gridptr->xunits[0]    = 0;
+  gridptr->yunits[0]    = 0;
+  gridptr->xstdname[0]  = 0;
+  gridptr->ystdname[0]  = 0;
+  memset(gridptr->uuid, 0, CDI_UUID_SIZE);
+  gridptr->name         = NULL;
 }
 
 
-static
-void zaxisDestroyP ( void * zaxisptr )
+void grid_free(grid_t *gridptr)
 {
-  zaxisDestroyKernel (( zaxis_t * ) zaxisptr );
-}
+  if ( gridptr->mask      ) free(gridptr->mask);
+  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
+  if ( gridptr->xvals     ) free(gridptr->xvals);
+  if ( gridptr->yvals     ) free(gridptr->yvals);
+  if ( gridptr->area      ) free(gridptr->area);
+  if ( gridptr->xbounds   ) free(gridptr->xbounds);
+  if ( gridptr->ybounds   ) free(gridptr->ybounds);
+  if ( gridptr->rowlon    ) free(gridptr->rowlon);
+  if ( gridptr->reference ) free(gridptr->reference);
+  if ( gridptr->name      ) free(gridptr->name);
 
+  grid_init(gridptr);
+}
 
-char *zaxisNamePtr(int zaxistype)
+static grid_t *
+gridNewEntry(cdiResH resH)
 {
-  char *name;
-
-  if ( zaxistype >= 0 && zaxistype < CDI_NumZaxistype )
-    name = ZaxistypeEntry[zaxistype].longname;
+  grid_t *gridptr = (grid_t*) xmalloc(sizeof(grid_t));
+  grid_init(gridptr);
+  if (resH == CDI_UNDEFID)
+    gridptr->self = reshPut(gridptr, &gridOps);
   else
-    name = ZaxistypeEntry[ZAXIS_GENERIC].longname;
-
-  return (name);
+    {
+      gridptr->self = resH;
+      reshReplace(resH, gridptr, &gridOps);
+    }
+  return gridptr;
 }
 
-
-void zaxisName(int zaxistype, char *zaxisname)
+static
+void gridInit (void)
 {
-  strcpy(zaxisname, zaxisNamePtr(zaxistype));
-}
+  static int gridInitialized = 0;
+  char *env;
 
-/*
- at Function  zaxisDefName
- at Title     Define the name of a Z-axis
+  if ( gridInitialized ) return;
 
- at Prototype void zaxisDefName(int zaxisID, const char *name)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  name     Name of the Z-axis.
+  gridInitialized = 1;
 
- at Description
-The function @func{zaxisDefName} defines the name of a Z-axis.
+  env = getenv("GRID_DEBUG");
+  if ( env ) GRID_Debug = atoi(env);
+}
 
- at EndFunction
-*/
-void zaxisDefName(int zaxisID, const char *name)
+static
+void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  int gridID2;
 
-  if ( name )
-    {
-      strncpy(zaxisptr->name, name, CDI_MAX_NAME - 1);
-      zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
+  gridID2 = gridptr2->self;
+  memcpy(gridptr2, gridptr1, sizeof(grid_t));
+  gridptr2->self = gridID2;
 }
 
-/*
- at Function  zaxisDefLongname
- at Title     Define the longname of a Z-axis
-
- at Prototype void zaxisDefLongname(int zaxisID, const char *longname)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  longname Longname of the Z-axis.
-
- at Description
-The function @func{zaxisDefLongname} defines the longname of a Z-axis.
-
- at EndFunction
-*/
-void zaxisDefLongname(int zaxisID, const char *longname)
+unsigned cdiGridCount(void)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return reshCountType(&gridOps);
+}
 
-  if ( longname )
+// used also in CDO
+void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
+{
+  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
     {
-      strncpy(zaxisptr->longname, longname, CDI_MAX_NAME - 1);
-      zaxisptr->longname[CDI_MAX_NAME - 1] = '\0';
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+      if ( xfirst >= xlast )
+        {
+          while ( xfirst >= xlast ) xlast += 360;
+          xinc = (xlast-xfirst)/(xsize);
+        }
+      else
+        {
+          xinc = (xlast-xfirst)/(xsize-1);
+        }
     }
-}
-
-/*
- at Function  zaxisDefUnits
- at Title     Define the units of a Z-axis
-
- at Prototype void zaxisDefUnits(int zaxisID, const char *units)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  units    Units of the Z-axis.
 
- at Description
-The function @func{zaxisDefUnits} defines the units of a Z-axis.
+  for ( int i = 0; i < xsize; ++i )
+    xvals[i] = xfirst + i*xinc;
+}
 
- at EndFunction
-*/
-void zaxisDefUnits(int zaxisID, const char *units)
+static
+void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  double *restrict yw = (double *)xmalloc((size_t)ysize * sizeof(double));
+  gaussaw(yvals, yw, (size_t)ysize);
+  free(yw);
+  for (int i = 0; i < ysize; i++ )
+    yvals[i] = asin(yvals[i])/M_PI*180.0;
 
-  if ( units )
+  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
     {
-      strncpy(zaxisptr->units, units, CDI_MAX_NAME - 1);
-      zaxisptr->units[CDI_MAX_NAME - 1] = '\0';
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+      int yhsize = ysize/2;
+      for (int i = 0; i < yhsize; i++ )
+        {
+          double ytmp = yvals[i];
+          yvals[i] = yvals[ysize-i-1];
+          yvals[ysize-i-1] = ytmp;
+        }
     }
 }
 
-/*
- at Function  zaxisInqName
- at Title     Get the name of a Z-axis
+// used also in CDO
+void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
+{
+  const double deleps = 0.002;
 
- at Prototype void zaxisInqName(int zaxisID, char *name)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-    @Item  name     Name of the Z-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
+    {
+      if ( ysize > 2 )
+	{
+	  calc_gaussgrid(yvals, ysize, yfirst, ylast);
 
- at Description
-The function @func{zaxisInqName} returns the name of a Z-axis.
+	  if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
+	    if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
+	      {
+		double yinc = fabs(ylast-yfirst)/(ysize-1);
+		double *restrict ytmp = NULL;
+		int nstart, lfound = 0;
+		int ny = (int) (180./yinc + 0.5);
+		ny -= ny%2;
+		/* printf("%g %g %g %g %g %d\n", ylast, yfirst, ylast-yfirst,yinc, 180/yinc, ny); */
+		if ( ny > ysize && ny < 4096 )
+		  {
+		    ytmp = (double *)xmalloc((size_t)ny * sizeof (double));
+		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
+                    int i;
+		    for ( i = 0; i < (ny-ysize); i++ )
+		      if ( fabs(ytmp[i] - yfirst) < deleps ) break;
 
- at Result
- at func{zaxisInqName} returns the name of the Z-axis to the parameter name.
+		    nstart = i;
 
- at EndFunction
-*/
-void zaxisInqName(int zaxisID, char *name)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  strcpy(name, zaxisptr->name);
-}
+		    lfound = (nstart+ysize-1) < ny
+                      && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
+		  }
 
-/*
- at Function  zaxisInqLongname
- at Title     Get the longname of a Z-axis
+		if ( lfound )
+		  {
+		    for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
+		  }
+		else
+		  {
+		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
+		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
+		    yvals[0] = yfirst;
+		    yvals[ysize-1] = ylast;
+		  }
 
- at Prototype void zaxisInqLongname(int zaxisID, char *longname)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-    @Item  longname Longname of the Z-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+		if ( ytmp ) free(ytmp);
+	      }
+	}
+      else
+        {
+          yvals[0] = yfirst;
+          yvals[ysize-1] = ylast;
+        }
+    }
+  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
+  else
+    {
+      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
+        {
+          if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
 
- at Description
-The function @func{zaxisInqLongname} returns the longname of a Z-axis.
+          if ( yfirst > ylast )
+            yinc = (yfirst-ylast)/(ysize-1);
+          else if ( yfirst < ylast )
+            yinc = (ylast-yfirst)/(ysize-1);
+          else
+            {
+              if ( ysize%2 != 0 )
+                {
+                  yinc = 180.0/(ysize-1);
+                  yfirst = -90;
+                }
+              else
+                {
+                  yinc = 180.0/ysize;
+                  yfirst = -90 + yinc/2;
+                }
+            }
+        }
 
- at Result
- at func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
+      if ( yfirst > ylast && yinc > 0 ) yinc = -yinc;
 
- at EndFunction
-*/
-void zaxisInqLongname(int zaxisID, char *longname)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  strcpy(longname, zaxisptr->longname);
+      for (int i = 0; i < ysize; i++ )
+        yvals[i] = yfirst + i*yinc;
+    }
+  /*
+    else
+    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
+  */
 }
 
 /*
- at Function  zaxisInqUnits
- at Title     Get the units of a Z-axis
+ at Function  gridCreate
+ at Title     Create a horizontal Grid
 
- at Prototype void zaxisInqUnits(int zaxisID, char *units)
+ at Prototype int gridCreate(int gridtype, int size)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-    @Item  units    Units of the Z-axis. The caller must allocate space for the
-                    returned string. The maximum possible length, in characters, of
-                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
+                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
+                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
+                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
+    @Item  size      Number of gridpoints.
 
 @Description
-The function @func{zaxisInqUnits} returns the units of a Z-axis.
+The function @func{gridCreate} creates a horizontal Grid.
 
 @Result
- at func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
+ at func{gridCreate} returns an identifier to the Grid.
 
+ at Example
+Here is an example using @func{gridCreate} to create a regular lon/lat Grid:
+
+ at Source
+   ...
+#define  nlon  12
+#define  nlat   6
+   ...
+double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
+double lats[nlat] = {-75, -45, -15, 15, 45, 75};
+int gridID;
+   ...
+gridID = gridCreate(GRID_LONLAT, nlon*nlat);
+gridDefXsize(gridID, nlon);
+gridDefYsize(gridID, nlat);
+gridDefXvals(gridID, lons);
+gridDefYvals(gridID, lats);
+   ...
+ at EndSource
 @EndFunction
 */
-void zaxisInqUnits(int zaxisID, char *units)
+int gridCreate(int gridtype, int size)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  strcpy(units, zaxisptr->units);
-}
-
+  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
 
-void zaxisInqStdname(int zaxisID, char *stdname)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  strcpy(stdname, zaxisptr->stdname);
-}
+  if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
 
+  gridInit();
 
-void zaxisDefPrec(int zaxisID, int prec)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
+  if ( ! gridptr ) Error("No memory");
 
-  if (zaxisptr->prec != prec)
-    {
-      zaxisptr->prec = prec;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+  int gridID = gridptr->self;
 
+  if ( CDI_Debug ) Message("gridID: %d", gridID);
 
-int zaxisInqPrec(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  gridptr->type = gridtype;
+  gridptr->size = size;
 
-  return (zaxisptr->prec);
-}
+  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
+  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
+  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
 
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+    case GRID_GAUSSIAN_REDUCED:
+    case GRID_CURVILINEAR:
+    case GRID_TRAJECTORY:
+      {
+        if ( gridtype == GRID_TRAJECTORY )
+          {
+            gridDefXname(gridID, "tlon");
+            gridDefYname(gridID, "tlat");
+          }
+        else
+          {
+            gridDefXname(gridID, "lon");
+            gridDefYname(gridID, "lat");
+          }
+        gridDefXlongname(gridID, "longitude");
+        gridDefYlongname(gridID, "latitude");
 
-void zaxisDefPositive(int zaxisID, int positive)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+        /*
+        if ( gridtype == GRID_CURVILINEAR )
+          {
+            strcpy(gridptr->xstdname, "grid_longitude");
+            strcpy(gridptr->ystdname, "grid_latitude");
+            gridDefXunits(gridID, "degrees");
+            gridDefYunits(gridID, "degrees");
+          }
+        else
+        */
+          {
+            strcpy(gridptr->xstdname, "longitude");
+            strcpy(gridptr->ystdname, "latitude");
+            gridDefXunits(gridID, "degrees_east");
+            gridDefYunits(gridID, "degrees_north");
+          }
 
-  if (zaxisptr->positive != positive)
-    {
-      zaxisptr->positive = (unsigned char)positive;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+        break;
+      }
+    case GRID_GME:
+    case GRID_UNSTRUCTURED:
+      {
+        gridDefXname(gridID, "lon");
+        gridDefYname(gridID, "lat");
+        strcpy(gridptr->xstdname, "longitude");
+        strcpy(gridptr->ystdname, "latitude");
+        gridDefXunits(gridID, "degrees_east");
+        gridDefYunits(gridID, "degrees_north");
+        break;
+      }
+    case GRID_GENERIC:
+      {
+        gridDefXname(gridID, "x");
+        gridDefYname(gridID, "y");
+        /*
+        strcpy(gridptr->xstdname, "grid_longitude");
+        strcpy(gridptr->ystdname, "grid_latitude");
+        gridDefXunits(gridID, "degrees");
+        gridDefYunits(gridID, "degrees");
+        */
+        break;
+      }
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
+      {
+        gridDefXname(gridID, "x");
+        gridDefYname(gridID, "y");
+        strcpy(gridptr->xstdname, "projection_x_coordinate");
+        strcpy(gridptr->ystdname, "projection_y_coordinate");
+        gridDefXunits(gridID, "m");
+        gridDefYunits(gridID, "m");
+        break;
+      }
     }
-}
-
-
-int zaxisInqPositive(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  return (zaxisptr->positive);
-}
-
-
-void zaxisDefLtype(int zaxisID, int ltype)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  if (zaxisptr->ltype != ltype)
-    {
-      zaxisptr->ltype = ltype;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
+  return (gridID);
 }
 
-
-int zaxisInqLtype(int zaxisID)
+static
+void gridDestroyKernel( grid_t * gridptr )
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  return (zaxisptr->ltype);
-}
-
+  int id;
 
-void zaxisDefLtype2(int zaxisID, int ltype2)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  xassert ( gridptr );
 
-  if (zaxisptr->ltype2 != ltype2)
-    {
-      zaxisptr->ltype2 = ltype2;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
-}
+  id = gridptr->self;
 
+  if ( gridptr->mask      ) free(gridptr->mask);
+  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
+  if ( gridptr->xvals     ) free(gridptr->xvals);
+  if ( gridptr->yvals     ) free(gridptr->yvals);
+  if ( gridptr->area      ) free(gridptr->area);
+  if ( gridptr->xbounds   ) free(gridptr->xbounds);
+  if ( gridptr->ybounds   ) free(gridptr->ybounds);
+  if ( gridptr->rowlon    ) free(gridptr->rowlon);
+  if ( gridptr->reference ) free(gridptr->reference);
 
-int zaxisInqLtype2(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  free ( gridptr );
 
-  return (zaxisptr->ltype2);
+  reshRemove ( id, &gridOps );
 }
 
 /*
- at Function  zaxisDefLevels
- at Title     Define the levels of a Z-axis
+ at Function  gridDestroy
+ at Title     Destroy a horizontal Grid
 
- at Prototype void zaxisDefLevels(int zaxisID, const double *levels)
+ at Prototype void gridDestroy(int gridID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  levels   All levels of the Z-axis.
-
- at Description
-The function @func{zaxisDefLevels} defines the levels of a Z-axis.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
 
 @EndFunction
 */
-void zaxisDefLevels(int zaxisID, const double *levels)
+void gridDestroy(int gridID)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  int size = zaxisptr->size;
-
-  double *vals = zaxisptr->vals;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  for (int ilev = 0; ilev < size; ilev++ )
-    vals[ilev] = levels[ilev];
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+  gridDestroyKernel ( gridptr );
 }
 
-/*
- at Function  zaxisDefLevel
- at Title     Define one level of a Z-axis
-
- at Prototype void zaxisDefLevel(int zaxisID, int levelID, double level)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  levelID  Level identifier.
-    @Item  level    Level.
-
- at Description
-The function @func{zaxisDefLevel} defines one level of a Z-axis.
-
- at EndFunction
-*/
-void zaxisDefLevel(int zaxisID, int levelID, double level)
+void gridDestroyP ( void * gridptr )
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( levelID >= 0 && levelID < zaxisptr->size )
-    zaxisptr->vals[levelID] = level;
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+  gridDestroyKernel (( grid_t * ) gridptr );
 }
 
 
-void zaxisDefNlevRef(int zaxisID, const int nhlev)
+const char *gridNamePtr(int gridtype)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  const char *name;
+  int size = (int) (sizeof(Grids)/sizeof(char *));
 
-  if (zaxisptr->nhlev != nhlev)
-    {
-      zaxisptr->nhlev = nhlev;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
+  name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
+
+  return (name);
 }
 
 
-int zaxisInqNlevRef(int zaxisID)
+void gridName(int gridtype, char *gridname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  return (zaxisptr->nhlev);
+  strcpy(gridname, gridNamePtr(gridtype));
 }
 
 /*
- at Function  zaxisDefNumber
- at Title     Define the reference number for a generalized Z-axis
+ at Function  gridDefXname
+ at Title     Define the name of a X-axis
 
- at Prototype void zaxisDefNumber(int zaxisID, const int number)
+ at Prototype void gridDefXname(int gridID, const char *name)
 @Parameter
-    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  number      Reference number for a generalized Z-axis.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  name     Name of the X-axis.
 
 @Description
-The function @func{zaxisDefNumber} defines the reference number for a generalized Z-axis.
+The function @func{gridDefXname} defines the name of a X-axis.
 
 @EndFunction
 */
-void zaxisDefNumber(int zaxisID, const int number)
+void gridDefXname(int gridID, const char *xname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if (zaxisptr->number != number)
+  if ( xname )
     {
-      zaxisptr->number = number;
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+      strncpy(gridptr->xname, xname, CDI_MAX_NAME);
+      gridptr->xname[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
 }
 
 /*
- at Function  zaxisInqNumber
- at Title     Get the reference number to a generalized Z-axis
+ at Function  gridDefXlongname
+ at Title     Define the longname of a X-axis
 
- at Prototype int zaxisInqNumber(int zaxisID)
+ at Prototype void gridDefXlongname(int gridID, const char *longname)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  longname Longname of the X-axis.
 
 @Description
-The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
+The function @func{gridDefXlongname} defines the longname of a X-axis.
 
- at Result
- at func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
 @EndFunction
 */
-int zaxisInqNumber(int zaxisID)
+void gridDefXlongname(int gridID, const char *xlongname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  return (zaxisptr->number);
+  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( xlongname )
+    {
+      strncpy(gridptr->xlongname, xlongname, CDI_MAX_NAME);
+      gridptr->xlongname[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
- at Function  zaxisDefUUID
- at Title     Define the UUID for a genralized Z-axis
+ at Function  gridDefXunits
+ at Title     Define the units of a X-axis
 
- at Prototype void zaxisDefUUID(int zaxisID, const char *uuid)
+ at Prototype void gridDefXunits(int gridID, const char *units)
 @Parameter
-    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  uuid        UUID for a generalized Z-axis.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  units    Units of the X-axis.
 
 @Description
-The function @func{zaxisDefUUID} defines the UUID for a generalized  Z-axis.
+The function @func{gridDefXunits} defines the units of a X-axis.
 
 @EndFunction
 */
-void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
+void gridDefXunits(int gridID, const char *xunits)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  memcpy(zaxisptr->uuid, uuid, CDI_UUID_SIZE);
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-}
-
-/*
- at Function  zaxisInqUUID
- at Title     Get the uuid to a generalized Z-axis
-
- at Prototype void zaxisInqUUID(int zaxisID, char *uuid)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-
- at Description
-The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
+  grid_t *gridptr = gridID2Ptr(gridID);
 
- at Result
- at func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
- at EndFunction
-*/
-void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  memcpy(uuid, zaxisptr->uuid, CDI_UUID_SIZE);
+  if ( xunits )
+    {
+      strncpy(gridptr->xunits, xunits, CDI_MAX_NAME);
+      gridptr->xunits[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
- at Function  zaxisInqLevel
- at Title     Get one level of a Z-axis
+ at Function  gridDefYname
+ at Title     Define the name of a Y-axis
 
- at Prototype double zaxisInqLevel(int zaxisID, int levelID)
+ at Prototype void gridDefYname(int gridID, const char *name)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-    @Item  levelID  Level index (range: 0 to nlevel-1).
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  name     Name of the Y-axis.
 
 @Description
-The function @func{zaxisInqLevel} returns one level of a Z-axis.
+The function @func{gridDefYname} defines the name of a Y-axis.
 
- at Result
- at func{zaxisInqLevel} returns the level of a Z-axis.
 @EndFunction
 */
-double zaxisInqLevel(int zaxisID, int levelID)
-{
-  double level = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( levelID >= 0 && levelID < zaxisptr->size )
-    level = zaxisptr->vals[levelID];
-
-  return (level);
-}
-
-double zaxisInqLbound(int zaxisID, int index)
-{
-  double level = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( zaxisptr->lbounds )
-    if ( index >= 0 && index < zaxisptr->size )
-      level = zaxisptr->lbounds[index];
-
-  return (level);
-}
-
-
-double zaxisInqUbound(int zaxisID, int index)
+void gridDefYname(int gridID, const char *yname)
 {
-  double level = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( zaxisptr->ubounds )
-    if ( index >= 0 && index < zaxisptr->size )
-      level = zaxisptr->ubounds[index];
-
-  return (level);
-}
-
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-const double *zaxisInqLevelsPtr(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  return ( zaxisptr->vals );
+  if ( yname )
+    {
+      strncpy(gridptr->yname, yname, CDI_MAX_NAME);
+      gridptr->yname[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
- at Function  zaxisInqLevels
- at Title     Get all levels of a Z-axis
+ at Function  gridDefYlongname
+ at Title     Define the longname of a Y-axis
 
- at Prototype void zaxisInqLevels(int zaxisID, double *levels)
+ at Prototype void gridDefYlongname(int gridID, const char *longname)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-    @Item  levels   Pointer to the location into which the levels are read.
-                    The caller must allocate space for the returned values.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  longname Longname of the Y-axis.
 
 @Description
-The function @func{zaxisInqLevels} returns all levels of a Z-axis.
+The function @func{gridDefYlongname} defines the longname of a Y-axis.
 
- at Result
- at func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
 @EndFunction
 */
-void zaxisInqLevels(int zaxisID, double *levels)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  int size = zaxisptr->size;
-  for (int i = 0; i < size; i++ )
-    levels[i] =  zaxisptr->vals[i];
-}
-
-
-int zaxisInqLbounds(int zaxisID, double *lbounds)
-{
-  int size = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( zaxisptr->lbounds )
-    {
-      size = zaxisptr->size;
-
-      if ( lbounds )
-        for (int i = 0; i < size; i++ )
-          lbounds[i] =  zaxisptr->lbounds[i];
-    }
-
-  return (size);
-}
-
-
-int zaxisInqUbounds(int zaxisID, double *ubounds)
-{
-  int size = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( zaxisptr->ubounds )
-    {
-      size = zaxisptr->size;
-
-      if ( ubounds )
-        for (int i = 0; i < size; i++ )
-          ubounds[i] =  zaxisptr->ubounds[i];
-    }
-
-  return (size);
-}
-
-
-int zaxisInqWeights(int zaxisID, double *weights)
+void gridDefYlongname(int gridID, const char *ylongname)
 {
-  int size = 0;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( zaxisptr->weights )
+  if ( ylongname )
     {
-      size = zaxisptr->size;
-
-      if ( weights )
-        for ( int i = 0; i < size; i++ )
-          weights[i] =  zaxisptr->weights[i];
+      strncpy(gridptr->ylongname, ylongname, CDI_MAX_NAME);
+      gridptr->ylongname[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-
-  return (size);
-}
-
-
-int zaxisInqLevelID(int zaxisID, double level)
-{
-  int levelID = CDI_UNDEFID;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  int size = zaxisptr->size;
-  for ( int i = 0; i < size; i++ )
-    if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
-      {
-        levelID = i;
-        break;
-      }
-
-  return (levelID);
-}
-
-/*
- at Function  zaxisInqType
- at Title     Get the type of a Z-axis
-
- at Prototype int zaxisInqType(int zaxisID)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
-
- at Description
-The function @func{zaxisInqType} returns the type of a Z-axis.
-
- at Result
- at func{zaxisInqType} returns the type of the Z-axis,
-one of the set of predefined CDI Z-axis types.
-The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
- at func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
- at func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
- at func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
- at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
- at func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
- at func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
- at func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
-
- at EndFunction
-*/
-int zaxisInqType(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  return (zaxisptr->type);
 }
 
 /*
- at Function  zaxisInqSize
- at Title     Get the size of a Z-axis
+ at Function  gridDefYunits
+ at Title     Define the units of a Y-axis
 
- at Prototype int zaxisInqSize(int zaxisID)
+ at Prototype void gridDefYunits(int gridID, const char *units)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  units    Units of the Y-axis.
 
 @Description
-The function @func{zaxisInqSize} returns the size of a Z-axis.
-
- at Result
- at func{zaxisInqSize} returns the number of levels of a Z-axis.
+The function @func{gridDefYunits} defines the units of a Y-axis.
 
 @EndFunction
 */
-int zaxisInqSize(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  return (zaxisptr->size);
-}
-
-
-void cdiCheckZaxis(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
-    {
-      int size = zaxisptr->size;
-      if ( size > 1 )
-        {
-          /* check direction */
-          if ( ! zaxisptr->direction )
-            {
-              int ups = 0, downs = 0;
-              for ( int i = 1; i < size; i++ )
-                {
-                  ups += (zaxisptr->vals[i] > zaxisptr->vals[i-1]);
-                  downs += (zaxisptr->vals[i] < zaxisptr->vals[i-1]);
-                }
-              if ( ups == size-1 )
-                {
-                  zaxisptr->direction = LevelUp;
-                }
-              else if ( downs == size-1 )
-                {
-                  zaxisptr->direction = LevelDown;
-                }
-              else /* !zaxisptr->direction */
-                {
-                  Warning("Direction undefined for zaxisID %d", zaxisID);
-                }
-            }
-        }
-    }
-}
-
-
-void zaxisDefVct(int zaxisID, int size, const double *vct)
+void gridDefYunits(int gridID, const char *yunits)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( zaxisptr->vct == 0 )
+  if ( yunits )
     {
-      zaxisptr->vctsize = size;
-      zaxisptr->vct = (double *)xmalloc((size_t)size * sizeof (double));
-      memcpy(zaxisptr->vct, vct, (size_t)size * sizeof (double));
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+      strncpy(gridptr->yunits, yunits, CDI_MAX_NAME);
+      gridptr->yunits[CDI_MAX_NAME - 1] = 0;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-  else
-    if ( zaxisptr->vctsize != size )
-      Warning("VCT was already defined");
 }
 
+/*
+ at Function  gridInqXname
+ at Title     Get the name of a X-axis
 
-void zaxisInqVct(int zaxisID, double *vct)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  memcpy(vct, zaxisptr->vct, (size_t)zaxisptr->vctsize * sizeof (double));
-}
-
+ at Prototype void gridInqXname(int gridID, char *name)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the X-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-int zaxisInqVctSize(int zaxisID)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  return (zaxisptr->vctsize);
-}
+ at Description
+The function @func{gridInqXname} returns the name of a X-axis.
 
+ at Result
+ at func{gridInqXname} returns the name of the X-axis to the parameter name.
 
-const double *zaxisInqVctPtr(int zaxisID)
+ at EndFunction
+*/
+void gridInqXname(int gridID, char *xname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  return (zaxisptr->vct);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(xname, gridptr->xname);
 }
 
+/*
+ at Function  gridInqXlongname
+ at Title     Get the longname of a X-axis
 
-void zaxisDefLbounds(int zaxisID, const double *lbounds)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+ at Prototype void gridInqXlongname(int gridID, char *longname)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the X-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  size_t size = (size_t)zaxisptr->size;
+ at Description
+The function @func{gridInqXlongname} returns the longname of a X-axis.
 
-  if ( CDI_Debug )
-    if ( zaxisptr->lbounds != NULL )
-      Warning("Lower bounds already defined for zaxisID = %d", zaxisID);
+ at Result
+ at func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
 
-  if ( zaxisptr->lbounds == NULL )
-    zaxisptr->lbounds = (double *)xmalloc(size*sizeof(double));
+ at EndFunction
+*/
+void gridInqXlongname(int gridID, char *xlongname)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  memcpy(zaxisptr->lbounds, lbounds, size*sizeof(double));
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+  strcpy(xlongname, gridptr->xlongname);
 }
 
+/*
+ at Function  gridInqXunits
+ at Title     Get the units of a X-axis
 
-void zaxisDefUbounds(int zaxisID, const double *ubounds)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+ at Prototype void gridInqXunits(int gridID, char *units)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the X-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  size_t size = (size_t)zaxisptr->size;
+ at Description
+The function @func{gridInqXunits} returns the units of a X-axis.
 
-  if ( CDI_Debug )
-    if ( zaxisptr->ubounds != NULL )
-      Warning("Upper bounds already defined for zaxisID = %d", zaxisID);
+ at Result
+ at func{gridInqXunits} returns the units of the X-axis to the parameter units.
 
-  if ( zaxisptr->ubounds == NULL )
-    zaxisptr->ubounds = (double *)xmalloc(size*sizeof(double));
+ at EndFunction
+*/
+void gridInqXunits(int gridID, char *xunits)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  memcpy(zaxisptr->ubounds, ubounds, size*sizeof(double));
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+  strcpy(xunits, gridptr->xunits);
 }
 
 
-void zaxisDefWeights(int zaxisID, const double *weights)
+void gridInqXstdname(int gridID, char *xstdname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  size_t size = (size_t)zaxisptr->size;
+  strcpy(xstdname, gridptr->xstdname);
+}
 
-  if ( CDI_Debug )
-    if ( zaxisptr->weights != NULL )
-      Warning("Weights already defined for zaxisID = %d", zaxisID);
+/*
+ at Function  gridInqYname
+ at Title     Get the name of a Y-axis
 
-  if ( zaxisptr->weights == NULL )
-    zaxisptr->weights = (double *)xmalloc(size*sizeof(double));
+ at Prototype void gridInqYname(int gridID, char *name)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the Y-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  memcpy(zaxisptr->weights, weights, size*sizeof(double));
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-}
+ at Description
+The function @func{gridInqYname} returns the name of a Y-axis.
 
+ at Result
+ at func{gridInqYname} returns the name of the Y-axis to the parameter name.
 
-void zaxisChangeType(int zaxisID, int zaxistype)
+ at EndFunction
+*/
+void gridInqYname(int gridID, char *yname)
 {
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-  zaxisptr->type = zaxistype;
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(yname, gridptr->yname);
 }
 
+/*
+ at Function  gridInqYlongname
+ at Title     Get the longname of a Y-axis
 
-void zaxisResize(int zaxisID, int size)
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+ at Prototype void gridInqXlongname(int gridID, char *longname)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the Y-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  xassert(size >= 0);
+ at Description
+The function @func{gridInqYlongname} returns the longname of a Y-axis.
 
-  zaxisptr->size = size;
+ at Result
+ at func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
 
-  if ( zaxisptr->vals )
-    zaxisptr->vals = (double *)xrealloc(zaxisptr->vals, (size_t)size * sizeof(double));
-}
+ at EndFunction
+*/
+void gridInqYlongname(int gridID, char *ylongname)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  strcpy(ylongname, gridptr->ylongname);
+}
 
-int zaxisDuplicate(int zaxisID)
-{
-  int zaxisIDnew;
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+/*
+ at Function  gridInqYunits
+ at Title     Get the units of a Y-axis
 
-  int zaxistype = zaxisInqType(zaxisID);
-  int zaxissize = zaxisInqSize(zaxisID);
+ at Prototype void gridInqYunits(int gridID, char *units)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the Y-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
-  zaxis_t *zaxisptrnew = reshGetVal(zaxisIDnew, &zaxisOps);
+ at Description
+The function @func{gridInqYunits} returns the units of a Y-axis.
 
-  zaxis_copy(zaxisptrnew, zaxisptr);
+ at Result
+ at func{gridInqYunits} returns the units of the Y-axis to the parameter units.
 
-  strcpy(zaxisptrnew->name, zaxisptr->name);
-  strcpy(zaxisptrnew->longname, zaxisptr->longname);
-  strcpy(zaxisptrnew->units, zaxisptr->units);
+ at EndFunction
+*/
+void gridInqYunits(int gridID, char *yunits)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( zaxisptr->vals != NULL )
-    {
-      size_t size = (size_t)zaxissize;
+  strcpy(yunits, gridptr->yunits);
+}
 
-      zaxisptrnew->vals = (double *)xmalloc(size * sizeof (double));
-      memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
-    }
+void gridInqYstdname(int gridID, char *ystdname)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( zaxisptr->lbounds )
-    {
-      size_t size = (size_t)zaxissize;
+  strcpy(ystdname, gridptr->ystdname);
+}
 
-      zaxisptrnew->lbounds = (double *)xmalloc(size * sizeof (double));
-      memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
-    }
+/*
+ at Function  gridInqType
+ at Title     Get the type of a Grid
 
-  if ( zaxisptr->ubounds )
-    {
-      size_t size = (size_t)zaxissize;
+ at Prototype int gridInqType(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-      zaxisptrnew->ubounds = (double *)xmalloc(size * sizeof (double));
-      memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
-    }
+ at Description
+The function @func{gridInqType} returns the type of a Grid.
 
-  if ( zaxisptr->vct != NULL )
-    {
-      size_t size = (size_t)zaxisptr->vctsize;
+ at Result
+ at func{gridInqType} returns the type of the grid,
+one of the set of predefined CDI grid types.
+The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
+ at func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
+ at func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
 
-      if ( size )
-        {
-          zaxisptrnew->vctsize = (int)size;
-          zaxisptrnew->vct = (double *)xmalloc(size * sizeof (double));
-          memcpy(zaxisptrnew->vct, zaxisptr->vct, size * sizeof (double));
-        }
-    }
+ at EndFunction
+*/
+int gridInqType(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  return (zaxisIDnew);
+  return (gridptr->type);
 }
 
 
-void zaxisPrintKernel ( zaxis_t * zaxisptr, FILE * fp )
-{
-  int zaxisID;
-  int type;
-  unsigned char uuid[CDI_UUID_SIZE];
-  int nlevels, levelID;
-  int nbyte0, nbyte;
-  double level;
+/*
+ at Function  gridInqSize
+ at Title     Get the size of a Grid
 
-  xassert ( zaxisptr );
+ at Prototype int gridInqSize(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  zaxisID = zaxisptr->self;
+ at Description
+The function @func{gridInqSize} returns the size of a Grid.
 
-  type    = zaxisptr->type;
-  nlevels = zaxisptr->size;
+ at Result
+ at func{gridInqSize} returns the number of grid points of a Grid.
 
-  nbyte0 = 0;
-  fprintf(fp, "#\n");
-  fprintf(fp, "# zaxisID %d\n", zaxisID);
-  fprintf(fp, "#\n");
-  fprintf(fp, "zaxistype = %s\n", zaxisNamePtr(type));
-  fprintf(fp, "size      = %d\n", nlevels);
-  if ( zaxisptr->name[0]     ) fprintf(fp, "name      = %s\n", zaxisptr->name);
-  if ( zaxisptr->longname[0] ) fprintf(fp, "longname  = %s\n", zaxisptr->longname);
-  if ( zaxisptr->units[0]    ) fprintf(fp, "units     = %s\n", zaxisptr->units);
+ at EndFunction
+*/
+int gridInqSize(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  nbyte0 = fprintf(fp, "levels    = ");
-  nbyte = nbyte0;
-  for ( levelID = 0; levelID < nlevels; levelID++ )
-    {
-      if ( nbyte > 80 )
-	{
-	  fprintf(fp, "\n");
-	  fprintf(fp, "%*s", nbyte0, "");
-	  nbyte = nbyte0;
-	}
-      level = zaxisInqLevel(zaxisID, levelID);
-      nbyte += fprintf(fp, "%.9g ", level);
-    }
-  fprintf(fp, "\n");
+  int size = gridptr->size;
 
-  if ( zaxisptr->lbounds && zaxisptr->ubounds )
+  if ( ! size )
     {
-      double level1, level2;
-      nbyte = nbyte0;
-      nbyte0 = fprintf(fp, "bounds    = ");
-      for ( levelID = 0; levelID < nlevels; levelID++ )
-	{
-	  if ( nbyte > 80 )
-	    {
-	      fprintf(fp, "\n");
-	      fprintf(fp, "%*s", nbyte0, "");
-	      nbyte = nbyte0;
-	    }
-	  level1 = zaxisInqLbound(zaxisID, levelID);
-	  level2 = zaxisInqUbound(zaxisID, levelID);
-	  nbyte += fprintf(fp, "%.9g-%.9g ", level1, level2);
-	}
-      fprintf(fp, "\n");
-    }
+      int xsize, ysize;
 
-  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
-    {
-      int i;
-      int vctsize;
-      const double *vct;
+      xsize = gridptr->xsize;
+      ysize = gridptr->ysize;
 
-      vctsize = zaxisptr->vctsize;
-      vct     = zaxisptr->vct;
-      fprintf(fp, "vctsize   = %d\n", vctsize);
-      if ( vctsize )
-        {
-          nbyte0 = fprintf(fp, "vct       = ");
-          nbyte = nbyte0;
-          for ( i = 0; i < vctsize; i++ )
-            {
-              if ( nbyte > 70 || i == vctsize/2 )
-                {
-                  fprintf(fp, "\n%*s", nbyte0, "");
-                  nbyte = nbyte0;
-                }
-              nbyte += fprintf(fp, "%.9g ", vct[i]);
-            }
-          fprintf(fp, "\n");
-          /*
-          nbyte0 = fprintf(fp, "vct_b     = ");
-          nbyte  = nbyte0;
-          for ( i = 0; i < vctsize/2; i++ )
-            {
-              if ( nbyte > 70 )
-                {
-                  fprintf(fp, "\n%*s", nbyte0, "");
-                  nbyte = nbyte0;
-                }
-              nbyte += fprintf(fp, "%.9g ", vct[vctsize/2+i]);
-            }
-          fprintf(fp, "\n");
-          */
-        }
-    }
+      if ( ysize )
+        size = xsize *ysize;
+      else
+        size = xsize;
 
-  if ( type == ZAXIS_REFERENCE )
-    {
-      const unsigned char *d;
-      zaxisInqUUID(zaxisID, uuid);
-      d = uuid;
-      fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
-              d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
-              d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+      gridptr->size = size;
     }
-}
-
 
-void zaxisPrint ( int zaxisID )
-{
-  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
-
-  zaxisPrintKernel ( zaxisptr, stdout );
+  return (size);
 }
 
-
 static
-void zaxisPrintP ( void * voidptr, FILE * fp )
+int nsp2trunc(int nsp)
 {
-  zaxis_t *zaxisptr = ( zaxis_t * ) voidptr;
-
-  xassert ( zaxisptr );
-
-  zaxisPrintKernel(zaxisptr, fp);
+  /*  nsp = (trunc+1)*(trunc+1)              */
+  /*      => trunc^2 + 3*trunc - (x-2) = 0   */
+  /*                                         */
+  /*  with:  y^2 + p*y + q = 0               */
+  /*         y = -p/2 +- sqrt((p/2)^2 - q)   */
+  /*         p = 3 and q = - (x-2)           */
+  int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
+  return (trunc);
 }
 
 
-static int
-zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
+int gridInqTrunc(int gridID)
 {
-  enum {
-    differ = 1,
-  };
-  int diff = 0;
-  xassert(z1 && z2);
-
-  diff |= (z1->type != z2->type)
-    | (z1->ltype != z2->ltype)
-    | (z1->direction != z2->direction)
-    | (z1->prec != z2->prec)
-    | (z1->size != z2->size)
-    | (z1->vctsize != z2->vctsize)
-    | (z1->positive != z2->positive);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if (diff)
-    return differ;
-  int size = z1->size;
-  int anyPresent = 0;
-  int present = (z1->vals != NULL);
-  diff |= (present ^ (z2->vals != NULL));
-  anyPresent |= present;
-  if (!diff && present)
+  if ( gridptr->trunc == 0 )
     {
-      const double *p = z1->vals, *q = z2->vals;
-      for (int i = 0; i < size; i++)
-        diff |= IS_NOT_EQUAL(p[i], q[i]);
+      if ( gridptr->type == GRID_SPECTRAL )
+        gridptr->trunc = nsp2trunc(gridptr->size);
+      /*
+      else if      ( gridptr->type == GRID_GAUSSIAN )
+        gridptr->trunc = nlat2trunc(gridptr->ysize);
+      */
     }
 
-  present = (z1->lbounds != NULL);
-  diff |= (present ^ (z2->lbounds != NULL));
-  anyPresent |= present;
-  if (!diff && present)
-    {
-      const double *p = z1->lbounds, *q = z2->lbounds;
-      for (int i = 0; i < size; i++)
-        diff |= IS_NOT_EQUAL(p[i], q[i]);
-    }
+  return (gridptr->trunc);
+}
 
-  present = (z1->ubounds != NULL);
-  diff |= (present ^ (z2->ubounds != NULL));
-  anyPresent |= present;
-  if (!diff && present)
-    {
-      const double *p = z1->ubounds, *q = z2->ubounds;
-      for (int i = 0; i < size; ++i)
-        diff |= IS_NOT_EQUAL(p[i], q[i]);
-    }
 
-  present = (z1->weights != NULL);
-  diff |= (present ^ (z2->weights != NULL));
-  anyPresent |= present;
-  if (!diff && present)
-    {
-      const double *p = z1->weights, *q = z2->weights;
-      for (int i = 0; i < size; ++i)
-        diff |= IS_NOT_EQUAL(p[i], q[i]);
-    }
+void gridDefTrunc(int gridID, int trunc)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  present = (z1->vct != NULL);
-  diff |= (present ^ (z2->vct != NULL));
-  if (!diff && present)
+  if (gridptr->trunc != trunc)
     {
-      int vctsize = z1->vctsize;
-      xassert(vctsize);
-      const double *p = z1->vct, *q = z2->vct;
-      for (int i = 0; i < vctsize; ++i)
-        diff |= IS_NOT_EQUAL(p[i], q[i]);
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      gridptr->trunc = trunc;
     }
-
-  if (anyPresent)
-    xassert(size);
-
-  diff |= strcmp(z1->name, z2->name)
-    | strcmp(z1->longname, z2->longname)
-    | strcmp(z1->stdname, z2->stdname)
-    | strcmp(z1->units, z2->units)
-    | memcmp(z1->uuid, z2->uuid, CDI_UUID_SIZE);
-  return diff != 0;
 }
 
+/*
+ at Function  gridDefXsize
+ at Title     Define the number of values of a X-axis
 
-static int
-zaxisTxCode ( void )
-{
-  return ZAXIS;
-}
-
-enum { zaxisNint     = 8,
-       vals     = 1 << 0,
-       lbounds  = 1 << 1,
-       ubounds  = 1 << 2,
-       weights  = 1 << 3,
-       vct      = 1 << 4,
-       zaxisHasUUIDFlag = 1 << 5,
-};
+ at Prototype void gridDefXsize(int gridID, int xsize)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  xsize    Number of values of a X-axis.
 
-#define ZAXIS_STR_SERIALIZE { zaxisP->name, zaxisP->longname, \
-      zaxisP->stdname, zaxisP->units }
+ at Description
+The function @func{gridDefXsize} defines the number of values of a X-axis.
 
-static
-int zaxisGetMemberMask ( zaxis_t * zaxisP )
+ at EndFunction
+*/
+void gridDefXsize(int gridID, int xsize)
 {
-  int memberMask = 0;
-
-  if ( zaxisP->vals )      memberMask |= vals;
-  if ( zaxisP->lbounds )   memberMask |= lbounds;
-  if ( zaxisP->ubounds )   memberMask |= ubounds;
-  if ( zaxisP->weights )   memberMask |= weights;
-  if ( zaxisP->vct )       memberMask |= vct;
-  if (!cdiUUIDIsNull(zaxisP->uuid)) memberMask |= zaxisHasUUIDFlag;
-  return memberMask;
-}
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-static int
-zaxisGetPackSize(void * voidP, void *context)
-{
-  zaxis_t * zaxisP = ( zaxis_t * ) voidP;
-  int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_UINT32, context);
+  int gridSize = gridInqSize(gridID);
+  if ( xsize > gridSize )
+    Error("xsize %d is greater then gridsize %d", xsize, gridSize);
 
-  if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
-    xassert(zaxisP->size);
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridSize )
+    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
 
-  if ( zaxisP->vals )
-    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
-      + serializeGetSize(1, DATATYPE_UINT32, context);
+  if (gridptr->xsize != xsize)
+    {
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      gridptr->xsize = xsize;
+    }
 
-  if ( zaxisP->lbounds )
-    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
-      + serializeGetSize(1, DATATYPE_UINT32, context);
+  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
+    {
+      long axisproduct = gridptr->xsize*gridptr->ysize;
+      if ( axisproduct > 0 && axisproduct != gridSize )
+        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
+              gridptr->xsize, gridptr->ysize, gridSize);
+    }
+}
 
-  if ( zaxisP->ubounds )
-    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
-      + serializeGetSize(1, DATATYPE_UINT32, context);
+/*
+ at Function
+ at Title
 
-  if ( zaxisP->weights )
-    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
-      + serializeGetSize(1, DATATYPE_UINT32, context);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( zaxisP->vct )
+ at EndFunction
+*/
+void gridDefPrec(int gridID, int prec)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if (gridptr->prec != prec)
     {
-      xassert ( zaxisP->vctsize );
-      packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
-        + serializeGetSize(1, DATATYPE_UINT32, context);
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      gridptr->prec = prec;
     }
+}
 
-  {
-    const char *strTab[] = ZAXIS_STR_SERIALIZE;
-    size_t numStr = sizeof (strTab) / sizeof (strTab[0]);
-    packBufferSize
-      += serializeStrTabGetPackSize(strTab, (int)numStr, context);
-  }
+/*
+ at Function
+ at Title
 
-  packBufferSize += serializeGetSize(1, DATATYPE_UCHAR, context);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if (!cdiUUIDIsNull(zaxisP->uuid))
-    packBufferSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+ at EndFunction
+*/
+int gridInqPrec(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  return packBufferSize;
+  return (gridptr->prec);
 }
 
+/*
+ at Function  gridInqXsize
+ at Title     Get the number of values of a X-axis
 
-void
-zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
-            int * unpackBufferPos, int originNamespace, void *context,
-            int force_id)
-{
-  int intBuffer[zaxisNint], memberMask;
-  uint32_t d;
+ at Prototype int gridInqXsize(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, zaxisNint, DATATYPE_INT, context);
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_UINT32, context);
+ at Description
+The function @func{gridInqXsize} returns the number of values of a X-axis.
 
-  xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
+ at Result
+ at func{gridInqXsize} returns the number of values of a X-axis.
 
-  zaxisInit();
+ at EndFunction
+*/
+int gridInqXsize(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  zaxis_t *zaxisP
-    = zaxisNewEntry(force_id ? namespaceAdaptKey(intBuffer[0], originNamespace)
-                    : CDI_UNDEFID);
+  return (gridptr->xsize);
+}
 
-  zaxisP->prec      = intBuffer[1];
-  zaxisP->type      = intBuffer[2];
-  zaxisP->ltype     = intBuffer[3];
-  zaxisP->size      = intBuffer[4];
-  zaxisP->direction = intBuffer[5];
-  zaxisP->vctsize   = intBuffer[6];
-  memberMask        = intBuffer[7];
+/*
+ at Function  gridDefYsize
+ at Title     Define the number of values of a Y-axis
 
-  if (memberMask & vals)
-    {
-      int size = zaxisP->size;
-      xassert(size >= 0);
+ at Prototype void gridDefYsize(int gridID, int ysize)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  ysize    Number of values of a Y-axis.
 
-      zaxisP->vals = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->vals, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
-    }
+ at Description
+The function @func{gridDefYsize} defines the number of values of a Y-axis.
 
-  if (memberMask & lbounds)
-    {
-      int size = zaxisP->size;
-      xassert(size >= 0);
+ at EndFunction
+*/
+void gridDefYsize(int gridID, int ysize)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-      zaxisP->lbounds = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->lbounds, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
-    }
+  int gridSize = gridInqSize(gridID);
 
-  if (memberMask & ubounds)
-    {
-      int size = zaxisP->size;
-      xassert(size >= 0);
+  if ( ysize > gridSize )
+    Error("ysize %d is greater then gridsize %d", ysize, gridSize);
 
-      zaxisP->ubounds = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->ubounds, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
-    }
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridSize )
+    Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridSize);
 
-  if (memberMask & weights)
+  if (gridptr->ysize != ysize)
     {
-      int size = zaxisP->size;
-      xassert(size >= 0);
-
-      zaxisP->weights = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->weights, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      gridptr->ysize = ysize;
     }
 
-  if ( memberMask & vct )
+  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
     {
-      int size = zaxisP->vctsize;
-      xassert(size >= 0);
-
-      zaxisP->vct = (double *)xmalloc((size_t)size * sizeof (double));
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->vct, size, DATATYPE_FLT64, context);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
+      long axisproduct = gridptr->xsize*gridptr->ysize;
+      if ( axisproduct > 0 && axisproduct != gridSize )
+        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
+              gridptr->xsize, gridptr->ysize, gridSize);
     }
+}
 
-  {
-    char *strTab[] = ZAXIS_STR_SERIALIZE;
-    int numStr = sizeof (strTab) / sizeof (strTab[0]);
-    serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                          strTab, numStr, context);
-  }
+/*
+ at Function  gridInqYsize
+ at Title     Get the number of values of a Y-axis
 
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &zaxisP->positive, 1, DATATYPE_UCHAR, context);
+ at Prototype int gridInqYsize(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  if (memberMask & zaxisHasUUIDFlag)
-    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+ at Description
+The function @func{gridInqYsize} returns the number of values of a Y-axis.
 
-}
+ at Result
+ at func{gridInqYsize} returns the number of values of a Y-axis.
 
-static void
-zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
-          int * packBufferPos, void *context)
+ at EndFunction
+*/
+int gridInqYsize(int gridID)
 {
-  zaxis_t   * zaxisP = ( zaxis_t * ) voidP;
-  int intBuffer[zaxisNint];
-  int memberMask;
-  uint32_t d;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  intBuffer[0]  = zaxisP->self;
-  intBuffer[1]  = zaxisP->prec;
-  intBuffer[2]  = zaxisP->type;
-  intBuffer[3]  = zaxisP->ltype;
-  intBuffer[4]  = zaxisP->size;
-  intBuffer[5]  = zaxisP->direction;
-  intBuffer[6]  = zaxisP->vctsize;
-  intBuffer[7]  = memberMask = zaxisGetMemberMask ( zaxisP );
+  return (gridptr->ysize);
+}
 
-  serializePack(intBuffer, zaxisNint, DATATYPE_INT,
-                packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_UINT32,
-                packBuffer, packBufferSize, packBufferPos, context);
+/*
+ at Function  gridDefNP
+ at Title     Define the number of parallels between a pole and the equator
 
+ at Prototype void gridDefNP(int gridID, int np)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  np       Number of parallels between a pole and the equator.
 
-  if ( memberMask & vals )
-    {
-      xassert(zaxisP->size);
-      serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+ at Description
+The function @func{gridDefNP} defines the number of parallels between a pole and the equator
+of a Gaussian grid.
 
-  if (memberMask & lbounds)
+ at EndFunction
+*/
+void gridDefNP(int gridID, int np)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if (gridptr->np != np)
     {
-      xassert(zaxisP->size);
-      serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+      gridptr->np = np;
     }
+}
 
-  if (memberMask & ubounds)
-    {
-      xassert(zaxisP->size);
+/*
+ at Function  gridInqNP
+ at Title     Get the number of parallels between a pole and the equator
 
-      serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+ at Prototype int gridInqNP(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  if (memberMask & weights)
-    {
-      xassert(zaxisP->size);
+ at Description
+The function @func{gridInqNP} returns the number of parallels between a pole and the equator
+of a Gaussian grid.
 
-      serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+ at Result
+ at func{gridInqNP} returns the number of parallels between a pole and the equator.
 
-  if (memberMask & vct)
-    {
-      xassert(zaxisP->vctsize);
+ at EndFunction
+*/
+int gridInqNP(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-      serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
-                    packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
-      serializePack(&d, 1, DATATYPE_UINT32,
-                    packBuffer, packBufferSize, packBufferPos, context);
-    }
+  return (gridptr->np);
+}
 
-  {
-    const char *strTab[] = ZAXIS_STR_SERIALIZE;
-    int numStr = sizeof (strTab) / sizeof (strTab[0]);
-    serializeStrTabPack(strTab, numStr,
-                        packBuffer, packBufferSize, packBufferPos, context);
-  }
+/*
+ at Function
+ at Title
 
-  serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
-                packBuffer, packBufferSize, packBufferPos, context);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if (memberMask & zaxisHasUUIDFlag)
-    serializePack(zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
-                  packBuffer, packBufferSize, packBufferPos, context);
+ at EndFunction
+*/
+void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  gridptr->rowlon = (int *)xmalloc((size_t)nrowlon * sizeof(int));
+  gridptr->nrowlon = nrowlon;
+  memcpy(gridptr->rowlon, rowlon, (size_t)nrowlon * sizeof(int));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-void zaxisGetIndexList ( int nzaxis, int * zaxisResHs )
+ at EndFunction
+*/
+void gridInqRowlon(int gridID, int *rowlon)
 {
-  reshGetResHListOfType ( nzaxis, zaxisResHs, &zaxisOps );
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->rowlon == 0 )  Error("undefined pointer!");
+
+  memcpy(rowlon, gridptr->rowlon, (size_t)gridptr->nrowlon * sizeof(int));
 }
 
-#undef ZAXIS_STR_SERIALIZE
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+int gridInqMask(int gridID, int *mask)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
+  long size = gridptr->size;
+
+  if ( CDI_Debug && size == 0 )
+    Warning("Size undefined for gridID = %d", gridID);
 
+  if (mask && gridptr->mask)
+    for (long i = 0; i < size; ++i)
+      mask[i] = (int)gridptr->mask[i];
 
-extern int CDF_Debug;
+  if ( gridptr->mask == NULL ) size = 0;
 
-#if  defined  (HAVE_LIBNETCDF)
-/*
-#if ! defined (MIN_BUF_SIZE)
-#  define  MIN_BUF_SIZE  131072L
-#endif
+  return (int)size;
+}
 
-static size_t ChunkSizeMin = MIN_BUF_SIZE;
-*/
-void cdf_create(const char *path, int cmode, int *ncidp)
+
+void gridDefMask(int gridID, const int *mask)
 {
-  int status;
-  int oldfill;
-  size_t initialsz = 0, chunksizehint = 0;
-  /*
-#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
-  struct stat filestat;
-  char basename[1024];
-  char *pend;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  pend = strrchr(path, '/');
-  if ( pend == 0 )
-    strcpy(basename, "./");
-  else
-    {
-      memcpy(basename, path, pend-path);
-      basename[pend-path] = 0;
-    }
+  long size = gridptr->size;
 
-  if ( stat(basename, &filestat) != 0 )
-    SysError(basename);
+  if ( size == 0 )
+    Error("Size undefined for gridID = %d", gridID);
 
-  chunksizehint = (size_t) filestat.st_blksize * 4;
-#endif
+  if ( mask == NULL )
+    {
+      if ( gridptr->mask )
+	{
+	  free(gridptr->mask);
+	  gridptr->mask = NULL;
+	}
+    }
+  else
+    {
+      if ( gridptr->mask == NULL )
+	gridptr->mask = (mask_t *)xmalloc((size_t)size*sizeof(mask_t));
+      else if ( CDI_Debug )
+	Warning("grid mask already defined!");
 
-  if ( chunksizehint < ChunkSizeMin ) chunksizehint = ChunkSizeMin;
-  */
-#if defined(__SX__) || defined(ES)
-  chunksizehint = 16777216; /* 16 MB */
-#endif
+      for (long i = 0; i < size; ++i )
+	gridptr->mask[i] = (mask_t)(mask[i] != 0);
+    }
+}
 
-  if ( cdiNcChunksizehint != CDI_UNDEFID )
-    chunksizehint = (size_t)cdiNcChunksizehint;
 
-  cdi_nc__create_funcp my_nc__create =
-    (cdi_nc__create_funcp)namespaceSwitchGet(NSSWITCH_NC__CREATE).func;
-  status = my_nc__create(path, cmode, initialsz, &chunksizehint, ncidp);
+int gridInqMaskGME(int gridID, int *mask)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  mode = %d  file = %s", *ncidp, cmode, path);
+  long size = gridptr->size;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("chunksizehint %d", chunksizehint);
+  if ( CDI_Debug && size == 0 )
+    Warning("Size undefined for gridID = %d", gridID);
 
-  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
+  if ( mask && gridptr->mask_gme )
+    for (long i = 0; i < size; ++i)
+      mask[i] = (int)gridptr->mask_gme[i];
 
-  status = nc_set_fill(*ncidp, NC_NOFILL, &oldfill);
+  if ( gridptr->mask_gme == NULL ) size = 0;
 
-  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
+  return (int)size;
 }
 
 
-int cdf_open(const char *path, int omode, int *ncidp)
+void gridDefMaskGME(int gridID, const int *mask)
 {
-  int status = 0;
-  int dapfile = FALSE;
-  struct stat filestat;
-  size_t chunksizehint = 0;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-#if  defined  (HAVE_LIBNC_DAP)
-  if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = TRUE;
-#endif
+  long size = gridptr->size;
 
-  if ( dapfile )
-    {
-      status = nc_open(path, omode, ncidp);
-    }
-  else
-    {
-      if ( stat(path, &filestat) != 0 ) SysError(path);
+  if ( size == 0 )
+    Error("Size undefined for gridID = %d", gridID);
 
-#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
-      chunksizehint = (size_t) filestat.st_blksize * 4;
-#endif
-      /*
-      if ( chunksizehint < ChunkSizeMin ) chunksizehint = ChunkSizeMin;
-      */
-      if ( cdiNcChunksizehint != CDI_UNDEFID )
-        chunksizehint = (size_t)cdiNcChunksizehint;
+  if ( gridptr->mask_gme == NULL )
+    gridptr->mask_gme = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
+  else if ( CDI_Debug )
+    Warning("mask already defined!");
 
-      /* FIXME: parallel part missing */
-      status = nc__open(path, omode, &chunksizehint, ncidp);
+  for (long i = 0; i < size; ++i)
+    gridptr->mask_gme[i] = (mask_t)(mask[i] != 0);
+}
 
-      if ( CDF_Debug ) Message("chunksizehint %d", chunksizehint);
-    }
+/*
+ at Function  gridInqXvals
+ at Title     Get all values of a X-axis
 
-  if ( CDF_Debug )
-    Message("ncid = %d  mode = %d  file = %s", *ncidp, omode, path);
+ at Prototype int gridInqXvals(int gridID, double *xvals)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  xvals    Pointer to the location into which the X-values are read.
+                    The caller must allocate space for the returned values.
 
-  if ( CDF_Debug && status != NC_NOERR ) Message("%s", nc_strerror(status));
+ at Description
+The function @func{gridInqXvals} returns all values of the X-axis.
 
-  return (status);
-}
+ at Result
+Upon successful completion @func{gridInqXvals} returns the number of values and
+the values are stored in @func{xvals}.
+Otherwise, 0 is returned and @func{xvals} is empty.
+
+ at EndFunction
+*/
+int gridInqXvals(int gridID, double *xvals)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  long size;
+  if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
+    size = gridptr->size;
+  else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
+    size = 2;
+  else
+    size = gridptr->xsize;
 
+  if ( CDI_Debug && size == 0 )
+    Warning("size undefined for gridID = %d", gridID);
 
-void cdf_close(int ncid)
-{
-  int status;
+  if ( size && xvals && gridptr->xvals )
+    memcpy(xvals, gridptr->xvals, (size_t)size * sizeof (double));
 
-  status = nc_close(ncid);
+  if ( gridptr->xvals == NULL ) size = 0;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (int)size;
 }
 
+/*
+ at Function  gridDefXvals
+ at Title     Define the values of a X-axis
 
-void cdf_redef(int ncid)
-{
-  int status;
-
-  status = nc_redef(ncid);
-
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+ at Prototype void gridDefXvals(int gridID, const double *xvals)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  xvals    X-values of the grid.
 
+ at Description
+The function @func{gridDefXvals} defines all values of the X-axis.
 
-void cdf_enddef(int ncid)
+ at EndFunction
+*/
+void gridDefXvals(int gridID, const double *xvals)
 {
-  int status;
-
-  status = nc_enddef(ncid);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  int gridtype;
+  long size;
 
+  gridtype = gridptr->type;
 
-void cdf__enddef(const int ncid, const size_t hdr_pad)
-{
-  int status;
-  const size_t v_align   = 4UL; /* [B] Alignment of beginning of data section for fixed variables */
-  const size_t v_minfree = 0UL; /* [B] Pad at end of data section for fixed size variables */
-  const size_t r_align   = 4UL; /* [B] Alignment of beginning of data section for record variables */
+  if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
+    size = gridptr->size;
+  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+    size = 2;
+  else
+    size = gridptr->xsize;
 
-  /* nc_enddef(ncid) is equivalent to nc__enddef(ncid, 0, 4, 0, 4) */
-  status = nc__enddef(ncid, hdr_pad, v_align, v_minfree, r_align);
+  if ( size == 0 )
+    Error("Size undefined for gridID = %d", gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->xvals && CDI_Debug)
+    Warning("values already defined!");
+  gridptr->xvals = (double *)xrealloc(gridptr->xvals,
+                                      (size_t)size * sizeof(double));
+  memcpy(gridptr->xvals, xvals, (size_t)size * sizeof (double));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
+/*
+ at Function  gridInqYvals
+ at Title     Get all values of a Y-axis
 
-void cdf_sync(int ncid)
-{
-  int status;
-
-  status = nc_sync(ncid);
+ at Prototype int gridInqYvals(int gridID, double *yvals)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  yvals    Pointer to the location into which the Y-values are read.
+                    The caller must allocate space for the returned values.
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+ at Description
+The function @func{gridInqYvals} returns all values of the Y-axis.
 
+ at Result
+Upon successful completion @func{gridInqYvals} returns the number of values and
+the values are stored in @func{yvals}.
+Otherwise, 0 is returned and @func{yvals} is empty.
 
-void cdf_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int *unlimdimidp)
+ at EndFunction
+*/
+int gridInqYvals(int gridID, double *yvals)
 {
-  int status;
-
-  status = nc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d ndims = %d nvars = %d ngatts = %d unlimid = %d",
-	    ncid, *ndimsp, *nvarsp, *ngattsp, *unlimdimidp);
+  int gridtype = gridptr->type;
+  long size
+    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+    ? gridptr->size : gridptr->ysize;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if ( CDI_Debug && size == 0 )
+    Warning("size undefined for gridID = %d!", gridID);
 
+  if ( size && yvals && gridptr->yvals )
+    memcpy(yvals, gridptr->yvals, (size_t)size * sizeof (double));
 
-void cdf_def_dim(int ncid, const char *name, size_t len, int *dimidp)
-{
-  int status;
+  if ( gridptr->yvals == NULL ) size = 0;
 
-  status = nc_def_dim(ncid, name, len, dimidp);
+  return (int)size;
+}
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  name = %s  len = %d", ncid, name, len);
+/*
+ at Function  gridDefYvals
+ at Title     Define the values of a Y-axis
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+ at Prototype void gridDefYvals(int gridID, const double *yvals)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  yvals    Y-values of the grid.
 
+ at Description
+The function @func{gridDefYvals} defines all values of the Y-axis.
 
-void cdf_inq_dimid(int ncid, const char *name, int *dimidp)
+ at EndFunction
+*/
+void gridDefYvals(int gridID, const double *yvals)
 {
-  int status;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  status = nc_inq_dimid(ncid, name, dimidp);
+  int gridtype = gridptr->type;
+  long size
+    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+    ? gridptr->size : gridptr->ysize;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  name = %s  dimid= %d", ncid, name, *dimidp);
+  if ( size == 0 )
+    Error("Size undefined for gridID = %d!", gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->yvals && CDI_Debug)
+    Warning("Values already defined!");
+
+  gridptr->yvals = (double *)xrealloc(gridptr->yvals, (size_t)size * sizeof (double));
+  memcpy(gridptr->yvals, yvals, (size_t)size * sizeof (double));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
 
-void cdf_inq_dim(int ncid, int dimid, char *name, size_t * lengthp)
+double gridInqXval(int gridID, int index)
 {
-  int status;
-
-  status = nc_inq_dim(ncid, dimid, name, lengthp);
+  double xval = 0;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  dimid = %d  length = %d name = %s", ncid, dimid, *lengthp, name);
+  if ( gridptr->xvals )
+    xval = gridptr->xvals[index];
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (xval);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_dimname(int ncid, int dimid, char *name)
-{
-  int status;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  status = nc_inq_dimname(ncid, dimid, name);
+ at EndFunction
+*/
+double gridInqYval(int gridID, int index)
+{
+  double yval = 0;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  dimid = %d  name = %s", ncid, dimid, name);
+  if ( gridptr->yvals )
+    yval = gridptr->yvals[index];
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (yval);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_dimlen(int ncid, int dimid, size_t * lengthp)
-{
-  int status;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  status = nc_inq_dimlen(ncid, dimid, lengthp);
+ at EndFunction
+*/
+double gridInqXinc(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d dimid = %d length = %d", ncid, dimid, *lengthp);
+  double xinc = gridptr->xinc;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if ( (! (fabs(xinc) > 0)) && gridptr->xvals )
+    {
+      int xsize = gridptr->xsize;
+      if ( xsize > 1 )
+        {
+          double *xvals = gridptr->xvals;
+          xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
+          int i;
+          for (i = 2; i < xsize; i++ )
+            if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc ) break;
 
+          if ( i < xsize ) xinc = 0;
+        }
+    }
 
-void cdf_def_var(int ncid, const char *name, nc_type xtype, int ndims,
-                 const int dimids[], int *varidp)
-{
-  cdi_cdf_def_var_funcp my_cdf_def_var
-    = (cdi_cdf_def_var_funcp)namespaceSwitchGet(NSSWITCH_CDF_DEF_VAR).func;
-  my_cdf_def_var(ncid, name, xtype, ndims, dimids, varidp);
+  return (xinc);
 }
 
-void
-cdf_def_var_serial(int ncid, const char *name, nc_type xtype, int ndims,
-                   const int dimids[], int *varidp)
-{
-  int status = nc_def_var(ncid, name, xtype, ndims, dimids, varidp);
+/*
+ at Function
+ at Title
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  name = %s  xtype = %d  ndims = %d  varid = %d",
-	    ncid, name, xtype, ndims, *varidp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+ at EndFunction
+*/
+double gridInqYinc(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  double yinc = gridptr->yinc;
 
+  if ( (! (fabs(yinc) > 0)) && gridptr->yvals )
+    {
+      int ysize;
+      double *yvals;
 
-void cdf_inq_varid(int ncid, const char *name, int *varidp)
-{
-  int status;
+      ysize = gridptr->ysize;
+      yvals = gridptr->yvals;
 
-  status = nc_inq_varid(ncid, name, varidp);
+      if ( ysize > 1 )
+        {
+          yinc = fabs(yvals[1] - yvals[0]);
+          int i;
+          for ( i = 2; i < ysize; i++ )
+            if ( fabs(fabs(yvals[i] - yvals[i-1]) - yinc) > (yinc/1000) ) break;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  name = %s  varid = %d ", ncid, name, *varidp);
+          if ( i < ysize ) yinc = 0;
+          else             yinc = yvals[1] - yvals[0];
+        }
+    }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (yinc);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_nvars(int ncid, int *nvarsp)
-{
-  int status;
-
-  status = nc_inq_nvars(ncid, nvarsp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d  nvars = %d", ncid, *nvarsp);
+ at EndFunction
+*/
+double gridInqXpole(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->xpole);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp,
-		 int dimids[], int *nattsp)
-{
-  int status;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  status = nc_inq_var(ncid, varid, name, xtypep, ndimsp, dimids, nattsp);
+ at EndFunction
+*/
+void gridDefXpole(int gridID, double xpole)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d ndims = %d xtype = %d natts = %d name = %s",
-	    ncid, varid, *ndimsp, *xtypep, *nattsp, name);
+  if ( memcmp(gridptr->xstdname, "grid", 4) != 0 )
+    strcpy(gridptr->xstdname, "grid_longitude");
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->xpole, xpole) )
+    {
+      gridptr->isRotated = TRUE;
+      gridptr->xpole = xpole;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_varname(int ncid, int varid, char *name)
-{
-  int status;
-
-  status = nc_inq_varname(ncid, varid, name);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
+ at EndFunction
+*/
+double gridInqYpole(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->ypole);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_vartype(int ncid, int varid, nc_type *xtypep)
-{
-  int status;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  status = nc_inq_vartype(ncid, varid, xtypep);
+ at EndFunction
+*/
+void gridDefYpole(int gridID, double ypole)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d xtype = %s", ncid, varid, *xtypep);
+  if ( memcmp(gridptr->ystdname, "grid", 4) != 0 )
+    strcpy(gridptr->ystdname, "grid_latitude");
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->ypole, ypole) )
+    {
+      gridptr->isRotated = TRUE;
+      gridptr->ypole = ypole;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_varndims(int ncid, int varid, int *ndimsp)
-{
-  int status;
-
-  status = nc_inq_varndims(ncid, varid, ndimsp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+ at EndFunction
+*/
+double gridInqAngle(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->angle);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_vardimid(int ncid, int varid, int dimids[])
-{
-  int status;
-
-  status = nc_inq_vardimid(ncid, varid, dimids);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+ at EndFunction
+*/
+void gridDefAngle(int gridID, double angle)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->angle, angle) )
+    {
+      gridptr->isRotated = TRUE;
+      gridptr->angle = angle;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_inq_varnatts(int ncid, int varid, int *nattsp)
-{
-  int status;
-
-  status = nc_inq_varnatts(ncid, varid, nattsp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d nattsp = %d", ncid, varid, *nattsp);
+ at EndFunction
+*/
+int gridInqGMEnd(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->nd);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_put_var_text(int ncid, int varid, const char *tp)
-{
-  int status;
-
-  status = nc_put_var_text(ncid, varid, tp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %s", ncid, varid, tp);
+ at EndFunction
+*/
+void gridDefGMEnd(int gridID, int nd)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->nd != nd)
+    {
+      gridptr->nd = nd;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_put_var_short(int ncid, int varid, const short *sp)
-{
-  int status;
-
-  status = nc_put_var_short(ncid, varid, sp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %hd", ncid, varid, *sp);
+ at EndFunction
+*/
+int gridInqGMEni(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->ni);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_put_var_int(int ncid, int varid, const int *ip)
-{
-  int status;
-
-  status = nc_put_var_int(ncid, varid, ip);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %d", ncid, varid, *ip);
+ at EndFunction
+*/
+void gridDefGMEni(int gridID, int ni)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->ni != ni)
+    {
+      gridptr->ni = ni;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_put_var_long(int ncid, int varid, const long *lp)
-{
-  int status;
-
-  status = nc_put_var_long(ncid, varid, lp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %ld", ncid, varid, *lp);
+ at EndFunction
+*/
+int gridInqGMEni2(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridptr->ni2);
 }
 
+/*
+ at Function
+ at Title
 
-void cdf_put_var_float(int ncid, int varid, const float *fp)
-{
-  int status;
-
-  status = nc_put_var_float(ncid, varid, fp);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %f", ncid, varid, *fp);
+ at EndFunction
+*/
+void gridDefGMEni2(int gridID, int ni2)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->ni2 != ni2)
+    {
+      gridptr->ni2 = ni2;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-void cdf_put_vara_double(int ncid, int varid, const size_t start[],
-                         const size_t count[], const double *dp)
+ at EndFunction
+*/
+int gridInqGMEni3(int gridID)
 {
-  int status;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  status = nc_put_vara_double(ncid, varid, start, count, dp);
+  return (gridptr->ni3);
+}
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+void gridDefGMEni3(int gridID, int ni3)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR )
+  if (gridptr->ni3 != ni3)
     {
-      char name[256];
-      nc_inq_varname(ncid, varid, name);
-      Message("varname = %s", name);
+      gridptr->ni3 = ni3;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
+/*
+ at Function
+ at Title
 
-void  cdf_put_vara_float(int ncid, int varid, const size_t start[],
-                         const size_t count[], const float *fp)
-{
-  int status;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  status = nc_put_vara_float(ncid, varid, start, count, fp);
+ at EndFunction
+*/
+void gridChangeType(int gridID, int gridtype)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *fp);
+  if ( CDI_Debug )
+    Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if (gridptr->type != gridtype)
+    {
+      gridptr->type = gridtype;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
-
-void  cdf_get_vara_int(int ncid, int varid, const size_t start[],
-                       const size_t count[], int *dp)
+static
+void grid_check_cyclic(grid_t *gridptr)
 {
-  int status;
-
-  status = nc_get_vara_int(ncid, varid, start, count, dp);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  int xsize, ysize;
+  long i1, i2, in, j, k1, k2, nc;
+  double xinc, x0;
+  const double *xvals, *xbounds;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  gridptr->isCyclic = FALSE;
 
+  xsize = gridptr->xsize;
+  ysize = gridptr->ysize;
+  xvals = gridptr->xvals;
+  xbounds = gridptr->xbounds;
 
-void  cdf_get_vara_double(int ncid, int varid, const size_t start[],
-                          const size_t count[], double *dp)
-{
-  int status;
+  if ( gridptr->type == GRID_GAUSSIAN || gridptr->type == GRID_LONLAT )
+    {
+      if ( xvals && xsize > 1 )
+        {
+          xinc = xvals[1] - xvals[0];
+          if ( IS_EQUAL(xinc, 0) ) xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
 
-  status = nc_get_vara_double(ncid, varid, start, count, dp);
+          x0 = 2*xvals[xsize-1]-xvals[xsize-2]-360;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+          if ( IS_NOT_EQUAL(xvals[0], xvals[xsize-1]) )
+            if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
+        }
+    }
+  else if ( gridptr->type == GRID_CURVILINEAR )
+    {
+      if ( xvals && xsize > 1 )
+        {
+          double val1, val2, valn;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+          nc = 0;
+          gridptr->isCyclic = FALSE;
+          for ( j = 0; j < ysize; ++j )
+            {
+              i1 = j*xsize;
+              i2 = j*xsize+1;
+              in = j*xsize+(xsize-1);
+              val1 = xvals[i1];
+              val2 = xvals[i2];
+              valn = xvals[in];
 
+              xinc = fabs(val2-val1);
 
-void  cdf_get_vara_float(int ncid, int varid, const size_t start[],
-                         const size_t count[], float *fp)
-{
-  int status;
+	      if ( val1 <    1 && valn > 300 ) val1 += 360;
+	      if ( valn <    1 && val1 > 300 ) valn += 360;
+	      if ( val1 < -179 && valn > 120 ) val1 += 360;
+	      if ( valn < -179 && val1 > 120 ) valn += 360;
+              if ( fabs(valn-val1) > 180 ) val1 += 360;
 
-  status = nc_get_vara_float(ncid, varid, start, count, fp);
+              if ( valn > val1 ) x0 = valn - xinc;
+              else               x0 = valn + xinc;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+              if ( fabs(x0-val1) < 0.5*xinc ) nc++;
+            }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+          if ( nc > 0.5*ysize ) gridptr->isCyclic = TRUE;
+        }
 
+      if ( xbounds && xsize > 1 )
+	{
+	  double val1, val2;
 
-void  cdf_get_vara_text(int ncid, int varid, const size_t start[],
-			const size_t count[], char *tp)
-{
-  int status;
+	  gridptr->isCyclic = TRUE;
+	  for ( j = 0; j < ysize; ++j )
+	    {
+	      i1 = j*xsize*4;
+	      i2 = j*xsize*4+(xsize-1)*4;
+	      nc = 0;
+	      for ( k1 = 0; k1 < 4; ++k1 )
+		{
+		  val1 = xbounds[i1+k1];
+		  for ( k2 = 0; k2 < 4; ++k2 )
+		    {
+		      val2 = xbounds[i2+k2];
 
-  status = nc_get_vara_text(ncid, varid, start, count, tp);
+		      if ( val1 <    1 && val2 > 300 ) val1 += 360;
+		      if ( val2 <    1 && val1 > 300 ) val2 += 360;
+		      if ( val1 < -179 && val2 > 120 ) val1 += 360;
+		      if ( val2 < -179 && val1 > 120 ) val2 += 360;
+                      if ( fabs(val2-val1) > 180 ) val1 += 360;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+		      if ( fabs(val1-val2) < 0.001 )
+			{
+			  nc++;
+			  break;
+			}
+		    }
+		}
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+	      if ( nc < 1 )
+		{
+		  gridptr->isCyclic = FALSE;
+		  break;
+		}
+	    }
+	}
+    }
 }
 
 
-void  cdf_get_vara_uchar(int ncid, int varid, const size_t start[], const size_t count[], unsigned char *tp)
+int gridIsCircular(int gridID)
 {
-  int status;
-
-  status = nc_get_vara_uchar(ncid, varid, start, count, tp);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  if ( gridptr->isCyclic == CDI_UNDEFID ) grid_check_cyclic(gridptr);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return ( gridptr->isCyclic );
 }
 
 
-void cdf_put_var_double(int ncid, int varid, const double *dp)
+int gridIsRotated(int gridID)
 {
-  int status;
-
-  status = nc_put_var_double(ncid, varid, dp);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return ( gridptr->isRotated );
 }
 
-
-void cdf_get_var1_text(int ncid, int varid, const size_t index[], char *tp)
+static
+int compareXYvals(int gridID, long xsize, long ysize, double *xvals0, double *yvals0)
 {
-  int status;
+  long i;
+  int differ = 0;
 
-  status = nc_get_var1_text(ncid, varid, index, tp);
+  if ( !differ && xsize == gridInqXvals(gridID, NULL) )
+    {
+      double *xvals = (double *)xmalloc((size_t)xsize * sizeof (double));
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+      gridInqXvals(gridID, xvals);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+      for ( i = 0; i < xsize; ++i )
+	if ( fabs(xvals0[i] - xvals[i]) > 1.e-10 )
+	  {
+	    differ = 1;
+	    break;
+	  }
 
+      free(xvals);
+    }
 
-void cdf_get_var1_double(int ncid, int varid, const size_t index[], double *dp)
-{
-  int status;
+  if ( !differ && ysize == gridInqYvals(gridID, NULL) )
+    {
+      double *yvals = (double *)xmalloc((size_t)ysize * sizeof (double));
 
-  status = nc_get_var1_double(ncid, varid, index, dp);
+      gridInqYvals(gridID, yvals);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+      for ( i = 0; i < ysize; ++i )
+	if ( fabs(yvals0[i] - yvals[i]) > 1.e-10 )
+	  {
+	    differ = 1;
+	    break;
+	  }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+      free(yvals);
+    }
 
+  return (differ);
+}
 
-void cdf_put_var1_double(int ncid, int varid, const size_t index[], const double *dp)
+static
+int compareXYvals2(int gridID, int gridsize, double *xvals, double *yvals)
 {
-  int status;
+  int differ = 0;
 
-  status = nc_put_var1_double(ncid, varid, index, dp);
+  if ( !differ && ((xvals == NULL && gridInqXvalsPtr(gridID) != NULL) || (xvals != NULL && gridInqXvalsPtr(gridID) == NULL)) ) differ = 1;
+  if ( !differ && ((yvals == NULL && gridInqYvalsPtr(gridID) != NULL) || (yvals != NULL && gridInqYvalsPtr(gridID) == NULL)) ) differ = 1;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d val = %f", ncid, varid, *dp);
+  if ( !differ && xvals && gridInqXvalsPtr(gridID) )
+    {
+      if ( fabs(xvals[0] - gridInqXval(gridID, 0)) > 1.e-9 ||
+	   fabs(xvals[gridsize-1] - gridInqXval(gridID, gridsize-1)) > 1.e-9 )
+	differ = 1;
+    }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( !differ && yvals && gridInqYvalsPtr(gridID) )
+    {
+      if ( fabs(yvals[0] - gridInqYval(gridID, 0)) > 1.e-9 ||
+	   fabs(yvals[gridsize-1] - gridInqYval(gridID, gridsize-1)) > 1.e-9 )
+	differ = 1;
+    }
+
+  return (differ);
 }
 
 
-void cdf_get_var_text(int ncid, int varid, char *tp)
+int gridCompare(int gridID, const grid_t *grid)
 {
-  int status;
-
-  status = nc_get_var_text(ncid, varid, tp);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  int differ = 1;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if ( grid->type == gridInqType(gridID) || grid->type == GRID_GENERIC )
+    {
+      if ( grid->size == gridInqSize(gridID) )
+	{
+	  differ = 0;
+	  if ( grid->type == GRID_LONLAT )
+	    {
+	      /*
+	      printf("gridID      %d\n", gridID);
+	      printf("grid.xdef   %d\n", grid->xdef);
+	      printf("grid.ydef   %d\n", grid->ydef);
+	      printf("grid.xsize  %d\n", grid->xsize);
+	      printf("grid.ysize  %d\n", grid->ysize);
+	      printf("grid.xfirst %f\n", grid->xfirst);
+	      printf("grid.yfirst %f\n", grid->yfirst);
+	      printf("grid.xfirst %f\n", gridInqXval(gridID, 0));
+	      printf("grid.yfirst %f\n", gridInqYval(gridID, 0));
+	      printf("grid.xinc   %f\n", grid->xinc);
+	      printf("grid.yinc   %f\n", grid->yinc);
+	      printf("grid.xinc   %f\n", gridInqXinc(gridID));
+	      printf("grid.yinc   %f\n", gridInqYinc(gridID));
+	      */
+	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
+		{
+		  if ( grid->xdef == 2 && grid->ydef == 2 )
+		    {
+		      if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
+			   ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0) && IS_EQUAL(grid->yinc, 0)) &&
+			   IS_NOT_EQUAL(grid->xfirst, grid->xlast) && IS_NOT_EQUAL(grid->yfirst, grid->ylast) )
+			{
+			  if ( IS_NOT_EQUAL(grid->xfirst, gridInqXval(gridID, 0)) ||
+			       IS_NOT_EQUAL(grid->yfirst, gridInqYval(gridID, 0)))
+			    {
+			      differ = 1;
+			    }
+			  if ( !differ && fabs(grid->xinc) > 0 &&
+			       fabs(fabs(grid->xinc) - fabs(gridInqXinc(gridID))) > fabs(grid->xinc/1000))
+			    {
+			      differ = 1;
+			    }
+			  if ( !differ && fabs(grid->yinc) > 0 &&
+			       fabs(fabs(grid->yinc) - fabs(gridInqYinc(gridID))) > fabs(grid->yinc/1000))
+			    {
+			      differ = 1;
+			    }
+			}
+		    }
+		  else
+		    {
+		      if ( grid->xvals && grid->yvals )
+			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
+		    }
+		}
+	      else
+		differ = 1;
+	    }
+	  else if ( grid->type == GRID_GENERIC )
+	    {
+	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
+		{
+		  if ( grid->xdef == 1 && grid->ydef == 1 )
+		    {
+		      if ( grid->xvals && grid->yvals )
+			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
+		    }
+		}
+	      else if ( (grid->ysize == 0 || grid->ysize == 1) &&
+			grid->xsize == gridInqXsize(gridID)*gridInqYsize(gridID) )
+		{
+		}
+	      else
+		differ = 1;
+	    }
+	  else if ( grid->type == GRID_GAUSSIAN )
+	    {
+	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
+		{
+		  if ( grid->xdef == 2 && grid->ydef == 2 )
+		    {
+		      if ( ! (IS_EQUAL(grid->xfirst, 0) && IS_EQUAL(grid->xlast, 0) && IS_EQUAL(grid->xinc, 0)) &&
+			   ! (IS_EQUAL(grid->yfirst, 0) && IS_EQUAL(grid->ylast, 0)) )
+			if ( fabs(grid->xfirst - gridInqXval(gridID, 0)) > 0.0015 ||
+			     fabs(grid->yfirst - gridInqYval(gridID, 0)) > 0.0015 ||
+			     (fabs(grid->xinc)>0 && fabs(fabs(grid->xinc) - fabs(gridInqXinc(gridID))) > fabs(grid->xinc/1000)) )
+			  {
+			    differ = 1;
+			  }
+		    }
+		  else
+		    {
+		      if ( grid->xvals && grid->yvals )
+			differ = compareXYvals(gridID, grid->xsize, grid->ysize, grid->xvals, grid->yvals);
+		    }
+		}
+	      else
+		differ = 1;
+	    }
+	  else if ( grid->type == GRID_CURVILINEAR )
+	    {
+	      /*
+	      printf("gridID      %d\n", gridID);
+	      printf("grid.xsize  %d\n", grid->xsize);
+	      printf("grid.ysize  %d\n", grid->ysize);
+	      printf("grid.xfirst %f\n", grid->xvals[0]);
+	      printf("grid.yfirst %f\n", grid->yvals[0]);
+	      printf("grid xfirst %f\n", gridInqXval(gridID, 0));
+	      printf("grid yfirst %f\n", gridInqYval(gridID, 0));
+	      printf("grid.xlast  %f\n", grid->xvals[grid->size-1]);
+	      printf("grid.ylast  %f\n", grid->yvals[grid->size-1]);
+	      printf("grid xlast  %f\n", gridInqXval(gridID, grid->size-1));
+	      printf("grid ylast  %f\n", gridInqYval(gridID, grid->size-1));
+	      printf("grid.nv     %d\n", grid->nvertex);
+	      printf("grid nv     %d\n", gridInqNvertex(gridID));
+	      */
+	      if ( grid->xsize == gridInqXsize(gridID) && grid->ysize == gridInqYsize(gridID) )
+		differ = compareXYvals2(gridID, grid->size, grid->xvals, grid->yvals);
+	    }
+	  else if ( grid->type == GRID_UNSTRUCTURED )
+	    {
+              unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+              gridInqUUID(gridID, uuidOfHGrid);
 
+              if ( !differ && memcmp(uuidOfHGrid, grid->uuid, CDI_UUID_SIZE) != 0 ) differ = 1;
 
-void cdf_get_var_short(int ncid, int varid, short *sp)
-{
-  int status;
+              if ( !differ && grid->nvertex != gridInqNvertex(gridID) ) differ = 1;
 
-  status = nc_get_var_short(ncid, varid, sp);
+              if ( !differ && grid->number != gridInqNumber(gridID) ) differ = 1;
+              if ( !differ && grid->position != gridInqPosition(gridID) ) differ = 1;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+              if ( !differ && grid->nvertex != gridInqNvertex(gridID) ) differ = 1;
+              if ( !differ && grid->number != gridInqNumber(gridID) ) differ = 1;
+              if ( !differ && grid->number > 0 && grid->position != gridInqPosition(gridID) ) differ = 1;
+	      if ( !differ )
+		differ = compareXYvals2(gridID, grid->size, grid->xvals, grid->yvals);
+	    }
+	}
+    }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (differ);
 }
 
 
-void cdf_get_var_int(int ncid, int varid, int *ip)
+int gridCompareP ( void * gridptr1, void * gridptr2 )
 {
-  int status;
+  grid_t * g1 = ( grid_t * ) gridptr1;
+  grid_t * g2 = ( grid_t * ) gridptr2;
+  enum { equal = 0,
+         differ = -1 };
+  int i, size;
 
-  status = nc_get_var_int(ncid, varid, ip);
+  xassert ( g1 );
+  xassert ( g2 );
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  if ( g1->type          != g2->type         ) return differ;
+  if ( g1->prec          != g2->prec         ) return differ;
+  if ( g1->lcc_projflag  != g2->lcc_projflag ) return differ;
+  if ( g1->lcc_scanflag  != g2->lcc_scanflag ) return differ;
+  if ( g1->lcc_defined   != g2->lcc_defined  ) return differ;
+  if ( g1->lcc2_defined  != g2->lcc2_defined ) return differ;
+  if ( g1->laea_defined  != g2->laea_defined ) return differ;
+  if ( g1->isCyclic      != g2->isCyclic     ) return differ;
+  if ( g1->isRotated     != g2->isRotated    ) return differ;
+  if ( g1->xdef          != g2->xdef         ) return differ;
+  if ( g1->ydef          != g2->ydef         ) return differ;
+  if ( g1->nd            != g2->nd           ) return differ;
+  if ( g1->ni            != g2->ni           ) return differ;
+  if ( g1->ni2           != g2->ni2          ) return differ;
+  if ( g1->ni3           != g2->ni3          ) return differ;
+  if ( g1->number        != g2->number       ) return differ;
+  if ( g1->position      != g2->position     ) return differ;
+  if ( g1->trunc         != g2->trunc        ) return differ;
+  if ( g1->nvertex       != g2->nvertex      ) return differ;
+  if ( g1->nrowlon       != g2->nrowlon      ) return differ;
+  if ( g1->size          != g2->size         ) return differ;
+  if ( g1->xsize         != g2->xsize        ) return differ;
+  if ( g1->ysize         != g2->ysize        ) return differ;
+  if ( g1->locked        != g2->locked       ) return differ;
+  if ( g1->lcomplex      != g2->lcomplex     ) return differ;
+
+  if ( g1->rowlon )
+    {
+      for ( i = 0; i < g1->nrowlon; i++ )
+	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ;
+    }
+  else if ( g2->rowlon )
+    return differ;
+
+  if ( IS_NOT_EQUAL(g1->xfirst        , g2->xfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->yfirst	      , g2->yfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xlast         , g2->xlast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ylast         , g2->ylast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->xinc	      , g2->xinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->yinc	      , g2->yinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLon , g2->lcc_originLon) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLat , g2->lcc_originLat) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lonParY   , g2->lcc_lonParY)   ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat1      , g2->lcc_lat1)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat2      , g2->lcc_lat2)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_xinc      , g2->lcc_xinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_yinc      , g2->lcc_yinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lon_0    , g2->lcc2_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_0    , g2->lcc2_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_1    , g2->lcc2_lat_1)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_2    , g2->lcc2_lat_2)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_a        , g2->lcc2_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lon_0    , g2->laea_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lat_0    , g2->laea_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_a        , g2->laea_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xpole         , g2->xpole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ypole         , g2->ypole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->angle         , g2->angle)         ) return differ;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if ( g1->xvals )
+    {
+      if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
+	size = g1->size;
+      else
+	size = g1->xsize;
+      xassert ( size );
 
+      if ( !g2->xvals ) return differ;
 
-void cdf_get_var_long(int ncid, int varid, long *lp)
-{
-  int status;
+      for ( i = 0; i < size; i++ )
+	if ( IS_NOT_EQUAL(g1->xvals[i], g2->xvals[i]) ) return differ;
+    }
+  else if ( g2->xvals )
+    return differ;
 
-  status = nc_get_var_long(ncid, varid, lp);
+  if ( g1->yvals )
+    {
+      if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
+	size = g1->size;
+      else
+	size = g1->ysize;
+      xassert ( size );
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+      if ( !g2->yvals ) return differ;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+      for ( i = 0; i < size; i++ )
+        if ( IS_NOT_EQUAL(g1->yvals[i], g2->yvals[i]) ) return differ;
+    }
+  else if ( g2->yvals )
+    return differ;
 
+  if ( g1->area )
+    {
+      xassert ( g1->size );
 
-void cdf_get_var_float(int ncid, int varid, float *fp)
-{
-  int status;
+      if ( !g2->area ) return differ;
 
-  status = nc_get_var_float(ncid, varid, fp);
+      for ( i = 0; i < g1->size; i++ )
+	if ( IS_NOT_EQUAL(g1->area[i], g2->area[i]) ) return differ;
+    }
+  else if ( g2->area )
+    return differ;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  if ( g1->xbounds )
+    {
+      xassert ( g1->nvertex );
+      if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
+	size = g1->nvertex * g1->size;
+      else
+	size = g1->nvertex * g1->xsize;
+      xassert ( size );
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+      if ( !g2->xbounds ) return differ;
 
+      for ( i = 0; i < size; i++ )
+	if ( IS_NOT_EQUAL(g1->xbounds[i], g2->xbounds[i]) ) return differ;
+    }
+  else if ( g2->xbounds )
+    return differ;
 
-void cdf_get_var_double(int ncid, int varid, double *dp)
-{
-  int status;
+  if ( g1->ybounds )
+    {
+      xassert ( g1->nvertex );
+      if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
+	size = g1->nvertex * g1->size;
+      else
+	size = g1->nvertex * g1->ysize;
+      xassert ( size );
 
-  status = nc_get_var_double(ncid, varid, dp);
+      if ( !g2->ybounds ) return differ;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d val[0] = %f", ncid, varid, *dp);
+      for ( i = 0; i < size; i++ )
+	if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
+    }
+  else if ( g2->ybounds )
+    return differ;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if (strcmp(g1->xname, g2->xname)) return differ;
+  if (strcmp(g1->yname, g2->yname)) return differ;
+  if (strcmp(g1->xlongname, g2->xlongname)) return differ;
+  if (strcmp(g1->ylongname, g2->ylongname)) return differ;
+  if (strcmp(g1->xstdname, g2->xstdname)) return differ;
+  if (strcmp(g1->ystdname, g2->ystdname)) return differ;
+  if (strcmp(g1->xunits, g2->xunits)) return differ;
+  if (strcmp(g1->yunits, g2->yunits)) return differ;
 
+  if ( g1->reference )
+    {
+      if ( !g2->reference ) return differ;
+      if ( strcmp(g1->reference, g2->reference) ) return differ;
+    }
+  else if ( g2->reference )
+    return differ;
 
-void cdf_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out,
-		  int varid_out)
-{
-  int status;
+  if ( g1->mask )
+    {
+      xassert ( g1->size );
+      if ( !g2->mask ) return differ;
+      if ( memcmp ( g1->mask, g2->mask, (size_t)g1->size * sizeof(mask_t)) ) return differ;
+    }
+  else if ( g2->mask )
+    return differ;
 
-  status = nc_copy_att(ncid_in, varid_in, name, ncid_out, varid_out);
+  if ( g1->mask_gme )
+    {
+      xassert ( g1->size );
+      if ( !g2->mask_gme ) return differ;
+      if ( memcmp ( g1->mask_gme, g2->mask_gme, (size_t)g1->size * sizeof(mask_t)) ) return differ;
+    }
+  else if ( g2->mask_gme )
+    return differ;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %s %d %d", ncid_in, varid_out, name, ncid_out, varid_out);
+  if (memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE))
+    return differ;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return equal;
 }
 
 
-void cdf_put_att_text(int ncid, int varid, const char *name, size_t len,
-		      const char *tp)
+int gridGenerate(const grid_t *grid)
 {
-  int status;
-
-  status = nc_put_att_text(ncid, varid, name, len, tp);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s text = %s",
-	    ncid, varid, name, tp);
+  int gridID = gridCreate(grid->type, grid->size);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  gridDefPrec(gridID, grid->prec);
 
-void cdf_put_att_int(int ncid, int varid, const char *name, nc_type xtype,
-		     size_t len, const int *ip)
-{
-  int status;
+  switch (grid->type)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+    case GRID_UNSTRUCTURED:
+    case GRID_CURVILINEAR:
+    case GRID_GENERIC:
+    case GRID_LCC:
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
+    case GRID_PROJECTION:
+      {
+	if ( grid->xsize > 0 ) gridDefXsize(gridID, grid->xsize);
+	if ( grid->ysize > 0 ) gridDefYsize(gridID, grid->ysize);
 
-  status = nc_put_att_int(ncid, varid, name, xtype, len, ip);
+        if ( grid->type == GRID_GAUSSIAN ) gridDefNP(gridID, grid->np);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s val = %d", ncid, varid, name, *ip);
+	if ( grid->nvertex > 0 )
+	  gridDefNvertex(gridID, grid->nvertex);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+	if ( grid->xdef == 1 )
+	  {
+	    gridDefXvals(gridID, grid->xvals);
+	    if ( grid->xbounds )
+	      gridDefXbounds(gridID, grid->xbounds);
+	  }
+	else if ( grid->xdef == 2 )
+	  {
+	    double *xvals
+              = (double *)xmalloc((size_t)grid->xsize * sizeof (double));
+	    gridGenXvals(grid->xsize, grid->xfirst, grid->xlast, grid->xinc, xvals);
+	    gridDefXvals(gridID, xvals);
+	    free(xvals);
+	    /*
+	    gridDefXinc(gridID, grid->xinc);
+	    */
+	  }
 
+	if ( grid->ydef == 1 )
+	  {
+	    gridDefYvals(gridID, grid->yvals);
+	    if ( grid->ybounds && grid->nvertex )
+	      gridDefYbounds(gridID, grid->ybounds);
+	  }
+	else if ( grid->ydef == 2 )
+	  {
+	    double *yvals
+              = (double *)xmalloc((size_t)grid->ysize * sizeof (double));
+	    gridGenYvals(grid->type, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
+	    gridDefYvals(gridID, yvals);
+	    free(yvals);
+	    /*
+	    gridDefYinc(gridID, grid->yinc);
+	    */
+	  }
 
-void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype,
-			size_t len, const double *dp)
-{
-  int status;
+	if ( grid->isRotated )
+	  {
+	    gridDefXname(gridID, "rlon");
+	    gridDefYname(gridID, "rlat");
+	    gridDefXlongname(gridID, "longitude in rotated pole grid");
+	    gridDefYlongname(gridID, "latitude in rotated pole grid");
+	    strcpy(gridptr->xstdname, "grid_longitude");
+	    strcpy(gridptr->ystdname, "grid_latitude");
+	    gridDefXunits(gridID, "degrees");
+	    gridDefYunits(gridID, "degrees");
 
-  status = nc_put_att_double(ncid, varid, name, xtype, len, dp);
+	    gridDefXpole(gridID, grid->xpole);
+	    gridDefYpole(gridID, grid->ypole);
+	    gridDefAngle(gridID, grid->angle);
+	  }
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("%d %d %f", ncid, varid, *dp);
+	if ( grid->area )
+	  {
+	    gridDefArea(gridID, grid->area);
+	  }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+	if ( grid->type == GRID_LAEA )
+	  gridDefLaea(gridID, grid->laea_a, grid->laea_lon_0, grid->laea_lat_0);
 
+	if ( grid->type == GRID_LCC2 )
+	  gridDefLcc2(gridID, grid->lcc2_a, grid->lcc2_lon_0, grid->lcc2_lat_0, grid->lcc2_lat_1, grid->lcc2_lat_2);
 
-void cdf_get_att_text(int ncid, int varid, const char *name, char *tp)
-{
-  int status;
+	if ( grid->type == GRID_LCC )
+	  gridDefLCC(gridID, grid->lcc_originLon, grid->lcc_originLat, grid->lcc_lonParY,
+		     grid->lcc_lat1, grid->lcc_lat2, grid->lcc_xinc, grid->lcc_yinc,
+		     grid->lcc_projflag, grid->lcc_scanflag);
 
-  status = nc_get_att_text(ncid, varid, name, tp);
+	if ( grid->type == GRID_UNSTRUCTURED )
+          {
+            int number = grid->number;
+            int position = grid->position;
+            if ( position < 0 ) position = 0;
+            if ( number > 0 )
+              {
+                gridDefNumber(gridID, number);
+                gridDefPosition(gridID, position);
+              }
+            gridDefUUID(gridID, grid->uuid);
+            if ( grid->reference ) gridDefReference(gridID, grid->reference);
+          }
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
+	if ( grid->type == GRID_PROJECTION )
+	  {
+	    gridptr->name = strdup(grid->name);
+	  }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+	break;
+      }
+    case GRID_GAUSSIAN_REDUCED:
+      {
+	gridDefNP(gridID, grid->np);
+	gridDefYsize(gridID, grid->ysize);
+	gridDefRowlon(gridID, grid->ysize, grid->rowlon);
 
-void cdf_get_att_string(int ncid, int varid, const char *name, char **tp)
-{
-#if  defined  (HAVE_NETCDF4)
-  int status;
+        if ( grid->xdef == 2 )
+          {
+            double xvals[2];
+            xvals[0] = grid->xfirst;
+            xvals[1] = grid->xlast;
+            gridDefXvals(gridID, xvals);
+          }
 
-  status = nc_get_att_string(ncid, varid, name, tp);
+	if ( grid->ydef == 1 )
+	  {
+	    gridDefYvals(gridID, grid->yvals);
+	    if ( grid->ybounds && grid->nvertex )
+	      gridDefYbounds(gridID, grid->ybounds);
+	  }
+	else if ( grid->ydef == 2 )
+	  {
+	    double *yvals
+              = (double *)xmalloc((size_t)grid->ysize * sizeof (double));
+	    gridGenYvals(grid->type, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
+	    gridDefYvals(gridID, yvals);
+	    free(yvals);
+	    /*
+	    gridDefYinc(gridID, grid->yinc);
+	    */
+	  }
+	break;
+      }
+    case GRID_SPECTRAL:
+      {
+        gridDefTrunc(gridID, grid->trunc);
+        if ( grid->lcomplex ) gridDefComplexPacking(gridID, 1);
+        break;
+      }
+    case GRID_FOURIER:
+      {
+	gridDefTrunc(gridID, grid->trunc);
+	break;
+      }
+    case GRID_GME:
+      {
+        gridDefGMEnd(gridID, grid->nd);
+        gridDefGMEni(gridID, grid->ni);
+        gridDefGMEni2(gridID, grid->ni2);
+        gridDefGMEni3(gridID, grid->ni3);
+        break;
+      }
+      /*
+    case GRID_GENERIC:
+      {
+        if ( grid->xsize > 0 && grid->ysize > 0 )
+          {
+            gridDefXsize(gridID, grid->xsize);
+            gridDefYsize(gridID, grid->ysize);
+            if ( grid->xvals ) gridDefXvals(gridID, grid->xvals);
+            if ( grid->yvals ) gridDefYvals(gridID, grid->yvals);
+          }
+        break;
+      }
+      */
+    case GRID_TRAJECTORY:
+      {
+        gridDefXsize(gridID, 1);
+        gridDefYsize(gridID, 1);
+        break;
+      }
+    default:
+      {
+	Error("Gridtype %s unsupported!", gridNamePtr(grid->type));
+	break;
+      }
+    }
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d name = %s", ncid, varid, name);
+  if ( grid->xname[0]     ) gridDefXname(gridID, grid->xname);
+  if ( grid->xlongname[0] ) gridDefXlongname(gridID, grid->xlongname);
+  if ( grid->xunits[0]    ) gridDefXunits(gridID, grid->xunits);
+  if ( grid->yname[0]     ) gridDefYname(gridID, grid->yname);
+  if ( grid->ylongname[0] ) gridDefYlongname(gridID, grid->ylongname);
+  if ( grid->yunits[0]    ) gridDefYunits(gridID, grid->yunits);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-#endif
+  return (gridID);
 }
 
+/*
+ at Function  gridDuplicate
+ at Title     Duplicate a horizontal Grid
 
-void cdf_get_att_int(int ncid, int varid, const char *name, int *ip)
-{
-  int status;
-
-  status = nc_get_att_int(ncid, varid, name, ip);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s val = %d", ncid, varid, name, *ip);
+ at Prototype int gridDuplicate(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+ at Description
+The function @func{gridDuplicate} duplicates a horizontal Grid.
 
+ at Result
+ at func{gridDuplicate} returns an identifier to the duplicated Grid.
 
-void cdf_get_att_double(int ncid, int varid, const char *name, double *dp)
+ at EndFunction
+*/
+int gridDuplicate(int gridID)
 {
-  int status;
-
-  status = nc_get_att_double(ncid, varid, name, dp);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s val = %.9g",
-	    ncid, varid, name, *dp);
+  grid_t *gridptr = reshGetVal(gridID, &gridOps);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  int gridtype = gridInqType(gridID);
+  int gridsize = gridInqSize(gridID);
 
+  int gridIDnew = gridCreate(gridtype, gridsize);
+  grid_t *gridptrnew = reshGetVal(gridIDnew, &gridOps);
 
-void cdf_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
-		 size_t *lenp)
-{
-  int status;
+  grid_copy(gridptrnew, gridptr);
 
-  status = nc_inq_att(ncid, varid, name, xtypep, lenp);
+  strcpy(gridptrnew->xname, gridptr->xname);
+  strcpy(gridptrnew->yname, gridptr->yname);
+  strcpy(gridptrnew->xlongname, gridptr->xlongname);
+  strcpy(gridptrnew->ylongname, gridptr->ylongname);
+  strcpy(gridptrnew->xunits, gridptr->xunits);
+  strcpy(gridptrnew->yunits, gridptr->yunits);
+  strcpy(gridptrnew->xstdname, gridptr->xstdname);
+  strcpy(gridptrnew->ystdname, gridptr->ystdname);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+  if (gridptr->reference)
+    gridptrnew->reference = strdupx(gridptr->reference);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  size_t nrowlon = (size_t)gridptr->nrowlon;
+  int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
+  if ( nrowlon )
+    {
+      gridptrnew->rowlon = (int *)xmalloc(nrowlon * sizeof (int));
+      memcpy(gridptrnew->rowlon, gridptr->rowlon, nrowlon * sizeof(int));
+    }
 
+  if ( gridptr->xvals != NULL )
+    {
+      size_t size  = (size_t)(irregular ? gridsize : gridptr->xsize);
 
-void cdf_inq_atttype(int ncid, int varid, const char *name, nc_type * xtypep)
-{
-  int status;
+      gridptrnew->xvals = (double *)xmalloc(size * sizeof (double));
+      memcpy(gridptrnew->xvals, gridptr->xvals, size * sizeof (double));
+    }
 
-  status = nc_inq_atttype(ncid, varid, name, xtypep);
+  if ( gridptr->yvals != NULL )
+    {
+      size_t size  = (size_t)(irregular ? gridsize : gridptr->ysize);
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+      gridptrnew->yvals = xmalloc(size * sizeof (double));
+      memcpy(gridptrnew->yvals, gridptr->yvals, size * sizeof (double));
+    }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+  if ( gridptr->xbounds != NULL )
+    {
+      size_t size  = (size_t)(irregular ? gridsize : gridptr->xsize)
+        * (size_t)gridptr->nvertex;
 
+      gridptrnew->xbounds = xmalloc(size * sizeof (double));
+      memcpy(gridptrnew->xbounds, gridptr->xbounds, size * sizeof (double));
+    }
 
-void cdf_inq_attlen(int ncid, int varid, const char *name, size_t * lenp)
-{
-  int status;
+  if ( gridptr->ybounds != NULL )
+    {
+      size_t size = (size_t)(irregular ? gridsize : gridptr->ysize)
+        * (size_t)gridptr->nvertex;
 
-  status = nc_inq_attlen(ncid, varid, name, lenp);
+      gridptrnew->ybounds = xmalloc(size * sizeof (double));
+      memcpy(gridptrnew->ybounds, gridptr->ybounds, size * sizeof (double));
+    }
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d name = %s len = %d", ncid, varid, name, *lenp);
+  if ( gridptr->area != NULL )
+    {
+      size_t size = (size_t)gridsize;
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+      gridptrnew->area = xmalloc(size * sizeof (double));
+      memcpy(gridptrnew->area, gridptr->area, size * sizeof (double));
+    }
 
+  if ( gridptr->mask != NULL )
+    {
+      size_t size = (size_t)gridsize;
 
-void cdf_inq_attname(int ncid, int varid, int attnum, char *name)
-{
-  int status;
+      gridptrnew->mask = xmalloc(size * sizeof(mask_t));
+      memcpy(gridptrnew->mask, gridptr->mask, size * sizeof (mask_t));
+    }
 
-  status = nc_inq_attname(ncid, varid, attnum, name);
+  if ( gridptr->mask_gme != NULL )
+    {
+      size_t size = (size_t)gridsize;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d attnum = %d name = %s", ncid, varid, attnum, name);
+      gridptrnew->mask_gme = xmalloc(size * sizeof (mask_t));
+      memcpy(gridptrnew->mask_gme, gridptr->mask_gme, size * sizeof(mask_t));
+    }
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  return (gridIDnew);
 }
 
 
-void cdf_inq_attid(int ncid, int varid, const char *name, int *attnump)
+void gridCompress(int gridID)
 {
-  int status;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  status = nc_inq_attid(ncid, varid, name, attnump);
+  int gridtype = gridInqType(gridID);
+  if ( gridtype == GRID_UNSTRUCTURED )
+    {
+      if ( gridptr->mask_gme != NULL )
+	{
+          size_t gridsize = (size_t)gridInqSize(gridID);
+	  size_t nv = (size_t)gridptr->nvertex;
 
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d", ncid, varid);
+	  size_t j = 0;
+          double *area = gridptr->area,
+            *xvals = gridptr->xvals,
+            *yvals = gridptr->yvals,
+            *xbounds = gridptr->xbounds,
+            *ybounds = gridptr->ybounds;
+          mask_t *mask_gme = gridptr->mask_gme;
+	  for (size_t i = 0; i < gridsize; i++ )
+	    {
+	      if (mask_gme[i])
+		{
+		  if (xvals) xvals[j] = xvals[i];
+		  if (yvals) yvals[j] = yvals[i];
+		  if (area) area[j]  = area[i];
+		  if (xbounds != NULL)
+		    for (size_t iv = 0; iv < nv; iv++)
+		      xbounds[j * nv + iv] = xbounds[i * nv + iv];
+		  if (ybounds != NULL)
+		    for (size_t iv = 0; iv < nv; iv++)
+		      ybounds[j * nv + iv] = ybounds[i * nv + iv];
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-}
+		  j++;
+		}
+	    }
 
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+	  /* fprintf(stderr, "grid compress %d %d %d\n", i, j, gridsize); */
+	  gridsize = j;
+	  gridptr->size  = (int)gridsize;
+	  gridptr->xsize = (int)gridsize;
+	  gridptr->ysize = (int)gridsize;
 
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
+	  if ( gridptr->xvals )
+	    gridptr->xvals = (double *)xrealloc(gridptr->xvals, gridsize*sizeof(double));
 
-const char *cdiStringError(int cdiErrno)
-{
-  static const char UnknownError[] = "Unknown Error";
-  static const char _EUFTYPE[]     = "Unsupported file type";
-  static const char _ELIBNAVAIL[]  = "Unsupported file type (library support not compiled in)";
-  static const char _EUFSTRUCT[]   = "Unsupported file structure";
-  static const char _EUNC4[]       = "Unsupported netCDF4 structure";
-  static const char _ELIMIT[]      = "Internal limits exceeded";
+	  if ( gridptr->yvals )
+	    gridptr->yvals = (double *)xrealloc(gridptr->yvals, gridsize*sizeof(double));
 
-  switch (cdiErrno) {
-  case CDI_ESYSTEM:
-    {
-      char *cp = (char *) strerror(errno);
-      if ( cp == NULL ) break;
-      return cp;
-    }
-  case CDI_EUFTYPE:    return _EUFTYPE;
-  case CDI_ELIBNAVAIL: return _ELIBNAVAIL;
-  case CDI_EUFSTRUCT:  return _EUFSTRUCT;
-  case CDI_EUNC4:      return _EUNC4;
-  case CDI_ELIMIT:     return _ELIMIT;
-  }
+	  if ( gridptr->area )
+	    gridptr->area  = (double *)xrealloc(gridptr->area, gridsize*sizeof(double));
 
-  return UnknownError;
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <stdio.h>
+	  if ( gridptr->xbounds )
+	    gridptr->xbounds = (double *)xrealloc(gridptr->xbounds, nv*gridsize*sizeof(double));
 
-void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
-{
-  unsigned uparam = (unsigned)param;
-  unsigned upnum;
+	  if ( gridptr->ybounds )
+	    gridptr->ybounds = (double *)xrealloc(gridptr->ybounds, nv*gridsize*sizeof(double));
 
-  *pdis = 0xff   & uparam;
-  *pcat = 0xff   & uparam >> 8;
-  upnum = 0xffff & uparam >> 16;
-  if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
-  *pnum = (int)upnum;
+	  free(gridptr->mask_gme);
+	  gridptr->mask_gme = NULL;
+          reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+	}
+    }
+  else
+    Warning("Unsupported grid type: %s", gridNamePtr(gridtype));
 }
 
 
-int cdiEncodeParam(int pnum, int pcat, int pdis)
+void gridDefArea(int gridID, const double *area)
 {
-  unsigned uparam, upnum;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( pcat < 0 || pcat > 255 ) pcat = 255;
-  if ( pdis < 0 || pdis > 255 ) pdis = 255;
+  size_t size = (size_t)gridptr->size;
 
-  upnum = (unsigned)pnum;
-  if ( pnum < 0 ) upnum = (unsigned)(0x8000 - pnum);
+  if ( size == 0 )
+    Error("size undefined for gridID = %d", gridID);
 
-  uparam = upnum << 16 | (unsigned)(pcat << 8) | (unsigned)pdis;
+  if ( gridptr->area == NULL )
+    gridptr->area = (double *)xmalloc(size*sizeof(double));
+  else if ( CDI_Debug )
+    Warning("values already defined!");
 
-  return ((int)uparam);
+  memcpy(gridptr->area, area, size * sizeof(double));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
 
-void cdiDecodeDate(int date, int *year, int *month, int *day)
+void gridInqArea(int gridID, double *area)
 {
-  int idate;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  *year  =  date / 10000;
-  idate  = date - *year*10000;
-  if ( idate < 0 ) idate = -idate;
-  *month = idate / 100;
-  *day   = idate - *month*100;
+  if (gridptr->area)
+    memcpy(area, gridptr->area, (size_t)gridptr->size * sizeof (double));
 }
 
 
-int cdiEncodeDate(int year, int month, int day)
+int gridHasArea(int gridID)
 {
-  int date;
-  int iyear;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  iyear = year;
-  if ( iyear < 0 ) iyear = -iyear;
-  date = iyear*10000 + month*100 + day;
-  if ( year < 0 ) date = -date;
+  int hasArea = (gridptr->area != NULL);
 
-  return (date);
+  return (hasArea);
 }
 
 
-void cdiDecodeTime(int time, int *hour, int *minute, int *second)
+const double *gridInqAreaPtr(int gridID)
 {
-  int itime;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  *hour   = time / 10000;
-  itime   = time - *hour*10000;
-  *minute = itime / 100;
-  *second = itime - *minute*100;
+  return (gridptr->area);
 }
 
 
-int cdiEncodeTime(int hour, int minute, int second)
+void gridDefNvertex(int gridID, int nvertex)
 {
-  int time;
-
-  time = hour*10000 + minute*100 + second;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  return (time);
+  if (gridptr->nvertex != nvertex)
+    {
+      gridptr->nvertex = nvertex;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 
-void cdiParamToString(int param, char *paramstr, int maxlen)
+int gridInqNvertex(int gridID)
 {
-  int dis, cat, num;
-  int len;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  cdiDecodeParam(param, &num, &cat, &dis);
+  return (gridptr->nvertex);
+}
 
-  if ( dis == 255 && (cat == 255 || cat == 0 ) )
-    len = sprintf(paramstr, "%d", num);
-  else  if ( dis == 255 )
-    len = sprintf(paramstr, "%d.%d", num, cat);
-  else
-    len = sprintf(paramstr, "%d.%d.%d", num, cat, dis);
+/*
+ at Function  gridDefXbounds
+ at Title     Define the bounds of a X-axis
 
-  if ( len > ( maxlen-1) )
-    fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
-}
+ at Prototype void gridDefXbounds(int gridID, const double *xbounds)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  xbounds  X-bounds of the grid.
 
+ at Description
+The function @func{gridDefXbounds} defines all bounds of the X-axis.
 
-char *cdiUnitNamePtr(int cdi_unit)
+ at EndFunction
+*/
+void gridDefXbounds(int gridID, const double *xbounds)
 {
-  char *cdiUnits[] = {
-    /*  0 */  "undefined",
-    /*  1 */  "Pa",
-    /*  2 */  "hPa",
-    /*  3 */  "mm",
-    /*  4 */  "cm",
-    /*  5 */  "dm",
-    /*  6 */  "m",
-  };
-  char *name;
-  int size = (int) (sizeof(cdiUnits)/sizeof(char *));
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( cdi_unit > 0 && cdi_unit < size )
-    name = cdiUnits[cdi_unit];
-  else
-    name = NULL;
+  size_t nvertex = (size_t)gridptr->nvertex;
+  if ( nvertex == 0 )
+    {
+      Warning("nvertex undefined for gridID = %d. Cannot define bounds!", gridID);
+      return;
+    }
 
-  return (name);
+  int irregular = gridptr->type == GRID_CURVILINEAR
+    || gridptr->type == GRID_UNSTRUCTURED;
+  size_t size = nvertex
+    * (size_t)(irregular ? gridptr->size : gridptr->xsize);
+  if ( size == 0 )
+    Error("size undefined for gridID = %d", gridID);
+
+  if (gridptr->xbounds == NULL)
+    gridptr->xbounds = xmalloc(size * sizeof (double));
+  else if ( CDI_Debug )
+    Warning("values already defined!");
+
+  memcpy(gridptr->xbounds, xbounds, size * sizeof (double));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ at Function  gridInqXbounds
+ at Title     Get the bounds of a X-axis
 
-#include <stdarg.h>
-#include <ctype.h>
+ at Prototype int gridInqXbounds(int gridID, double *xbounds)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  xbounds  Pointer to the location into which the X-bounds are read.
+                    The caller must allocate space for the returned values.
 
-#ifdef HAVE_LIBNETCDF
-#endif
+ at Description
+The function @func{gridInqXbounds} returns the bounds of the X-axis.
 
-#if  defined  (HAVE_LIBCGRIBEX)
-#endif
+ at Result
+Upon successful completion @func{gridInqXbounds} returns the number of bounds and
+the bounds are stored in @func{xbounds}.
+Otherwise, 0 is returned and @func{xbounds} is empty.
 
-extern int cdiPioSerialOpenFileMap(int streamID);
+ at EndFunction
+*/
+int gridInqXbounds(int gridID, double *xbounds)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
+  size_t nvertex = (size_t)gridptr->nvertex;
 
-int cdiDefaultInstID   = CDI_UNDEFID;
-int cdiDefaultModelID  = CDI_UNDEFID;
-int cdiDefaultTableID  = CDI_UNDEFID;
-//int cdiNcMissingValue  = CDI_UNDEFID;
-int cdiNcChunksizehint = CDI_UNDEFID;
-int cdiChunkType       = CHUNK_GRID;
-int cdiSplitLtype105   = CDI_UNDEFID;
+  int irregular = gridptr->type == GRID_CURVILINEAR
+    || gridptr->type == GRID_UNSTRUCTURED;
+  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->xsize);
 
-int cdiIgnoreAttCoordinates = FALSE;
-int cdiIgnoreValidRange     = FALSE;
-int cdiSkipRecords          = 0;
-int cdiInventoryMode        = 1;
-size_t CDI_netcdf_hdr_pad   = 0UL;
+  if ( size && xbounds && gridptr->xbounds )
+    memcpy(xbounds, gridptr->xbounds, size * sizeof (double));
 
-char *cdiPartabPath   = NULL;
-int   cdiPartabIntern = 1;
+  if ( gridptr->xbounds == NULL ) size = 0;
 
-double cdiDefaultMissval = -9.E33;
+  return ((int)size);
+}
 
-const char Filetypes[][9] = {
-  "UNKNOWN",
-  "GRIB",
-  "GRIB2",
-  "netCDF",
-  "netCDF2",
-  "netCDF4",
-  "netCDF4c",
-  "SERVICE",
-  "EXTRA",
-  "IEG",
-  "HDF5",
-};
 
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
+const double *gridInqXboundsPtr(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  return (gridptr->xbounds);
+}
 
-int CDI_Debug   = 0;    /* If set to 1, debugging           */
+/*
+ at Function  gridDefYbounds
+ at Title     Define the bounds of a Y-axis
 
-int cdiGribApiDebug     = 0;
-int cdiDefaultLeveltype = -1;
-int cdiDataUnreduced = 0;
-int cdiSortName = 0;
-int cdiHaveMissval = 0;
+ at Prototype void gridDefYbounds(int gridID, const double *ybounds)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  ybounds  Y-bounds of the grid.
 
+ at Description
+The function @func{gridDefYbounds} defines all bounds of the Y-axis.
 
-static long cdiGetenvInt(char *envName)
+ at EndFunction
+*/
+void gridDefYbounds(int gridID, const double *ybounds)
 {
-  char *envString;
-  long envValue = -1;
-  long fact = 1;
-
-  envString = getenv(envName);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( envString )
+  size_t nvertex = (size_t)gridptr->nvertex;
+  if ( nvertex == 0 )
     {
-      int loop, len;
-
-      len = (int) strlen(envString);
-      for ( loop = 0; loop < len; loop++ )
-	{
-	  if ( ! isdigit((int) envString[loop]) )
-	    {
-	      switch ( tolower((int) envString[loop]) )
-		{
-		case 'k':  fact = 1024;        break;
-		case 'm':  fact = 1048576;     break;
-		case 'g':  fact = 1073741824;  break;
-		default:
-		  fact = 0;
-		  Message("Invalid number string in %s: %s", envName, envString);
-		  Warning("%s must comprise only digits [0-9].",envName);
-		  break;
-		}
-	      break;
-	    }
-	}
-
-      if ( fact ) envValue = fact*atol(envString);
-
-      if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
+      Warning("nvertex undefined for gridID = %d. Cannot define bounds!", gridID);
+      return;
     }
 
-  return (envValue);
-}
+  int irregular = gridptr->type == GRID_CURVILINEAR
+    || gridptr->type == GRID_UNSTRUCTURED;
+  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
 
-static void
-cdiPrintDefaults(void)
-{
-  fprintf(stderr, "default instID     :  %d\n"
-          "default modelID    :  %d\n"
-          "default tableID    :  %d\n"
-          "default missval    :  %g\n", cdiDefaultInstID,
-          cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
-}
+  if ( size == 0 )
+    Error("size undefined for gridID = %d", gridID);
 
-void cdiPrintVersion(void)
-{
-  fprintf(stderr, "     CDI library version : %s\n", cdiLibraryVersion());
-#if  defined  (HAVE_LIBCGRIBEX)
-  fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
-#endif
-#if  defined  (HAVE_LIBGRIB_API)
-  fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-  fprintf(stderr, "  netCDF library version : %s\n", cdfLibraryVersion());
-#endif
-#if  defined  (HAVE_LIBHDF5)
-  fprintf(stderr, "    HDF5 library version : %s\n", hdfLibraryVersion());
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-  fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-  fprintf(stderr, "   EXTRA library version : %s\n", extLibraryVersion());
-#endif
-#if  defined  (HAVE_LIBIEG)
-  fprintf(stderr, "     IEG library version : %s\n", iegLibraryVersion());
-#endif
-  fprintf(stderr, "    FILE library version : %s\n", fileLibraryVersion());
+  if ( gridptr->ybounds == NULL )
+    gridptr->ybounds = xmalloc(size * sizeof (double));
+  else if ( CDI_Debug )
+    Warning("values already defined!");
+
+  memcpy(gridptr->ybounds, ybounds, size * sizeof (double));
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
 }
 
-void cdiDebug(int level)
-{
-  if ( level == 1 || (level &  2) ) CDI_Debug = 1;
+/*
+ at Function  gridInqYbounds
+ at Title     Get the bounds of a Y-axis
 
-  if ( CDI_Debug ) Message("debug level %d", level);
+ at Prototype int gridInqYbounds(int gridID, double *ybounds)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  ybounds  Pointer to the location into which the Y-bounds are read.
+                    The caller must allocate space for the returned values.
 
-  if ( level == 1 || (level &  4) ) memDebug(1);
+ at Description
+The function @func{gridInqYbounds} returns the bounds of the Y-axis.
 
-  if ( level == 1 || (level &  8) ) fileDebug(1);
+ at Result
+Upon successful completion @func{gridInqYbounds} returns the number of bounds and
+the bounds are stored in @func{ybounds}.
+Otherwise, 0 is returned and @func{ybounds} is empty.
 
-  if ( level == 1 || (level & 16) )
-    {
-#if  defined  (HAVE_LIBCGRIBEX)
-      gribSetDebug(1);
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-      cdfDebug(1);
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-      srvDebug(1);
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-      extDebug(1);
-#endif
-#if  defined  (HAVE_LIBIEG)
-      iegDebug(1);
-#endif
-    }
+ at EndFunction
+*/
+int gridInqYbounds(int gridID, double *ybounds)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( CDI_Debug )
-    {
-      cdiPrintDefaults();
-      cdiPrintDatatypes();
-    }
-}
+  size_t nvertex = (size_t)gridptr->nvertex;
 
+  int irregular = gridptr->type == GRID_CURVILINEAR
+    || gridptr->type == GRID_UNSTRUCTURED;
+  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
 
-int cdiHaveFiletype(int filetype)
-{
-  int status = 0;
+  if ( size && ybounds && gridptr->ybounds )
+    memcpy(ybounds, gridptr->ybounds, size * sizeof (double));
 
-  switch (filetype)
-    {
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBGRIB)
-#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
-    case FILETYPE_GRB:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBGRIB_API)
-    case FILETYPE_GRB2: { status = 1; break; }
-#endif
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:   { status = 1; break; }
-#if  defined  (HAVE_NETCDF2)
-    case FILETYPE_NC2:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_NETCDF4)
-    case FILETYPE_NC4:  { status = 1; break; }
-    case FILETYPE_NC4C: { status = 1; break; }
-#endif
-#endif
-    default: { status = 0; break; }
-    }
+  if ( gridptr->ybounds == NULL ) size = 0;
 
-  return (status);
+  return ((int)size);
 }
 
-void cdiDefTableID(int tableID)
+
+const double *gridInqYboundsPtr(int gridID)
 {
-  cdiDefaultTableID = tableID;
-  int modelID = cdiDefaultModelID = tableInqModel(tableID);
-  cdiDefaultInstID = modelInqInstitut(modelID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return (gridptr->ybounds);
 }
 
-static
-void cdiSetChunk(const char *chunkAlgo)
+
+void gridPrintKernel(grid_t * gridptr, int index, int opt, FILE *fp)
 {
-  //char *pch;
-  //size_t len = strlen(chunkAlgo);
-  int algo = -1;
+  int xdim, ydim;
+  int nbyte;
+  int i, iv;
+  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+  int gridID = gridptr->self;
+  const double *area    = gridInqAreaPtr(gridID);
+  const double *xvals   = gridInqXvalsPtr(gridID);
+  const double *yvals   = gridInqYvalsPtr(gridID);
+  const double *xbounds = gridInqXboundsPtr(gridID);
+  const double *ybounds = gridInqYboundsPtr(gridID);
 
-  if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CHUNK_AUTO;
-  else if ( strcmp("grid",  chunkAlgo)   == 0 ) algo = CHUNK_GRID;
-  else if ( strcmp("lines", chunkAlgo)   == 0 ) algo = CHUNK_LINES;
-  /*
-  else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
+  int type     = gridInqType(gridID);
+  int trunc    = gridInqTrunc(gridID);
+  int gridsize = gridInqSize(gridID);
+  int xsize    = gridInqXsize(gridID);
+  int ysize    = gridInqYsize(gridID);
+  int nvertex  = gridInqNvertex(gridID);
+
+  int nbyte0 = 0;
+  fprintf(fp, "#\n");
+  fprintf(fp, "# gridID %d\n", index);
+  fprintf(fp, "#\n");
+  fprintf(fp, "gridtype  = %s\n", gridNamePtr(type));
+  fprintf(fp, "gridsize  = %d\n", gridsize);
+
+  if ( type != GRID_GME )
     {
-      int ix, iy;
-      ix = atoi(chunkAlgo);
-      iy = atoi(pch+1);
-      if ( ix > 0 && iy > 0 )
+      if ( xvals )
         {
-          cdiChunkX = ix;
-          cdiChunkY = iy;
-          algo = CHUNK_USER;
+          if ( gridptr->xname[0]     )     fprintf(fp, "xname     = %s\n", gridptr->xname);
+          if ( gridptr->xlongname[0] )     fprintf(fp, "xlongname = %s\n", gridptr->xlongname);
+          if ( gridptr->xunits[0]    )     fprintf(fp, "xunits    = %s\n", gridptr->xunits);
         }
-      else
-        Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
+      if ( yvals )
+        {
+          if ( gridptr->yname[0]     )     fprintf(fp, "yname     = %s\n", gridptr->yname);
+          if ( gridptr->ylongname[0] )     fprintf(fp, "ylongname = %s\n", gridptr->ylongname);
+          if ( gridptr->yunits[0]    )     fprintf(fp, "yunits    = %s\n", gridptr->yunits);
+        }
+      if ( type == GRID_UNSTRUCTURED && nvertex > 0 ) fprintf(fp, "nvertex   = %d\n", nvertex);
     }
-  */
-  else
-    Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
 
-  if ( algo != -1 )
+  switch (type)
     {
-      cdiChunkType = algo;
-      if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
-    }
-}
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+    case GRID_GAUSSIAN_REDUCED:
+    case GRID_GENERIC:
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
+    case GRID_CURVILINEAR:
+    case GRID_UNSTRUCTURED:
+      {
+        if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np        = %d\n", gridptr->np);
 
+	if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
+	  {
+	    xdim = gridsize;
+	    ydim = gridsize;
+	  }
+        else if ( type == GRID_GAUSSIAN_REDUCED )
+          {
+	    xdim = 2;
+	    ydim = ysize;
+          }
+	else
+	  {
+	    xdim = xsize;
+	    ydim = ysize;
+	  }
 
-void cdiInitialize(void)
-{
-  static int Init_CDI = FALSE;
-  char *envString;
-  long value;
+	if ( type != GRID_UNSTRUCTURED )
+	  {
+	    if ( xsize > 0 ) fprintf(fp, "xsize     = %d\n", xsize);
+	    if ( ysize > 0 ) fprintf(fp, "ysize     = %d\n", ysize);
+	  }
 
-  if ( ! Init_CDI )
-    {
-      Init_CDI = TRUE;
+	if ( type == GRID_UNSTRUCTURED )
+          {
+            int number = gridInqNumber(gridID);
+            int position = gridInqPosition(gridID);
+            // const unsigned char *d;
+            if ( number > 0 )
+              {
+                fprintf(fp, "number    = %d\n", number);
+                if ( position >= 0 ) fprintf(fp, "position  = %d\n", position);
+              }
+            /*
+              gridInqUUID(gridID, uuidOfHGrid);
+              d = (unsigned char *) &uuidOfHGrid;
+              fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+              d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+              d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+            */
+            if ( gridInqReference(gridID, NULL) )
+              {
+                char reference_link[8192];
+                gridInqReference(gridID, reference_link);
+                fprintf(fp, "uri       = %s\n", reference_link);
+              }
+          }
 
-#if  defined  (HAVE_LIBCGRIBEX)
-      gribFixZSE(1);   // 1: Fix ZeroShiftError of simple packed spherical harmonics
-      gribSetConst(1); // 1: Don't pack constant fields on regular grids
-#endif
+	if ( type == GRID_LAEA )
+	  {
+	    double a = 0, lon_0 = 0, lat_0 = 0;
+	    gridInqLaea(gridID, &a, &lon_0, &lat_0);
+	    fprintf(fp, "a         = %g\n", a);
+	    fprintf(fp, "lon_0     = %g\n", lon_0);
+	    fprintf(fp, "lat_0     = %g\n", lat_0);
+	  }
 
-      value = cdiGetenvInt("CDI_DEBUG");
-      if ( value >= 0 ) CDI_Debug = (int) value;
+	if ( type == GRID_LCC2 )
+	  {
+	    double a = 0, lon_0 = 0, lat_0 = 0, lat_1 = 0, lat_2 = 0;
+	    gridInqLcc2(gridID, &a, &lon_0, &lat_0, &lat_1, &lat_2);
+	    fprintf(fp, "a         = %g\n", a);
+	    fprintf(fp, "lon_0     = %g\n", lon_0);
+	    fprintf(fp, "lat_0     = %g\n", lat_0);
+	    fprintf(fp, "lat_1     = %g\n", lat_1);
+	    fprintf(fp, "lat_2     = %g\n", lat_2);
+	  }
 
-      value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
-      if ( value >= 0 ) cdiGribApiDebug = (int) value;
+	if ( gridptr->isRotated )
+	  {
+	    if ( xsize > 0 ) fprintf(fp, "xnpole    = %g\n", gridptr->xpole);
+	    if ( ysize > 0 ) fprintf(fp, "ynpole    = %g\n", gridptr->ypole);
+	    if ( IS_NOT_EQUAL(gridptr->angle, 0) ) fprintf(fp, "angle     = %g\n", gridptr->angle);
+ 	  }
 
-      value = cdiGetenvInt("CDI_REGULARGRID");
-      if ( value >= 0 ) cdiDataUnreduced = (int) value;
+	if ( xvals )
+	  {
+	    double xfirst = 0.0, xinc = 0.0;
 
-      value = cdiGetenvInt("CDI_SORTNAME");
-      if ( value >= 0 ) cdiSortName = (int) value;
+	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN ||
+		 type == GRID_GENERIC    || type == GRID_LCC2     ||
+                 type == GRID_SINUSOIDAL || type == GRID_LAEA )
+	      {
+		xfirst = gridInqXval(gridID, 0);
+		xinc   = gridInqXinc(gridID);
+	      }
 
-      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
-      if ( value >= 0 ) cdiHaveMissval = (int) value;
+	    if ( IS_NOT_EQUAL(xinc, 0) && opt )
+	      {
+	  	fprintf(fp, "xfirst    = %g\n", xfirst);
+		fprintf(fp, "xinc      = %g\n", xinc);
+	      }
+	    else
+	      {
+		nbyte0 = fprintf(fp, "xvals     = ");
+		nbyte = nbyte0;
+		for ( i = 0; i < xdim; i++ )
+		  {
+		    if ( nbyte > 80 )
+		      {
+			fprintf(fp, "\n");
+			fprintf(fp, "%*s", nbyte0, "");
+			nbyte = nbyte0;
+		      }
+		    nbyte += fprintf(fp, "%.9g ", xvals[i]);
+		  }
+		fprintf(fp, "\n");
+	      }
+	  }
 
-      value = cdiGetenvInt("CDI_LEVELTYPE");
-      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
+	if ( xbounds )
+	  {
+	    nbyte0 = fprintf(fp, "xbounds   = ");
+	    for ( i = 0; i < xdim; i++ )
+	      {
+		if ( i ) fprintf(fp, "%*s", nbyte0, "");
 
-      value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
-      if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
+		for ( iv = 0; iv < nvertex; iv++ )
+		  fprintf(fp, "%.9g ", xbounds[i*nvertex+iv]);
+		fprintf(fp, "\n");
+	      }
+	  }
 
-      envString = getenv("CDI_MISSVAL");
-      if ( envString ) cdiDefaultMissval = atof(envString);
-      /*
-      envString = getenv("NC_MISSING_VALUE");
-      if ( envString ) cdiNcMissingValue = atoi(envString);
-      */
-      envString = getenv("NC_CHUNKSIZEHINT");
-      if ( envString ) cdiNcChunksizehint = atoi(envString);
+	if ( yvals )
+	  {
+	    double yfirst = 0.0, yinc = 0.0;
 
-      envString = getenv("CDI_CHUNK_ALGO");
-      if ( envString ) cdiSetChunk(envString);
+	    if ( type == GRID_LONLAT || type == GRID_GENERIC || type == GRID_LCC2 ||
+		 type == GRID_SINUSOIDAL || type == GRID_LAEA )
+	      {
+		yfirst = gridInqYval(gridID, 0);
+		yinc   = gridInqYinc(gridID);
+	      }
 
-      envString = getenv("SPLIT_LTYPE_105");
-      if ( envString ) cdiSplitLtype105 = atoi(envString);
+	    if ( IS_NOT_EQUAL(yinc, 0) && opt )
+	      {
+	  	fprintf(fp, "yfirst    = %g\n", yfirst);
+		fprintf(fp, "yinc      = %g\n", yinc);
+	      }
+	    else
+	      {
+		nbyte0 = fprintf(fp, "yvals     = ");
+		nbyte = nbyte0;
+		for ( i = 0; i < ydim; i++ )
+		  {
+		    if ( nbyte > 80 )
+		      {
+			fprintf(fp, "\n");
+			fprintf(fp, "%*s", nbyte0, "");
+			nbyte = nbyte0;
+		      }
+		    nbyte += fprintf(fp, "%.9g ", yvals[i]);
+		  }
+		fprintf(fp, "\n");
+	      }
+	  }
 
-      envString = getenv("IGNORE_ATT_COORDINATES");
-      if ( envString ) cdiIgnoreAttCoordinates = atoi(envString);
+	if ( ybounds )
+	  {
+	    nbyte0 = fprintf(fp, "ybounds   = ");
+	    for ( i = 0; i < ydim; i++ )
+	      {
+		if ( i ) fprintf(fp, "%*s", nbyte0, "");
 
-      envString = getenv("IGNORE_VALID_RANGE");
-      if ( envString ) cdiIgnoreValidRange = atoi(envString);
+		for ( iv = 0; iv < nvertex; iv++ )
+		  fprintf(fp, "%.9g ", ybounds[i*nvertex+iv]);
+		fprintf(fp, "\n");
+	      }
+	  }
 
-      envString = getenv("CDI_SKIP_RECORDS");
-      if ( envString )
-	{
-	  cdiSkipRecords = atoi(envString);
-	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
-	}
+	if ( area )
+	  {
+	    nbyte0 = fprintf(fp, "area      = ");
+	    nbyte  = nbyte0;
+	    for ( i = 0; i < gridsize; i++ )
+	      {
+		if ( nbyte > 80 )
+		  {
+		    fprintf(fp, "\n");
+		    fprintf(fp, "%*s", nbyte0, "");
+		    nbyte = nbyte0;
+		  }
+		nbyte += fprintf(fp, "%.9g ", area[i]);
+	      }
+	    fprintf(fp, "\n");
+	  }
 
-      envString = getenv("CDI_INVENTORY_MODE");
-      if ( envString )
-	{
-	  if ( strncmp(envString, "time", 4) == 0 )
-	    {
-	      cdiInventoryMode = 2;
-	      if ( CDI_Debug )
-		Message("Inventory mode was set to timestep!");
-	    }
-	}
+        if ( type == GRID_GAUSSIAN_REDUCED )
+          {
+            int *rowlon;
+            nbyte0 = fprintf(fp, "rowlon    = ");
+            nbyte  = nbyte0;
+            rowlon = (int *)xmalloc((size_t)ysize*sizeof(int));
+            gridInqRowlon(gridID, rowlon);
+            for ( i = 0; i < ysize; i++ )
+              {
+                if ( nbyte > 80 )
+                  {
+                    fprintf(fp, "\n");
+                    fprintf(fp, "%*s", nbyte0, "");
+                    nbyte = nbyte0;
+                  }
+                nbyte += fprintf(fp, "%d ", rowlon[i]);
+              }
+            fprintf(fp, "\n");
+            free(rowlon);
+          }
 
-      envString = getenv("CDI_CALENDAR");
-      if ( envString )
-	{
-	  if      ( strncmp(envString, "standard", 8) == 0 )
-	    cdiDefaultCalendar = CALENDAR_STANDARD;
-	  else if ( strncmp(envString, "proleptic", 9) == 0 )
-	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
-	  else if ( strncmp(envString, "360days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_360DAYS;
-	  else if ( strncmp(envString, "365days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_365DAYS;
-	  else if ( strncmp(envString, "366days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_366DAYS;
-	  else if ( strncmp(envString, "none", 4) == 0 )
-	    cdiDefaultCalendar = CALENDAR_NONE;
+	break;
+      }
+    case GRID_LCC:
+      {
+	double originLon = 0, originLat = 0, lonParY = 0, lat1 = 0, lat2 = 0, xincm = 0, yincm = 0;
+	int projflag = 0, scanflag = 0;
+	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
+		   &projflag, &scanflag);
 
-	  if ( CDI_Debug )
-	    Message("Default calendar set to %s!", envString);
-	}
-#if  defined  (HAVE_LIBCGRIBEX)
-      gribSetCalendar(cdiDefaultCalendar);
-#endif
+	fprintf(fp, "xsize     = %d\n", xsize);
+	fprintf(fp, "ysize     = %d\n", ysize);
 
-      envString = getenv("PARTAB_INTERN");
-      if ( envString ) cdiPartabIntern = atoi(envString);
+	fprintf(fp, "originLon = %g\n", originLon);
+	fprintf(fp, "originLat = %g\n", originLat);
+	fprintf(fp, "lonParY   = %g\n", lonParY);
+	fprintf(fp, "lat1      = %g\n", lat1);
+	fprintf(fp, "lat2      = %g\n", lat2);
+	fprintf(fp, "xinc      = %g\n", xincm);
+	fprintf(fp, "yinc      = %g\n", yincm);
+	if ( (projflag & 128) == 0 )
+	  fprintf(fp, "projection = northpole\n");
+	else
+	  fprintf(fp, "projection = southpole\n");
 
-      envString = getenv("PARTAB_PATH");
-      if ( envString ) cdiPartabPath = strdup(envString);
+	break;
+      }
+    case GRID_SPECTRAL:
+      {
+        fprintf(fp, "truncation = %d\n", trunc);
+        fprintf(fp, "complexpacking = %d\n", gridptr->lcomplex );
+        break;
+      }
+    case GRID_FOURIER:
+      {
+	fprintf(fp, "truncation = %d\n", trunc);
+	break;
+      }
+    case GRID_GME:
+      {
+        fprintf(fp, "ni        = %d\n", gridptr->ni );
+        break;
+      }
+   default:
+      {
+	fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
+        break;
+      }
     }
-}
 
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( !cdiUUIDIsNull(uuidOfHGrid) )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        fprintf(fp, "uuid      = %s\n", uuidOfHGridStr);
+    }
 
-const char *strfiletype(int filetype)
-{
-  const char *name;
-  int size = (int) (sizeof(Filetypes)/sizeof(char *));
-
-  if ( filetype > 0 && filetype < size )
-    name = Filetypes[filetype];
-  else
-    name = Filetypes[0];
-
-  return (name);
+  if ( gridptr->mask )
+    {
+      nbyte0 = fprintf(fp, "mask      = ");
+      nbyte  = nbyte0;
+      for ( i = 0; i < gridsize; i++ )
+        {
+          if ( nbyte > 80 )
+            {
+              fprintf(fp, "\n");
+              fprintf(fp, "%*s", nbyte0, "");
+              nbyte = nbyte0;
+            }
+          nbyte += fprintf(fp, "%d ", (int) gridptr->mask[i]);
+        }
+      fprintf(fp, "\n");
+    }
 }
 
-
-int streamSize(void)
+void gridPrint ( int gridID, int index, int opt )
 {
-  return reshCountType ( &streamOps );
-}
-
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-void cdiDefGlobal(const char *string, int val)
-{
-  if      ( strcmp(string, "REGULARGRID")      == 0 ) cdiDataUnreduced = val;
-  else if ( strcmp(string, "GRIBAPI_DEBUG")    == 0 ) cdiGribApiDebug = val;
-  else if ( strcmp(string, "SORTNAME")         == 0 ) cdiSortName = val;
-  else if ( strcmp(string, "HAVE_MISSVAL")     == 0 ) cdiHaveMissval = val;
-  else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
-  else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
-  else Warning("Unsupported global key: %s", string);
+  gridPrintKernel ( gridptr, index, opt, stdout );
 }
 
 
-void cdiDefMissval(double missval)
-{
-  cdiInitialize();
-
-  cdiDefaultMissval = missval;
-}
 
-
-double cdiInqMissval(void)
+void gridPrintP ( void * voidptr, FILE * fp )
 {
-  cdiInitialize();
+  grid_t * gridptr = ( grid_t * ) voidptr;
+  int nbyte0, nbyte, i;
 
-  return (cdiDefaultMissval);
-}
+  xassert ( gridptr );
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  gridPrintKernel ( gridptr , gridptr->self, 0, fp );
 
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-#endif
+  fprintf ( fp, "precision = %d\n", gridptr->prec);
+  fprintf ( fp, "nd        = %d\n", gridptr->nd );
+  fprintf ( fp, "ni        = %d\n", gridptr->ni );
+  fprintf ( fp, "ni2       = %d\n", gridptr->ni2 );
+  fprintf ( fp, "ni3       = %d\n", gridptr->ni3 ); 
+  fprintf ( fp, "number    = %d\n", gridptr->number );
+  fprintf ( fp, "position  = %d\n", gridptr->position );
+  fprintf ( fp, "trunc     = %d\n", gridptr->trunc );
+  fprintf ( fp, "lcomplex  = %d\n", gridptr->lcomplex );
+  fprintf ( fp, "nrowlon   = %d\n", gridptr->nrowlon );
 
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+  if ( gridptr->rowlon )
+    {
+      nbyte0 = fprintf(fp, "rowlon    = ");
+      nbyte  = nbyte0;
+      for ( i = 0; i < gridptr->nrowlon; i++ )
+        {
+          if ( nbyte > 80 )
+            {
+              fprintf(fp, "\n");
+              fprintf(fp, "%*s", nbyte0, "");
+              nbyte = nbyte0;
+            }
+          nbyte += fprintf(fp, "%d ", gridptr->rowlon[i]);
+        }
+      fprintf(fp, "\n");
+    }
 
+  if ( gridptr->mask_gme )
+    {
+      nbyte0 = fprintf(fp, "mask_gme  = ");
+      nbyte  = nbyte0;
+      for ( i = 0; i < gridptr->size; i++ )
+        {
+          if ( nbyte > 80 )
+            {
+              fprintf(fp, "\n");
+              fprintf(fp, "%*s", nbyte0, "");
+              nbyte = nbyte0;
+            }
+          nbyte += fprintf(fp, "%d ", (int) gridptr->mask_gme[i]);
+        }
+      fprintf(fp, "\n");
+    }
+}
 
 
+const double *gridInqXvalsPtr(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-static stream_t *stream_new_entry(int resH);
-static void stream_delete_entry(stream_t *streamptr);
-static int streamCompareP(void * streamptr1, void * streamptr2);
-static void streamDestroyP(void * streamptr);
-static void streamPrintP(void * streamptr, FILE * fp);
-static int streamGetPackSize(void * streamptr, void *context);
-static void streamPack(void * streamptr, void * buff, int size, int * position, void *context);
-static int streamTxCode(void);
+  return ( gridptr->xvals );
+}
 
-const resOps streamOps = {
-  streamCompareP,
-  streamDestroyP,
-  streamPrintP,
-  streamGetPackSize,
-  streamPack,
-  streamTxCode
-};
 
+const double *gridInqYvalsPtr(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
+  return ( gridptr->yvals );
+}
 
+/*
+ at Function  gridDefLCC
+ at Title     Define the parameter of a Lambert Conformal Conic grid
 
-#undef  IsBigendian
-#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
+ at Prototype void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag)
+ at Parameter
+    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  originLon Longitude of the first grid point.
+    @Item  originLat Latitude of the first grid point.
+    @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
+    @Item  lat1      First latitude from the pole at which the secant cone cuts the sphere.
+    @Item  lat2      Second latitude at which the secant cone cuts the sphere.
+    @Item  xinc      X-direction grid lenght in meter.
+    @Item  yinc      Y-direction grid lenght in meter.
+    @Item  projflag  Projection centre flag.
+    @Item  scanflag  Scanning mode flag.
 
+ at Description
+The function @func{gridDefLCC} defines the parameter of a Lambert Conformal Conic grid.
 
-static
-int getByteorder(int byteswap)
+ at EndFunction
+*/
+void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
+                double lat1, double lat2, double xinc, double yinc,
+                int projflag, int scanflag)
 {
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-  int byteorder = -1;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( IsBigendian() )
-    {
-      if ( byteswap ) byteorder = CDI_LITTLEENDIAN;
-      else            byteorder = CDI_BIGENDIAN;
-    }
+  if ( gridptr->type != GRID_LCC )
+    Warning("Definition of LCC grid for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
   else
     {
-      if ( byteswap ) byteorder = CDI_BIGENDIAN;
-      else            byteorder = CDI_LITTLEENDIAN;
+      gridptr->lcc_originLon = originLon;
+      gridptr->lcc_originLat = originLat;
+      gridptr->lcc_lonParY   = lonParY;
+      gridptr->lcc_lat1      = lat1;
+      gridptr->lcc_lat2      = lat2;
+      gridptr->lcc_xinc      = xinc;
+      gridptr->lcc_yinc      = yinc;
+      gridptr->lcc_projflag  = projflag;
+      gridptr->lcc_scanflag  = scanflag;
+      gridptr->lcc_defined   = TRUE;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-
-  return (byteorder);
 }
 
-// used also in CDO
-int cdiGetFiletype(const char *filename, int *byteorder)
-{
-  int filetype = CDI_EUFTYPE;
-  int swap = 0;
-  int version;
-  long recpos;
-  char buffer[8];
+/*
+ at Function  gridInqLCC
+ at Title     Get the parameter of a Lambert Conformal Conic grid
 
-  int fileID = fileOpen(filename, "r");
+ at Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
+ at Parameter
+    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  originLon Longitude of the first grid point.
+    @Item  originLat Latitude of the first grid point.
+    @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
+    @Item  lat1      First latitude from the pole at which the secant cone cuts the sphere.
+    @Item  lat2      Second latitude at which the secant cone cuts the sphere.
+    @Item  xinc      X-direction grid lenght in meter.
+    @Item  yinc      Y-direction grid lenght in meter.
+    @Item  projflag  Projection centre flag.
+    @Item  scanflag  Scanning mode flag.
+ 
+ at Description
+The function @func{gridInqLCC} returns the parameter of a Lambert Conformal Conic grid.
 
-  if ( fileID == CDI_UNDEFID )
+ at EndFunction
+*/
+void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY,
+                double *lat1, double *lat2, double *xinc, double *yinc,
+                int *projflag, int *scanflag)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->type != GRID_LCC )
+    Warning("Inquire of LCC grid definition for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
     {
-      if ( strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0 )
-	return (FILETYPE_NC);
+      if ( gridptr->lcc_defined )
+        {
+          *originLon = gridptr->lcc_originLon;
+          *originLat = gridptr->lcc_originLat;
+          *lonParY   = gridptr->lcc_lonParY;
+          *lat1      = gridptr->lcc_lat1;
+          *lat2      = gridptr->lcc_lat2;
+          *xinc      = gridptr->lcc_xinc;
+          *yinc      = gridptr->lcc_yinc;
+          *projflag  = gridptr->lcc_projflag;
+          *scanflag  = gridptr->lcc_scanflag;
+        }
       else
-	return (CDI_ESYSTEM);
+	Warning("Lambert Conformal grid undefined (gridID = %d)", gridID);
     }
+}
 
-  if ( fileRead(fileID, buffer, 8) != 8 ) return (CDI_EUFTYPE);
-
-  fileRewind(fileID);
+void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( memcmp(buffer, "GRIB", 4) == 0 )
-    {
-      version = buffer[7];
-      if ( version <= 1 )
-	{
-	  filetype = FILETYPE_GRB;
-	  if ( CDI_Debug ) Message("found GRIB file = %s, version %d", filename, version);
-	}
-      else if ( version == 2 )
-	{
-	  filetype = FILETYPE_GRB2;
-	  if ( CDI_Debug ) Message("found GRIB2 file = %s", filename);
-	}
-    }
-  else if ( memcmp(buffer, "CDF\001", 4) == 0 )
-    {
-      filetype = FILETYPE_NC;
-      if ( CDI_Debug ) Message("found CDF1 file = %s", filename);
-    }
-  else if ( memcmp(buffer, "CDF\002", 4) == 0 )
-    {
-      filetype = FILETYPE_NC2;
-      if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
-    }
-  else if ( memcmp(buffer+1, "HDF", 3) == 0 )
-    {
-      filetype = FILETYPE_NC4;
-      if ( CDI_Debug ) Message("found HDF file = %s", filename);
-    }
-#if  defined  (HAVE_LIBSERVICE)
-  else if ( srvCheckFiletype(fileID, &swap) )
-    {
-      filetype = FILETYPE_SRV;
-      if ( CDI_Debug ) Message("found SRV file = %s", filename);
-    }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-  else if ( extCheckFiletype(fileID, &swap) )
+  if ( gridptr->type != GRID_LCC2 )
+    Warning("Definition of LCC2 grid for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
     {
-      filetype = FILETYPE_EXT;
-      if ( CDI_Debug ) Message("found EXT file = %s", filename);
+      gridptr->lcc2_a       = earth_radius;
+      gridptr->lcc2_lon_0   = lon_0;
+      gridptr->lcc2_lat_0   = lat_0;
+      gridptr->lcc2_lat_1   = lat_1;
+      gridptr->lcc2_lat_2   = lat_2;
+      gridptr->lcc2_defined = TRUE;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-#endif
-#if  defined  (HAVE_LIBIEG)
-  else if ( iegCheckFiletype(fileID, &swap) )
+}
+
+
+void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0, double *lat_1, double *lat_2)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->type != GRID_LCC2 )
+    Warning("Inquire of LCC2 grid definition for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
     {
-      filetype = FILETYPE_IEG;
-      if ( CDI_Debug ) Message("found IEG file = %s", filename);
+      if ( gridptr->lcc2_defined )
+        {
+          *earth_radius = gridptr->lcc2_a;
+          *lon_0        = gridptr->lcc2_lon_0;
+          *lat_0        = gridptr->lcc2_lat_0;
+          *lat_1        = gridptr->lcc2_lat_1;
+          *lat_2        = gridptr->lcc2_lat_2;
+        }
+      else
+        Warning("LCC2 grid undefined (gridID = %d)", gridID);
     }
-#endif
-  else if ( gribCheckSeek(fileID, &recpos, &version) == 0 )
+}
+
+void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->type != GRID_LAEA )
+    Warning("Definition of LAEA grid for %s grid not allowed!",
+            gridNamePtr(gridptr->type));
+  else
     {
-      if ( version <= 1 )
-	{
-	  filetype = FILETYPE_GRB;
-	  if ( CDI_Debug ) Message("found seeked GRIB file = %s", filename);
-	}
-      else if ( version == 2 )
-	{
-	  filetype = FILETYPE_GRB2;
-	  if ( CDI_Debug ) Message("found seeked GRIB2 file = %s", filename);
-	}
+      gridptr->laea_a       = earth_radius;
+      gridptr->laea_lon_0   = lon_0;
+      gridptr->laea_lat_0   = lat_0;
+      gridptr->laea_defined = TRUE;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  fileClose(fileID);
 
-  *byteorder = getByteorder(swap);
+void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
+{
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (filetype);
+  if ( gridptr->type != GRID_LAEA )
+    Warning("Inquire of LAEA grid definition for %s grid not allowed!",
+            gridNamePtr(gridptr->type));
+  else
+    {
+      if ( gridptr->laea_defined )
+        {
+          *earth_radius = gridptr->laea_a;
+          *lon_0        = gridptr->laea_lon_0;
+          *lat_0        = gridptr->laea_lat_0;
+        }
+      else
+        Warning("LAEA grid undefined (gridID = %d)", gridID);
+    }
 }
 
-/*
- at Function  streamInqFiletype
- at Title     Get the filetype
 
- at Prototype int streamInqFiletype(int streamID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+void gridDefComplexPacking(int gridID, int lcomplex)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
- at Description
-The function @func{streamInqFiletype} returns the filetype of a stream.
 
- at Result
- at func{streamInqFiletype} returns the type of the file format,
-one of the set of predefined CDI file format types.
-The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC}, @func{FILETYPE_NC2},
- at func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV}, @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
+  if (gridptr->lcomplex != lcomplex)
+    {
+      gridptr->lcomplex = lcomplex;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
+}
 
- at EndFunction
-*/
-int streamInqFiletype(int streamID)
-{
-  stream_t *streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
+int gridInqComplexPacking(int gridID)
+{
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (streamptr->filetype);
+  return (gridptr->lcomplex);
 }
 
 
-int getByteswap(int byteorder)
+void gridDefHasDims(int gridID, int hasdims)
 {
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-  int byteswap = 0;
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  if ( IsBigendian() )
-    {
-      if ( byteorder == CDI_LITTLEENDIAN ) byteswap = TRUE;
-    }
-  else
+  if (gridptr->hasdims != hasdims)
     {
-      if ( byteorder == CDI_BIGENDIAN ) byteswap = TRUE;
+      gridptr->hasdims = hasdims;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  return (byteswap);
+
+int gridInqHasDims(int gridID)
+{
+  grid_t* gridptr = gridID2Ptr(gridID);
+
+  return (gridptr->hasdims);
 }
 
 /*
- at Function  streamDefByteorder
- at Title     Define the byte order
+ at Function  gridDefNumber
+ at Title     Define the reference number for an unstructured grid
 
- at Prototype void streamDefByteorder(int streamID, int byteorder)
+ at Prototype void gridDefNumber(int gridID, const int number)
 @Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  byteorder The byte order of a dataset, one of the CDI constants @func{CDI_BIGENDIAN} and
-                     @func{CDI_LITTLEENDIAN}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  number   Reference number for an unstructured grid.
 
 @Description
-The function @func{streamDefByteorder} defines the byte order of a binary dataset
-with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
+The function @func{gridDefNumber} defines the reference number for an unstructured grid.
 
 @EndFunction
 */
-void streamDefByteorder(int streamID, int byteorder)
+void gridDefNumber(int gridID, const int number)
 {
-  int filetype;
-  stream_t *streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  streamptr->byteorder = byteorder;
-  filetype = streamptr->filetype;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  switch (filetype)
+  if (gridptr->number != number)
     {
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-	srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-	srvp->byteswap = getByteswap(byteorder);
-
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-	extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-	extp->byteswap = getByteswap(byteorder);
-
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-	iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
-	iegp->byteswap = getByteswap(byteorder);
-
-	break;
-      }
-#endif
+      gridptr->number = number;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
     }
-  reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
 }
 
 /*
- at Function  streamInqByteorder
- at Title     Get the byte order
+ at Function  gridInqNumber
+ at Title     Get the reference number to an unstructured grid
 
- at Prototype int streamInqByteorder(int streamID)
+ at Prototype int gridInqNumber(int gridID)
 @Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
-The function @func{streamInqByteorder} returns the byte order of a binary dataset
-with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
+The function @func{gridInqNumber} returns the reference number to an unstructured grid.
 
 @Result
- at func{streamInqByteorder} returns the type of the byte order.
-The valid CDI byte order types are @func{CDI_BIGENDIAN} and @func{CDI_LITTLEENDIAN}
-
+ at func{gridInqNumber} returns the reference number to an unstructured grid.
 @EndFunction
 */
-int streamInqByteorder(int streamID)
+int gridInqNumber(int gridID)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (streamptr->byteorder);
+  return (gridptr->number);
 }
 
+/*
+ at Function  gridDefPosition
+ at Title     Define the position of grid in the reference file
 
-char *streamFilesuffix(int filetype)
-{
-  // static char *fileSuffix[] = {"", ".grb", ".g2", ".nc", ".nc", ".nc4", ".nc4", ".srv", ".ext", ".ieg"};
-  static char *fileSuffix[] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
-  int size = (int) (sizeof(fileSuffix)/sizeof(char *));
-
-  if ( filetype > 0 && filetype < size )
-    return (fileSuffix[filetype]);
-  else
-    return (fileSuffix[0]);
-}
+ at Prototype void gridDefPosition(int gridID, const int position)
+ at Parameter
+    @Item  gridID     Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  position   Position of grid in the reference file.
 
+ at Description
+The function @func{gridDefPosition} defines the position of grid in the reference file.
 
-char *streamFilename(int streamID)
+ at EndFunction
+*/
+void gridDefPosition(int gridID, int position)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (streamptr->filename);
+  if (gridptr->position != position)
+    {
+      gridptr->position = position;
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
-static
-long cdiInqTimeSize(int streamID)
-{
-  int tsID = 0, nrecs;
-  stream_t *streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  long ntsteps = streamptr->ntsteps;
+/*
+ at Function  gridInqPosition
+ at Title     Get the position of grid in the reference file
 
-  if ( ntsteps == (long)CDI_UNDEFID )
-    while ( (nrecs = streamInqTimestep(streamID, tsID++)) )
-      ntsteps = streamptr->ntsteps;
+ at Prototype int gridInqPosition(int gridID)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-  return (ntsteps);
-}
+ at Description
+The function @func{gridInqPosition} returns the position of grid in the reference file.
 
-static
-int cdiInqContents(stream_t * streamptr)
+ at Result
+ at func{gridInqPosition} returns the position of grid in the reference file.
+ at EndFunction
+*/
+int gridInqPosition(int gridID)
 {
-  int status = 0;
-
-  int filetype = streamptr->filetype;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  switch (filetype)
-    {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        status = grbInqContents(streamptr);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        status = srvInqContents(streamptr);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        status = extInqContents(streamptr);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        status = iegInqContents(streamptr);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-        status = cdfInqContents(streamptr);
-	break;
-      }
-#endif
-    default:
-      {
-	if ( CDI_Debug )
-	  Message("%s support not compiled in!", strfiletype(filetype));
+  return (gridptr->position);
+}
 
-	status = CDI_ELIBNAVAIL;
-        break;
-      }
-    }
+/*
+ at Function  gridDefReference
+ at Title     Define the reference URI for an unstructured grid
 
-  if ( status == 0 )
+ at Prototype void gridDefReference(int gridID, const char *reference)
+ at Parameter
+    @Item  gridID      Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  reference   Reference URI for an unstructured grid.
+
+ at Description
+The function @func{gridDefReference} defines the reference URI for an unstructured grid.
+
+ at EndFunction
+*/
+void gridDefReference(int gridID, const char *reference)
+{
+  grid_t* gridptr = gridID2Ptr(gridID);
+
+  if ( reference )
     {
-      int vlistID = streamptr->vlistID;
-      int taxisID = vlistInqTaxis(vlistID);
-      if ( taxisID != CDI_UNDEFID )
+      if ( gridptr->reference )
         {
-          taxis_t *taxisptr1 = &streamptr->tsteps[0].taxis;
-          taxis_t *taxisptr2 = taxisPtr(taxisID);
-          ptaxisCopy(taxisptr2, taxisptr1);
+          free(gridptr->reference);
+          gridptr->reference = NULL;
         }
-    }
 
-  return (status);
+      gridptr->reference = strdupx(reference);
+      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+    }
 }
 
-int cdiStreamOpenDefaultDelegate(const char *filename, const char *filemode,
-                                 int filetype, stream_t *streamptr,
-                                 int recordBufIsToBeCreated)
+/*
+ at Function  gridInqReference
+ at Title     Get the reference URI to an unstructured grid
+
+ at Prototype char *gridInqReference(int gridID, char *reference)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+
+ at Description
+The function @func{gridInqReference} returns the reference URI to an unstructured grid.
+
+ at Result
+ at func{gridInqReference} returns the reference URI to an unstructured grid.
+ at EndFunction
+*/
+int gridInqReference(int gridID, char *reference)
 {
-  int fileID;
-  switch (filetype)
+  int len = 0;
+  grid_t* gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->reference && reference )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        fileID = gribOpen(filename, filemode);
-        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
-        if (recordBufIsToBeCreated)
-          {
-            streamptr->record = (Record *) malloc(sizeof(Record));
-            streamptr->record->buffer = NULL;
-          }
-        break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        fileID = fileOpen(filename, filemode);
-        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
-        if (recordBufIsToBeCreated)
-          {
-            streamptr->record = (Record *) malloc(sizeof(Record));
-            streamptr->record->buffer = NULL;
-            streamptr->record->exsep  = srvNew();
-          }
-        break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        fileID = fileOpen(filename, filemode);
-        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
-        if (recordBufIsToBeCreated)
-          {
-            streamptr->record = (Record *) malloc(sizeof(Record));
-            streamptr->record->buffer = NULL;
-            streamptr->record->exsep  = extNew();
-          }
-        break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        fileID = fileOpen(filename, filemode);
-        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
-        if (recordBufIsToBeCreated)
-          {
-            streamptr->record = (Record *) malloc(sizeof(Record));
-            streamptr->record->buffer = NULL;
-            streamptr->record->exsep   = iegNew();
-          }
-        break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-      {
-        fileID = cdfOpen(filename, filemode);
-        break;
-      }
-    case FILETYPE_NC2:
-      {
-        fileID = cdfOpen64(filename, filemode);
-        break;
-      }
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-        fileID = cdf4Open(filename, filemode, &filetype);
-        break;
-      }
-#endif
-    default:
-      {
-        if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
-        return (CDI_ELIBNAVAIL);
-      }
+      strcpy(reference, gridptr->reference);
     }
 
-  streamptr->filetype = filetype;
-
-  return fileID;
+  return (len);
 }
 
+/*
+ at Function  gridDefUUID
+ at Title     Define the UUID for an unstructured grid
 
-static int
-streamOpenID(const char *filename, const char *filemode, int filetype,
-             int resH)
-{
-  int fileID = CDI_UNDEFID;
-  int status;
-
-  if ( CDI_Debug )
-    Message("Open %s mode %c file %s", strfiletype(filetype), (int) *filemode,
-            filename?filename:"(NUL)");
+ at Prototype void gridDefUUID(int gridID, const char *uuid)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  uuid     UUID for an unstructured grid.
 
-  if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
+ at Description
+The function @func{gridDefUUID} defines the UUID for an unstructured grid.
 
-  stream_t *streamptr = stream_new_entry(resH);
-  int streamID = CDI_ESYSTEM;
+ at EndFunction
+*/
+void gridDefUUID(int gridID, const unsigned char uuid[CDI_UUID_SIZE])
+{
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  {
-    int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
-      = (int (*)(const char *, const char *, int, stream_t *, int))
-      namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
+  memcpy(gridptr->uuid, uuid, CDI_UUID_SIZE);
+  reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
+}
 
-    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
-  }
+/*
+ at Function  gridInqUUID
+ at Title     Get the UUID to an unstructured grid
 
-  if (fileID < 0)
-    {
-      free(streamptr->record);
-      stream_delete_entry(streamptr);
-      streamID = fileID;
-    }
-  else
-    {
-      streamID  = streamptr->self;
+ at Prototype void gridInqUUID(int gridID, char *uuid)
+ at Parameter
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
-      if ( streamID < 0 ) return (CDI_ELIMIT);
+ at Description
+The function @func{gridInqUUID} returns the UUID to an unstructured grid.
 
-      streamptr->filemode = tolower(*filemode);
-      streamptr->filename = strdupx(filename);
-      streamptr->fileID   = fileID;
+ at Result
+ at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
+ at EndFunction
+*/
+void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-      if ( streamptr->filemode == 'r' )
-	{
-	  int vlistID = vlistCreate();
-	  if ( vlistID < 0 ) return(CDI_ELIMIT);
+  memcpy(uuid, gridptr->uuid, CDI_UUID_SIZE);
+}
 
-	  streamptr->vlistID = vlistID;
-	  /* cdiReadByteorder(streamID); */
-	  status = cdiInqContents(streamptr);
-	  if ( status < 0 ) return (status);
-	  vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
-	  vlistptr->ntsteps = streamptr->ntsteps;
-	}
-    }
 
-  return (streamID);
+void cdiGridGetIndexList(unsigned ngrids, int * gridIndexList)
+{
+  reshGetResHListOfType(ngrids, gridIndexList, &gridOps);
 }
 
-int streamOpen(const char *filename, const char *filemode, int filetype)
+
+static int
+gridTxCode ()
 {
-  return streamOpenID(filename, filemode, filetype, CDI_UNDEFID);
+  return GRID;
 }
 
-static int streamOpenA(const char *filename, const char *filemode, int filetype)
-{
-  int fileID = CDI_UNDEFID;
-  int streamID = CDI_ESYSTEM;
-  int status;
-  stream_t *streamptr = stream_new_entry(CDI_UNDEFID);
-  vlist_t *vlistptr;
+enum { gridNint    = 27,
+       gridNdouble = 24,
+       gridHasMaskFlag = 1 << 0,
+       gridHasGMEMaskFlag = 1 << 1,
+       gridHasXValsFlag = 1 << 2,
+       gridHasYValsFlag = 1 << 3,
+       gridHasAreaFlag = 1 << 4,
+       gridHasXBoundsFlag = 1 << 5,
+       gridHasYBoundsFlag = 1 << 6,
+       gridHasReferenceFlag = 1 << 7,
+       gridHasRowLonFlag = 1 << 8,
+       gridHasUUIDFlag = 1 << 9,
+};
 
-  if ( CDI_Debug )
-    Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
-  if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
 
-  if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
+static int gridGetComponentFlags(const grid_t * gridP)
+{
+  int flags = (gridHasMaskFlag & (int)((unsigned)(gridP->mask == NULL) - 1U))
+    | (gridHasGMEMaskFlag & (int)((unsigned)(gridP->mask_gme == NULL) - 1U))
+    | (gridHasXValsFlag & (int)((unsigned)(gridP->xvals == NULL) - 1U))
+    | (gridHasYValsFlag & (int)((unsigned)(gridP->yvals == NULL) - 1U))
+    | (gridHasAreaFlag & (int)((unsigned)(gridP->area == NULL) - 1U))
+    | (gridHasXBoundsFlag & (int)((unsigned)(gridP->xbounds == NULL) - 1U))
+    | (gridHasYBoundsFlag & (int)((unsigned)(gridP->ybounds == NULL) - 1U))
+    | (gridHasReferenceFlag & (int)((unsigned)(gridP->reference == NULL) - 1U))
+    | (gridHasRowLonFlag & (int)((unsigned)(gridP->rowlon == NULL) - 1U))
+    | (gridHasUUIDFlag & (int)((unsigned)cdiUUIDIsNull(gridP->uuid) - 1U));
+  return flags;
+}
 
-  {
-    int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
-      = (int (*)(const char *, const char *, int, stream_t *, int))
-      namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
 
-    fileID = streamOpenDelegate(filename, "r", filetype, streamptr, 1);
-  }
+#define GRID_STR_SERIALIZE { gridP->xname, gridP->yname, \
+    gridP->xlongname, gridP->ylongname, \
+    gridP->xstdname, gridP->ystdname, \
+    gridP->xunits, gridP->yunits }
 
-  if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return (fileID);
+static int
+gridGetPackSize(void * voidP, void *context)
+{
+  grid_t * gridP = ( grid_t * ) voidP;
+  int packBuffSize = 0, count;
 
-  streamID = streamptr->self;
+  packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
-  streamptr->filemode = tolower(*filemode);
-  streamptr->filename = strdupx(filename);
-  streamptr->fileID   = fileID;
+  if (gridP->rowlon)
+    {
+      xassert(gridP->nrowlon);
+      packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
+        + serializeGetSize( 1, DATATYPE_UINT32, context);
+    }
 
-  streamptr->vlistID = vlistCreate();
-  /* cdiReadByteorder(streamID); */
-  status = cdiInqContents(streamptr);
-  if ( status < 0 ) return (status);
-  vlistptr = vlist_to_pointer(streamptr->vlistID);
-  vlistptr->ntsteps = (int)cdiInqTimeSize(streamID);
+  packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
 
-  {
-    void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
-      = (void (*)(stream_t *, int))
-      namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+  if (gridP->xvals)
+    {
+      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+	count = gridP->size;
+      else
+	count = gridP->xsize;
+      xassert(count);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
-    streamCloseDelegate(streamptr, 0);
-  }
+  if (gridP->yvals)
+    {
+      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+	count = gridP->size;
+      else
+	count = gridP->ysize;
+      xassert(count);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
-  switch (filetype)
+  if (gridP->area)
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        fileID = gribOpen(filename, filemode);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        fileID = fileOpen(filename, filemode);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        fileID = fileOpen(filename, filemode);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        fileID = fileOpen(filename, filemode);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-      {
-	fileID = cdfOpen(filename, filemode);
-	streamptr->ncmode = 2;
-	break;
-      }
-    case FILETYPE_NC2:
-      {
-	fileID = cdfOpen64(filename, filemode);
-	streamptr->ncmode = 2;
-	break;
-      }
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-	fileID = cdf4Open(filename, filemode, &filetype);
-	streamptr->ncmode = 2;
-	break;
-      }
-#endif
-    default:
-      {
-	if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
-	return (CDI_ELIBNAVAIL);
-      }
+      xassert(gridP->size);
+      packBuffSize +=
+        serializeGetSize(gridP->size, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
-  if ( fileID == CDI_UNDEFID )
-    streamID = CDI_UNDEFID;
-  else
-    streamptr->fileID = fileID;
+  if (gridP->xbounds)
+    {
+      xassert(gridP->nvertex);
+      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+	count = gridP->size;
+      else
+	count = gridP->xsize;
+      xassert(count);
+      packBuffSize
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
+    }
 
-  return (streamID);
-}
+  if (gridP->ybounds)
+    {
+      xassert(gridP->nvertex);
+      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+	count = gridP->size;
+      else
+	count = gridP->ysize;
+      xassert(count);
+      packBuffSize
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
+    }
 
-/*
- at Function  streamOpenRead
- at Title     Open a dataset for reading
+  {
+    const char *strTab[] = GRID_STR_SERIALIZE;
+    int numStr = (int)(sizeof (strTab) / sizeof (strTab[0]));
+    packBuffSize
+      += serializeStrTabGetPackSize(strTab, numStr, context);
+  }
 
- at Prototype int streamOpenRead(const char *path)
- at Parameter
-    @Item  path  The name of the dataset to be read.
+  if (gridP->reference)
+    {
+      size_t len = strlen(gridP->reference);
+      packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
+        + serializeGetSize((int)len + 1, DATATYPE_TXT, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
- at Description
-The function @func{streamOpenRead} opens an existing dataset for reading.
+  if (gridP->mask)
+    {
+      xassert(gridP->size);
+      packBuffSize
+        += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
- at Result
-Upon successful completion @func{streamOpenRead} returns an identifier to the
-open stream. Otherwise, a negative number with the error status is returned.
+  if (gridP->mask_gme)
+    {
+      xassert(gridP->size);
+      packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
- at Errors
- at List
-   @Item  CDI_ESYSTEM     Operating system error.
-   @Item  CDI_EINVAL      Invalid argument.
-   @Item  CDI_EUFILETYPE  Unsupported file type.
-   @Item  CDI_ELIBNAVAIL  Library support not compiled in.
- at EndList
+  if (!cdiUUIDIsNull(gridP->uuid))
+    packBuffSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
- at Example
-Here is an example using @func{streamOpenRead} to open an existing netCDF
-file named @func{foo.nc} for reading:
+  return packBuffSize;
+}
 
- at Source
-   ...
-int streamID;
-   ...
-streamID = streamOpenRead("foo.nc");
-if ( streamID < 0 ) handle_error(streamID);
-   ...
- at EndSource
- at EndFunction
-*/
-int streamOpenRead(const char *filename)
+void
+gridUnpack(char * unpackBuffer, int unpackBufferSize,
+           int * unpackBufferPos, int originNamespace, void *context,
+           int force_id)
 {
-  cdiInitialize();
+  grid_t * gridP;
+  uint32_t d;
+  int memberMask, size;
 
-  int byteorder = 0;
-  int filetype = cdiGetFiletype(filename, &byteorder);
+  gridInit();
 
-  if ( filetype < 0 ) return (filetype);
+  {
+    int intBuffer[gridNint];
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    intBuffer, gridNint, DATATYPE_INT, context);
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    &d, 1, DATATYPE_UINT32, context);
 
-  int streamID = streamOpen(filename, "r", filetype);
+    xassert(cdiCheckSum(DATATYPE_INT, gridNint, intBuffer) == d);
+    int targetID = namespaceAdaptKey(intBuffer[0], originNamespace);
+    gridP = gridNewEntry(force_id?targetID:CDI_UNDEFID);
+
+    xassert(!force_id || targetID == gridP->self);
+
+    gridP->type          =   intBuffer[1];
+    gridP->prec          =   intBuffer[2];
+    gridP->lcc_projflag  =   intBuffer[3];
+    gridP->lcc_scanflag  =   intBuffer[4];
+    gridP->lcc_defined   =   intBuffer[5];
+    gridP->lcc2_defined  =   intBuffer[6];
+    gridP->laea_defined  =   intBuffer[7];
+    gridP->isCyclic      =   intBuffer[8];
+    gridP->isRotated     =   intBuffer[9];
+    gridP->xdef          =   intBuffer[10];
+    gridP->ydef          =   intBuffer[11];
+    gridP->nd            =   intBuffer[12];
+    gridP->ni            =   intBuffer[13];
+    gridP->ni2           =   intBuffer[14];
+    gridP->ni3           =   intBuffer[15];
+    gridP->number        =   intBuffer[16];
+    gridP->position      =   intBuffer[17];
+    gridP->trunc         =   intBuffer[18];
+    gridP->nvertex       =   intBuffer[19];
+    gridP->nrowlon       =   intBuffer[20];
+    gridP->size          =   intBuffer[21];
+    gridP->xsize         =   intBuffer[22];
+    gridP->ysize         =   intBuffer[23];
+    gridP->locked        =   intBuffer[24];
+    gridP->lcomplex      =   intBuffer[25];
+    memberMask           =   intBuffer[26];
+  }
 
-  if ( streamID >= 0 )
+  if (memberMask & gridHasRowLonFlag)
     {
-      stream_t *streamptr = stream_to_pointer(streamID);
-      streamptr->byteorder = byteorder;
+      xassert(gridP->nrowlon);
+      gridP->rowlon = (int *)xmalloc((size_t)gridP->nrowlon * sizeof (int));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
     }
 
-  return (streamID);
-}
+  {
+    double doubleBuffer[gridNdouble];
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    &d, 1, DATATYPE_UINT32, context);
+    xassert(d == cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer));
 
+    gridP->xfirst = doubleBuffer[0];
+    gridP->yfirst = doubleBuffer[1];
+    gridP->xlast = doubleBuffer[2];
+    gridP->ylast = doubleBuffer[3];
+    gridP->xinc = doubleBuffer[4];
+    gridP->yinc = doubleBuffer[5];
+    gridP->lcc_originLon = doubleBuffer[6];
+    gridP->lcc_originLat = doubleBuffer[7];
+    gridP->lcc_lonParY = doubleBuffer[8];
+    gridP->lcc_lat1 = doubleBuffer[9];
+    gridP->lcc_lat2 = doubleBuffer[10];
+    gridP->lcc_xinc = doubleBuffer[11];
+    gridP->lcc_yinc = doubleBuffer[12];
+    gridP->lcc2_lon_0 = doubleBuffer[13];
+    gridP->lcc2_lat_0 = doubleBuffer[14];
+    gridP->lcc2_lat_1 = doubleBuffer[15];
+    gridP->lcc2_lat_2 = doubleBuffer[16];
+    gridP->lcc2_a = doubleBuffer[17];
+    gridP->laea_lon_0 = doubleBuffer[18];
+    gridP->laea_lat_0 = doubleBuffer[19];
+    gridP->laea_a = doubleBuffer[20];
+    gridP->xpole = doubleBuffer[21];
+    gridP->ypole = doubleBuffer[22];
+    gridP->angle = doubleBuffer[23];
+  }
 
-int streamOpenAppend(const char *filename)
-{
-  cdiInitialize();
+  int irregular = gridP->type == GRID_UNSTRUCTURED
+    || gridP->type == GRID_CURVILINEAR;
+  if (memberMask & gridHasXValsFlag)
+    {
+      size = irregular ? gridP->size : gridP->xsize;
 
-  int byteorder = 0;
-  int filetype = cdiGetFiletype(filename, &byteorder);
+      gridP->xvals = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->xvals, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
+    }
 
-  if ( filetype < 0 ) return (filetype);
+  if (memberMask & gridHasYValsFlag)
+    {
+      size = irregular ? gridP->size : gridP->ysize;
 
-  int streamID = streamOpenA(filename, "a", filetype);
+      gridP->yvals = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->yvals, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
+    }
 
-  if ( streamID >= 0 )
+  if (memberMask & gridHasAreaFlag)
     {
-      stream_t *streamptr = stream_to_pointer(streamID);
-      streamptr->byteorder = byteorder;
+      size = gridP->size;
+      xassert(size);
+      gridP->area = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->area, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
     }
 
-  return (streamID);
-}
+  if (memberMask & gridHasXBoundsFlag)
+    {
+      size = gridP->nvertex * (irregular ? gridP->size : gridP->xsize);
+      xassert(size);
 
-/*
- at Function  streamOpenWrite
- at Title     Create a new dataset
+      gridP->xbounds = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->xbounds, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
+    }
 
- at Prototype int streamOpenWrite(const char *path, int filetype)
- at Parameter
-    @Item  path      The name of the new dataset.
-    @Item  filetype  The type of the file format, one of the set of predefined CDI file format types.
-                     The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC},
-                     @func{FILETYPE_NC2}, @func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV},
-                     @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
+  if (memberMask & gridHasYBoundsFlag)
+    {
+      size = gridP->nvertex * (irregular ? gridP->size : gridP->ysize);
+      xassert(size);
 
- at Description
-The function @func{streamOpenWrite} creates a new datset.
- at Result
-Upon successful completion @func{streamOpenWrite} returns an identifier to the
-open stream. Otherwise, a negative number with the error status is returned.
+      gridP->ybounds = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+			  gridP->ybounds, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
+    }
 
- at Errors
- at List
-   @Item  CDI_ESYSTEM     Operating system error.
-   @Item  CDI_EINVAL      Invalid argument.
-   @Item  CDI_EUFILETYPE  Unsupported file type.
-   @Item  CDI_ELIBNAVAIL  Library support not compiled in.
- at EndList
+  {
+    char *strTab[] = GRID_STR_SERIALIZE;
+    int numStr = sizeof (strTab) / sizeof (strTab[0]);
+    serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                          strTab, numStr, context);
+  }
 
- at Example
-Here is an example using @func{streamOpenWrite} to create a new netCDF file named @func{foo.nc} for writing:
+  if (memberMask & gridHasReferenceFlag)
+    {
+      int referenceSize;
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &referenceSize, 1, DATATYPE_INT, context);
+      gridP->reference = (char *)xmalloc((size_t)referenceSize);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->reference, referenceSize, DATATYPE_TXT, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
+    }
 
- at Source
-   ...
-int streamID;
-   ...
-streamID = streamOpenWrite("foo.nc", FILETYPE_NC);
-if ( streamID < 0 ) handle_error(streamID);
-   ...
- at EndSource
- at EndFunction
-*/
-int streamOpenWrite(const char *filename, int filetype)
-{
-  cdiInitialize();
+  if (memberMask & gridHasMaskFlag)
+    {
+      xassert((size = gridP->size));
+      gridP->mask = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->mask, gridP->size, DATATYPE_UCHAR, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
+    }
 
-  return (streamOpen(filename, "w", filetype));
+  if (memberMask & gridHasGMEMaskFlag)
+    {
+      xassert((size = gridP->size));
+      gridP->mask_gme = (mask_t *)xmalloc((size_t)size * sizeof (mask_t));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
+    }
+  if (memberMask & gridHasUUIDFlag)
+    {
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
+    }
 }
 
-static
-void streamDefaultValue ( stream_t * streamptr )
-{
-  int i;
-
-  streamptr->self              = CDI_UNDEFID;
-  streamptr->accesstype        = CDI_UNDEFID;
-  streamptr->accessmode        = 0;
-  streamptr->filetype          = FILETYPE_UNDEF;
-  streamptr->byteorder         = CDI_UNDEFID;
-  streamptr->fileID            = 0;
-  streamptr->filemode          = 0;
-  streamptr->numvals           = 0;
-  streamptr->filename          = NULL;
-  streamptr->record            = NULL;
-  streamptr->varsAllocated     = 0;
-  streamptr->nrecs             = 0;
-  streamptr->nvars             = 0;
-  streamptr->vars              = NULL;
-  streamptr->ncmode            = 0;
-  streamptr->curTsID           = CDI_UNDEFID;
-  streamptr->rtsteps           = 0;
-  streamptr->ntsteps           = CDI_UNDEFID;
-  streamptr->tsteps            = NULL;
-  streamptr->tstepsTableSize   = 0;
-  streamptr->tstepsNextID      = 0;
-  streamptr->historyID         = CDI_UNDEFID;
-  streamptr->vlistID           = CDI_UNDEFID;
-  streamptr->globalatts        = 0;
-  streamptr->localatts         = 0;
-  streamptr->vct.ilev          = 0;
-  streamptr->vct.mlev          = 0;
-  streamptr->vct.ilevID        = CDI_UNDEFID;
-  streamptr->vct.mlevID        = CDI_UNDEFID;
-  streamptr->unreduced         = cdiDataUnreduced;
-  streamptr->sortname          = cdiSortName;
-  streamptr->have_missval      = cdiHaveMissval;
-  streamptr->comptype          = COMPRESS_NONE;
-  streamptr->complevel         = 0;
-
-  basetimeInit(&streamptr->basetime);
-
-  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->xdimID[i]   = CDI_UNDEFID;
-  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ydimID[i]   = CDI_UNDEFID;
-  for ( i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i]  = CDI_UNDEFID;
-  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncxvarID[i] = CDI_UNDEFID;
-  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncyvarID[i] = CDI_UNDEFID;
-  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncavarID[i] = CDI_UNDEFID;
 
-  streamptr->gribContainers    = NULL;
-  streamptr->vlistIDorig       = CDI_UNDEFID;
-}
+static void
+gridPack(void * voidP, void * packBuffer, int packBufferSize,
+         int * packBufferPos, void *context)
+{
+  grid_t   * gridP = ( grid_t * )   voidP;
+  int size;
+  uint32_t d;
+  int memberMask;
 
+  {
+    int intBuffer[gridNint];
 
-static stream_t *stream_new_entry(int resH)
-{
-  stream_t *streamptr;
+    intBuffer[0]  = gridP->self;
+    intBuffer[1]  = gridP->type;
+    intBuffer[2]  = gridP->prec;
+    intBuffer[3]  = gridP->lcc_projflag;
+    intBuffer[4]  = gridP->lcc_scanflag;
+    intBuffer[5]  = gridP->lcc_defined;
+    intBuffer[6]  = gridP->lcc2_defined;
+    intBuffer[7]  = gridP->laea_defined;
+    intBuffer[8]  = gridP->isCyclic;
+    intBuffer[9]  = gridP->isRotated;
+    intBuffer[10] = gridP->xdef;
+    intBuffer[11] = gridP->ydef;
+    intBuffer[12] = gridP->nd;
+    intBuffer[13] = gridP->ni;
+    intBuffer[14] = gridP->ni2;
+    intBuffer[15] = gridP->ni3;
+    intBuffer[16] = gridP->number;
+    intBuffer[17] = gridP->position;
+    intBuffer[18] = gridP->trunc;
+    intBuffer[19] = gridP->nvertex;
+    intBuffer[20] = gridP->nrowlon;
+    intBuffer[21] = gridP->size;
+    intBuffer[22] = gridP->xsize;
+    intBuffer[23] = gridP->ysize;
+    intBuffer[24] = gridP->locked;
+    intBuffer[25] = gridP->lcomplex;
+    intBuffer[26] = memberMask = gridGetComponentFlags(gridP);
 
-  cdiInitialize(); /* ***************** make MT version !!! */
+    serializePack(intBuffer, gridNint, DATATYPE_INT,
+                  packBuffer, packBufferSize, packBufferPos, context);
+    d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
+                  packBuffer, packBufferSize, packBufferPos, context);
+  }
 
-  streamptr = (stream_t *) xmalloc(sizeof(stream_t));
-  streamDefaultValue ( streamptr );
-  if (resH == CDI_UNDEFID)
-    streamptr->self = reshPut(streamptr, &streamOps);
-  else
+  if (memberMask & gridHasRowLonFlag)
     {
-      streamptr->self = resH;
-      reshReplace(resH, streamptr, &streamOps);
+      size = gridP->nrowlon;
+      xassert(size > 0);
+      serializePack(gridP->rowlon, size, DATATYPE_INT,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
 
-  return streamptr;
-}
-
-
-void
-cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
-{
-  int fileID   = streamptr->fileID;
-  int filetype = streamptr->filetype;
-  if ( fileID == CDI_UNDEFID )
-    Warning("File %s not open!", streamptr->filename);
-  else
-    switch (filetype)
-      {
-#if  defined  (HAVE_LIBGRIB)
-      case FILETYPE_GRB:
-      case FILETYPE_GRB2:
-        {
-          gribClose(fileID);
-          if (recordBufIsToBeDeleted)
-            gribContainersDelete(streamptr);
-          break;
-        }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-      case FILETYPE_SRV:
-        {
-          fileClose(fileID);
-          if (recordBufIsToBeDeleted)
-            srvDelete(streamptr->record->exsep);
-          break;
-        }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-      case FILETYPE_EXT:
-        {
-          fileClose(fileID);
-          if (recordBufIsToBeDeleted)
-            extDelete(streamptr->record->exsep);
-          break;
-        }
-#endif
-#if  defined  (HAVE_LIBIEG)
-      case FILETYPE_IEG:
-        {
-          fileClose(fileID);
-          if (recordBufIsToBeDeleted)
-            iegDelete(streamptr->record->exsep);
-          break;
-        }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-      case FILETYPE_NC:
-      case FILETYPE_NC2:
-      case FILETYPE_NC4:
-      case FILETYPE_NC4C:
-        {
-          cdfClose(fileID);
-          break;
-        }
-#endif
-      default:
-        {
-          Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
-          break;
-        }
-      }
-}
-
+  {
+    double doubleBuffer[gridNdouble];
 
-/*
- at Function  streamClose
- at Title     Close an open dataset
+    doubleBuffer[0]  = gridP->xfirst;
+    doubleBuffer[1]  = gridP->yfirst;
+    doubleBuffer[2]  = gridP->xlast;
+    doubleBuffer[3]  = gridP->ylast;
+    doubleBuffer[4]  = gridP->xinc;
+    doubleBuffer[5]  = gridP->yinc;
+    doubleBuffer[6]  = gridP->lcc_originLon;
+    doubleBuffer[7]  = gridP->lcc_originLat;
+    doubleBuffer[8]  = gridP->lcc_lonParY;
+    doubleBuffer[9]  = gridP->lcc_lat1;
+    doubleBuffer[10] = gridP->lcc_lat2;
+    doubleBuffer[11] = gridP->lcc_xinc;
+    doubleBuffer[12] = gridP->lcc_yinc;
+    doubleBuffer[13] = gridP->lcc2_lon_0;
+    doubleBuffer[14] = gridP->lcc2_lat_0;
+    doubleBuffer[15] = gridP->lcc2_lat_1;
+    doubleBuffer[16] = gridP->lcc2_lat_2;
+    doubleBuffer[17] = gridP->lcc2_a;
+    doubleBuffer[18] = gridP->laea_lon_0;
+    doubleBuffer[19] = gridP->laea_lat_0;
+    doubleBuffer[20] = gridP->laea_a;
+    doubleBuffer[21] = gridP->xpole;
+    doubleBuffer[22] = gridP->ypole;
+    doubleBuffer[23] = gridP->angle;
 
- at Prototype  void streamClose(int streamID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+    serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
+                  packBuffer, packBufferSize, packBufferPos, context);
+    d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
+                  packBuffer, packBufferSize, packBufferPos, context);
+  }
 
- at Description
-The function @func{streamClose} closes an open dataset.
+  if (memberMask & gridHasXValsFlag)
+    {
+      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
+	size = gridP->size;
+      else
+	size = gridP->xsize;
+      xassert(size);
 
- at EndFunction
-*/
-void streamClose(int streamID)
-{
-  int index;
-  int vlistID;
-  stream_t *streamptr = stream_to_pointer(streamID);
+      serializePack(gridP->xvals, size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  stream_check_ptr(__func__, streamptr);
+  if (memberMask & gridHasYValsFlag)
+    {
+      if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR )
+	size = gridP->size;
+      else
+	size = gridP->ysize;
+      xassert(size);
+      serializePack(gridP->yvals, size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->yvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  if ( CDI_Debug )
-    Message("streamID = %d filename = %s", streamID, streamptr->filename);
+  if (memberMask & gridHasAreaFlag)
+    {
+      xassert(gridP->size);
 
-  vlistID  = streamptr->vlistID;
+      serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
-    = (void (*)(stream_t *, int))
-    namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+  if (memberMask & gridHasXBoundsFlag)
+    {
+      xassert ( gridP->nvertex );
+      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+	size = gridP->nvertex * gridP->size;
+      else
+	size = gridP->nvertex * gridP->xsize;
+      xassert ( size );
 
-  if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
+      serializePack(gridP->xbounds, size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  if ( streamptr->record )
+  if (memberMask & gridHasYBoundsFlag)
     {
-      if ( streamptr->record->buffer )
-        free(streamptr->record->buffer);
+      xassert(gridP->nvertex);
+      if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
+	size = gridP->nvertex * gridP->size;
+      else
+	size = gridP->nvertex * gridP->ysize;
+      xassert ( size );
 
-      free(streamptr->record);
+      serializePack(gridP->ybounds, size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
 
-  streamptr->filetype = 0;
-  if ( streamptr->filename ) free(streamptr->filename);
+  {
+    const char *strTab[] = GRID_STR_SERIALIZE;
+    int numStr = sizeof (strTab) / sizeof (strTab[0]);
+    serializeStrTabPack(strTab, numStr,
+                        packBuffer, packBufferSize, packBufferPos, context);
+  }
 
-  for ( index = 0; index < streamptr->nvars; index++ )
+  if (memberMask & gridHasReferenceFlag)
     {
-      if ( streamptr->vars[index].level )
-	free(streamptr->vars[index].level);
-      if ( streamptr->vars[index].lindex )
-	free(streamptr->vars[index].lindex);
+      size = (int)strlen(gridP->reference) + 1;
+      serializePack(&size, 1, DATATYPE_INT,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      serializePack(gridP->reference, size, DATATYPE_TXT,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
-  free(streamptr->vars);
 
-  for ( index = 0; index < streamptr->ntsteps; ++index )
+  if (memberMask & gridHasMaskFlag)
     {
-      if ( streamptr->tsteps[index].records )
-	free(streamptr->tsteps[index].records);
-      if ( streamptr->tsteps[index].recIDs )
-	free(streamptr->tsteps[index].recIDs);
-      taxisDestroyKernel(&streamptr->tsteps[index].taxis);
+      xassert((size = gridP->size));
+      serializePack(gridP->mask, size, DATATYPE_UCHAR,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
 
-  if ( streamptr->tsteps ) free(streamptr->tsteps);
-
-  if ( streamptr->basetime.timevar_cache ) free(streamptr->basetime.timevar_cache);
-
-  if ( vlistID != -1 )
+  if (memberMask & gridHasGMEMaskFlag)
     {
-      if ( streamptr->filemode != 'w' )
-	if ( vlistInqTaxis(vlistID) != -1 )
-	  {
-	    taxisDestroy(vlistInqTaxis(vlistID));
-	  }
+      xassert((size = gridP->size));
 
-      vlist_unlock(vlistID);
-      vlistDestroy(vlistID);
+      serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
 
-  stream_delete_entry(streamptr);
+  if (memberMask & gridHasUUIDFlag)
+    serializePack(gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
+                  packBuffer, packBufferSize, packBufferPos, context);
 }
 
-static void stream_delete_entry(stream_t *streamptr)
-{
-  int idx;
+#undef GRID_STR_SERIALIZE
 
-  xassert ( streamptr );
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  idx = streamptr->self;
-  free ( streamptr );
-  reshRemove ( idx, &streamOps );
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
 
-  if ( CDI_Debug )
-    Message("Removed idx %d from stream list", idx);
+
+
+
+static int initIegLib      = 0;
+static int iegDefaultDprec = 0;
+
+
+/*
+ * A version string.
+ */
+
+#undef  LIBVERSION
+#define LIBVERSION      1.3.3
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
+static const char ieg_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
+
+const char *iegLibraryVersion(void)
+{
+  return (ieg_libvers);
 }
 
 
-void cdiStreamSync_(stream_t *streamptr)
+int IEG_Debug = 0;    /* If set to 1, debugging */
+
+
+
+void iegLibInit()
 {
-  int fileID   = streamptr->fileID;
-  int filetype = streamptr->filetype;
-  int vlistID  = streamptr->vlistID;
-  int nvars    = vlistNvars(vlistID);
+  char *envString;
+  char *envName = "IEG_PRECISION";
 
-  if ( fileID == CDI_UNDEFID )
-    Warning("File %s not open!", streamptr->filename);
-  else if ( vlistID == CDI_UNDEFID )
-    Warning("Vlist undefined for file %s!", streamptr->filename);
-  else if ( nvars == 0 )
-    Warning("No variables defined!");
-  else
+
+  envString = getenv(envName);
+  if ( envString )
     {
-      if ( streamptr->filemode == 'w' || streamptr->filemode == 'a' )
+      int pos;
+      int nrun;
+      if ( strlen(envString) == 2 ) nrun = 1;
+      else                          nrun = 2;
+
+      pos = 0;
+      while ( nrun-- )
 	{
-	  switch (filetype)
+	  switch ( tolower((int) envString[pos]) )
 	    {
-#if  defined  (HAVE_LIBNETCDF)
-	    case FILETYPE_NC:
-	    case FILETYPE_NC2:
-	    case FILETYPE_NC4:
-	    case FILETYPE_NC4C:
+	    case 'r':
 	      {
-		void cdf_sync(int ncid);
-		if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
+		switch ( (int) envString[pos+1] )
+		  {
+		  case '4': iegDefaultDprec = SINGLE_PRECISION; break;
+		  case '8': iegDefaultDprec = DOUBLE_PRECISION; break;
+		  default:
+		    Message("Invalid digit in %s: %s", envName, envString);
+		  }
 		break;
 	      }
-#endif
 	    default:
-	      {
-		fileFlush(fileID);
-		break;
-	      }
-	    }
+              {
+                Message("Invalid character in %s: %s", envName, envString);
+                break;
+              }
+            }
+	  pos += 2;
 	}
     }
-}
-
-/*
- at Function  streamSync
- at Title     Synchronize an Open Dataset to Disk
 
- at Prototype  void streamSync(int streamID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+  initIegLib = 1;
+}
 
- at Description
-The function @func{streamSync} offers a way to synchronize the disk copy of a dataset with in-memory buffers.
 
- at EndFunction
-*/
-void streamSync(int streamID)
+void iegDebug(int debug)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  IEG_Debug = debug;
 
-  void (*myStreamSync_)(stream_t *streamptr)
-    = (void (*)(stream_t *))namespaceSwitchGet(NSSWITCH_STREAM_SYNC).func;
-  myStreamSync_(streamptr);
+  if ( IEG_Debug )
+    Message("debug level %d", debug);
 }
 
 
-int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
+void iegInit(iegrec_t *iegp)
 {
-  int taxisID;
-
-  if ( CDI_Debug )
-    Message("streamID = %d  tsID = %d", streamptr->self, tsID);
+  iegp->checked    = 0;
+  iegp->byteswap   = 0;
+  iegp->dprec      = 0;
+  iegp->refval     = 0;
+  iegp->datasize   = 0;
+  iegp->buffersize = 0;
+  iegp->buffer     = NULL;
+}
 
-  stream_check_ptr(__func__, streamptr);
 
-  int vlistID = streamptr->vlistID;
+void iegInitMem(iegrec_t *iegp)
+{
+  memset(iegp->ipdb, 0, sizeof(iegp->ipdb));
+  memset(iegp->igdb, 0, sizeof(iegp->igdb));
+  memset(iegp->vct,  0, sizeof(iegp->vct));
+}
 
-  int time_is_varying = vlistHasTime(vlistID);
 
-  if ( time_is_varying )
-    {
-      taxisID = vlistInqTaxis(vlistID);
-      if ( taxisID == CDI_UNDEFID )
-        {
-          Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
-          taxisID = taxisCreate(TAXIS_ABSOLUTE);
-          vlistDefTaxis(vlistID, taxisID);
-        }
-    }
+iegrec_t *iegNew(void)
+{
+  iegrec_t *iegp;
 
-  int newtsID = tstepsNewEntry(streamptr);
+  if ( ! initIegLib ) iegLibInit();
 
-  if ( tsID != newtsID )
-    Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
+  iegp = (iegrec_t *) malloc(sizeof(iegrec_t));
 
-  streamptr->curTsID = tsID;
+  iegInit(iegp);
+  iegInitMem(iegp);
 
-  if ( time_is_varying )
-    {
-      taxis_t *taxisptr1 = taxisPtr(taxisID);
-      taxis_t *taxisptr2 = &streamptr->tsteps[tsID].taxis;
-      ptaxisCopy(taxisptr2, taxisptr1);
-    }
+  return (iegp);
+}
 
-  streamptr->ntsteps = tsID + 1;
 
-#ifdef HAVE_LIBNETCDF
-  if ((streamptr->filetype == FILETYPE_NC  ||
-       streamptr->filetype == FILETYPE_NC2 ||
-       streamptr->filetype == FILETYPE_NC4 ||
-       streamptr->filetype == FILETYPE_NC4C)
-      && vlistHasTime(vlistID))
+void iegDelete(iegrec_t *iegp)
+{
+  if ( iegp )
     {
-      void (*myCdfDefTimestep)(stream_t *streamptr, int tsID)
-        = (void (*)(stream_t *, int))
-        namespaceSwitchGet(NSSWITCH_CDF_DEF_TIMESTEP).func;
-      myCdfDefTimestep(streamptr, tsID);
+      if ( iegp->buffer ) free(iegp->buffer);
+      free(iegp);
     }
-#endif
-
-  cdi_create_records(streamptr, tsID);
-
-  return (int)streamptr->ntsteps;
 }
 
-/*
- at Function  streamDefTimestep
- at Title     Define time step
-
- at Prototype int streamDefTimestep(int streamID, int tsID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  tsID      Timestep identifier.
-
- at Description
-The function @func{streamDefTimestep} defines the time step of a stream.
-
- at Result
- at func{streamDefTimestep} returns the number of records of the time step.
-
- at EndFunction
-*/
-int streamDefTimestep(int streamID, int tsID)
-{
-  stream_t *streamptr = stream_to_pointer(streamID);
-  int (*myStreamDefTimestep_)(stream_t *streamptr, int tsID)
-    = (int (*)(stream_t *, int))
-    namespaceSwitchGet(NSSWITCH_STREAM_DEF_TIMESTEP_).func;
-  return myStreamDefTimestep_(streamptr, tsID);
-}
 
-int streamInqCurTimestepID(int streamID)
+int iegCheckFiletype(int fileID, int *swap)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
-  return streamptr->curTsID;
-}
-
-
-/*
- at Function  streamInqTimestep
- at Title     Get time step
-
- at Prototype int streamInqTimestep(int streamID, int tsID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
-    @Item  tsID      Timestep identifier.
-
- at Description
-The function @func{streamInqTimestep} returns the time step of a stream.
-
- at Result
- at func{streamInqTimestep} returns the number of records of the time step.
+  size_t blocklen = 0;
+  size_t sblocklen = 0;
+  size_t data = 0;
+  size_t dimx = 0, dimy = 0;
+  size_t fact = 0;
+  unsigned char buffer[1048], *pbuf;
 
- at EndFunction
-*/
-int streamInqTimestep(int streamID, int tsID)
-{
-  int nrecs = 0;
-  int taxisID;
-  stream_t *streamptr = stream_to_pointer(streamID);
+  if ( fileRead(fileID, buffer, 4) != 4 ) return (0);
 
-  stream_check_ptr(__func__, streamptr);
+  blocklen  = get_UINT32(buffer);
+  sblocklen = get_SUINT32(buffer);
 
-  int vlistID = streamptr->vlistID;
+  if ( IEG_Debug )
+    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
 
-  if ( tsID < streamptr->rtsteps )
+  if ( blocklen == 636 || blocklen == 640 )
     {
-      streamptr->curTsID = tsID;
-      nrecs = streamptr->tsteps[tsID].nrecs;
-      streamptr->tsteps[tsID].curRecID = CDI_UNDEFID;
-      taxisID = vlistInqTaxis(vlistID);
-      if ( taxisID == -1 )
-	Error("Timestep undefined for fileID = %d", streamID);
-      ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
-
-      return (nrecs);
+     *swap = 0;
+      fact = 4;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (0);
+      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
     }
-
-  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+  else if ( blocklen == 1040 || blocklen == 1036 )
     {
-      return (0);
+     *swap = 0;
+      fact = 8;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (0);
+      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
+    }
+  else if ( sblocklen == 636 || sblocklen == 640 )
+    {
+     *swap = 1;
+      fact = 4;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (0);
+      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
+    }
+  else if ( sblocklen == 1040 || sblocklen == 1036 )
+    {
+     *swap = 1;
+      fact = 8;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (0);
+      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
     }
 
-  int filetype = streamptr->filetype;
+  fileRewind(fileID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  tsID = %d  filetype = %d", streamID, tsID, filetype);
+  int found = data && (dimx*dimy*fact == data || dimx*dimy*8 == data);
 
-  switch (filetype)
+  if ( IEG_Debug )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        nrecs = grbInqTimestep(streamptr, tsID);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        nrecs = srvInqTimestep(streamptr, tsID);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        nrecs = extInqTimestep(streamptr, tsID);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        nrecs = iegInqTimestep(streamptr, tsID);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-        nrecs = cdfInqTimestep(streamptr, tsID);
-	break;
-      }
-#endif
-    default:
-      {
-	Error("%s support not compiled in!", strfiletype(filetype));
-	break;
-      }
+      Message("swap = %d fact = %d", *swap, fact);
+      Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
     }
 
-  taxisID = vlistInqTaxis(vlistID);
-  if ( taxisID == -1 )
-    Error("Timestep undefined for fileID = %d", streamID);
+  return (found);
+}
 
-  ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
 
-  return (nrecs);
+void iegCopyMeta(iegrec_t *diegp, iegrec_t *siegp)
+{
+  /*  diegp->byteswap = siegp->byteswap; */
+  diegp->dprec    = siegp->dprec;
+  diegp->refval   = siegp->refval;
+
+  memcpy(diegp->ipdb, siegp->ipdb, sizeof(siegp->ipdb));
+  memcpy(diegp->igdb, siegp->igdb, sizeof(siegp->igdb));
+  memcpy(diegp->vct,  siegp->vct,  sizeof(siegp->vct));
 }
 
-/* the single image implementation */
-static
-void cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmiss)
-{
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamID, varID);
 
-  check_parg(data);
-  check_parg(nmiss);
+int iegInqData(iegrec_t *iegp, int prec, void *data)
+{
+  size_t datasize;
+  size_t i;
+  int ierr = 0;
+  int dprec;
+  void *buffer;
+  int byteswap = iegp->byteswap;
 
-  stream_t *streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
+  datasize = iegp->datasize;
 
-  int filetype = streamptr->filetype;
+  buffer = iegp->buffer;
 
-  *nmiss = 0;
+  dprec = iegp->dprec;
 
-  switch (filetype)
-    {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbReadVar not implemented for memtype float!");
-        grbReadVarDP(streamptr, varID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("srvReadVar not implemented for memtype float!");
-        srvReadVarDP(streamptr, varID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("extReadVar not implemented for memtype float!");
-        extReadVarDP(streamptr, varID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("iegReadVar not implemented for memtype float!");
-        iegReadVarDP(streamptr, varID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
+  switch ( dprec )
+    {
+    case SINGLE_PRECISION:
       {
-        if ( memtype == MEMTYPE_FLOAT )
-          cdfReadVarSP(streamptr, varID, data, nmiss);
-        else
-          cdfReadVarDP(streamptr, varID, data, nmiss);
+	if ( sizeof(FLT32) == 4 )
+	  {
+	    if ( byteswap ) swap4byte(buffer, datasize);
 
+	    if ( dprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT32));
+	    else
+	      for (i = 0; i < datasize; i++)
+		((double *) data)[i] = (double) ((float *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT32));
+	  }
 	break;
       }
-#endif
+    case DOUBLE_PRECISION:
+	if ( sizeof(FLT64) == 8 )
+	  {
+	    if ( byteswap ) swap8byte(buffer, datasize);
+
+	    if ( dprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT64));
+	    else
+	      for (i = 0; i < datasize; i++)
+		((float *) data)[i] = (float) ((double *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT64));
+	  }
+	break;
     default:
       {
-	Error("%s support not compiled in!", strfiletype(filetype));
-	break;
+	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
-}
 
-/*
- at Function  streamReadVar
- at Title     Read a variable
+  return (ierr);
+}
 
- at Prototype void streamReadVar(int streamID, int varID, double *data, int *nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
-    @Item  varID     Variable identifier.
-    @Item  data      Pointer to the location into which the data values are read.
-                     The caller must allocate space for the returned values.
-    @Item  nmiss     Number of missing values.
 
- at Description
-The function streamReadVar reads all the values of one time step of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+int iegInqDataSP(iegrec_t *iegp, float *data)
 {
-  cdiStreamReadVar(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
+  return (iegInqData(iegp, SINGLE_PRECISION, (void *) data));
 }
 
-/*
- at Function  streamReadVarF
- at Title     Read a variable
-
- at Prototype void streamReadVar(int streamID, int varID, float *data, int *nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
-    @Item  varID     Variable identifier.
-    @Item  data      Pointer to the location into which the data values are read.
-                     The caller must allocate space for the returned values.
-    @Item  nmiss     Number of missing values.
 
- at Description
-The function streamReadVar reads all the values of one time step of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVarF(int streamID, int varID, float *data, int *nmiss)
+int iegInqDataDP(iegrec_t *iegp, double *data)
 {
-  cdiStreamReadVar(streamID, varID, MEMTYPE_FLOAT, data, nmiss);
+  return (iegInqData(iegp, DOUBLE_PRECISION, (void *) data));
 }
 
-/* the single image implementation */
-void cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss)
+
+int iegDefData(iegrec_t *iegp, int prec, const void *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+  size_t datasize;
+  size_t blocklen;
+  size_t buffersize;
+  size_t i;
+  int dprec;
+  void *buffer;
 
-  check_parg(data);
 
-  stream_t *streamptr = stream_to_pointer(streamID);
+  if ( iegDefaultDprec ) dprec = iegDefaultDprec;
+  else                   dprec = iegp->dprec;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( ! dprec ) dprec = prec;
 
-  // check taxis
-  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+  iegp->dprec = dprec;
 
-  int filetype = streamptr->filetype;
+  datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
+  blocklen = datasize * (size_t)dprec;
 
-  switch (filetype)
+  iegp->datasize = datasize;
+
+  buffersize = iegp->buffersize;
+
+  if ( buffersize != blocklen )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        grb_write_var(streamptr, varID, memtype, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVar not implemented for memtype float!");
-        srvWriteVarDP(streamptr, varID, data);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVar not implemented for memtype float!");
-        extWriteVarDP(streamptr, varID, data);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
+      buffersize = blocklen;
+      buffer = iegp->buffer;
+      buffer = realloc(buffer, buffersize);
+      iegp->buffer = buffer;
+      iegp->buffersize = buffersize;
+    }
+  else
+    buffer = iegp->buffer;
+
+  switch ( dprec )
+    {
+    case SINGLE_PRECISION:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVar not implemented for memtype float!");
-        iegWriteVarDP(streamptr, varID, data);
+	if ( dprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT32));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((float *) buffer)[i] = (float) ((double *) data)[i];
+
 	break;
       }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
+    case DOUBLE_PRECISION:
       {
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
-        cdf_write_var(streamptr, varID, memtype, data, nmiss);
+	if ( dprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT64));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((double *) buffer)[i] = (double) ((float *) data)[i];
+
 	break;
       }
-#endif
     default:
       {
-	Error("%s support not compiled in!", strfiletype(filetype));
-	break;
+	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
-}
 
-/*
- at Function  streamWriteVar
- at Title     Write a variable
+  return (0);
+}
 
- at Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  varID     Variable identifier.
-    @Item  data      Pointer to a block of double precision floating point data values to be written.
-    @Item  nmiss     Number of missing values.
 
- at Description
-The function streamWriteVar writes the values of one time step of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
- at EndFunction
-*/
-void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
+int iegDefDataSP(iegrec_t *iegp, const float *data)
 {
-  void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
-                               const void *data, int nmiss)
-    = (void (*)(int, int, int, const void *, int))
-    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
-  myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
+  return (iegDefData(iegp, SINGLE_PRECISION, (void *) data));
 }
 
-/*
- at Function  streamWriteVarF
- at Title     Write a variable
-
- at Prototype void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  varID     Variable identifier.
-    @Item  data      Pointer to a block of single precision floating point data values to be written.
-    @Item  nmiss     Number of missing values.
 
- at Description
-The function streamWriteVarF writes the values of one time step of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
-Only support for netCDF was implemented in this function.
- at EndFunction
-*/
-void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+int iegDefDataDP(iegrec_t *iegp, const double *data)
 {
-  void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
-                               const void *data, int nmiss)
-    = (void (*)(int, int, int, const void *, int))
-    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
-  myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, data, nmiss);
+  return (iegDefData(iegp, DOUBLE_PRECISION, (void *) data));
 }
 
-static
-int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, int *nmiss)
+
+int iegRead(int fileID, iegrec_t *iegp)
 {
-  // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
-  // A value > 0 is returned in this case, otherwise it returns zero.
-  int status = 0;
+  size_t datasize;
+  size_t blocklen, blocklen2;
+  size_t i;
+  char tmpbuffer[800], *tmpbuf = tmpbuffer;
+  int dprec = 0;
+  void *buffer;
+  int byteswap;
+  int status;
 
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamID, varID);
+  if ( ! iegp->checked )
+    {
+      status = iegCheckFiletype(fileID, &iegp->byteswap);
+      if ( status == 0 ) Error("Not a IEG file!");
+      iegp->checked = 1;
+    }
 
-  check_parg(data);
-  check_parg(nmiss);
+  byteswap = iegp->byteswap;
 
-  stream_t *streamptr = stream_to_pointer(streamID);
+  /* read header record */
+  blocklen = binReadF77Block(fileID, byteswap);
 
-  stream_check_ptr(__func__, streamptr);
+  if ( fileEOF(fileID) ) return (-1);
 
-  int filetype = streamptr->filetype;
+  if ( IEG_Debug )
+    Message("blocklen = %lu", blocklen);
 
-  *nmiss = 0;
+  if ( blocklen == 636 || blocklen == 640 )
+    dprec = 4;
+  else if ( blocklen == 1040 || blocklen == 1036 )
+    dprec = 8;
+  else
+    {
+      Warning("unexpecteted header size %d!", (int) blocklen);
+      return (-1);
+    }
 
-  switch (filetype)
+  iegp->dprec = dprec;
+
+  binReadInt32(fileID, byteswap, 37, (INT32 *) tmpbuf);
+  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = (int) ((INT32 *) tmpbuf)[i];
+
+  binReadInt32(fileID, byteswap, 18, (INT32 *) tmpbuf);
+  for ( i = 0; i < 18; i++ ) iegp->igdb[i] = (int) ((INT32 *) tmpbuf)[i];
+
+  if ( blocklen == 636 || blocklen == 1036 )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) return 1;
-        grbReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) return 1;
-        srvReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) return 1;
-        extReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) return 1;
-        iegReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-        if ( memtype == MEMTYPE_FLOAT )
-          cdfReadVarSliceSP(streamptr, varID, levelID, data, nmiss);
-        else
-          cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-        break;
-      }
-#endif
-    default:
-      {
-	Error("%s support not compiled in!", strfiletype(filetype));
-        status = 2;
-	break;
-      }
+      fileRead(fileID, tmpbuf, 4);
+      if ( byteswap ) swap4byte(tmpbuf, 1);
+      iegp->refval = (double) ((float *) tmpbuf)[0];
+    }
+  else
+    {
+      fileRead(fileID, tmpbuf, 8);
+      if ( byteswap ) swap8byte(tmpbuf, 1);
+      iegp->refval = (double) ((double *) tmpbuf)[0];
     }
 
-  return status;
-}
+  binReadInt32(fileID, byteswap, 3, (INT32 *) tmpbuf);
+  for ( i = 0; i < 3; i++ ) iegp->igdb[18+i] = (int) ((INT32 *) tmpbuf)[i];
 
-/*
- at Function  streamReadVarSlice
- at Title     Read a horizontal slice of a variable
+  if ( dprec == SINGLE_PRECISION )
+    {
+      fileRead(fileID, tmpbuf, 400);
+      if ( byteswap ) swap4byte(tmpbuf, 100);
+      for ( i = 0; i < 100; i++ )
+	iegp->vct[i] = (double) ((float *) tmpbuf)[i];
+    }
+  else
+    {
+      fileRead(fileID, tmpbuf, 800);
+      if ( byteswap ) swap8byte(tmpbuf, 100);
+      for ( i = 0; i < 100; i++ )
+	iegp->vct[i] = (double) ((double *) tmpbuf)[i];
+    }
 
- at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
-    @Item  varID     Variable identifier.
-    @Item  levelID   Level identifier.
-    @Item  data      Pointer to the location into which the data values are read.
-                     The caller must allocate space for the returned values.
-    @Item  nmiss     Number of missing values.
+  /*
+  fprintf(stderr, "refval %g\n", iegp->refval);
 
- at Description
-The function streamReadVarSlice reads all the values of a horizontal slice of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
-{
-  if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss) )
+  for ( i = 0; i < 100; i++ )
+    fprintf(stderr, "%3d %g\n", i, iegp->vct[i]);
+
+  {
+    int i;
+    for ( i = 0; i < 37; i++ )
+      fprintf(stderr, "pdb: %d %d\n", i, iegp->ipdb[i]);
+    for ( i = 0; i < 22; i++ )
+      fprintf(stderr, "gdb: %d %d\n", i, iegp->igdb[i]);
+  }
+  */
+  blocklen2 = binReadF77Block(fileID, byteswap);
+
+  if ( blocklen2 != blocklen )
     {
-      Warning("Unexpected error returned from cdiStreamReadVarSlice()!");
-      size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
-      memset(data, 0, elementCount * sizeof(*data));
+      Warning("header blocklen differ!");
+      return (-1);
     }
-}
 
-/*
- at Function  streamReadVarSliceF
- at Title     Read a horizontal slice of a variable
+  iegp->datasize = (size_t)IEG_G_NumLon(iegp->igdb)
+    * (size_t)IEG_G_NumLat(iegp->igdb);
 
- at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
-    @Item  varID     Variable identifier.
-    @Item  levelID   Level identifier.
-    @Item  data      Pointer to the location into which the data values are read.
-                     The caller must allocate space for the returned values.
-    @Item  nmiss     Number of missing values.
+  if ( IEG_Debug )
+    Message("datasize = %lu", iegp->datasize);
 
- at Description
-The function streamReadVarSliceF reads all the values of a horizontal slice of a variable
-from an open dataset.
- at EndFunction
-*/
-void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
-{
-  if ( cdiStreamReadVarSlice(streamID, varID,levelID, MEMTYPE_FLOAT, data, nmiss) )
+  blocklen = binReadF77Block(fileID, byteswap);
+
+  size_t buffersize = iegp->buffersize;
+
+  if ( buffersize < blocklen )
     {
-      // In case the file format does not support single precision reading,
-      // we fall back to double precision reading, converting the data on the fly.
-      size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
-      double* conversionBuffer = malloc(elementCount * sizeof(*conversionBuffer));
-      streamReadVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
-      for (size_t i = elementCount; i--; ) data[i] = (float)conversionBuffer[i];
-      free(conversionBuffer);
+      buffersize = blocklen;
+      buffer = iegp->buffer;
+      buffer = realloc(buffer, buffersize);
+      iegp->buffer = buffer;
+      iegp->buffersize = buffersize;
+    }
+  else
+    buffer = iegp->buffer;
+
+  datasize = iegp->datasize;
+
+  if ( dprec != (int) (blocklen/datasize) )
+    {
+      Warning("data precision differ! (h = %d; d = %d)",
+	      (int) dprec, (int) (blocklen/datasize));
+      return (-1);
+    }
+
+  fileRead(fileID, buffer, blocklen);
+
+  blocklen2 = binReadF77Block(fileID, byteswap);
+
+  if ( blocklen2 != blocklen )
+    {
+      Warning("data blocklen differ!");
+      return (-1);
     }
+
+  return (0);
 }
 
-static
-void cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
+
+int iegWrite(int fileID, iegrec_t *iegp)
 {
-  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+  size_t datasize;
+  size_t blocklen;
+  size_t i;
+  int dprec;
+  float refvalf;
+  double refval;
+  char tmpbuf[800];
+  float fvct[100];
+  void *buffer;
+  int byteswap = iegp->byteswap;
+
+
+  dprec  = iegp->dprec;
+
+  /* write header record */
+  if ( dprec == SINGLE_PRECISION )
+    blocklen = 636;
+  else
+    blocklen = 1040;
+
+  binWriteF77Block(fileID, byteswap, blocklen);
+
+  for ( i = 0; i < 37; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->ipdb[i];
+  binWriteInt32(fileID, byteswap, 37, (INT32 *) tmpbuf);
+
+  for ( i = 0; i < 18; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->igdb[i];
+  binWriteInt32(fileID, byteswap, 18, (INT32 *) tmpbuf);
+
+  refval = iegp->refval;
+  refvalf = (float) refval;
+  if ( dprec == SINGLE_PRECISION )
+    binWriteFlt32(fileID, byteswap, 1, (FLT32 *) &refvalf);
+  else
+    binWriteFlt64(fileID, byteswap, 1, (FLT64 *) &refval);
+
+  for ( i = 0; i < 3; i++ ) ((INT32 *) tmpbuf)[i] = (INT32) iegp->igdb[18+i];
+  binWriteInt32(fileID, byteswap, 3, (INT32 *) tmpbuf);
+
+  if ( dprec == SINGLE_PRECISION )
+    {
+      for ( i = 0; i < 100; i++ ) fvct[i] = (float) iegp->vct[i];
+      binWriteFlt32(fileID, byteswap, 100, fvct);
+    }
+  else
+    {
+      binWriteFlt64(fileID, byteswap, 100, iegp->vct);
+    }
 
-  check_parg(data);
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  stream_t *streamptr = stream_to_pointer(streamID);
+  datasize = (size_t)iegp->igdb[4] * (size_t)iegp->igdb[5];
+  blocklen = datasize * (size_t)dprec;
 
-  stream_check_ptr(__func__, streamptr);
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  // check taxis
-  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+  iegp->datasize = datasize;
 
-  int filetype = streamptr->filetype;
+  buffer = iegp->buffer;
 
-  switch (filetype)
+  switch ( dprec )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      {
-        grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      {
-        if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVarSlice not implemented for memtype float!");
-        srvWriteVarSliceDP(streamptr, varID, levelID, data);
-	break;
-      }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
+    case SINGLE_PRECISION:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVarSlice not implemented for memtype float!");
-        extWriteVarSliceDP(streamptr, varID, levelID, data);
+	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
 	break;
       }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
+    case DOUBLE_PRECISION:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVarSlice not implemented for memtype float!");
-        iegWriteVarSliceDP(streamptr, varID, levelID, data);
+	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
 	break;
       }
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
-      cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
-      break;
-#endif
     default:
       {
-	Error("%s support not compiled in!", strfiletype(filetype));
-	break;
+	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
-}
-
-/*
- at Function  streamWriteVarSlice
- at Title     Write a horizontal slice of a variable
 
- at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  varID     Variable identifier.
-    @Item  levelID   Level identifier.
-    @Item  data      Pointer to a block of double precision floating point data values to be written.
-    @Item  nmiss     Number of missing values.
+  binWriteF77Block(fileID, byteswap, blocklen);
 
- at Description
-The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
- at EndFunction
-*/
-void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
-{
-  cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss);
+  return (0);
 }
-
 /*
- at Function  streamWriteVarSliceF
- at Title     Write a horizontal slice of a variable
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+#define INCLUDE_GUARD_CDI_REFERENCE_COUNTING
 
- at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  varID     Variable identifier.
-    @Item  levelID   Level identifier.
-    @Item  data      Pointer to a block of single precision floating point data values to be written.
-    @Item  nmiss     Number of missing values.
 
- at Description
-The function streamWriteVarSliceF writes the values of a horizontal slice of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
-Only support for netCDF was implemented in this function.
- at EndFunction
+#include <sys/types.h>
+#include <stdlib.h>
+
+/*
+This is a base class for all objects that need reference counting.
+A CdiReferencedObject has a reference count of one when it is constructed, refObjectRetain() increments the reference count, refObject Release() decrements it.
+When the reference count reaches zero, the destructor function is called before the memory of the object is deallocated with free().
+
+>>> Warning <<<
+This code is currently not thread-safe.
+
+We are currently using the C99 standard, which does not have atomic types.
+Also, there are still tons of systems out there that have a gcc without wrong C11 atomics support
+(__STDC_NO_ATOMICS__ not defined even though stdatomics.h is not even present).
+Consequently, it is impossible to write preprocessor code to even check for the presence of atomic types.
+So, we have two options: provide multithreading support by means of locks, or wait a year or two before doing this right.
+I, for one, prefer doing things right.
 */
-void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
-{
-  cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss);
-}
+typedef struct CdiReferencedObject CdiReferencedObject;
+struct CdiReferencedObject {
+  //protected:
+    void (*destructor)(CdiReferencedObject* me);  //Subclass constructors should set this to their own destructor.
 
+  //private:    //Subclasses may read it to determine whether there is only one reference, though.
+    size_t refCount;
+};
 
-void
-streamWriteVarChunk(int streamID, int varID,
-                    const int rect[][2], const double *data, int nmiss)
-{
-  void (*myCdiStreamWriteVarChunk_)(int streamID, int varID, int memtype,
-                                    const int rect[][2], const void *data,
-                                    int nmiss)
-    = (void (*)(int, int, int, const int [][2], const void *, int))
-    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_CHUNK_).func;
-  myCdiStreamWriteVarChunk_(streamID, varID, MEMTYPE_DOUBLE, rect, data, nmiss);
-}
+void cdiRefObject_construct(CdiReferencedObject* me);
+void cdiRefObject_retain(CdiReferencedObject* me);
+void cdiRefObject_release(CdiReferencedObject* me);
+void cdiRefObject_destruct(CdiReferencedObject* me);
 
-/* single image implementation */
-void
-cdiStreamwriteVarChunk_(int streamID, int varID, int memtype,
-                        const int rect[][2], const void *data, int nmiss)
-{
-  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+#endif
+#ifndef INCLUDE_GUARD_CDI_GRIB_FILE_H
+#define INCLUDE_GUARD_CDI_GRIB_FILE_H
 
-  stream_t *streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
+/*
+CdiInputFile is a file abstraction that allows accessing an input file through any number of channels:
+It is reference counted, so that it is closed at the right place,
+and it is stateless, so that accesses from different callers cannot interfere with each other.
+Once the reference counting code is threadsafe, CdiInputFile will also be threadsafe.
+*/
+typedef struct CdiInputFile {
+  //public:
+    CdiReferencedObject super;
 
-  // streamDefineTaxis(streamID);
+  //private:
+    char* path;
+    int fileDescriptor;
+} CdiInputFile;
 
-  int filetype = streamptr->filetype;
+//Final class, the constructor is private and not defined here.
+CdiInputFile* cdiInputFile_make(const char* path);   //The caller is responsible to call cdiRefObject_release() on the returned object.
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer);       //Returns one of CDI_EINVAL, CDI_ESYSTEM, CDI_EEOF, OR CDI_NOERR.
+char* cdiInputFile_copyPath(const CdiInputFile* me);    //Returns a malloc'ed string, don't forget to free() it.
+//Destructor is private as well.
 
-  switch (filetype)
-    {
-#if defined (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-#endif
-#if defined (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-#endif
-#if defined (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-#endif
-#if defined (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-#endif
-#if  defined (HAVE_LIBGRIB) || defined (HAVE_LIBSERVICE)      \
-  || defined (HAVE_LIBEXTRA) || defined (HAVE_LIBIEG)
-      xabort("streamWriteVarChunk not implemented for filetype %s!",
-             strfiletype(filetype));
-      break;
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
-      cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
-      break;
 #endif
-    default:
-      Error("%s support not compiled in!", strfiletype(filetype));
-      break;
-    }
-}
 
-void streamWriteContents(int streamID, char *cname)
-{
-  stream_t *streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
 
-  int vlistID = streamptr->vlistID;
+static void cdiInputFile_destruct(CdiInputFile* me);
 
-  FILE *cnp = fopen(cname, "w");
+//For an explanation of the condestruct() pattern, see the comment in iterator_grib.c
+//path != NULL -> construction
+//path = NULL -> destruction
+static CdiInputFile* cdiInputFile_condestruct(CdiInputFile* me, const char* path)
+{
+  #define super() (&me->super)
+  if(!path) goto destruct;
+  cdiRefObject_construct(super());
+  me->path = myStrDup(path);
+  if(!me->path) goto destructSuper;
+  do
+    {
+      me->fileDescriptor = open(me->path, O_RDONLY);
+    }
+  while(me->fileDescriptor == -1 && (errno == EINTR || errno == EAGAIN));
+  if(me->fileDescriptor == -1) goto freePath;
+  //construction successfull, now we can set our own destructor
+  super()->destructor = (void(*)(CdiReferencedObject*))cdiInputFile_destruct;
+  goto success;
 
-  if ( cnp == NULL ) SysError(cname);
+// ^        constructor code       ^
+// |                               |
+// v destructor/error-cleanup code v
 
-  fprintf(cnp, "#CDI library version %s\n", cdiLibraryVersion());
-  fprintf(cnp, "#\n");
+destruct:
+  close(me->fileDescriptor);
+freePath:
+  free(me->path);
+destructSuper:
+  cdiRefObject_destruct(super());
+  me = NULL;
 
-  fprintf(cnp, "filename: %s\n", streamptr->filename);
-  int filetype = streamptr->filetype;
-  fprintf(cnp, "filetype: %s\n", strfiletype(filetype));
+success:
+  return me;
+  #undef super
+}
 
-  fprintf(cnp, "#\n");
-  fprintf(cnp, "#grids:\n");
+static CdiInputFile** openFileList = NULL;
+static size_t openFileCount = 0, openFileListSize = 0;
+static pthread_mutex_t openFileListLock = PTHREAD_MUTEX_INITIALIZER;
 
-  int ngrids = vlistNgrids(vlistID);
-  for ( int i = 0; i < ngrids; i++ )
+//This either returns a new object, or retains and returns a preexisting open file.
+CdiInputFile* cdiInputFile_make(const char* path)
+{
+  CdiInputFile* result = NULL;
+  xassert(path);
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
     {
-      int gridID   = vlistGrid(vlistID, i);
-      int gridtype = gridInqType(gridID);
-      int xsize    = gridInqXsize(gridID);
-      int ysize    = gridInqYsize(gridID);
-      fprintf(cnp, "%4d:%4d:%4d:%4d\n", i+1, gridtype, xsize, ysize);
+      //Check the list of open files for the given path.
+      for(size_t i = openFileCount; i-- && !result; )
+        {
+          if(!strcmp(path, openFileList[i]->path)) result = openFileList[i];
+        }
+      //If no open file was found, we open one, otherwise we just retain the existing one one more time.
+      if(result)
+        {
+          cdiRefObject_retain(&result->super);
+        }
+      else
+        {
+          result = xmalloc(sizeof(*result));
+          if(!cdiInputFile_condestruct(result, path))
+            {
+              //An error occured during construction, avoid a memory leak.
+              free(result);
+              result = NULL;
+            }
+          else
+            {
+              //Add the new file to the list of open files.
+              if(openFileCount == openFileListSize)
+                {
+                  openFileListSize *= 2;
+                  if(openFileListSize < 16) openFileListSize = 16;
+                  openFileList = xrealloc(openFileList, openFileListSize);
+                }
+              xassert(openFileCount < openFileListSize);
+              openFileList[openFileCount++] = result;
+            }
+        }
     }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  return result;
+}
 
-  fprintf(cnp, "#\n");
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer)
+{
+  char* byteBuffer = buffer;
+  size_t trash;
+  if(!outActualReadSize) outActualReadSize = &trash;
+  *outActualReadSize = 0;
+  while(readSize)
+    {
+      ssize_t bytesRead = pread(me->fileDescriptor, byteBuffer, readSize, readPosition);
+      if(bytesRead == -1) return (errno == EINVAL) ?  CDI_EINVAL : CDI_ESYSTEM;
+      if(bytesRead == 0) return CDI_EEOF;
+      byteBuffer += bytesRead;
+      readPosition += bytesRead;
+      readSize -= bytesRead;
+      *outActualReadSize += bytesRead;
+    }
+  return CDI_NOERR;
+}
 
-  fprintf(cnp, "varID:code:gridID:zaxisID:tsteptype:datatype\n");
+char* cdiInputFile_copyPath(const CdiInputFile* me)
+{
+  return myStrDup(me->path);
+}
 
-  int nvars = vlistNvars(vlistID);
-  for ( int varID = 0; varID < nvars; varID++ )
+void cdiInputFile_destruct(CdiInputFile* me)
+{
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
     {
-      int code      = vlistInqVarCode(vlistID, varID);
-      int gridID    = vlistInqVarGrid(vlistID, varID);
-      int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-      int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-      int datatype  = vlistInqVarDatatype(vlistID, varID);
-      fprintf(cnp, "%4d:%4d:%4d:%4d:%4d:%4d:\n",
-	      varID+1, code, gridID, zaxisID, tsteptype, datatype);
+      //Find the position of me in the list of open files.
+      ssize_t position;
+      for(position = openFileCount; position--; ) if(openFileList[position] == me) break;
+      xassert(position != -1);
+      //Remove me from the list
+      openFileList[position] = openFileList[--openFileCount];
     }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  cdiInputFile_condestruct(me, NULL);
+}
+#ifndef INSTITUTION_H
+#define INSTITUTION_H
 
-  fprintf(cnp, "#\n");
-
-  fprintf(cnp, "tsID:nrecs:date:time\n");
+int
+instituteUnpack(void *buf, int size, int *position, int originNamespace,
+                void *context, int force_id);
 
-  int tsID = 0;
-  while (1)
-    {
-      int nrecs      = streamptr->tsteps[tsID].nallrecs;
-      int date       = streamptr->tsteps[tsID].taxis.vdate;
-      int time       = streamptr->tsteps[tsID].taxis.vtime;
-      off_t position = streamptr->tsteps[tsID].position;
+void instituteDefaultEntries(void);
 
-      fprintf(cnp, "%4d:%4d:%4d:%4d:%ld\n",
-	      tsID, nrecs, date, time, (long) position);
+#endif
 
-      if ( streamptr->tsteps[tsID].next )
-	tsID++;
-      else
-	break;
-    }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  fprintf(cnp, "#\n");
+#include <assert.h>
+#include <limits.h>
 
-  fprintf(cnp, "tsID:recID:varID:levID:size:pos\n");
 
-  tsID = 0;
-  while (1)
-    {
-      int nrecs = streamptr->tsteps[tsID].nallrecs;
-      for ( int recID = 0; recID < nrecs; recID++ )
-	{
-	  int varID   = streamptr->tsteps[tsID].records[recID].varID;
-	  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
-	  off_t recpos = streamptr->tsteps[tsID].records[recID].position;
-	  long recsize = (long)streamptr->tsteps[tsID].records[recID].size;
-	  fprintf(cnp, "%4d:%4d:%4d:%4d:%4ld:%ld\n",
-		  tsID, recID, varID, levelID, recsize, (long) recpos);
-	}
+#undef  UNDEFID
+#define UNDEFID  -1
 
-      if ( streamptr->tsteps[tsID].next )
-	tsID++;
-      else
-	break;
-    }
+int ECMWF  = UNDEFID;
+int MPIMET = UNDEFID;
+int DWD    = UNDEFID;
+int MCH    = UNDEFID;
 
-  fclose(cnp);
+typedef struct
+{
+  int    self;
+  int    used;
+  int    center;
+  int    subcenter;
+  char  *name;
+  char  *longname;
 }
+institute_t;
 
-// This function is used in CDO!
-off_t streamNvals(int streamID)
-{
-  stream_t *streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
+static int instituteCompareKernel(institute_t *ip1, institute_t *ip2);
+static void instituteDestroyP(institute_t *instituteptr);
+static void   institutePrintP(institute_t *instituteptr, FILE * fp);
+static int instituteGetPackSize(institute_t *instituteptr, void *context);
+static void   institutePackP    ( void * instituteptr, void *buf, int size, int *position, void *context );
+static int    instituteTxCode   ( void );
 
-  return (streamptr->numvals);
-}
+static const resOps instituteOps = {
+  (int (*)(void *, void *))instituteCompareKernel,
+  (void (*)(void *))instituteDestroyP,
+  (void (*)(void *, FILE *))institutePrintP,
+  (int (*)(void *, void *))instituteGetPackSize,
+  institutePackP,
+  instituteTxCode
+};
 
-/*
- at Function  streamDefVlist
- at Title     Define the variable list
+static
+void instituteDefaultValue ( institute_t * instituteptr )
+{
+  instituteptr->self       = UNDEFID;
+  instituteptr->used       = 0;
+  instituteptr->center     = UNDEFID;
+  instituteptr->subcenter  = UNDEFID;
+  instituteptr->name       = NULL;
+  instituteptr->longname   = NULL;
+}
 
- at Prototype void streamDefVlist(int streamID, int vlistID)
- at Parameter
-    @Item  streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+void instituteDefaultEntries ( void )
+{
+  cdiResH resH[]
+    = { ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts"),
+        MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology"),
+        institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology"),
+        institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology"),
+        institutDef( 78,   0, "DWD",       "Deutscher Wetterdienst"),
+        institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst"),
+        MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss"),
+        institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction"),
+        institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction"),
+        institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research"),
+        institutDef( 74,   0, "METOFFICE", "U.K. Met Office"),
+        institutDef( 97,   0, "ESA",       "European Space Agency"),
+        institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute"),
+  };
+  /*     (void) institutDef(  0,   0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
 
- at Description
-The function @func{streamDefVlist} defines the variable list of a stream.
+  size_t n = sizeof(resH)/sizeof(*resH);
 
- at EndFunction
-*/
-void streamDefVlist(int streamID, int vlistID)
-{
-  void (*myStreamDefVlist)(int streamID, int vlistID)
-    = (void (*)(int, int))namespaceSwitchGet(NSSWITCH_STREAM_DEF_VLIST_).func;
-  myStreamDefVlist(streamID, vlistID);
+  for (size_t i = 0; i < n ; i++ )
+    reshSetStatus(resH[i], &instituteOps, RESH_IN_USE);
 }
 
-/* the single image implementation of streamDefVlist */
-void
-cdiStreamDefVlist_(int streamID, int vlistID)
+
+static int
+instituteCompareKernel(institute_t *  ip1, institute_t * ip2)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  int differ = 0;
+  size_t len1, len2;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( ip1->name )
+    {
+      if ( ip1->center    > 0 && ip2->center    != ip1->center )    differ = 1;
+      if ( ip1->subcenter > 0 && ip2->subcenter != ip1->subcenter ) differ = 1;
 
-  if ( streamptr->vlistID == CDI_UNDEFID )
-    cdiStreamSetupVlist(streamptr, vlistDuplicate(vlistID), vlistID);
+      if ( !differ )
+        {
+          if ( ip2->name )
+            {
+              len1 = strlen(ip1->name);
+              len2 = strlen(ip2->name);
+              if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
+            }
+        }
+    }
+  else if ( ip1->longname )
+    {
+      if ( ip2->longname )
+        {
+          len1 = strlen(ip1->longname);
+          len2 = strlen(ip2->longname);
+          if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
+        }
+    }
   else
-    Warning("vlist already defined for %s!", streamptr->filename);
+    {
+      if ( !( ip2->center    == ip1->center &&
+              ip2->subcenter == ip1->subcenter )) differ = 1;
+    }
+
+  return differ;
 }
 
-/*
- at Function  streamInqVlist
- at Title     Get the variable list
 
- at Prototype int streamInqVlist(int streamID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+struct instLoc
+{
+  institute_t *ip;
+  int id;
+};
 
- at Description
-The function @func{streamInqVlist} returns the variable list of a stream.
+static enum cdiApplyRet
+findInstitute(int id, void *res, void *data)
+{
+  institute_t * ip1 = ((struct instLoc *)data)->ip;
+  institute_t * ip2 = (institute_t*) res;
+  if (ip2->used && !instituteCompareKernel(ip1, ip2))
+    {
+      ((struct instLoc *)data)->id = id;
+      return CDI_APPLY_STOP;
+    }
+  else
+    return CDI_APPLY_GO_ON;
+}
 
- at Result
- at func{streamInqVlist} returns an identifier to the variable list.
 
- at EndFunction
-*/
-int streamInqVlist(int streamID)
+int institutInq(int center, int subcenter, const char *name, const char *longname)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t * ip_ref = (institute_t *)xmalloc(sizeof (*ip_ref));
+  ip_ref->self       = UNDEFID;
+  ip_ref->used       = 0;
+  ip_ref->center     = center;
+  ip_ref->subcenter  = subcenter;
+  ip_ref->name       = name && name[0] ? (char *)name : NULL;
+  ip_ref->longname   = longname && longname[0] ? (char *)longname : NULL;
 
-  stream_check_ptr(__func__, streamptr);
+  struct instLoc state = { .ip = ip_ref, .id = UNDEFID };
+  cdiResHFilterApply(&instituteOps, findInstitute, &state);
 
-  return (streamptr->vlistID);
-}
+  free(ip_ref);
 
+  return state.id;
+}
 
-int streamInqVlistIDorig(int streamID)
+static
+institute_t *instituteNewEntry(cdiResH resH, int center, int subcenter,
+                               const char *name, const char *longname)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t *instituteptr = (institute_t*) xmalloc(sizeof(institute_t));
+  instituteDefaultValue(instituteptr);
+  if (resH == CDI_UNDEFID)
+    instituteptr->self = reshPut(instituteptr, &instituteOps);
+  else
+    {
+      instituteptr->self = resH;
+      reshReplace(resH, instituteptr, &instituteOps);
+    }
+  instituteptr->used = 1;
+  instituteptr->center = center;
+  instituteptr->subcenter = subcenter;
+  if ( name && *name )
+    instituteptr->name = strdupx(name);
+  if (longname && *longname)
+    instituteptr->longname = strdupx(longname);
+  return  instituteptr;
+}
 
-  stream_check_ptr(__func__, streamptr);
 
-  return (streamptr->vlistIDorig);
+int institutDef(int center, int subcenter, const char *name, const char *longname)
+{
+  institute_t * instituteptr
+    = instituteNewEntry(CDI_UNDEFID, center, subcenter, name, longname);
+  return instituteptr->self;
 }
 
 
-void streamDefCompType(int streamID, int comptype)
+int institutInqCenter(int instID)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t * instituteptr = NULL;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( instID != UNDEFID )
+    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  if (streamptr->comptype != comptype)
-    {
-      streamptr->comptype = comptype;
-      reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
-    }
+  return  instituteptr ? instituteptr->center : UNDEFID;
 }
 
 
-void streamDefCompLevel(int streamID, int complevel)
+int institutInqSubcenter(int instID)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t * instituteptr = NULL;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( instID != UNDEFID )
+    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  if (streamptr->complevel != complevel)
-    {
-      streamptr->complevel = complevel;
-      reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
-    }
+  return instituteptr ? instituteptr->subcenter: UNDEFID;
 }
 
 
-int streamInqCompType(int streamID)
+const char *institutInqNamePtr(int instID)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t * instituteptr = NULL;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( instID != UNDEFID )
+    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  return (streamptr->comptype);
+  return instituteptr ? instituteptr->name : NULL;
 }
 
 
-int streamInqCompLevel(int streamID)
+const char *institutInqLongnamePtr(int instID)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
+  institute_t * instituteptr = NULL;
 
-  stream_check_ptr(__func__, streamptr);
+  if ( instID != UNDEFID )
+    instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  return (streamptr->complevel);
+  return instituteptr ? instituteptr->longname : NULL;
 }
 
-int streamInqFileID(int streamID)
+static enum cdiApplyRet
+activeInstitutes(int id, void *res, void *data)
 {
-  stream_t *streamptr;
-
-  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
-
-  return (streamptr->fileID);
+  (void)id;
+  if (res && ((institute_t *)res)->used)
+    ++(*(int *)data);
+  return CDI_APPLY_GO_ON;
 }
 
-void cdiDefAccesstype(int streamID, int type)
+int institutInqNumber(void)
 {
-  stream_t *streamptr = reshGetVal(streamID, &streamOps);
+  int instNum = 0;
 
-  if ( streamptr->accesstype == CDI_UNDEFID )
-    {
-      streamptr->accesstype = type;
-    }
-  else if ( streamptr->accesstype != type )
-    Error("Changing access type from %s not allowed!",
-          streamptr->accesstype == TYPE_REC ? "REC to VAR" : "VAR to REC");
+  cdiResHFilterApply(&instituteOps, activeInstitutes, &instNum);
+  return instNum;
 }
 
 
-int cdiInqAccesstype(int streamID)
+static void
+instituteDestroyP(institute_t *instituteptr)
 {
-  stream_t *streamptr;
-
-  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
+  xassert(instituteptr);
 
-  return (streamptr->accesstype);
+  int instituteID = instituteptr->self;
+  free(instituteptr->name);
+  free(instituteptr->longname);
+  reshRemove(instituteID, &instituteOps);
+  free(instituteptr);
 }
 
-static
-int streamTxCode(void)
+
+static void institutePrintP(institute_t *ip, FILE * fp )
 {
-  return STREAM;
+  if (ip)
+    fprintf(fp, "#\n"
+            "# instituteID %d\n"
+            "#\n"
+            "self          = %d\n"
+            "used          = %d\n"
+            "center        = %d\n"
+            "subcenter     = %d\n"
+            "name          = %s\n"
+            "longname      = %s\n",
+            ip->self, ip->self, ip->used, ip->center, ip->subcenter,
+            ip->name ? ip->name : "NN",
+            ip->longname ? ip->longname : "NN");
 }
 
 
-void cdiStreamSetupVlist(stream_t *streamptr, int vlistID, int vlistIDorig)
+static int
+instituteTxCode ( void )
 {
-  vlist_lock(vlistID);
-  int nvars = vlistNvars(vlistID);
-  streamptr->vlistID = vlistID;
-  streamptr->vlistIDorig = vlistIDorig;
-  for (int varID = 0; varID < nvars; varID++ )
-    {
-      int gridID  = vlistInqVarGrid(vlistID, varID);
-      int zaxisID = vlistInqVarZaxis(vlistID, varID);
-      stream_new_var(streamptr, gridID, zaxisID);
-      if ( streamptr->have_missval )
-        vlistDefVarMissval(vlistID, varID,
-                           vlistInqVarMissval(vlistID, varID));
-    }
-
-  if (streamptr->filemode == 'w' )
-    switch (streamptr->filetype)
-      {
-#ifdef HAVE_LIBNETCDF
-      case FILETYPE_NC:
-      case FILETYPE_NC2:
-      case FILETYPE_NC4:
-      case FILETYPE_NC4C:
-        {
-          void (*myCdfDefVars)(stream_t *streamptr)
-            = (void (*)(stream_t *))
-            namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
-          myCdfDefVars(streamptr);
-        }
-        break;
-#endif
-      case FILETYPE_GRB:
-      case FILETYPE_GRB2:
-        gribContainersNew(streamptr);
-        break;
-      }
+  return INSTITUTE;
 }
 
+enum {
+  institute_nints = 5,
+};
 
-void streamGetIndexList ( int nstreams, int * streamIndexList )
+static int instituteGetPackSize(institute_t *ip, void *context)
 {
-  reshGetResHListOfType ( nstreams, streamIndexList, &streamOps );
+  size_t namelen = strlen(ip->name), longnamelen = strlen(ip->longname);
+  xassert(namelen < INT_MAX && longnamelen < INT_MAX);
+  size_t txsize = (size_t)serializeGetSize(institute_nints, DATATYPE_INT, context)
+    + (size_t)serializeGetSize((int)namelen + 1, DATATYPE_TXT, context)
+    + (size_t)serializeGetSize((int)longnamelen + 1, DATATYPE_TXT, context);
+  xassert(txsize <= INT_MAX);
+  return (int)txsize;
 }
 
-int streamInqNvars ( int streamID )
+static void institutePackP(void * instituteptr, void *buf, int size, int *position, void *context)
 {
-  stream_t *streamptr = reshGetVal(streamID, &streamOps);
-  return streamptr->nvars;
+  institute_t *p = (institute_t*) instituteptr;
+  int tempbuf[institute_nints];
+  tempbuf[0] = p->self;
+  tempbuf[1] = p->center;
+  tempbuf[2] = p->subcenter;
+  tempbuf[3] = (int)strlen(p->name) + 1;
+  tempbuf[4] = (int)strlen(p->longname) + 1;
+  serializePack(tempbuf, institute_nints, DATATYPE_INT, buf, size, position, context);
+  serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
+  serializePack(p->longname, tempbuf[4], DATATYPE_TXT, buf, size, position, context);
 }
 
-
-static int streamCompareP(void * streamptr1, void * streamptr2)
+int instituteUnpack(void *buf, int size, int *position, int originNamespace,
+                    void *context, int force_id)
 {
-  stream_t * s1 = ( stream_t * ) streamptr1;
-  stream_t * s2 = ( stream_t * ) streamptr2;
-  enum {
-    differ = -1,
-    equal  = 0,
-  };
+  int tempbuf[institute_nints];
+  int instituteID;
+  char *name, *longname;
+  serializeUnpack(buf, size, position, tempbuf, institute_nints, DATATYPE_INT, context);
+  name = (char *)xmalloc((size_t)tempbuf[3] + (size_t)tempbuf[4]);
+  longname = name + tempbuf[3];
+  serializeUnpack(buf, size, position, name, tempbuf[3], DATATYPE_TXT, context);
+  serializeUnpack(buf, size, position, longname, tempbuf[4], DATATYPE_TXT, context);
+  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
+  institute_t *ip = instituteNewEntry(force_id?targetID:CDI_UNDEFID,
+                                      tempbuf[1], tempbuf[2], name, longname);
+  instituteID = ip->self;
+  xassert(!force_id || instituteID == targetID);
+  free(name);
+  return instituteID;
+}
 
-  xassert ( s1 );
-  xassert ( s2 );
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+/*
+ * This file is for the use of iterator.c and the CdiIterator subclasses only.
+ */
 
-  if ( s1->filetype  != s2->filetype  ) return differ;
-  if (  namespaceAdaptKey2 ( s1->vlistIDorig ) !=
-	namespaceAdaptKey2 ( s2->vlistIDorig )) return differ;
-  if ( s1->byteorder != s2->byteorder ) return differ;
-  if ( s1->comptype  != s2->comptype  ) return differ;
-  if ( s1->complevel != s2->complevel ) return differ;
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_INT_H
+#define INCLUDE_GUARD_CDI_ITERATOR_INT_H
 
-  if ( s1->filename )
-    {
-      if (strcmp(s1->filename, s2->filename))
-	return differ;
-    }
-  else if ( s2->filename )
-    return differ;
 
-  return equal;
-}
+#include <stdbool.h>
 
+/*
+class CdiIterator
 
-void streamDestroyP ( void * streamptr )
-{
-  stream_t * sp = ( stream_t * ) streamptr;
+An iterator is an object that identifies the position of one record in a file, where a record is defined as the data belonging to one level, timestep, and variable.
+Using iterators to read a file can be significantly faster than using streams, because they can avoid building an index of the file.
+For file formats like grib that do not provide an index within the file, this makes the difference between reading the file once or reading the file twice.
 
-  xassert ( sp );
+CdiIterator is an abstract base class. Which derived class is used depends on the type of the file. The class hierarchy currently looks like this:
 
-  int id = sp->self;
-  streamClose ( id );
-}
+    CdiIterator <|--+-- CdiFallbackIterator
+                    |
+                    +-- CdiGribIterator
 
+The fallback implementation currently uses the stream interface of CDI under the hood to provide full functionality for all filetypes for which no iterator implementation exists yet.
+*/
+//TODO[NH]: Debug messages, print function.
 
-void streamPrintP   ( void * streamptr, FILE * fp )
-{
-  stream_t * sp = ( stream_t * ) streamptr;
+struct CdiIterator {
+  int filetype;      //This is used to dispatch calls to the correct subclass.
+  bool isAdvanced;    //Used to catch inquiries before the first call to CdiIteratorNextField(). //XXX: Advanced is probably not a good word (initialized?)
 
-  if ( !sp ) return;
+  //The metadata that can be accessed by the inquiry calls.
+  //While theoretically redundant, these fields allow the handling of most inquiry calls within the base class.
+  //Only the name is excempted because it needs an allocation.
+  //These fields are set by the subclasses in the xxxIterNextField() method.
+  int datatype, timesteptype;
+  int gridId;
+  CdiParam param;
 
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "# streamID %d\n", sp->self);
-  fprintf ( fp, "#\n");
-  fprintf ( fp, "self          = %d\n", sp->self );
-  fprintf ( fp, "accesstype    = %d\n", sp->accesstype );
-  fprintf ( fp, "accessmode    = %d\n", sp->accessmode );
-  fprintf ( fp, "filetype      = %d\n", sp->filetype );
-  fprintf ( fp, "byteorder     = %d\n", sp->byteorder );
-  fprintf ( fp, "fileID        = %d\n", sp->fileID );
-  fprintf ( fp, "filemode      = %d\n", sp->filemode );
-  fprintf ( fp, "//off_t numvals;\n" );
-  fprintf ( fp, "filename      = %s\n", sp->filename );
-  fprintf ( fp, "//Record   *record;\n" );
-  fprintf ( fp, "nrecs         = %d\n", sp->nrecs );
-  fprintf ( fp, "nvars         = %d\n", sp->nvars );
-  fprintf ( fp, "//svarinfo_t *vars;\n" );
-  fprintf ( fp, "varsAllocated = %d\n", sp->varsAllocated );
-  fprintf ( fp, "curTsID       = %d\n", sp->curTsID );
-  fprintf ( fp, "rtsteps       = %d\n", sp->rtsteps );
-  fprintf ( fp, "//long ntsteps;\n" );
-  fprintf ( fp, "//  tsteps_t   *tsteps;\n" );
-  fprintf ( fp, "tstepsTableSize= %d\n", sp->tstepsTableSize );
-  fprintf ( fp, "tstepsNextID  = %d\n", sp->tstepsNextID );
-  fprintf ( fp, "//basetime_t  basetime;\n" );
-  fprintf ( fp, "ncmode        = %d\n", sp->ncmode );
-  fprintf ( fp, "vlistID       = %d\n", sp->vlistID );
-  fprintf ( fp, "//  int       xdimID[MAX_GRIDS_PS];\n" );
-  fprintf ( fp, "//  int       ydimID[MAX_GRIDS_PS];\n" );
-  fprintf ( fp, "//  int       zaxisID[MAX_ZAXES_PS];\n" );
-  fprintf ( fp, "//  int       ncxvarID[MAX_GRIDS_PS];\n" );
-  fprintf ( fp, "//  int       ncyvarID[MAX_GRIDS_PS];\n" );
-  fprintf ( fp, "//  int       ncavarID[MAX_GRIDS_PS];\n" );
-  fprintf ( fp, "historyID     = %d\n", sp->historyID );
-  fprintf ( fp, "globalatts    = %d\n", sp->globalatts );
-  fprintf ( fp, "localatts     = %d\n", sp->localatts );
-  fprintf ( fp, "//  VCT       vct;\n" );
-  fprintf ( fp, "unreduced     = %d\n", sp->unreduced );
-  fprintf ( fp, "sortname      = %d\n", sp->sortname );
-  fprintf ( fp, "have_missval  = %d\n", sp->have_missval );
-  fprintf ( fp, "ztype         = %d\n", sp->comptype );
-  fprintf ( fp, "zlevel        = %d\n", sp->complevel );
-  fprintf ( fp, "//  void    **gribContainers;\n" );
-  fprintf ( fp, "vlistIDorig   = %d\n", sp->vlistIDorig );
-}
+  //The status information for reading/advancing is added in the subclasses.
+};
 
+void baseIterConstruct(CdiIterator* me, int filetype);
+const char* baseIter_constructFromString(CdiIterator* me, const char* description);     //Returns a pointer past the end of the parsed portion of the description string.
+void baseIterDestruct(CdiIterator* me);
 
-enum {
-  streamNint = 11,
-};
+#endif
+/*
+ * A fallback implementation of the iterator interface that opens a stream under the hood.
+ *
+ * This implementation is mainly available to provide iterator access to file formats that don't support iterator access natively,
+ * nevertheless, it allows the file to dictate the order in which data is read, possibly providing performance benefits.
+ */
 
-static int
-streamGetPackSize(void * voidP, void *context)
-{
-  stream_t * streamP = ( stream_t * ) voidP;
-  int packBufferSize
-    = serializeGetSize(streamNint, DATATYPE_INT, context)
-    + serializeGetSize(2, DATATYPE_UINT32, context)
-    + serializeGetSize((int)strlen(streamP->filename) + 1,
-                       DATATYPE_TXT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
-  return packBufferSize;
-}
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+#define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
 
 
-static void
-streamPack(void * streamptr, void * packBuffer, int packBufferSize,
-           int * packBufferPos, void *context)
-{
-  stream_t * streamP = ( stream_t * ) streamptr;
-  int intBuffer[streamNint];
+typedef struct CdiFallbackIterator {
+  CdiIterator super;
+  int streamId, vlistId;
+  char* path;   //needed for clone() & serialize()
 
-  intBuffer[0]  = streamP->self;
-  intBuffer[1]  = streamP->filetype;
-  intBuffer[2]  = (int)strlen(streamP->filename) + 1;
-  intBuffer[3]  = streamP->vlistID;
-  intBuffer[4]  = streamP->vlistIDorig;
-  intBuffer[5]  = streamP->byteorder;
-  intBuffer[6]  = streamP->comptype;
-  intBuffer[7]  = streamP->complevel;
-  intBuffer[8]  = streamP->unreduced;
-  intBuffer[9]  = streamP->sortname;
-  intBuffer[10] = streamP->have_missval;
+  int variableCount, curVariable;
+  int curLevelCount, curLevel;
+  int curTimestep;
+} CdiFallbackIterator;
 
-  serializePack(intBuffer, streamNint, DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
-  uint32_t d = cdiCheckSum(DATATYPE_INT, streamNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype);
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* me);
+char* cdiFallbackIterator_serialize(CdiIterator* me);
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* me);
 
-  serializePack(&cdiDefaultMissval, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
-  serializePack(streamP->filename, intBuffer[2], DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(DATATYPE_TXT, intBuffer[2], streamP->filename);
-  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
-}
+int cdiFallbackIterator_nextField(CdiIterator* me);
 
-struct streamAssoc
-streamUnpack(char * unpackBuffer, int unpackBufferSize,
-             int * unpackBufferPos, int originNamespace, void *context)
-{
-  int intBuffer[streamNint], streamID;
-  uint32_t d;
-  char filename[CDI_MAX_NAME];
+char* cdiFallbackIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiFallbackIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiFallbackIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiFallbackIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiFallbackIterator_copyVariableName(CdiIterator* me);
 
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, streamNint, DATATYPE_INT, context);
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_UINT32, context);
-  xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
+void cdiFallbackIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiFallbackIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
 
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &filename, intBuffer[2], DATATYPE_TXT, context);
-  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_UINT32, context);
-  xassert(d == cdiCheckSum(DATATYPE_TXT, intBuffer[2], filename));
-  int targetStreamID = namespaceAdaptKey(intBuffer[0], originNamespace);
-  streamID = streamOpenID(filename, "w", intBuffer[1], targetStreamID);
-  xassert(streamID >= 0 && targetStreamID == streamID);
-  streamDefByteorder(streamID, intBuffer[5]);
-  streamDefCompType(streamID, intBuffer[6]);
-  streamDefCompLevel(streamID, intBuffer[7]);
-  stream_t *streamptr = stream_to_pointer(streamID);
-  streamptr->unreduced = intBuffer[8];
-  streamptr->sortname = intBuffer[9];
-  streamptr->have_missval = intBuffer[10];
-  struct streamAssoc retval = { streamID, intBuffer[3], intBuffer[4] };
-  return retval;
-}
+void cdiFallbackIterator_delete(CdiIterator* super);
+
+#endif
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
+ * An implementation of the iterator interface for GRIB files.
+ * Since GRIB files do not contain an index, this avoids scanning the entire file to generate an in-memory index as streamOpenRead() does.
+ * Consequently, using this interface is much more efficient for GRIB files.
  */
-#if defined (HAVE_CONFIG_H)
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+#define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+
+
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
 #endif
 
+typedef struct recordList recordList;
+struct CdiGribIterator {
+  CdiIterator super;
 
+  CdiInputFile* file;
+  off_t fileOffset;
+  unsigned char* gribBuffer;
+  size_t bufferSize, curRecordSize;
+#ifdef HAVE_LIBGRIB_API
+  grib_handle* gribHandle;
+#else
+  void* gribHandle;
+#endif
+};
 
-void streamDefHistory(int streamID, int length, const char *history)
-{
-#ifdef HAVE_LIBNETCDF
-  stream_t *streamptr = stream_to_pointer(streamID);
+CdiIterator* cdiGribIterator_new(const char* path, int filetype);
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* me);
+char* cdiGribIterator_serialize(CdiIterator* me);
+CdiGribIterator* cdiGribIterator_deserialize(const char* me);
 
-  if ( streamptr->filetype == FILETYPE_NC  ||
-       streamptr->filetype == FILETYPE_NC2 ||
-       streamptr->filetype == FILETYPE_NC4 ||
-       streamptr->filetype == FILETYPE_NC4C )
+int cdiGribIterator_nextField(CdiIterator* me);
+
+char* cdiGribIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiGribIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiGribIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiGribIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiGribIterator_copyVariableName(CdiIterator* me);
+
+void cdiGribIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiGribIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
+
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+
+const char* const kUnexpectedFileTypeMessage = "Internal error: Unexpected file type encountered in iterator.\nThis is either due to an illegal memory access by the application or an internal logical error in CDI (unlikely, but possible).";
+const char* const kAdvancedString = "advanced";
+const char* const kUnadvancedString = "unadvanced";
+
+//Returns a static string.
+static const char* fileType2String(int fileType)
+{
+  switch(fileType)
     {
-      char *histstring;
-      size_t len;
-      if ( history )
-	{
-	  len = strlen(history);
-	  if ( len )
-	    {
-              /* FIXME: what's the point of strdupx? Why not use
-               * history argument directly? */
-	      histstring = strdupx(history);
-	      cdfDefHistory(streamptr, length, histstring);
-	      free(histstring);
-	    }
-	}
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB: return "CDI::Iterator::GRIB1";
+        case FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
+      #endif
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC: return "CDI::Iterator::NetCDF";
+        case FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
+        case FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
+        case FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV: return "CDI::Iterator::SRV";
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT: return "CDI::Iterator::EXT";
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG: return "CDI::Iterator::IEG";
+      #endif
+
+      default: return NULL;
     }
-#else
-  (void)streamID; (void)length; (void)history;
-#endif
 }
 
-
-int streamInqHistorySize(int streamID)
+static int string2FileType(const char* fileType, const char** outRestString)
 {
-  int size = 0;
-#ifdef HAVE_LIBNETCDF
-  stream_t *streamptr = stream_to_pointer(streamID);
+  //This first part unconditionally checks all known type strings, and only if the given string matches one of these strings, we use fileType2string() to check whether support for this type has been compiled in. This is to avoid throwing "invalid type string" errors when we just have a library version mismatch.
+  #define check(givenString, typeString, typeConstant) do \
+    { \
+      if(givenString == strstr(givenString, typeString)) \
+        { \
+          if(outRestString) *outRestString = givenString + strlen(typeString); \
+          if(fileType2String(typeConstant)) return typeConstant; \
+          Error("Support for " typeString " not compiled in. Please check that the result of `cdiIterator_serialize()` is only passed to a `cdiIterator_deserialize()` implementation of the same CDI library version."); \
+          return FILETYPE_UNDEF; \
+        } \
+    } while(0)
+  check(fileType, "CDI::Iterator::GRIB1", FILETYPE_GRB);
+  check(fileType, "CDI::Iterator::GRIB2", FILETYPE_GRB2);
+  check(fileType, "CDI::Iterator::NetCDF", FILETYPE_NC);
+  check(fileType, "CDI::Iterator::NetCDF2", FILETYPE_NC2);
+  check(fileType, "CDI::Iterator::NetCDF4", FILETYPE_NC4);
+  check(fileType, "CDI::Iterator::NetCDF4C", FILETYPE_NC4C);
+  check(fileType, "CDI::Iterator::SRV", FILETYPE_SRV);
+  check(fileType, "CDI::Iterator::EXT", FILETYPE_EXT);
+  check(fileType, "CDI::Iterator::IEG", FILETYPE_IEG);
+  #undef check
+
+  //If this point is reached, the given string does not seem to be produced by a cdiIterator_serialize() call.
+  Error("The string \"%s\" does not start with a valid iterator type. Please check the source of this string.", fileType);
+  *outRestString = fileType;
+  return FILETYPE_UNDEF;
+}
 
-  if ( streamptr->filetype == FILETYPE_NC  ||
-       streamptr->filetype == FILETYPE_NC2 ||
-       streamptr->filetype == FILETYPE_NC4 ||
-       streamptr->filetype == FILETYPE_NC4C )
+/**
+ at Function cdiIterator_new
+ at Title Create an iterator for an input file
+
+ at Prototype CdiIterator* cdiIterator_new(const char* path)
+ at Parameter
+    @item path Path to the file that is to be read.
+
+ at Result An iterator for the given file.
+
+ at Description
+    Combined allocator and constructor for CdiIterator.
+
+    The returned iterator does not point to the first field yet,
+    it must first be advanced once before the first field can be introspected.
+    This design decision has two benefits: 1. Empty files require no special
+    cases, 2. Users can start a while(!cdiIterator_nextField(iterator)) loop
+    right after the call to cdiIterator_new().
+*/
+CdiIterator* cdiIterator_new(const char* path)
+{
+  int trash;
+  int filetype = cdiGetFiletype(path, &trash);
+  switch(filetype)
     {
-      size = cdfInqHistorySize(streamptr);
+      case FILETYPE_UNDEF:
+        Warning("Can't open file \"%s\": unknown format\n", path);
+        return NULL;
+
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_new(path, filetype);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_new(path, filetype);
+
+      default:
+        Warning("the file \"%s\" is of type %s, but support for this format is not compiled in!", path, strfiletype(filetype));
+        return NULL;
     }
-#else
-  (void)streamID;
-#endif
-  return (size);
 }
 
-
-void streamInqHistoryString(int streamID, char *history)
+void baseIterConstruct(CdiIterator* me, int filetype)
 {
-#ifdef HAVE_LIBNETCDF
-  stream_t *streamptr = stream_to_pointer(streamID);
+  me->filetype = filetype;
+  me->isAdvanced = false;
+}
 
-  if ( streamptr->filetype == FILETYPE_NC  ||
-       streamptr->filetype == FILETYPE_NC2 ||
-       streamptr->filetype == FILETYPE_NC4 ||
-       streamptr->filetype == FILETYPE_NC4C )
+const char* baseIter_constructFromString(CdiIterator* me, const char* description)
+{
+  const char* result = description;
+  me->filetype = string2FileType(result, &result);
+  assert(me->filetype != FILETYPE_UNDEF && "Please report this error.");        //This condition should have been checked for in a calling function.
+  for(; *result && isspace(*result); result++);
+  if(result == strstr(result, kAdvancedString))
     {
-      cdfInqHistoryString(streamptr, history);
+      me->isAdvanced = true;
+      result += strlen(kAdvancedString);
     }
-#else
-  (void)streamID; (void)history;
-#endif
+  else if(result == strstr(result, kUnadvancedString))
+    {
+      me->isAdvanced = false;
+      result += strlen(kUnadvancedString);
+    }
+  else
+    {
+      Error("Invalid iterator description string \"%s\". Please check the origin of this string.", description);
+      return NULL;
+    }
+  return result;
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
 
-#include <stdio.h>
-// #include <float.h>  /* FLT_EPSILON */
+#define sanityCheck(me) do { \
+    if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+    if(!me->isAdvanced) xabort("Calling %s is not allowed without calling cdiIterator_nextField() first.", __func__); \
+} while(0)
 
+/**
+ at Function cdiIterator_clone
+ at Title Make a copy of an iterator
 
-#if  defined  (HAVE_LIBCGRIBEX)
-#endif
+ at Prototype CdiIterator* cdiIterator_clone(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to copy.
 
-extern int cdiInventoryMode;
+ at Result The clone.
 
-typedef struct {
-  int param;
-  int level1;
-  int level2;
-  int ltype;
-  int tsteptype;
-} compvar_t;
+ at Description
+    Clones the given iterator. Make sure to call cdiIterator_delete() on both
+    the copy and the original.
+
+    This is not a cheap operation: Depending on the type of the file, it will
+    either make a copy of the current field in memory (GRIB files), or reopen
+    the file (all other file types). Use it sparingly. And if you do, try to
+    avoid keeping too many clones around: their memory footprint is
+    significant.
+*/
+CdiIterator* cdiIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_clone(me)->super;
+      #endif
 
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_clone(me)->super;
 
-#if  defined  (HAVE_LIBCGRIBEX)
-static
-int cgribexGetGridType(int *isec2)
-{
-  int gridtype = GRID_GENERIC;
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
 
-  switch (ISEC2_GridType)
+/**
+ at Function cdiGribIterator_clone
+ at Title Gain access to GRIB specific functionality
+
+ at Prototype CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A clone that allows access to GRIB specific functionality, or NULL if the underlying file is not a GRIB file.
+
+ at Description
+    Clones the given iterator iff the underlying file is a GRIB file, the returned iterator allows access to GRIB specific functionality.
+    Make sure to check that the return value is not NULL, and to call cdiGribIterator_delete() on the copy.
+
+    This is not a cheap operation: It will make a copy of the current field in memory. Use it sparingly. And if you do, try to avoid keeping too many clones around, their memory footprint is significant.
+*/
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
     {
-    case  GRIB1_GTYPE_LATLON:     { if ( ISEC2_Reduced )      break; }
-    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT;   break; }
-    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;      break; }
-    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
-	                              gridtype = GRID_GAUSSIAN_REDUCED;
-                         	    else
-				      gridtype = GRID_GAUSSIAN;
-          	                    break;
-                                  }
-    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL; break; }
-    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;      break; }
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_makeClone(me);
+      #endif
+
+      default:
+        return NULL;
     }
+}
+
+/**
+ at Function cdiIterator_serialize
+ at Title Serialize an iterator for sending it to another process
 
-  return (gridtype);
-}
+ at Prototype char* cdiIterator_serialize(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-static
-int cgribexGetIsRotated(int *isec2)
-{
-  int isRotated = 0;
+ at Result A malloc'ed string that contains the full description of the iterator.
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+ at Description
+    Make sure to call free() on the resulting string.
+*/
+char* cdiIterator_serialize(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+  char* subclassDescription = NULL;
+  switch(me->filetype)
     {
-      isRotated = 1;
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          subclassDescription = cdiGribIterator_serialize(me);
+          break;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          subclassDescription = cdiFallbackIterator_serialize(me);
+          break;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
     }
 
-  return (isRotated);
+  char* result = myAsprintf("%s %s %s", fileType2String(me->filetype), (me->isAdvanced ? kAdvancedString : kUnadvancedString), subclassDescription);
+  free(subclassDescription);
+  return result;
 }
 
-static
-int cgribexGetZaxisHasBounds(int grb_ltype)
-{
-  int lbounds = 0;
+/**
+ at Function cdiIterator_deserialize
+ at Title Recreate an iterator from its textual description
 
-  switch (grb_ltype)
-    {
-    case GRIB1_LTYPE_SIGMA_LAYER:
-    case GRIB1_LTYPE_HYBRID_LAYER:
-    case GRIB1_LTYPE_LANDDEPTH_LAYER:
-      {
-	lbounds = 1;
-	break;
-      }
-    }
+ at Prototype CdiIterator* cdiIterator_deserialize(const char* description)
+ at Parameter
+    @item description The result of a call to cdiIterator_serialize().
 
-  return (lbounds);
-}
+ at Result A clone of the original iterator.
 
-static
-int cgribexGetTimeUnit(int *isec1)
-{
-  int timeunit = TUNIT_HOUR;
-  static int lprint = TRUE;
+ at Description
+    A pair of cdiIterator_serialize() and cdiIterator_deserialize() is functionally equivalent to a call to cdiIterator_clone()
 
-  switch ( ISEC1_TimeUnit )
+    This function will reread the current field from disk, so don't expect immediate return.
+*/
+//This only checks the type of the iterator and calls the corresponding subclass function,
+//the real deserialization is done in baseIter_constructFromString().
+CdiIterator* cdiIterator_deserialize(const char* description)
+{
+  switch(string2FileType(description, NULL))
     {
-    case ISEC1_TABLE4_MINUTE:    timeunit = TUNIT_MINUTE;    break;
-    case ISEC1_TABLE4_QUARTER:   timeunit = TUNIT_QUARTER;   break;
-    case ISEC1_TABLE4_30MINUTES: timeunit = TUNIT_30MINUTES; break;
-    case ISEC1_TABLE4_HOUR:      timeunit = TUNIT_HOUR;      break;
-    case ISEC1_TABLE4_3HOURS:    timeunit = TUNIT_3HOURS;    break;
-    case ISEC1_TABLE4_6HOURS:    timeunit = TUNIT_6HOURS;    break;
-    case ISEC1_TABLE4_12HOURS:   timeunit = TUNIT_12HOURS;   break;
-    case ISEC1_TABLE4_DAY:       timeunit = TUNIT_DAY;       break;
-    default:
-      if ( lprint )
-	{
-	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
-	  lprint = FALSE;
-	}
-      break;
-    }
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_deserialize(description)->super;
+      #endif
 
-  return (timeunit);
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_deserialize(description)->super;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
 }
 
-static
-int cgribexTimeIsFC(int *isec1)
-{
-  int isFC = TRUE;
 
-  if ( ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0 )
-    isFC = FALSE;
+/**
+ at Function cdiIterator_print
+ at Title Print a textual description of the iterator to a stream
 
-  return (isFC);
-}
+ at Prototype void cdiIterator_print(CdiIterator* iterator, FILE* stream);
+ at Parameter
+    @item iterator The iterator to print.
+    @item stream The stream to print to.
 
-static
-int cgribexGetTsteptype(int timerange)
+ at Description
+    Use for debugging output.
+*/
+void cdiIterator_print(CdiIterator* me, FILE* stream)
 {
-  int tsteptype = TSTEP_INSTANT;
-  static int lprint = TRUE;
+  char* description = cdiIterator_serialize(me);
+  fprintf(stream, "%s\n", description);
+  free(description);
+}
 
-  switch ( timerange )
-    {
-    case  0:  tsteptype = TSTEP_INSTANT;  break;
-    case  1:  tsteptype = TSTEP_INSTANT2; break;
-    case  2:  tsteptype = TSTEP_RANGE;    break;
-    case  3:  tsteptype = TSTEP_AVG;      break;
-    case  4:  tsteptype = TSTEP_ACCUM;    break;
-    case  5:  tsteptype = TSTEP_DIFF;     break;
-    case 10:  tsteptype = TSTEP_INSTANT3; break;
-    default:
-      if ( lprint )
-	{
-	  Message("Time range indicator %d unsupported, set to 0!", timerange);
-	  lprint = FALSE;
-	}
-      break;
-    }
 
-  return (tsteptype);
-}
+/**
+ at Function cdiIterator_nextField
+ at Title Advance an iterator to the next field in the file
 
-static
-void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
-{
-  int compyinc = TRUE;
-  int gridtype = cgribexGetGridType(isec2);
+ at Prototype int cdiIterator_nextField(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
+ at Result An error code. May be one of:
+  * CDI_NOERR: The iterator has successfully been advanced to the next field.
+  * CDI_EEOF: No more fields to read in this file.
+
+ at Description
+    One call to cdiIterator_nextField() is required before the metadata of the first field can be examined.
+    Usually, it will be used directly as the condition for a while() loop.
+*/
+int cdiIterator_nextField(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  me->isAdvanced = true;
+  switch(me->filetype)
     {
-      int ilat, nlon = 0;
-      for ( ilat = 0; ilat < ISEC2_NumLat; ++ilat )
-        if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
-      gridtype = GRID_GAUSSIAN;
-      ISEC2_NumLon = nlon;
-      ISEC4_NumValues = nlon*ISEC2_NumLat;
-      compyinc = FALSE;
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_nextField(me);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_nextField(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
     }
+}
 
-  memset(grid, 0, sizeof(grid_t));
-  switch (gridtype)
+static char* cdiIterator_inqTime(CdiIterator* me, bool getEndTime)
+{
+  sanityCheck(me);
+  switch(me->filetype)
     {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-      {
-	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
-	grid->size  = ISEC4_NumValues;
-	grid->xsize = ISEC2_NumLon;
-	grid->ysize = ISEC2_NumLat;
-        if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
-	grid->xinc  = 0;
-	grid->yinc  = 0;
-	grid->xdef  = 0;
-	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-                int recompinc = TRUE;
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_inqTime(me, getEndTime);
+      #endif
 
-                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_inqTime(me, getEndTime);
 
-		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
-                  {
-                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
-                      {
-                        recompinc = FALSE;
-                        grid->xinc = ISEC2_LonIncr * 0.001;
-                      }
-                  }
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
 
-		/* recompute xinc if necessary */
-                if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize-1);
+/**
+ at Function cdiIterator_inqStartTime
+ at Title Get the start time of a measurement
 
-		/* correct xinc if necessary */
-		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
-		  {
-		    double xinc = 360. / grid->xsize;
+ at Prototype char* cdiIterator_inqStartTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-		    if ( fabs(grid->xinc-xinc) > 0.0 )
-		      {
-			grid->xinc = xinc;
-			if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-		      }
-		  }
-	      }
-	    grid->xfirst = ISEC2_FirstLon * 0.001;
-	    grid->xlast  = ISEC2_LastLon  * 0.001;
-	    grid->xdef   = 2;
-	  }
-	grid->ydef  = 0;
-	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
-	  {
-	    if ( grid->ysize > 1 && compyinc )
-	      {
-                int recompinc = TRUE;
-		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
-                  {
-                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
-                      {
-                        recompinc = FALSE;
-                        grid->yinc = ISEC2_LatIncr * 0.001;
-                      }
-                  }
+ at Result A malloc'ed string containing the (start) time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
 
-		/* recompute yinc if necessary */
-                if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
-	      }
-	    grid->yfirst = ISEC2_FirstLat * 0.001;
-	    grid->ylast  = ISEC2_LastLat  * 0.001;
-	    grid->ydef   = 2;
-	  }
-	break;
-      }
-    case GRID_GAUSSIAN_REDUCED:
-      {
-        grid->np     = ISEC2_NumPar;
-	grid->size   = ISEC4_NumValues;
-        grid->rowlon = ISEC2_RowLonPtr;
-	grid->ysize  = ISEC2_NumLat;
-	grid->xinc   = 0;
-	grid->yinc   = 0;
-	grid->xdef   = 0;
-	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+ at Description
+The returned time is either the time of the data (fields defined at a time point),
+or the start time of an integration time range (statistical fields).
 
-		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
-		  grid->xinc = ISEC2_LonIncr * 0.001;
-		else
-		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
-	      }
-	    grid->xfirst = ISEC2_FirstLon * 0.001;
-	    grid->xlast  = ISEC2_LastLon  * 0.001;
-	    grid->xdef   = 2;
-	  }
-	grid->ydef  = 0;
-	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
-		  grid->yinc = ISEC2_LatIncr * 0.001;
-		else
-		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
-	      }
-	    grid->yfirst = ISEC2_FirstLat * 0.001;
-	    grid->ylast  = ISEC2_LastLat  * 0.001;
-	    grid->ydef   = 2;
-	  }
-	break;
-      }
-    case GRID_LCC:
-      {
-	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
-		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
 
-	grid->size  = ISEC4_NumValues;
-	grid->xsize = ISEC2_NumLon;
-	grid->ysize = ISEC2_NumLat;
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqStartTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, false);
+}
 
-	grid->lcc_xinc      = ISEC2_Lambert_dx;
-	grid->lcc_yinc      = ISEC2_Lambert_dy;
-	grid->lcc_originLon = ISEC2_FirstLon * 0.001;
-	grid->lcc_originLat = ISEC2_FirstLat * 0.001;
-	grid->lcc_lonParY   = ISEC2_Lambert_Lov * 0.001;
-	grid->lcc_lat1      = ISEC2_Lambert_LatS1 * 0.001;
-	grid->lcc_lat2      = ISEC2_Lambert_LatS2 * 0.001;
-	grid->lcc_projflag  = ISEC2_Lambert_ProjFlag;
-	grid->lcc_scanflag  = ISEC2_ScanFlag;
+/**
+ at Function cdiIterator_inqEndTime
+ at Title Get the end time of a measurement
 
-	grid->xdef   = 0;
-	grid->ydef   = 0;
+ at Prototype char* cdiIterator_inqEndTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	grid->size  = ISEC4_NumValues;
-	grid->trunc = ISEC2_PentaJ;
-	if ( ISEC2_RepMode == 2 )
-	  grid->lcomplex = 1;
-	else
-	  grid->lcomplex = 0;
+ at Result A malloc'ed string containing the end time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm", or NULL if no such time is defined.
 
-	break;
-      }
-    case GRID_GME:
-      {
-	grid->size  = ISEC4_NumValues;
-	grid->nd    = ISEC2_GME_ND;
-	grid->ni    = ISEC2_GME_NI;
-	grid->ni2   = ISEC2_GME_NI2;
-	grid->ni3   = ISEC2_GME_NI3;
-	break;
-      }
-    case GRID_GENERIC:
-      {
-	grid->size  = ISEC4_NumValues;
-	grid->xsize = 0;
-	grid->ysize = 0;
-	break;
-      }
-    default:
-      {
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-	break;
-      }
-    }
+ at Description
+The returned time is the end time of an integration period if such a time exists (statistical fields).
+Otherwise, NULL is returned.
 
-  grid->isRotated = FALSE;
-  if ( cgribexGetIsRotated(isec2) )
-    {
-      grid->isRotated = TRUE;
-      grid->ypole     = - ISEC2_LatSP*0.001;
-      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
-      grid->angle     = 0;
-    }
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
 
-  grid->xvals = NULL;
-  grid->yvals = NULL;
-  grid->type  = gridtype;
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqEndTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, true);
 }
 
-static
-void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
-		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
-{
-  int varID;
-  int levelID = 0;
-  grid_t grid;
+/**
+ at Function cdiIterator_inqVTime
+ at Title Get the validity time of the current field
 
-  int vlistID = streamptr->vlistID;
-  int tsID    = streamptr->curTsID;
-  int recID   = recordNewEntry(streamptr, tsID);
-  record_t *record  = &streamptr->tsteps[tsID].records[recID];
+ at Prototype char* cdiIterator_inqVTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
-  int numavg    = ISEC1_AvgNum;
+ at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
 
-  int level1  = ISEC1_Level1;
-  int level2  = ISEC1_Level2;
+ at Description
+The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
+That is, if the field is a time point, its time is returned,
+if it is a statistical field with an integration period, the end time of the integration period is returned.
 
-  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
 
-  record->size      = (size_t)recsize;
-  record->position  = position;
-  record->param     = param;
-  record->ilevel    = level1;
-  record->ilevel2   = level2;
-  record->ltype     = ISEC1_LevelType;
-  record->tsteptype = tsteptype;
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqVTime(CdiIterator* me)
+{
+  char* result = cdiIterator_inqEndTime(me);
+  return (result) ? result : cdiIterator_inqStartTime(me);
+}
 
-  cgribexGetGrid(streamptr, isec2, isec4, &grid, iret);
+/**
+ at Function cdiIterator_inqLevelType
+ at Title Get the type of a level
 
-  int gridID = varDefGrid(vlistID, &grid, 0);
+ at Prototype int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName = NULL, char** outLongName = NULL, char** outStdName = NULL, char** outUnit = NULL)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outName Will be set to a malloc()'ed string with the name of the level if not NULL.
+    @item outLongName Will be set to a malloc()'ed string with the long name of the level if not NULL.
+    @item outStdName Will be set to a malloc()'ed string with the standard name of the level if not NULL.
+    @item outUnit Will be set to a malloc()'ed string with the unit of the level if not NULL.
 
-  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
+ at Result An integer indicating the type of the level.
 
-  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
+ at Description
+Find out some basic information about the given level, the levelSelector selects the function of the requested level.
+If the requested level does not exist, this returns CDI_UNDEFID.
+*/
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  sanityCheck(me);
+  switch(me->filetype)
     {
-      size_t vctsize = (size_t)ISEC2_NumVCP;
-      double *vctptr = &fsec2[10];
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+      #endif
 
-      varDefVCT(vctsize, vctptr);
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_UNDEFID;
     }
+}
 
-  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
+/**
+ at Function cdiIterator_inqLevel
+ at Title Get the value of the z-coordinate
 
-  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
-  if ( datatype <  0 ) datatype = DATATYPE_PACK;
+ at Prototype void cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2 = NULL)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outValue1 For "normal" levels this returns the value, for hybrid levels the first coordinate, for generalized levels the level number.
+    @item outValue2 Zero for "normal" levels, for hybrid levels, this returns the second coordinate, for generalized levels the level count.
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
-	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1, NULL, NULL, NULL, NULL);
+ at Result An error code.
 
-  (*record).varID   = (short)varID;
-  (*record).levelID = (short)levelID;
+ at Description
+Returns the value of the z-coordinate, whatever that may be.
+*/
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
+      #endif
 
-  varDefCompType(varID, comptype);
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
 
-  if ( ISEC1_LocalFLag )
-    {
-      if      ( ISEC1_CenterID == 78  && isec1[36] == 253 ) // DWD local extension
-        varDefEnsembleInfo(varID, isec1[54], isec1[53], isec1[52]);
-      else if ( ISEC1_CenterID == 252 && isec1[36] ==   1 ) // MPIM local extension
-        varDefEnsembleInfo(varID, isec1[38], isec1[39], isec1[37]);
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
     }
+}
 
-  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);
+/**
+ at Function cdiIterator_inqLevelUuid
+ at Title Get the UUID of the z-axis used by this field
 
-  if ( varInqInst(varID) == CDI_UNDEFID )
-    {
-      int center, subcenter, instID;
-      center    = ISEC1_CenterID;
-      subcenter = ISEC1_SubCenterID;
-      instID    = institutInq(center, subcenter, NULL, NULL);
-      if ( instID == CDI_UNDEFID )
-	instID = institutDef(center, subcenter, NULL, NULL);
-      varDefInst(varID, instID);
-    }
+ at Prototype int cdiIterator_inqLevelUuid(CdiIterator* me, int levelSelector, unsigned char (*outUuid)[16])
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item outVgridNumber The number of the associated vertical grid description.
+    @item outLevelCount The number of levels in the associated vertical grid description.
+    @item outUuid A pointer to a user supplied buffer of 16 bytes to store the UUID in.
 
-  if ( varInqModel(varID) == CDI_UNDEFID )
-    {
-      int modelID;
-      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
-      if ( modelID == CDI_UNDEFID )
-	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
-      varDefModel(varID, modelID);
-    }
+ at Result An error code.
 
-  if ( varInqTable(varID) == CDI_UNDEFID )
+ at Description
+Returns identifying information for the external z-axis description. May only be called for generalized levels.
+*/
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  sanityCheck(me);
+  switch(me->filetype)
     {
-      int tableID;
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+      #endif
 
-      tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
 
-      if ( tableID == CDI_UNDEFID )
-	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
-      varDefTable(varID, tableID);
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_ELIBNAVAIL;
     }
-
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
 }
 
-static
-void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
+/**
+ at Function cdiIterator_inqParam
+ at Title Get discipline, category, and number
+
+ at Prototype CdiParam cdiIterator_inqParam(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A struct containing the requested information.
+
+ at Description
+    Simple metadata inspection function.
+*/
+CdiParam cdiIterator_inqParam(CdiIterator* me)
 {
-  /* 2010-01-13: Oliver Fuhrer */
-  if ( ISEC1_CenterID == 215 ) {
-    if (isec1[34] != 0 && isec1[34] != 255) {
-      if (isec1[34] & 2) {
-        if (isec1[34] & 1) {
-          *undef_pds = -0.99*pow(10.0,-isec1[35]);
-        } else {
-          *undef_pds = +0.99*pow(10.0,-isec1[35]);
-        }
-        *undef_eps = pow(10.0,-isec1[35]-1);
-      } else {
-        if (isec1[34] & 1) {
-          *undef_pds = -0.99*pow(10.0,+isec1[35]);
-        } else {
-          *undef_pds = +0.99*pow(10.0,+isec1[35]);
-        }
-        *undef_eps = pow(10.0,isec1[35]-1);
-      }
-    }
-  }
+  sanityCheck(me);
+  return me->param;
 }
 
-static
-void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
-			 int *isec3, double *fsec3, int *isec4, double *fsec4,
-			 int *gribbuffer, int recsize, int *lmv, int *iret)
-{
-  int ipunp = 0, iword = 0;
+/**
+ at Function cdiIterator_inqDatatype
+ at Title Get the datatype of the current field
 
-  memset(isec1, 0, 256*sizeof(int));
+ at Prototype int cdiIterator_inqDatatype(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
-	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
+ at Result The datatype that is used to store this field on disk.
 
-  *lmv = 0;
+ at Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqDatatype(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->datatype;
+}
 
-  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
-    {
-      double undef_pds, undef_eps;
+/**
+ at Function cdiIterator_inqTsteptype
+ at Title Get the timestep type
 
-      MCH_get_undef(isec1, &undef_pds, &undef_eps);
-      FSEC3_MissVal = undef_pds;
-      *lmv = 1;
-    }
-}
+ at Prototype int cdiIterator_inqTsteptype(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
 
-static
-compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
+ at Result The timestep type.
+
+ at Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqTsteptype(CdiIterator* me)
 {
-  compvar_t compVar;
-  int tsteptype = cgribexGetTsteptype(trange);
+  sanityCheck(me);
+  return me->timesteptype;
+}
 
-  compVar.param     = param;
-  compVar.level1    = level1;
-  compVar.level2    = level2;
-  compVar.ltype     = leveltype;
-  compVar.tsteptype = tsteptype;
+/**
+ at Function cdiIterator_inqVariableName
+ at Title Get the variable name of the current field
+
+ at Prototype char* cdiIterator_inqVariableName(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A pointer to a C-string containing the name. The storage for this string is allocated with malloc(), and it is the responsibility of the caller to free() it.
+
+ at Description
+    Allocates a buffer to hold the string, copies the current variable name into this buffer, and returns the buffer.
+    The caller is responsible to make the corresponding free() call.
+*/
+char* cdiIterator_inqVariableName(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_copyVariableName(me);
+      #endif
 
-  return (compVar);
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_copyVariableName(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
 }
 
-static inline int
-cgribexVarCompare(compvar_t compVar, record_t record, int flag)
+/**
+ at Function cdiIterator_inqGridId
+ at Title Get the ID of the current grid
+
+ at Prototype int cdiIterator_inqGridId(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A gridId that can be used for further introspection.
+
+ at Description
+    This provides access to the grid related metadata.
+    The resulting ID is only valid until the next time cdiIterator_nextField() is called.
+*/
+int cdiIterator_inqGridId(CdiIterator* me)
 {
-  int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
-                                     & (record.tsteptype == TSTEP_INSTANT3))
-                                    |((compVar.tsteptype == TSTEP_INSTANT3)
-                                      & (record.tsteptype == TSTEP_INSTANT)))))
-    & (compVar.tsteptype != record.tsteptype);
-  int rstatus = (compVar.param != record.param)
-    |           (compVar.level1 != record.ilevel)
-    |           (compVar.level2 != record.ilevel2)
-    |           (compVar.ltype != record.ltype)
-    |           tstepDiff;
-  return (rstatus);
+  sanityCheck(me);
+  return me->gridId;
 }
-#endif
 
-#define gribWarning(text, nrecs, timestep, paramstr, level1, level2) \
-            Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text)
+/**
+ at Function cdiIterator_readField
+ at Title Read the whole field into a double buffer
 
-#if  defined  (HAVE_LIBCGRIBEX)
+ at Prototype void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
 
-static inline void
-cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
+ at Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
 {
-  if ( streamptr->ntsteps == -1 )
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
     {
-      int tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readField(me, buffer, nmiss);
+	  return;
+      #endif
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readField(me, buffer, nmiss);
+          return;
+      default:
+        Error(kUnexpectedFileTypeMessage);
     }
 }
 
-static inline void
-cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
+/**
+ at Function cdiIterator_readFieldF
+ at Title Read the whole field into a double buffer
+
+ at Prototype void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+
+ at Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
 {
-  int vlistID = streamptr->vlistID;
-  if ( streamptr->ntsteps == 1 )
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
     {
-      if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for (int varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readFieldF(me, buffer, nmiss);
+	  return;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readFieldF(me, buffer, nmiss);
+          return; 
+      default:
+        Error(kUnexpectedFileTypeMessage);
     }
 }
 
+/**
+ at Function cdiIterator_delete
+ at Title Destroy an iterator
 
-int cgribexScanTimestep1(stream_t * streamptr)
+ at Prototype void cdiIterator_delete(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Description
+    Combined destructor & deallocator.
+*/
+void cdiIterator_delete(CdiIterator* me)
 {
-  int *isec0, *isec1, *isec2, *isec3, *isec4;
-  double fsec2[512], fsec3[2], *fsec4 = NULL;
-  int lmv = 0, iret = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer = NULL;
-  size_t buffersize = 0;
-  int rstatus;
-  int fileID;
-  int param = 0;
-  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  size_t readsize;
-  unsigned nrecords, recID;
-  int nrecs_scanned = 0;
-  int datatype;
-  long recsize = 0;
-  int warn_time = TRUE;
-  int warn_numavg = TRUE;
-  int taxisID = -1;
-  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
-  taxis_t *taxis;
-  int vlistID;
-  int comptype;
-  long unzipsize;
-  char paramstr[32];
-  extern int cdiSkipRecords;
-  int nskip = cdiSkipRecords;
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_delete((CdiGribIterator*)me);
+          break;
+      #endif
 
-  streamptr->curTsID = 0;
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_delete(me);
+          break;
 
-  isec0 = streamptr->record->sec0;
-  isec1 = streamptr->record->sec1;
-  isec2 = streamptr->record->sec2;
-  isec3 = streamptr->record->sec3;
-  isec4 = streamptr->record->sec4;
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+void baseIterDestruct(CdiIterator* me) { /*currently empty, but that's no reason not to call it*/ }
+#ifndef _VLIST_H
+#define _VLIST_H
 
-  if ( tsID != 0 )
-    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+#ifdef HAVE_CONFIG_H
+#endif
 
-  fileID = streamptr->fileID;
+#ifndef  _ERROR_H
+#endif
 
-  while ( nskip-- > 0 )
-    {
-      recsize = gribGetSize(fileID);
-      if ( recsize == 0 )
-	Error("Skipping of %d records failed!", cdiSkipRecords);
+#include <stddef.h>  /* size_t */
 
-      recpos  = fileGetPos(fileID);
-      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
-    }
+#ifndef _CDI_LIMITS_H
+#endif
 
-  unsigned nrecs = 0;
-  while ( TRUE )
-    {
-      recsize = gribGetSize(fileID);
-      recpos  = fileGetPos(fileID);
+#define VALIDMISS 1.e+303
 
-      if ( recsize == 0 )
-	{
-	  if ( nrecs == 0 )
-	    Error("No GRIB records found!");
+/*
+ * CDI attribute
+ */
+typedef struct {
+  size_t    xsz;	  /* amount of space at xvalue                      */
+  size_t    namesz;       /* size of name                                   */
+  char     *name;         /* attribute name                                 */
+  int       indtype;	  /* internal data type of xvalue (INT, FLT or TXT) */
+  int       exdtype;      /* external data type                             */
+                          /* indtype    exdtype                             */
+                          /* TXT        TXT                                 */
+                          /* INT        INT16, INT32                        */
+                          /* FLT        FLT32, FLT64                        */
+  size_t    nelems;    	  /* number of elements                             */
+  void     *xvalue;       /* the actual data                                */
+} cdi_att_t;
 
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      if ( (size_t)recsize > buffersize )
-	{
-	  buffersize = (size_t)recsize;
-	  gribbuffer = (unsigned char *)xrealloc(gribbuffer, buffersize);
-	}
 
-      readsize = (size_t)recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
-      if ( rstatus ) break;
+typedef struct {
+  size_t     nalloc;		/* number allocated >= nelems */
+  size_t     nelems;		/* length of the array */
+  cdi_att_t  value[MAX_ATTRIBUTES];
+} cdi_atts_t;
 
-      comptype = COMPRESS_NONE;
-      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
-	{
-	  comptype = COMPRESS_SZIP;
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < (size_t)unzipsize )
-	    {
-	      buffersize = (size_t)unzipsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
-	}
 
-      nrecs_scanned++;
-      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
-			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
+typedef struct
+{
+  int      flag;
+  int      index;
+  int      mlevelID;
+  int      flevelID;
+}
+levinfo_t;
 
-      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+#define DEFAULT_LEVINFO(levID) \
+  (levinfo_t){ 0, -1, levID, levID}
+/*
+#define DEFAULT_LEVINFO(levID) \
+  (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
+*/
+typedef struct
+{
+  int ens_index;
+  int ens_count;
+  int forecast_init_type;
+}
+ensinfo_t;
 
-      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
-      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
-      level1   = ISEC1_Level1;
-      level2   = ISEC1_Level2;
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
 
-      gribDateTime(isec1, &vdate, &vtime);
+/* Length of optional keyword/value pair list */
+#define MAX_OPT_GRIB_ENTRIES 50
 
-      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
-	datatype = ISEC4_NumBits;
-      else
-        datatype = DATATYPE_PACK;
 
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	  rdate = gribRefDate(isec1);
-	  rtime = gribRefTime(isec1);
-	  tunit = cgribexGetTimeUnit(isec1);
-	  fcast = cgribexTimeIsFC(isec1);
-	}
-      else
-	{
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+typedef struct
+{
+  int         flag;
+  int         isUsed;
+  int         mvarID;
+  int         fvarID;
+  int         param;
+  int         gridID;
+  int         zaxisID;
+  int         tsteptype; /* TSTEP_* */
+  int         datatype;  /* DATATYPE_PACKX for GRIB data, else DATATYPE_FLT32 or DATATYPE_FLT64 */
+  int         instID;
+  int         modelID;
+  int         tableID;
+  int         timave;
+  int         timaccu;
+  int         typeOfGeneratingProcess;
+  int         productDefinitionTemplate;
+  int         chunktype;
+  int         xyz;
+  int         missvalused; /* TRUE if missval is defined */
+  int         lvalidrange;
+  char       *name;
+  char       *longname;
+  char       *stdname;
+  char       *units;
+  char       *extra;
+  double      missval;
+  double      scalefactor;
+  double      addoffset;
+  double      validrange[2];
+  levinfo_t  *levinfo;
+  int         comptype;     // compression type
+  int         complevel;    // compression level
+  ensinfo_t  *ensdata;      /* Ensemble information */
+  cdi_atts_t  atts;
+  int         iorank;
+#if  defined  (HAVE_LIBGRIB_API)
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
 
-	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+  /* (Optional) list of keyword/double value pairs */
+  int    opt_grib_dbl_nentries;
+  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_dbl_update[MAX_OPT_GRIB_ENTRIES];
+  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int    opt_grib_int_nentries;
+  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_update[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
+}
+var_t;
 
-	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
-	    }
 
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      if ( recID < nrecs ) break;
-	      if ( warn_time )
-		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
-		  {
-                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
-		    warn_time = FALSE;
-		  }
-	    }
-	  else
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+typedef struct
+{
+  int         locked;
+  int         self;
+  int         nvars;        /* number of variables                */
+  int         ngrids;
+  int         nzaxis;
+  long        ntsteps;
+  int         taxisID;
+  int         tableID;
+  int         instID;
+  int         modelID;
+  int         varsAllocated;
+  int         gridIDs[MAX_GRIDS_PS];
+  int         zaxisIDs[MAX_ZAXES_PS];
+  var_t      *vars;
+  cdi_atts_t  atts;
+}
+vlist_t;
 
-	      if ( recID < nrecs )
-		{
-		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
-		  continue;
-		}
-	    }
-	}
 
-      if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
-	    {
-	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
+vlist_t *vlist_to_pointer(int vlistID);
+void vlistCheckVarID(const char *caller, int vlistID, int varID);
+const char *vlistInqVarNamePtr(int vlistID, int varID);
+const char *vlistInqVarLongnamePtr(int vlistID, int varID);
+const char *vlistInqVarStdnamePtr(int vlistID, int varID);
+const char *vlistInqVarUnitsPtr(int vlistID, int varID);
+void     vlistDestroyVarName(int vlistID, int varID);
+void     vlistDestroyVarLongname(int vlistID, int varID);
+void     vlistDestroyVarUnits(int vlistID, int varID);
+void     vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
+int      vlistInqVarMissvalUsed(int vlistID, int varID);
+int      vlistHasTime(int vlistID);
 
-      nrecs++;
+int      vlistDelAtts(int vlistID, int varID);
+int      vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2);
 
-      if ( CDI_Debug )
-	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
+void     vlistUnpack(char * buffer, int bufferSize, int * pos,
+                     int originNamespace, void *context, int force_id);
 
-      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
-		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
-    }
+/*      vlistDefVarValidrange: Define the valid range of a Variable */
+void    vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
 
-  streamptr->rtsteps = 1;
+/*      vlistInqVarValidrange: Get the valid range of a Variable */
+int     vlistInqVarValidrange(int vlistID, int varID, double *validrange);
 
-  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
+void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3]);
 
-  cdi_generate_vars(streamptr);
+int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
 
-  if ( fcast )
-    {
-      taxisID = taxisCreate(TAXIS_RELATIVE);
-      taxis->type  = TAXIS_RELATIVE;
-      taxis->rdate = rdate;
-      taxis->rtime = rtime;
-      taxis->unit  = tunit;
-    }
-  else
+void vlist_lock(int vlistID);
+void vlist_unlock(int vlistID);
+
+static inline void
+vlistAdd2GridIDs(vlist_t *vlistptr, int gridID)
+{
+  int index, ngrids = vlistptr->ngrids;
+  for ( index = 0; index < ngrids; index++ )
+    if (vlistptr->gridIDs[index] == gridID ) break;
+  if ( index == ngrids )
     {
-      taxisID = taxisCreate(TAXIS_ABSOLUTE);
-      taxis->type  = TAXIS_ABSOLUTE;
-      taxis->unit  = tunit;
+      if (ngrids >= MAX_GRIDS_PS)
+        Error("Internal limit exceeded: more than %d grids.", MAX_GRIDS_PS);
+      ++(vlistptr->ngrids);
+      vlistptr->gridIDs[ngrids] = gridID;
     }
+}
 
-  taxis->vdate = (int)datetime0.date;
-  taxis->vtime = (int)datetime0.time;
-
-  vlistID = streamptr->vlistID;
-  vlistDefTaxis(vlistID, taxisID);
+static inline void
+vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
+{
+  int index, nzaxis = vlistptr->nzaxis;
+  for ( index = 0; index < nzaxis; index++ )
+    if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
 
-  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
-  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
+  if ( index == nzaxis )
     {
-      streamptr->tsteps[0].recordSize = (int)nrecords;
-      streamptr->tsteps[0].records =
-      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
+      if ( nzaxis >= MAX_ZAXES_PS )
+	Error("Internal limit exceeded: more than %d zaxis.", MAX_ZAXES_PS);
+      vlistptr->zaxisIDs[nzaxis] = zaxisID;
+      vlistptr->nzaxis++;
     }
-
-  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
-  streamptr->tsteps[0].nrecs = (int)nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[0].recIDs[recID] = (int)recID;
-
-  streamptr->record->buffer     = gribbuffer;
-  streamptr->record->buffersize = (size_t)buffersize;
-
-  cgribexScanTsFixNtsteps(streamptr, recpos);
-  cgribexScanTsConstAdjust(streamptr, taxis);
-
-  return (0);
 }
 
 
-int cgribexScanTimestep2(stream_t * streamptr)
-{
-  int rstatus = 0;
-  int *isec0, *isec1, *isec2, *isec3, *isec4;
-  double fsec2[512], fsec3[2], *fsec4 = NULL;
-  int lmv = 0, iret = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer = NULL;
-  size_t buffersize = 0;
-  int fileID;
-  int param = 0;
-  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID, gridID;
-  size_t readsize;
-  int nrecords, nrecs, recID, rindex;
-  int nrecs_scanned = 0;
-  long recsize = 0;
-  int warn_numavg = TRUE;
-  int tsteptype;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  long unzipsize;
-  char paramstr[32];
-
-  streamptr->curTsID = 1;
-
-  isec0 = streamptr->record->sec0;
-  isec1 = streamptr->record->sec1;
-  isec2 = streamptr->record->sec2;
-  isec3 = streamptr->record->sec3;
-  isec4 = streamptr->record->sec4;
+#if  defined  (HAVE_LIBGRIB_API)
+extern int   cdiNAdditionalGRIBKeys;
+extern char* cdiAdditionalGRIBKeys[];
+#endif
 
-  fileID  = streamptr->fileID;
-  vlistID = streamptr->vlistID;
-  taxisID = vlistInqTaxis(vlistID);
+extern
+#ifndef __cplusplus
+const
+#endif
+resOps vlistOps;
 
-  gribbuffer = (unsigned char *) streamptr->record->buffer;
-  buffersize = streamptr->record->buffersize;
+#endif  /* _VLIST_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
 
-  tsID = streamptr->rtsteps;
-  if ( tsID != 1 )
-    Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+#include <assert.h>
+#include <stdlib.h>
 
-  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+//For more information on the condestruct() pattern, see comment in src/iterator_grib.c
+static CdiFallbackIterator* cdiFallbackIterator_condestruct(CdiFallbackIterator* me, const char* path, int filetype)
+{
+  if(me) goto destruct;
 
-  cdi_create_records(streamptr, tsID);
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(&me->super, filetype);
 
-  nrecords = streamptr->tsteps[tsID].nallrecs;
-  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof(int));
-  streamptr->tsteps[1].nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[1].recIDs[recID] = -1;
+  me->streamId = streamOpenRead(path);
+  if(me->streamId == CDI_UNDEFID) goto destructSuper;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
+  me->variableCount = vlistNvars(me->vlistId);
+  if(me->variableCount <= 0) goto closeStream;
+  me->curLevelCount = -1;        //Will be set in cdiFallbackIterator_nextField()
 
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position =	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     =	streamptr->tsteps[0].records[recID].size;
-    }
+  //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
+  me->curTimestep = 0;
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  me->curVariable = 0;
+  me->curLevel = -1;
+  me->path = myStrDup(path);
+  if(!me->path) goto closeStream;
 
-  nrecs_scanned = nrecords;
-  rindex = 0;
-  while ( TRUE )
-    {
-      if ( rindex > nrecords ) break;
+  return me;
 
-      recsize = gribGetSize(fileID);
-      recpos  = fileGetPos(fileID);
-      if ( recsize == 0 )
-	{
-	  streamptr->ntsteps = 2;
-	  break;
-	}
-      if ( (size_t)recsize > buffersize )
-	{
-	  buffersize = (size_t)recsize;
-	  gribbuffer = (unsigned char *)xrealloc(gribbuffer, buffersize);
-	}
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
 
-      readsize = (size_t)recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
-      if ( rstatus ) break;
+destruct:
+  free(me->path);
+closeStream:
+  streamClose(me->streamId);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+  return NULL;
+}
 
-      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
-	{
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < (size_t)unzipsize )
-	    {
-	      buffersize = (size_t)unzipsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
-	}
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype)
+{
+  return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
+}
 
-      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
-			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
+//Fetches the info that is published by the variables in the base class from the current field.
+static void fetchSuperInfo(CdiFallbackIterator* me)
+{
+  me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
+  me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
+  me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
+  int param = vlistInqVarParam(me->vlistId, me->curVariable);
+  cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
+}
 
-      nrecs_scanned++;
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
 
-      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+  //Make another stream for this file. This yields an unadvanced iterator.
+  CdiFallbackIterator* clone = cdiFallbackIterator_condestruct(NULL, me->path, me->super.filetype);
+  if(!clone) return NULL;
 
-      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
-      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
-      level1    = ISEC1_Level1;
-      level2    = ISEC1_Level2;
+  //Point the clone to the same position in the file.
+  clone->variableCount = me->variableCount;
+  clone->curVariable = me->curVariable;
+  clone->curLevelCount = me->curLevelCount;
+  clone->curLevel = me->curLevel;
+  clone->curTimestep = me->curTimestep;
 
-      gribDateTime(isec1, &vdate, &vtime);
+  clone->super.isAdvanced = super->isAdvanced;
+  if(super->isAdvanced) fetchSuperInfo(clone);
 
-      if ( rindex == 0 )
-	{
-	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
-	    {
-	      taxis->type  = TAXIS_RELATIVE;
-	      taxis->rdate = gribRefDate(isec1);
-	      taxis->rtime = gribRefTime(isec1);
-	    }
-	  else
-	    {
-	      taxis->type  = TAXIS_ABSOLUTE;
-	    }
-	  taxis->unit  = cgribexGetTimeUnit(isec1);
-	  taxis->vdate = vdate;
-	  taxis->vtime = vtime;
+  return clone;
+}
 
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	}
+char* cdiFallbackIterator_serialize(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
 
-      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
+  char* escapedPath = cdiEscapeSpaces(me->path);
+  char* result = myAsprintf("%s %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curTimestep);
+  free(escapedPath);
+  return result;
+}
 
-      if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg &&
-        	(taxis->numavg != ISEC1_AvgNum) )
-	    {
-	  /*
-	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
-	  */
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* description)
+{
+  CdiFallbackIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
 
-      datetime.date  = vdate;
-      datetime.time  = vtime;
+  description = baseIter_constructFromString(&me->super, description);
 
-      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+  while(*description == ' ') description++;
+  me->path = cdiUnescapeSpaces(description, &description);
+  if(!me->path) goto destructSuper;
 
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
-	}
+  me->streamId = streamOpenRead(me->path);
+  if(me->streamId == CDI_UNDEFID) goto freePath;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
 
-      if ( recID == nrecords )
-	{
-	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
-	  return (CDI_EUFSTRUCT);
-	}
+  //This reads one variable from the description string, does error checking, and advances the given string pointer.
+  #define decodeValue(variable, description) do \
+    { \
+      const char* savedStart = description; \
+      long long decodedValue = strtoll(description, (char**)&description, 0);   /*The cast is a workaround for the wrong signature of strtoll().*/ \
+      variable = (int)decodedValue; \
+      if(savedStart == description) goto closeStream; \
+      if((long long)decodedValue != (long long)variable) goto closeStream; \
+    } while(0)
+  decodeValue(me->variableCount, description);
+  decodeValue(me->curVariable, description);
+  decodeValue(me->curLevelCount, description);
+  decodeValue(me->curLevel, description);
+  decodeValue(me->curTimestep, description);
+  #undef decodeValue
 
-      if ( cdiInventoryMode == 1 )
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
-	    {
-	      break;
-	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }
-	}
-      else
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  if(me->super.isAdvanced) fetchSuperInfo(me);
 
-              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
-	      continue;
-	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }
-	}
+  return me;
 
-      if ( CDI_Debug )
-	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
+closeStream:
+  streamClose(me->streamId);
+freePath:
+  free(me->path);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
 
-      streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+static int advance(CdiFallbackIterator* me)
+{
+  me->curLevel++;
+  if(me->curLevel == me->curLevelCount)
+    {
+      me->curLevel = 0;
+      me->curVariable++;
+      if(me->curVariable == me->variableCount)
+        {
+          me->curVariable = 0;
+          me->curTimestep++;
+          if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
+        }
+    }
+  return CDI_NOERR;
+}
 
-      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
-	{
-	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		  tsID, recID,
-		  streamptr->tsteps[tsID].records[recID].param, param,
-		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
-	  return (CDI_EUFSTRUCT);
-	}
+int cdiFallbackIterator_nextField(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int result = advance(me);
+  if(result) return result;
 
-      streamptr->tsteps[1].records[recID].position = recpos;
-      varID = streamptr->tsteps[tsID].records[recID].varID;
-      gridID = vlistInqVarGrid(vlistID, varID);
-      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
-	{
-	  if ( IS_NOT_EQUAL(gridInqXval(gridID, 0),ISEC2_FirstLon*0.001) ||
-	       IS_NOT_EQUAL(gridInqYval(gridID, 0),ISEC2_FirstLat*0.001) )
-	    gridChangeType(gridID, GRID_TRAJECTORY);
-	}
+  if(!me->curLevel)
+    { //Fetch the information that may have changed (we are processing a new variable/timestep if this point is reached).
+      fetchSuperInfo(me);
+      me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
+    }
+  return CDI_NOERR;
+}
 
-      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
-	vlistDefVarTsteptype(vlistID, varID, tsteptype);
+char* cdiFallbackIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  if(getEndTime) return NULL;   //The stream interface does not export the start/end times of statistical fields, so we treat all data as point of time data, returning the validity time as the start time.
+  int taxisId = vlistInqTaxis(me->vlistId);
+  int date = taxisInqVdate(taxisId);
+  int time = taxisInqVtime(taxisId);
+  int year, month, day, hour, minute, second;
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", year, month, day, hour, minute, second);
+}
 
-      rindex++;
+int cdiFallbackIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  #define copyString(outPointer, function) do \
+    { \
+      if(outPointer) \
+        { \
+          char tempBuffer[CDI_MAX_NAME]; \
+          function(zaxisId, tempBuffer); \
+          *outPointer = myStrDup(tempBuffer); \
+        } \
+    } \
+  while(0)
+  copyString(outName, zaxisInqName);    //FIXME: zaxisInqName is unsafe.
+  copyString(outLongName, zaxisInqLongname);    //FIXME: zaxisInqLongname is unsafe.
+  copyString(outStdName, zaxisInqStdname);    //FIXME: zaxisInqStdname is unsafe.
+  copyString(outUnit, zaxisInqUnits);    //FIXME: zaxisInqUnits is unsafe.
+  #undef copyString
+  return zaxisInqLtype(zaxisId);
+}
+
+int cdiFallbackIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+
+  //handle NULL pointers once and for all
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+
+  //get the level value
+  if(levelSelector)
+    {
+      *outValue1 = (zaxisInqLbounds(zaxisId, NULL))
+                 ? zaxisInqLbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
     }
-
-  nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
+  else
     {
-      if ( ! streamptr->tsteps[tsID].records[recID].used )
-	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	}
-      else
-	{
-	  nrecs++;
-	}
+      *outValue1 = (zaxisInqUbounds(zaxisId, NULL))
+                 ? zaxisInqUbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
     }
-  streamptr->tsteps[tsID].nrecs = nrecs;
+  *outValue2 = 0.0;
 
-  streamptr->rtsteps = 2;
+  //if this is a hybrid zaxis, lookup the coordinates in the vertical coordinate table
+  ssize_t intLevel = (ssize_t)(2**outValue1);
+  if(0 <= intLevel && intLevel < zaxisInqVctSize(zaxisId) - 1)
+    {
+      const double* coordinateTable = zaxisInqVctPtr(zaxisId);
+      *outValue1 = coordinateTable[intLevel];
+      *outValue2 = coordinateTable[intLevel + 1];
+    }
+  return CDI_NOERR;
+}
 
-  cgribexScanTsFixNtsteps(streamptr, recpos);
+int cdiFallbackIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  if(zaxisInqLtype(zaxisId) != ZAXIS_HYBRID) return CDI_EINVAL;
+  if(outVgridNumber) *outVgridNumber = zaxisInqNumber(zaxisId);
+  if(outLevelCount) *outLevelCount = zaxisInqNlevRef(zaxisId);
+  if(outUuid) zaxisInqUUID(zaxisId, *outUuid);
+  return CDI_NOERR;
+}
 
-  streamptr->record->buffer     = gribbuffer;
-  streamptr->record->buffersize = buffersize;
+char* cdiFallbackIterator_copyVariableName(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  return vlistCopyVarName(me->vlistId, me->curVariable);
+}
 
-  return (rstatus);
+void cdiFallbackIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
 }
-#endif
 
+void cdiFallbackIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
+}
 
-#if  defined  (HAVE_LIBCGRIBEX)
-int cgribexScanTimestep(stream_t * streamptr)
+void cdiFallbackIterator_delete(CdiIterator* super)
 {
-  int rstatus = 0;
-  double fsec2[512], fsec3[2], *fsec4 = NULL;
-  int lmv = 0, iret = 0;
-  long recsize = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer;
-  size_t buffersize = 0;
-  int fileID;
-  int param = 0;
-  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int vrecID, recID;
-  int warn_numavg = TRUE;
-  size_t readsize;
-  int taxisID = -1;
-  int rindex, nrecs = 0;
-  int nrecs_scanned;
-  long unzipsize;
-  char paramstr[32];
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  cdiFallbackIterator_condestruct(me, NULL, 0);
+}
+#ifndef _STREAM_GRB_H
+#define _STREAM_GRB_H
 
-  /*
-  if ( CDI_Debug )
-    {
-      Message("streamID = %d", streamptr->self);
-      Message("cts = %d", streamptr->curTsID);
-      Message("rts = %d", streamptr->rtsteps);
-      Message("nts = %d", streamptr->ntsteps);
-    }
-  */
-  int *isec0 = streamptr->record->sec0;
-  int *isec1 = streamptr->record->sec1;
-  int *isec2 = streamptr->record->sec2;
-  int *isec3 = streamptr->record->sec3;
-  int *isec4 = streamptr->record->sec4;
+int   grbBitsPerValue(int datatype);
 
-  int tsID  = streamptr->rtsteps;
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+int   grbInqContents(stream_t * streamptr);
+int   grbInqTimestep(stream_t * streamptr, int tsID);
 
-  if ( streamptr->tsteps[tsID].recordSize == 0 )
-    {
-      gribbuffer = (unsigned char *) streamptr->record->buffer;
-      buffersize = streamptr->record->buffersize;
+int   grbInqRecord(stream_t * streamptr, int *varID, int *levelID);
+void  grbDefRecord(stream_t * streamptr);
+void  grbReadRecord(stream_t * streamptr, double *data, int *nmiss);
+void  grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss);
+void  grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1);
 
-      cdi_create_records(streamptr, tsID);
+void  grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss);
+void  grb_write_var(stream_t * streamptr, int varID, int memtype, const void *data, int nmiss);
 
-      nrecs = streamptr->tsteps[1].nrecs;
+void  grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss);
+void  grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
-      streamptr->tsteps[tsID].nrecs = nrecs;
-      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
-      for ( recID = 0; recID < nrecs; recID++ )
-	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
+int   grib1ltypeToZaxisType(int grib_ltype);
+int   grib2ltypeToZaxisType(int grib_ltype);
 
-      fileID = streamptr->fileID;
+int   zaxisTypeToGrib1ltype(int zaxistype);
+int   zaxisTypeToGrib2ltype(int zaxistype);
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+#endif  /* _STREAM_GRB_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _ZAXIS_H
+#define _ZAXIS_H
 
-      nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
-      rindex = 0;
-      while ( TRUE )
-	{
-	  if ( rindex > nrecs ) break;
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit);  //The returned const char* point to static storage. Don't free or modify them.
 
-	  recsize = gribGetSize(fileID);
-	  recpos  = fileGetPos(fileID);
-	  if ( recsize == 0 )
-	    {
-	      streamptr->ntsteps = streamptr->rtsteps + 1;
-	      break;
-	    }
-	  if ( recsize > 0 && (size_t)recsize > buffersize )
-	    {
-	      buffersize = (size_t)recsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
+int zaxisSize(void);
 
-	  if ( rindex >= nrecs ) break;
+unsigned cdiZaxisCount(void);
 
-	  readsize = (size_t)recsize;
-	  rstatus = gribRead(fileID, gribbuffer, &readsize);
-	  if ( rstatus )
-	    {
-	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
-                      streamptr->tsteps[tsID].recordSize);
-	      break;
-	    }
+void cdiZaxisGetIndexList(unsigned numIDs, int IDs[numIDs]);
 
-	  if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
-	    {
-	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	      if ( buffersize < (size_t)unzipsize )
-		{
-		  buffersize = (size_t)unzipsize;
-		  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-		}
-	    }
+void
+zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
+            int * unpackBufferPos, int originNamespace, void *context,
+            int force_id);
 
-	  cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
-			      (int *) gribbuffer, (int)recsize, &lmv, &iret);
+void zaxisDefLtype2(int zaxisID, int ltype2);
 
-          nrecs_scanned++;
+extern const resOps zaxisOps;
 
-	  param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
-          cdiParamToString(param, paramstr, sizeof(paramstr));
+#endif
 
-	  if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
-	  if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
-	  level1   = ISEC1_Level1;
-	  level2   = ISEC1_Level2;
 
-	  gribDateTime(isec1, &vdate, &vtime);
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
 
-	  if ( rindex == nrecs ) break;
 
-	  if ( rindex == 0 )
-	    {
-              int vlistID = streamptr->vlistID;
-	      taxisID = vlistInqTaxis(vlistID);
-	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
-		{
-		  taxis->type  = TAXIS_RELATIVE;
-		  taxis->rdate = gribRefDate(isec1);
-		  taxis->rtime = gribRefTime(isec1);
-		}
-	      else
-		{
-		  taxis->type  = TAXIS_ABSOLUTE;
-		}
-	      taxis->unit  = cgribexGetTimeUnit(isec1);
-	      taxis->vdate = vdate;
-	      taxis->vtime = vtime;
+#ifdef HAVE_LIBGRIB_API
 
-	      datetime0.date = vdate;
-	      datetime0.time = vtime;
-	    }
+//Since the error handling in constructors is usually very closely related to the workings of a destructor,
+//this function combines both functions in one, using a centralized exit.
+//The mode of operation depends on whether me is a NULL pointer on entry:
+//If it is NULL, a new object is allocated and constructed, which is returned if construction is successful.
+//If a non-NULL pointer is passed in, the object is destructed and NULL is returned. In this case, the other arguments are ignored.
+static CdiGribIterator* cdiGribIterator_condestruct(CdiGribIterator* me, const char* path, int filetype)
+{
+  #define super() (&me->super)
+  if(me) goto destruct;
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(super(), filetype);
 
-	  if ( ISEC1_AvgNum )
-	    {
-	      if (  taxis->numavg && warn_numavg &&
-		   (taxis->numavg != ISEC1_AvgNum) )
-		{
-	      /*
-	          Warning("Changing numavg from %d to %d not supported!", streamptr->tsteps[tsID].taxis.numavg, ISEC1_AvgNum);
-	      */
-		  warn_numavg = FALSE;
-		}
-	      else
-		{
-		  taxis->numavg = ISEC1_AvgNum;
-		}
-	    }
+  me->file = cdiInputFile_make(path);
+  if(!me->file) goto destructSuper;
+  me->fileOffset = 0;
+  me->gribHandle = NULL;
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->super.gridId = CDI_UNDEFID;
 
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+  goto success;
 
-	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
 
-	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
-	    {
-	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
-	    }
+destruct:
+  if(me->super.gridId != CDI_UNDEFID) gridDestroy(me->super.gridId);
+  if(me->gribHandle) grib_handle_delete(me->gribHandle);
+  free(me->gribBuffer);
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(super());
+  free(me);
+  me = NULL;
 
-	  if ( vrecID == nrecs )
-	    {
-	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+success:
+  return me;
+  #undef super
+}
 
-	      if ( cdiInventoryMode == 1 )
-		return (CDI_EUFSTRUCT);
-	      else
-		continue;
-	    }
+CdiIterator* cdiGribIterator_new(const char* path, int filetype)
+{
+  return &cdiGribIterator_condestruct(NULL, path, filetype)->super;
+}
 
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }
-	  else
-	    {
-	      if ( streamptr->tsteps[tsID].records[recID].used )
-		{
-		  char paramstr[32];
-		  cdiParamToString(param, paramstr, sizeof(paramstr));
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+  //Allocate memory and copy data. (operations that may fail)
+  CdiGribIterator* result = xmalloc(sizeof(*result));
+  if(!result) goto fail;
+  *result = (CdiGribIterator)
+    {
+      .file = me->file,
+      .fileOffset = me->fileOffset,
+      .gribBuffer = NULL,
+      .bufferSize = me->bufferSize,
+      .curRecordSize = me->curRecordSize,
+      .gribHandle = NULL
+    };
+  if(me->gribBuffer)
+    {
+      result->gribBuffer = xmalloc(me->bufferSize);
+      if(!result->gribBuffer) goto freeResult;
+      memcpy(result->gribBuffer, me->gribBuffer, me->curRecordSize);
+    }
+  if(me->gribHandle)
+    {
+      result->gribHandle = grib_handle_new_from_message(NULL, result->gribBuffer, result->curRecordSize);
+      if(!result->gribHandle) goto freeBuffer;
+    }
+  if(super->gridId != CDI_UNDEFID)
+    {
+      result->super.gridId = gridDuplicate(super->gridId);
+      if(result->super.gridId == CDI_UNDEFID) goto deleteGribHandle;
+    }
 
-		  if ( CDI_Debug )
-                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+  //Finish construction. (operations that cannot fail)
+  baseIterConstruct(&result->super, super->filetype);
+  result->super.datatype = super->datatype;
+  result->super.timesteptype = super->timesteptype;
+  result->super.param = super->param;
+  cdiRefObject_retain(&result->file->super);
 
-		  continue;
-		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
-	    }
+  return result;
 
-	  if ( CDI_Debug )
-            Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
+  //Error handling.
+deleteGribHandle:
+  if(result->gribHandle) grib_handle_delete(result->gribHandle);
+freeBuffer:
+  free(result->gribBuffer);
+freeResult:
+  free(result);
+fail:
+  return NULL;
+}
 
-	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
-	    {
-	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		      tsID, recID,
-		      streamptr->tsteps[tsID].records[recID].param, param,
-		      streamptr->tsteps[tsID].records[recID].ilevel, level1);
-	      Error("Invalid, unsupported or inconsistent record structure");
-	    }
+char* cdiGribIterator_serialize(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+  char* path = cdiInputFile_copyPath(me->file);
+  char* escapedPath = cdiEscapeSpaces(path);
+  free(path);
+  char* result = myAsprintf("%s %zu", escapedPath, me->fileOffset);
+  free(escapedPath);
+  return result;
+}
 
-	  rindex++;
-	}
 
-      for ( vrecID = 0; vrecID < nrecs; vrecID++ )
-	{
-	  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-	  if ( ! streamptr->tsteps[tsID].records[recID].used ) break;
-	}
+CdiGribIterator* cdiGribIterator_deserialize(const char* description)
+{
+  char* path;
+  CdiGribIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
 
-      if ( vrecID < nrecs )
-	{
-	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
-	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, paramstr,
-                      streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
-	  return (CDI_EUFSTRUCT);
-	}
+  description = baseIter_constructFromString(&me->super, description);
 
-      streamptr->rtsteps++;
+  while(*description == ' ') description++;
+  path = cdiUnescapeSpaces(description, &description);
+  if(!path) goto destructSuper;
 
-      if ( streamptr->ntsteps != streamptr->rtsteps )
-	{
-	  tsID = tstepsNewEntry(streamptr);
-	  if ( tsID != streamptr->rtsteps )
-	    Error("Internal error. tsID = %d", tsID);
+  me->file = cdiInputFile_make(path);
+  free(path);
+  if(!me->file) goto destructSuper;
 
-	  streamptr->tsteps[tsID-1].next   = 1;
-	  streamptr->tsteps[tsID].position = recpos;
-	}
+  {
+    const char* savedStart = description;
+    long long decodedOffset = strtoll(description, (char**)&description, 0);    //The cast is a workaround for the wrong signature of strtoll() (it should have been `long long strtoll(const char*, const char**, int)`, not `long long strtoll(const char*, char**, int)`.
+    me->fileOffset = (off_t)decodedOffset;
+    if(savedStart == description) goto closeFile;
+    if((unsigned long long)decodedOffset > (unsigned long long)me->fileOffset) goto closeFile;
+  }
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
-      streamptr->tsteps[tsID].position = recpos;
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->gribHandle = NULL;
+  me->super.gridId = CDI_UNDEFID;
+  if(me->super.isAdvanced && cdiGribIterator_nextField(&me->super)) goto closeFile;
+
+  return me;
+
+
+closeFile:
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
+#endif
+
+#ifdef HAVE_LIBGRIB_API
+static void cdiGribIterator_ensureBuffer(CdiGribIterator* me, size_t requiredSize)
+{
+  if(me->bufferSize < requiredSize)
+    {
+      me->bufferSize *= 2;
+      if(me->bufferSize < requiredSize) me->bufferSize = requiredSize;
+      me->gribBuffer = xrealloc(me->gribBuffer, me->bufferSize);
+    }
+}
+
+static bool isGrib1DualLevel(int levelType)
+{
+  switch(levelType)
+    {
+      case 101: case 104: case 106: case 108: case 110: case 112:
+      case 114: case 116: case 120: case 121: case 128: case 141:   //This is the complete list after grib_api-1.12.3/definitions/grib1/sections.1.def:106-117:, the code in cdi/src/stream_gribapi.c:grib1GetLevel() seems to be incomplete.
+        return true;
+      default:
+        return false;
+    }
+}
+
+static const unsigned char* positionOfGribMarker(const unsigned char* data, size_t size)
+{
+  for(const unsigned char* currentPosition = data, *end = data + size; currentPosition < end; currentPosition++)
+    {
+      currentPosition = memchr(currentPosition, 'G', size - (currentPosition - data) - 3);      //-3 to ensure that we don't overrun the buffer during the strncmp() call.
+      if(!currentPosition) return NULL;
+      if(!strncmp((const char*)currentPosition, "GRIB", 4)) return currentPosition;
+    }
+  return NULL;
+}
+
+//This clobbers the contents of the gribBuffer!
+//Returns the file offset of the next 'GRIB' marker.
+static ssize_t scanToGribMarker(CdiGribIterator* me)
+{
+  cdiGribIterator_ensureBuffer(me, 8*1024);
+  const size_t kMaxScanSize = 16*1024*1024;
+  for(size_t scannedBytes = 0, scanSize; scannedBytes < kMaxScanSize; scannedBytes += scanSize)
+    {
+      //Load a chunk of data into our buffer.
+      scanSize = me->bufferSize;
+      if(scannedBytes + scanSize > kMaxScanSize) scanSize = kMaxScanSize - scannedBytes;
+      assert(scanSize <= me->bufferSize);
+      int status = cdiInputFile_read(me->file, me->fileOffset + scannedBytes, scanSize, &scanSize, me->gribBuffer);
+      if(status != CDI_NOERR && status != CDI_EEOF) return status;
+
+      const unsigned char* startPosition = positionOfGribMarker(me->gribBuffer, scanSize);
+      if(startPosition)
+        {
+          return me->fileOffset + scannedBytes + (startPosition - me->gribBuffer);
+        }
+
+      //Get the offset for the next iteration if there is a next iteration.
+      scanSize -= 3;        //so that we won't miss a 'GRIB' sequence that happens to be cut off
+      scannedBytes += scanSize;
+      scannedBytes &= ~0xf; //make 16 bytes aligned
+    }
+  return -1;
+}
+
+static unsigned decode24(void* beData)
+{
+  unsigned char* bytes = beData;
+  return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
+}
 
-      streamptr->record->buffer     = gribbuffer;
-      streamptr->record->buffersize = buffersize;
-    }
+static uint64_t decode64(void* beData)
+{
+  unsigned char* bytes = beData;
+  uint64_t result = 0;
+  for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
+  return result;
+}
 
-  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+//Determine the size of the GRIB record that begins at the given file offset.
+static int getRecordSize(CdiGribIterator* me, off_t gribFileOffset, size_t* outRecordSize)
+{
+  char buffer[16];
+  size_t readSize;
+  int status = cdiInputFile_read(me->file, gribFileOffset, sizeof(buffer), &readSize, buffer);
+  if(status != CDI_NOERR && status != CDI_EEOF) return status;
+  if(readSize < sizeof(buffer)) return CDI_EEOF;
+  *outRecordSize = 0;
+  switch(buffer[7])
     {
-      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
-      streamptr->ntsteps = tsID;
-    }
+      case 1:
+        *outRecordSize = decode24(&buffer[4]);
+        if(*outRecordSize & (1 << 23))
+          {
+            *outRecordSize = 120*(*outRecordSize & ((1 << 23) - 1));    //Rescaling for long records.
+            //The corresponding code in cgribexlib.c:4532-4570: is much more complicated
+            //due to the fact that it subtracts the padding bytes that are inserted after section 4.
+            //However, we are only interested in the total size of data we need to read here,
+            //so we can ignore the presence of some padding bytes.
+          }
+        return CDI_NOERR;
 
-  rstatus = (int)streamptr->ntsteps;
+      case 2:
+        *outRecordSize =  decode64(&buffer[8]);
+        return CDI_NOERR;
 
-  return (rstatus);
+      default:
+        return CDI_EUFTYPE;
+    }
 }
-#endif
 
-#ifdef gribWarning
-#undef gribWarning
+#if 0
+static void hexdump(void* data, size_t size)
+{
+  unsigned char* charData = data;
+  for(size_t offset = 0; offset < size; )
+    {
+      printf("%016zx:", offset);
+      for(size_t i = 0; i < 64 && offset < size; i++, offset++)
+        {
+          if((i & 63) && !(i & 15)) printf(" |");
+          if((i & 15) && !(i & 3)) printf("  ");
+          printf(" %02x", charData[offset]);
+        }
+      printf("\n");
+    }
+}
 #endif
 
-#if  defined  (HAVE_LIBCGRIBEX)
-int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, double missval)
+//Read a record into memory and wrap it in a grib_handle.
+//XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this [...]
+static int readMessage(CdiGribIterator* me)
 {
-  int status = 0;
-  int iret = 0, iword = 0;
-  int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
-  double fsec2[512], fsec3[2];
-  char hoper[2];
+  //Destroy the old grib_handle.
+  if(me->gribHandle) grib_handle_delete(me->gribHandle), me->gribHandle = NULL;
+  me->fileOffset += me->curRecordSize;
 
-  if ( unreduced ) strcpy(hoper, "R");
-  else             strcpy(hoper, "D");
+  //Find the next record and determine its size.
+  ssize_t gribFileOffset = scanToGribMarker(me);
+  int result = CDI_EEOF;
+  if(gribFileOffset < 0) goto fail;
+  result = getRecordSize(me, gribFileOffset, &me->curRecordSize);
+  if(result) goto fail;
 
-  FSEC3_MissVal = missval;
+  //Load the whole record into our buffer and create a grib_handle for it.
+  cdiGribIterator_ensureBuffer(me, me->curRecordSize);
+  result = cdiInputFile_read(me->file, gribFileOffset, me->curRecordSize, NULL, me->gribBuffer);
+  if(result) goto fail;
+  me->gribHandle = grib_handle_new_from_message(NULL, me->gribBuffer, me->curRecordSize);
+  result = CDI_EUFSTRUCT;
+  if(!me->gribHandle) goto fail;
 
-  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, data,
-	   gridsize, (int *) gribbuffer, gribsize, &iword, hoper, &iret);
+  return CDI_NOERR;
 
-  if ( ISEC1_Sec2Or3Flag & 64 )
-    *nmiss = ISEC4_NumValues - ISEC4_NumNonMissValues;
-  else
-    *nmiss = 0;
+fail:
+  me->curRecordSize = 0;        //This ensures that we won't jump to an uncontrolled file position if cdiGribIterator_nextField() is called another time after it has returned an error.
+  return result;
+}
 
-  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
-    {
-      double undef_pds, undef_eps;
-      int i;
+int cdiGribIterator_nextField(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-      MCH_get_undef(isec1, &undef_pds, &undef_eps);
+  if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
 
-      *nmiss = 0;
-      for ( i = 0; i < gridsize; i++ )
-        if ( (fabs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
-          data[i] = missval;
-          (*nmiss)++;
-        }
-    }
+  //Get the next GRIB message into our buffer.
+  int result = readMessage(me);
+  if(result) return result;
 
-  return (status);
+  //Get the metadata that's published as variables in the base class.
+  super->datatype = gribGetDatatype(me->gribHandle);
+  super->timesteptype = gribapiGetTsteptype(me->gribHandle);
+  cdiDecodeParam(gribapiGetParam(me->gribHandle), &super->param.number, &super->param.category, &super->param.discipline);
+  grid_t grid;
+  gribapiGetGrid(me->gribHandle, &grid);
+  super->gridId = gridGenerate(&grid);
+
+  return CDI_NOERR;
 }
-#endif
 
+char* cdiGribIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribMakeTimeString(me->gribHandle, getEndTime);
+}
 
-#if  defined  (HAVE_LIBCGRIBEX)
-static
-void cgribexDefInstitut(int *isec1, int vlistID, int varID)
+int cdiGribIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
 {
-  int instID;
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
-    instID = vlistInqInstitut(vlistID);
+  //First determine the zaxis type corresponding to the given level.
+  int zaxisType = ZAXIS_GENERIC;
+  if(gribEditionNumber(me->gribHandle) <= 1)
+    {
+      int levelType = gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", 255);
+      if(levelSelector && !isGrib1DualLevel(levelType)) levelType = 255;
+      zaxisType = grib1ltypeToZaxisType(levelType);
+    }
   else
-    instID = vlistInqVarInstitut(vlistID, varID);
-
-  if ( instID != CDI_UNDEFID )
     {
-      int center, subcenter;
-      center    = institutInqCenter(instID);
-      subcenter = institutInqSubcenter(instID);
-      ISEC1_CenterID    = center;
-      ISEC1_SubCenterID = subcenter;
+      int levelType = gribGetLongDefault(me->gribHandle, levelSelector ? "typeOfSecondFixedSurface" : "typeOfFirstFixedSurface", 255);
+      zaxisType = grib2ltypeToZaxisType(levelType);
     }
+
+  //Then lookup the requested names.
+  const char* name, *longName, *stdName, *unit;
+  zaxisGetTypeDescription(zaxisType, NULL, &name, &longName, &stdName, &unit);
+  if(outName) *outName = myStrDup(name);
+  if(outLongName) *outLongName = myStrDup(longName);
+  if(outStdName) *outStdName = myStrDup(stdName);
+  if(outUnit) *outUnit = myStrDup(unit);
+
+  return zaxisType;
 }
 
-static
-void cgribexDefModel(int *isec1, int vlistID, int varID)
+static double logicalLevelValue2(long gribType, long storedValue, long power)
 {
-  int modelID;
+  double factor = 1;
+  while(power--) factor *= 10;      //this is precise up to factor == 22.
+  switch(gribType)
+    {
+      case GRIB2_LTYPE_LANDDEPTH:
+      case GRIB2_LTYPE_ISOBARIC:
+      case GRIB2_LTYPE_SIGMA:
+        return storedValue*(1000/factor);      //The evaluation order allows the factors of ten to cancel out before rounding.
 
-  if ( vlistInqModel(vlistID) != CDI_UNDEFID )
-    modelID = vlistInqModel(vlistID);
-  else
-    modelID = vlistInqVarModel(vlistID, varID);
+      case 255:
+        return 0;
 
-  if ( modelID != CDI_UNDEFID )
-    ISEC1_ModelID = modelInqGribID(modelID);
+      default:
+        return storedValue/factor;
+    }
 }
 
-static
-void cgribexDefParam(int *isec1, int param)
+//The output values must be preinitialized, this function does not always write them.
+static int readLevel2(grib_handle* gribHandle, const char* levelTypeKey, const char* powerKey, const char* valueKey, double* outValue1, double* outValue2)
 {
-  int pdis, pcat, pnum;
-  static bool lwarn_pdis = true, lwarn_pnum = true;
+  assert(levelTypeKey && powerKey && valueKey && outValue1 && outValue2);
 
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  long levelType = gribGetLongDefault(gribHandle, levelTypeKey, 255);   //1 byte
+  switch(levelType)
+    {
+      case 255: break;
 
-  if ( pnum < 0 ) pnum = -pnum;
+      case 105: case 113:
+        {
+          unsigned long value = (unsigned long)gribGetLongDefault(gribHandle, valueKey, 0);
+          unsigned long coordinateCount = (unsigned long)gribGetLongDefault(gribHandle, "numberOfCoordinatesValues", 0);
+          if(value >= coordinateCount/2)
+            {
+              Error("Invalid level coordinate: Level has the hybrid coordinate index %lu, but only %lu coordinate pairs are present.", value, coordinateCount/2);
+              return CDI_EUFSTRUCT;
+            }
+          int status;
+          //XXX: I'm not 100% sure about how the coordinate pairs are stored in the file.
+          //     I'm assuming an array of pairs due to the example code in grib_api-1.12.3/examples/F90/set_pv.f90, but that may be wrong.
+          if((status = grib_get_double_element(gribHandle, "pv", value*2    , outValue1))) return status;
+          if((status = grib_get_double_element(gribHandle, "pv", value*2 + 1, outValue2))) return status;
+          break;
+        }
 
-  if ( pdis != 255 )
-    {
-      char paramstr[32];
-      cdiParamToString(param, paramstr, sizeof(paramstr));
-      if ( lwarn_pdis )
+      default:
         {
-          Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
-          lwarn_pdis = false;
+          long power = gribGetLongDefault(gribHandle, powerKey, 0);  //1 byte
+          if(power == 255) power = 0;
+          long value = gribGetLongDefault(gribHandle, valueKey, 0);   //4 bytes
+          *outValue1 = logicalLevelValue2(levelType, value, power);
         }
     }
+  return CDI_NOERR;
+}
+
+int cdiGribIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+  *outValue1 = *outValue2 = 0;
 
-  if ( pnum > 255 )
+  if(gribEditionNumber(me->gribHandle) > 1)
     {
-      if ( lwarn_pnum )
+      if(levelSelector)
+        {
+          return readLevel2(me->gribHandle, "typeOfFirstFixedSurface", "scaleFactorOfFirstFixedSurface", "scaledValueOfFirstFixedSurface", outValue1, outValue2);
+        }
+      else
         {
-          Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
-          lwarn_pnum = false;
-          pnum = pnum%256;
+          return readLevel2(me->gribHandle, "typeOfSecondFixedSurface", "scaleFactorOfSecondFixedSurface", "scaledValueOfSecondFixedSurface", outValue1, outValue2);
         }
     }
-
-  ISEC1_CodeTable = pcat;
-  ISEC1_Parameter = pnum;
+  else
+    {
+      long levelType = (uint8_t)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", -1);    //1 byte
+      if(levelType == 255)
+        {}
+      else if(isGrib1DualLevel(levelType))
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0);
+        }
+      else if(levelType == 100)
+        {
+          *outValue1 = 100*gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+      else
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+    }
+  return CDI_NOERR;
 }
 
-static
-int cgribexDefTimerange(int tsteptype, int factor, int calendar,
-			int rdate, int rtime, int vdate, int vtime, int *pip1, int *pip2)
+int cdiGribIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
 {
-  int timerange = -1;
-  int year, month, day, hour, minute, second;
-  int julday1, secofday1, julday2, secofday2, days, secs;
-  int ip, ip1 = 0, ip2 = 0;
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-  cdiDecodeDate(rdate, &year, &month, &day);
-  cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
+  if(outVgridNumber)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "numberOfVGridUsed", &temp)) return CDI_EINVAL;
+      *outVgridNumber = (int)temp;
+    }
+  if(outLevelCount)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "nlev", &temp)) return CDI_EINVAL;
+      *outLevelCount = (int)temp;
+    }
+  if(outUuid)
+    {
+      size_t size = sizeof(*outUuid);
+      if(grib_get_bytes(me->gribHandle, "uuidOfVGrid", *outUuid, &size)) return CDI_EINVAL;
+      if(size != sizeof(*outUuid)) return CDI_EUFSTRUCT;
+    }
 
-  cdiDecodeDate(vdate, &year, &month, &day);
-  cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
+  return CDI_NOERR;
+}
 
-  (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+char* cdiGribIterator_copyVariableName(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribCopyString(me->gribHandle, "shortName");
+}
 
-  if ( !(int) fmod(days*86400.0 + secs, factor) )
-    {
-      ip = (int) ((days*86400.0 + secs)/factor);
+void cdiGribIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-      switch ( tsteptype )
-	{
-	case TSTEP_INSTANT:  timerange =  0; ip1 = ip; ip2 = 0;  break;
-	case TSTEP_INSTANT2: timerange =  1; ip1 = 0;  ip2 = 0;  break;
-	case TSTEP_RANGE:    timerange =  2; ip1 = 0;  ip2 = ip; break;
-	case TSTEP_AVG:      timerange =  3; ip1 = 0;  ip2 = ip; break;
-	case TSTEP_ACCUM:    timerange =  4; ip1 = 0;  ip2 = ip; break;
-	case TSTEP_DIFF:     timerange =  5; ip1 = 0;  ip2 = ip; break;
-	case TSTEP_INSTANT3:
-	default:             timerange = 10; ip1 = ip/256; ip2 = ip%256;  break;
-	}
+  gribGetDoubleArray(me->gribHandle, "values", buffer);
+  long gridType = gribGetLong(me->gribHandle, "gridDefinitionTemplateNumber");
+  if(nmiss)
+    {
+      *nmiss = (gridType >= 50 && gridType <= 53) ? 0 : (int)gribGetLong(me->gribHandle, "numberOfMissing");        //The condition excludes harmonic data.
     }
+}
 
-  *pip1 = ip1;
-  *pip2 = ip2;
+void cdiGribIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
 
-  return (timerange);
+  size_t valueCount = gribGetArraySize(me->gribHandle, "values");
+  double* temp = malloc(valueCount*sizeof(*temp));
+  cdiGribIterator_readField(super, temp, nmiss);
+  for(size_t i = valueCount; i--; ) buffer[i] = temp[i];
+  free(temp);
 }
 
-static
-int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
+/**
+ at Function cdiGribIterator_delete
+ at Title Dispose off a CdiGribIterator instance.
+
+ at Prototype void cdiGribIterator_delete(CdiGribIterator* me)
+ at Parameter
+    @item me The iterator to delete.
+
+ at Description
+    Combined destructor and deallocator. Make sure to match every call to cdiGribIterator_clone() with a call to this function.
+*/
+void cdiGribIterator_delete(CdiGribIterator* me)
 {
-  int year, month, day, hour, minute, second;
-  int century = 0;
-  int factor = 1;
+  if(me) cdiGribIterator_condestruct(me, NULL, 0);
+}
 
-  cdiDecodeDate(date, &year, &month, &day);
-  cdiDecodeTime(time, &hour, &minute, &second);
 
-  century =  year / 100;
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// callthroughs to provide direct access to the grib keys //////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
 
-  ISEC1_Year = year - century*100;
+/**
+ at Function cdiGribIterator_inqEdition
+ at Title Get the version of the GRIB standard that is used
 
-  if ( year < 0 )
-    {
-      century = -century;
-      ISEC1_Year = -ISEC1_Year;
-    }
+ at Prototype int cdiGribIterator_inqEdition(CdiGribIterator* me)
+ at Parameter
+    @item me The iterator to operate on.
 
-  if ( ISEC1_Year == 0 )
-    {
-      century -= 1;
-      ISEC1_Year = 100;
-    }
+ at Result The GRIB version.
 
-  century += 1;
-  if ( year < 0 ) century = -century;
+ at Description
+    Returns the version of the file format.
+*/
+int cdiGribIterator_inqEdition(CdiGribIterator* me)
+{
+  return gribEditionNumber(me->gribHandle);
+}
 
-  ISEC1_Month  = month;
-  ISEC1_Day    = day;
-  ISEC1_Hour   = hour;
-  ISEC1_Minute = minute;
+/**
+ at Function cdiGribIterator_getLong
+ at Title Access to grib_get_long()
 
-  ISEC1_Century = century;
+ at Prototype int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-  switch (timeunit)
-    {
-    case TUNIT_MINUTE:    factor =    60; ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE;    break;
-    case TUNIT_QUARTER:   factor =   900; ISEC1_TimeUnit = ISEC1_TABLE4_QUARTER;   break;
-    case TUNIT_30MINUTES: factor =  1800; ISEC1_TimeUnit = ISEC1_TABLE4_30MINUTES; break;
-    case TUNIT_HOUR:      factor =  3600; ISEC1_TimeUnit = ISEC1_TABLE4_HOUR;      break;
-    case TUNIT_3HOURS:    factor = 10800; ISEC1_TimeUnit = ISEC1_TABLE4_3HOURS;    break;
-    case TUNIT_6HOURS:    factor = 21600; ISEC1_TimeUnit = ISEC1_TABLE4_6HOURS;    break;
-    case TUNIT_12HOURS:   factor = 43200; ISEC1_TimeUnit = ISEC1_TABLE4_12HOURS;   break;
-    case TUNIT_DAY:       factor = 86400; ISEC1_TimeUnit = ISEC1_TABLE4_DAY;       break;
-    default:              factor =  3600; ISEC1_TimeUnit = ISEC1_TABLE4_HOUR;      break;
-    }
+ at Result An error code.
 
-  return (factor);
+ at Description
+    Callthrough to grib_get_long().
+*/
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+{
+  return grib_get_long(me->gribHandle, key, result);
 }
 
-static
-void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg, int taxisID)
+/**
+ at Function cdiGribIterator_getLength
+ at Title Access to grib_get_length()
+
+ at Prototype int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_length().
+*/
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
 {
-  int timetype = TAXIS_ABSOLUTE;
-  int timerange = 0;
-  int timeunit = TUNIT_HOUR;
+  return grib_get_length(me->gribHandle, key, result);
+}
 
-  if ( taxisID != -1 )
-    {
-      timetype = taxisInqType(taxisID);
-      timeunit = taxisInqTunit(taxisID);
-    }
+/**
+ at Function cdiGribIterator_getString
+ at Title Access to grib_get_string()
 
-  if ( timetype == TAXIS_RELATIVE )
-    {
-      int factor = 1;
-      int rdate, rtime;
-      int ip1 = 0, ip2 = 0;
-      int calendar;
+ at Prototype int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-      calendar = taxisInqCalendar(taxisID);
-      rdate    = taxisInqRdate(taxisID);
-      rtime    = taxisInqRtime(taxisID);
+ at Result An error code.
 
-      factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
+ at Description
+    Callthrough to grib_get_string().
+*/
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+{
+  return grib_get_string(me->gribHandle, key, result, length);
+}
 
-      timerange = cgribexDefTimerange(tsteptype, factor, calendar,
-				      rdate, rtime, vdate, vtime, &ip1, &ip2);
+/**
+ at Function cdiGribIterator_inqLongValue
+ at Title Get the value of a GRIB-API key as a long
 
-      if ( timerange == -1 || timerange == 3 )
-	{
-	  timetype = TAXIS_ABSOLUTE;
-	}
-      /*
-      else if ( timerange == 10 )
-	{
-	  if ( ip1 < 0 || ip1 > 0xFFFF ) timetype = TAXIS_ABSOLUTE;
-	  if ( ip2 < 0 || ip2 > 0xFFFF ) timetype = TAXIS_ABSOLUTE;
-	}
-      */
-      else
-	{
-	  if ( ip1 < 0 || ip1 > 0xFF   ) timetype = TAXIS_ABSOLUTE;
-	  if ( ip2 < 0 || ip2 > 0xFF   ) timetype = TAXIS_ABSOLUTE;
-	}
+ at Prototype long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
 
-      ISEC1_TimeRange   = timerange;
-      ISEC1_TimePeriod1 = ip1;
-      ISEC1_TimePeriod2 = ip2;
-    }
+ at Result The value of the key.
 
-  if ( timetype == TAXIS_ABSOLUTE )
-    {
-      (void) cgribexDefDateTime(isec1, timeunit, vdate, vtime);
+ at Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetLong(me->gribHandle, key);
+}
 
-      /*
-      if ( numavg > 0 )
-	ISEC1_TimeRange = 0;
-      else
-      */
-      if ( ISEC1_TimeRange != 3 )
-	ISEC1_TimeRange   = 10;
+/**
+ at Function cdiGribIterator_inqLongDefaultValue
+ at Title Get the value of a GRIB-API key as a long
 
-      ISEC1_TimePeriod1 = 0;
-      ISEC1_TimePeriod2 = 0;
-    }
+ at Prototype long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
 
-  ISEC1_AvgNum         = numavg;
-  ISEC1_AvgMiss        = 0;
-  ISEC1_DecScaleFactor = 0;
+ at Result The value of the key or the given default value.
+
+ at Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+{
+  return gribGetLongDefault(me->gribHandle, key, defaultValue);
 }
 
-static
-void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
+/**
+ at Function cdiGribIterator_inqStringValue
+ at Title Safely retrieve a GRIB-API key with a string value
+
+ at Prototype char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+ at Result A malloc'ed string or NULL.
+
+ at Description
+    This will first call grib_get_length() to inquire the actual size of the string,
+    allocate memory accordingly, call grib_get_string(), and return the pointer to the new string.
+    Returns NULL on failure.
+*/
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
 {
-  int gridtype;
-  bool lcurvi = false;
-  static bool lwarning = true;
+  return gribCopyString(me->gribHandle, key);
+}
 
-  memset(isec2, 0, 16*sizeof(int));
+/**
+ at Function cdiGribIterator_getDouble
+ at Title Access to grib_get_double()
 
-  ISEC1_Sec2Or3Flag = 128;
+ at Prototype int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-  gridtype = gridInqType(gridID);
+ at Result An error code.
 
-  ISEC1_GridDefinition = 255;
+ at Description
+    Callthrough to grib_get_double().
+*/
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+{
+  return grib_get_double(me->gribHandle, key, result);
+}
 
-  if ( gridtype == GRID_GENERIC )
-    {
-      int xsize, ysize, gridsize;
+/**
+ at Function cdiGribIterator_getSize
+ at Title Access to grib_get_size()
 
-      gridsize = gridInqSize(gridID);
-      xsize = gridInqXsize(gridID);
-      ysize = gridInqYsize(gridID);
+ at Prototype int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-      if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
-	    ysize ==  96 || ysize == 160 || ysize == 192 ||
-	    ysize == 240 || ysize == 320 || ysize == 384 ||
-	    ysize == 480 || ysize == 768 ) &&
-	   (xsize == 2*ysize || xsize == 1) )
-	{
-	  gridtype = GRID_GAUSSIAN;
-	  gridChangeType(gridID, gridtype);
-	}
-      else if ( gridsize == 1 )
-	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
-	}
-      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
-	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
-	}
-    }
-  else if ( gridtype == GRID_CURVILINEAR )
-    {
-      if ( lwarning && gridInqSize(gridID) > 1 )
-	{
-	  lwarning = false;
-	  Warning("Curvilinear grids are unsupported in GRIB1! Created wrong GDS!");
-	}
-      gridtype = GRID_LONLAT;
-      lcurvi = true;
-    }
+ at Result An error code.
 
-  ISEC2_Reduced  = FALSE;
-  ISEC2_ScanFlag = 0;
+ at Description
+    Callthrough to grib_get_size().
+*/
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+{
+  return grib_get_size(me->gribHandle, key, result);
+}
 
-  switch (gridtype)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_GAUSSIAN_REDUCED:
-    case GRID_TRAJECTORY:
-      {
-	int nlon = 0, nlat;
-	double xfirst = 0, xlast = 0, xinc = 0;
-	double yfirst = 0, ylast = 0, yinc = 0;
+/**
+ at Function cdiGribIterator_getLongArray
+ at Title Access to grib_get_long_array()
 
-	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
-          ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN;
-        else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
-	  ISEC2_GridType = GRIB1_GTYPE_LATLON_ROT;
-	else
-	  ISEC2_GridType = GRIB1_GTYPE_LATLON;
+ at Prototype int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-	nlon = gridInqXsize(gridID);
-	nlat = gridInqYsize(gridID);
+ at Result An error code.
 
-	if ( gridtype == GRID_GAUSSIAN_REDUCED )
-	  {
-	    ISEC2_Reduced = TRUE;
-	    nlon = 0;
-	    gridInqRowlon(gridID, ISEC2_RowLonPtr);
-	  }
-	else
-	  {
-	    if ( nlon == 0 )
-	      {
-		nlon = 1;
-	      }
-	    else
-	      {
-		xfirst = gridInqXval(gridID,      0);
-		if ( lcurvi )
-		  xlast  = gridInqXval(gridID, nlon*nlat-1);
-		else
-		  xlast  = gridInqXval(gridID, nlon-1);
-		xinc   = gridInqXinc(gridID);
-	      }
-	  }
+ at Description
+    Callthrough to grib_get_long_array().
+*/
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+{
+  return grib_get_long_array(me->gribHandle, key, result, size);
+}
 
-	if ( nlat == 0 )
-	  {
-	    nlat = 1;
-	  }
-	else
-	  {
-	    yfirst = gridInqYval(gridID,      0);
-	    if ( lcurvi )
-	      ylast  = gridInqYval(gridID, nlon*nlat-1);
-	    else
-	      ylast  = gridInqYval(gridID, nlat-1);
-	    yinc   = gridInqYinc(gridID);
-	    if ( yinc < 0 ) yinc = -yinc;
-	  }
+/**
+ at Function cdiGribIterator_getDoubleArray
+ at Title Access to grib_get_double_array()
 
-	ISEC2_NumLon   = nlon;
-	ISEC2_NumLat   = nlat;
-	ISEC2_FirstLat = (int)lround(yfirst*1000);
-	ISEC2_LastLat  = (int)lround(ylast*1000);
-	if ( gridtype == GRID_GAUSSIAN_REDUCED )
-	  {
-	    ISEC2_FirstLon = 0;
-	    ISEC2_LastLon  = (int)lround(1000*(360.-360./(nlat*2)));
-	    ISEC2_LonIncr  = (int)lround(1000*360./(nlat*2));
-	  }
-	else
-	  {
-	    ISEC2_FirstLon = (int)lround(xfirst*1000);
-	    ISEC2_LastLon  = (int)lround(xlast*1000);
-	    ISEC2_LonIncr  = (int)lround(xinc*1000);
-	  }
+ at Prototype int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
 
-	// if ( fabs(xinc*1000 - ISEC2_LonIncr) > FLT_EPSILON ) ISEC2_LonIncr = 0;
+ at Result An error code.
 
-	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
-          {
-            int np = gridInqNP(gridID);
-            if ( np == 0 ) np = nlat/2;
-            ISEC2_NumPar = np;
-          }
-	else
-	  {
-	    ISEC2_LatIncr = (int)lround(yinc*1000);
-	    // if ( fabs(yinc*1000 - ISEC2_LatIncr) > FLT_EPSILON ) ISEC2_LatIncr = 0;
+ at Description
+    Callthrough to grib_get_double_array().
+*/
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+{
+  return grib_get_double_array(me->gribHandle, key, result, size);
+}
 
-	    if ( ISEC2_LatIncr < 0 ) ISEC2_LatIncr = -ISEC2_LatIncr;
-	  }
+/**
+ at Function cdiGribIterator_inqDoubleValue
+ at Title Get the value of a GRIB-API key as a double
 
-	if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
-	  if ( ISEC2_LonIncr != 0 && ISEC2_LatIncr == 0 ) ISEC2_LatIncr = ISEC2_LonIncr;
+ at Prototype double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
 
-	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
-	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
+ at Result The value of the key.
 
-	if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
-	  ISEC2_ResFlag = 0;
-	else
-	  ISEC2_ResFlag = 128;
+ at Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetDouble(me->gribHandle, key);
+}
 
-	if ( gridIsRotated(gridID) )
-	  {
-	    ISEC2_LatSP = - (int)lround(gridInqYpole(gridID) * 1000);
-	    ISEC2_LonSP =   (int)lround((gridInqXpole(gridID) + 180) * 1000);
-	  }
+/**
+ at Function cdiGribIterator_inqDoubleDefaultValue
+ at Title Get the value of a GRIB-API key as a double
+
+ at Prototype double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
+
+ at Result The value of the key or the given default value.
+
+ at Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+{
+  return gribGetDoubleDefault(me->gribHandle, key, defaultValue);
+}
+
+#endif
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <limits.h>
+
+
+#undef  UNDEFID
+#define UNDEFID -1
 
-	/* East -> West */
-	if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
+int ECHAM4 = UNDEFID;
+int ECHAM5 = UNDEFID;
+int COSMO  = UNDEFID;
 
-	/* South -> North */
-	if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
+typedef struct
+{
+  int      self;
+  int      used;
+  int      instID;
+  int      modelgribID;
+  char    *name;
+}
+model_t;
 
-	break;
-      }
-    case GRID_LCC:
-      {
-	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
-	int xsize, ysize;
-	int projflag, scanflag;
 
-	xsize = gridInqXsize(gridID);
-	ysize = gridInqYsize(gridID);
+static int  MODEL_Debug = 0;   /* If set to 1, debugging */
 
-	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
-		   &projflag, &scanflag);
+static void modelInit(void);
 
-	ISEC2_GridType = GRIB1_GTYPE_LCC;
-	ISEC2_NumLon   = xsize;
-	ISEC2_NumLat   = ysize;
-	ISEC2_FirstLon = (int)lround(originLon * 1000);
-	ISEC2_FirstLat = (int)lround(originLat * 1000);
-	ISEC2_Lambert_Lov    = (int)lround(lonParY * 1000);
-	ISEC2_Lambert_LatS1  = (int)lround(lat1 * 1000);
-	ISEC2_Lambert_LatS2  = (int)lround(lat2 * 1000);
-	ISEC2_Lambert_dx     = (int)lround(xincm);
-	ISEC2_Lambert_dy     = (int)lround(yincm);
-	ISEC2_Lambert_LatSP  = 0;
-	ISEC2_Lambert_LatSP  = 0;
-	ISEC2_Lambert_ProjFlag = projflag;
-	ISEC2_ScanFlag = scanflag;
 
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	ISEC2_GridType = GRIB1_GTYPE_SPECTRAL;
-	ISEC2_PentaJ   = gridInqTrunc(gridID);
-	ISEC2_PentaK   = ISEC2_PentaJ;
-	ISEC2_PentaM   = ISEC2_PentaJ;
-	ISEC2_RepType  = 1;
-	isec4[2]       = 128;
-	if ( gridInqComplexPacking(gridID) && ISEC2_PentaJ >= 21 )
-	  {
-	    ISEC2_RepMode  = 2;
-	    isec4[3]       = 64;
-	    isec4[16]      = 0;
-	    isec4[17]      = 20;
-	    isec4[18]      = 20;
-	    isec4[19]      = 20;
-	  }
-	else
-	  {
-	    ISEC2_RepMode  = 1;
-	    isec4[3]       = 0;
-	  }
-	break;
-      }
-    case GRID_GME:
-      {
-	ISEC2_GridType   = GRIB1_GTYPE_GME;
-	ISEC2_GME_ND     = gridInqGMEnd(gridID);
-	ISEC2_GME_NI     = gridInqGMEni(gridID);
-	ISEC2_GME_NI2    = gridInqGMEni2(gridID);
-	ISEC2_GME_NI3    = gridInqGMEni3(gridID);
-	ISEC2_GME_AFlag  = 0;
-	ISEC2_GME_LatPP  = 90000;
-	ISEC2_GME_LonPP  = 0;
-	ISEC2_GME_LonMPL = 0;
-	ISEC2_GME_BFlag  = 0;
-	break;
-      }
-    default:
-      {
-	Warning("The CGRIBEX library can not store fields on the used grid!");
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-	break;
-      }
-    }
-}
+static int modelCompareP(void *modelptr1, void *modelptr2);
+static void   modelDestroyP ( void * modelptr );
+static void   modelPrintP   ( void * modelptr, FILE * fp );
+static int    modelGetSizeP ( void * modelptr, void *context);
+static void   modelPackP    ( void * modelptr, void * buff, int size,
+                              int *position, void *context);
+static int    modelTxCode   ( void );
+
+static const resOps modelOps = {
+  modelCompareP,
+  modelDestroyP,
+  modelPrintP,
+  modelGetSizeP,
+  modelPackP,
+  modelTxCode
+};
 
 static
-void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int levelID)
+void modelDefaultValue ( model_t *modelptr )
 {
-  double level;
-  int ilevel, zaxistype, ltype;
-  static bool lwarning = true;
-  static bool lwarning_vct = true;
+  modelptr->self        = UNDEFID;
+  modelptr->used        = 0;
+  modelptr->instID      = UNDEFID;
+  modelptr->modelgribID = UNDEFID;
+  modelptr->name        = NULL;
+}
 
-  zaxistype = zaxisInqType(zaxisID);
-  ltype = zaxisInqLtype(zaxisID);
+static model_t *
+modelNewEntry(cdiResH resH, int instID, int modelgribID, const char *name)
+{
+  model_t *modelptr;
 
-  if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
+  modelptr = (model_t *) xmalloc(sizeof(model_t));
+  modelDefaultValue ( modelptr );
+  if (resH == CDI_UNDEFID)
+    modelptr->self = reshPut(modelptr, &modelOps);
+  else
     {
-      Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(zaxistype),
-	      zaxisNamePtr(ZAXIS_PRESSURE));
-      zaxistype = ZAXIS_PRESSURE;
-      zaxisChangeType(zaxisID, zaxistype);
-      zaxisDefUnits(zaxisID, "Pa");
+      modelptr->self = resH;
+      reshReplace(resH, modelptr, &modelOps);
     }
+  modelptr->used = 1;
+  modelptr->instID = instID;
+  modelptr->modelgribID = modelgribID;
+  if ( name && *name ) modelptr->name = strdupx(name);
 
-  ISEC2_NumVCP = 0;
-
-  switch (zaxistype)
-    {
-    case ZAXIS_SURFACE:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_SURFACE;
-	ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_CLOUD_BASE:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_CLOUD_BASE;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_CLOUD_TOP:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_CLOUD_TOP;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_ISOTHERM_ZERO:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_ISOTHERM0;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_TOA:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_TOA;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_SEA_BOTTOM:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_SEA_BOTTOM;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_ATMOSPHERE:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_ATMOSPHERE;
-	ISEC1_Level1    = 0;
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_MEANSEA:
-      {
-	ISEC1_LevelType = GRIB1_LTYPE_MEANSEA;
-	ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
-	ISEC1_Level2    = 0;
-	break;
-      }
-    case ZAXIS_HYBRID:
-    case ZAXIS_HYBRID_HALF:
-      {
-	int vctsize;
-
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-	  {
-	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID_LAYER;
-	    ISEC1_Level1    = (int) zaxisInqLbound(zaxisID, levelID);
-	    ISEC1_Level2    = (int) zaxisInqUbound(zaxisID, levelID);
-	  }
-	else
-	  {
-	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID;
-	    ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
-	    ISEC1_Level2    = 0;
-	  }
+  return (modelptr);
+}
 
-	vctsize = zaxisInqVctSize(zaxisID);
-	if ( vctsize == 0 && lwarning )
-	  {
-	    Warning("VCT missing. ( param = %d, zaxisID = %d )", ISEC1_Parameter, zaxisID);
-	    lwarning = false;
-	  }
-	if ( vctsize > 255 )
-	  {
-	    ISEC2_NumVCP = 0;
-	    if ( lwarning_vct )
-	      {
-		Warning("VCT size of %d is too large (maximum is 255). Set to 0!", vctsize);
-		lwarning_vct = false;
-	      }
-	  }
-	else
-	  {
-	    ISEC2_NumVCP = vctsize;
-	    zaxisInqVct(zaxisID, &fsec2[10]);
-	  }
-	break;
-      }
-    case ZAXIS_PRESSURE:
-      {
-	double dum;
-	char units[128];
+void modelDefaultEntries ( void )
+{
+  int instID, i;
+  enum { nDefModels = 10 };
+  cdiResH resH[nDefModels];
 
-	level = zaxisInqLevel(zaxisID, levelID);
-	if ( level < 0 )
-	  Warning("Pressure level of %f Pa is below zero!", level);
+  instID  = institutInq(  0,   0, "ECMWF", NULL);
+  /* (void)    modelDef(instID, 131, "ERA15"); */
+  /* (void)    modelDef(instID, 199, "ERA40"); */
+  instID  = institutInq(  0,   0, "MPIMET", NULL);
 
-	zaxisInqUnits(zaxisID, units);
-	if ( memcmp(units, "Pa", 2) != 0 ) level *= 100;
+  resH[0] = ECHAM5  = modelDef(instID,  64, "ECHAM5.4");
+  resH[1] = modelDef(instID,  63, "ECHAM5.3");
+  resH[2] = modelDef(instID,  62, "ECHAM5.2");
+  resH[3] = modelDef(instID,  61, "ECHAM5.1");
 
-	ilevel = (int) level;
-	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-	  {
-	    ISEC1_LevelType = GRIB1_LTYPE_99;
-	    ISEC1_Level1    = ilevel;
-	    ISEC1_Level2    = 0;
-	  }
-	else
-	  {
-	    ISEC1_LevelType = GRIB1_LTYPE_ISOBARIC;
-	    ISEC1_Level1    = ilevel/100;
-	    ISEC1_Level2    = 0;
-	  }
-	break;
-      }
-    case ZAXIS_HEIGHT:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+  instID  = institutInq( 98, 255, "MPIMET", NULL);
+  resH[4] = modelDef(instID,  60, "ECHAM5.0");
+  resH[5] = ECHAM4  = modelDef(instID,  50, "ECHAM4");
+  resH[6] = modelDef(instID, 110, "MPIOM1");
 
-	ilevel = (int) level;
-	ISEC1_LevelType = GRIB1_LTYPE_HEIGHT;
-	ISEC1_Level1    = ilevel;
-	ISEC1_Level2    = 0;
+  instID  = institutInq(  0,   0, "DWD", NULL);
+  resH[7] = modelDef(instID, 149, "GME");
 
-	break;
-      }
-    case ZAXIS_ALTITUDE:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+  instID  = institutInq(  0,   0, "MCH", NULL);
+  //(void)  = modelDef(instID, 137, "COSMO");
+  resH[8] = COSMO   = modelDef(instID, 255, "COSMO");
 
-	ilevel = (int) level;
-	ISEC1_LevelType = GRIB1_LTYPE_ALTITUDE;
-	ISEC1_Level1    = ilevel;
-	ISEC1_Level2    = 0;
+  instID  = institutInq(  0,   1, "NCEP", NULL);
+  resH[9] = modelDef(instID,  80, "T62L28MRF");
 
-	break;
-      }
-    case ZAXIS_SIGMA:
-      {
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-	  {
-	    ISEC1_LevelType = GRIB1_LTYPE_SIGMA_LAYER;
-	    ISEC1_Level1    = (int) zaxisInqLbound(zaxisID, levelID);
-	    ISEC1_Level2    = (int) zaxisInqUbound(zaxisID, levelID);
-	  }
-	else
-	  {
-            level = zaxisInqLevel(zaxisID, levelID);
+  /* pre-defined models are not synchronized */
+  for ( i = 0; i < nDefModels ; i++ )
+    reshSetStatus(resH[i], &modelOps, RESH_IN_USE);
+}
 
-            ilevel = (int) level;
-            ISEC1_LevelType = GRIB1_LTYPE_SIGMA;
-            ISEC1_Level1    = ilevel;
-            ISEC1_Level2    = 0;
-          }
+static
+void modelInit(void)
+{
+  static int modelInitialized = 0;
 
-	break;
-      }
-    case ZAXIS_DEPTH_BELOW_LAND:
-      {
-	char units[128];
-	double factor;
+  if (modelInitialized) return;
 
-	zaxisInqUnits(zaxisID, units);
+  modelInitialized = 1;
+  char *env = getenv("MODEL_DEBUG");
+  if ( env ) MODEL_Debug = atoi(env);
+}
 
-        if      ( memcmp(units, "mm", 2) == 0 ) factor =   0.1;
-        else if ( memcmp(units, "cm", 2) == 0 ) factor =   1;
-        else if ( memcmp(units, "dm", 2) == 0 ) factor =  10;
-        else                                    factor = 100; // meter
+struct modelLoc
+{
+  char *name;
+  int instID, modelgribID, resID;
+};
 
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-	  {
-            double level1, level2;
-            level1 = zaxisInqLbound(zaxisID, levelID);
-            level2 = zaxisInqUbound(zaxisID, levelID);
-	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH_LAYER;
-	    ISEC1_Level1    = (int) (level1*factor);
-	    ISEC1_Level2    = (int) (level2*factor);
-	  }
-	else
-	  {
-	    level = zaxisInqLevel(zaxisID, levelID);
+static enum cdiApplyRet
+findModelByID(int resID, void *res, void *data)
+{
+  model_t *modelptr = (model_t*) res;
+  struct modelLoc *ret = (struct modelLoc*) data;
+  int instID = ret->instID, modelgribID = ret->modelgribID;
+  if (modelptr->used
+      && modelptr->instID == instID
+      && modelptr->modelgribID == modelgribID)
+    {
+      ret->resID = resID;
+      return CDI_APPLY_STOP;
+    }
+  else
+    return CDI_APPLY_GO_ON;
+}
 
-	    ilevel = (int) (level*factor);
-	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH;
-	    ISEC1_Level1    = ilevel;
-	    ISEC1_Level2    = 0;
-	  }
+static enum cdiApplyRet
+findModelByName(int resID, void *res, void *data)
+{
+  model_t *modelptr = (model_t*) res;
+  struct modelLoc *ret = (struct modelLoc*) data;
+  int instID = ret->instID, modelgribID = ret->modelgribID;
+  const char *name = ret->name;
+  if (modelptr->used
+      && (instID == -1 || modelptr->instID == instID)
+      && (modelgribID == 0 || modelptr->modelgribID == modelgribID)
+      && modelptr->name)
+    {
+      const char *p = name, *q = modelptr->name;
+      while (*p != '\0' && *p == *q)
+        ++p, ++q;
+      if (*p == '\0' || *q == '\0')
+        {
+          ret->resID = resID;
+          return CDI_APPLY_STOP;
+        }
+    }
+  return CDI_APPLY_GO_ON;
+}
 
-	break;
-      }
-    case ZAXIS_DEPTH_BELOW_SEA:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+int modelInq(int instID, int modelgribID, char *name)
+{
+  modelInit ();
 
-	ilevel = (int) level;
-	ISEC1_LevelType = GRIB1_LTYPE_SEADEPTH;
-	ISEC1_Level1    = ilevel;
-	ISEC1_Level2    = 0;
+  struct modelLoc searchState = { .name = name, .instID = instID,
+                                  .modelgribID = modelgribID,
+                                  .resID = UNDEFID };
+  if (name && *name)
+    cdiResHFilterApply(&modelOps, findModelByName, &searchState);
+  else
+    cdiResHFilterApply(&modelOps, findModelByID, &searchState);
+  return searchState.resID;
+}
 
-	break;
-      }
-    case ZAXIS_ISENTROPIC:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
 
-	ilevel = (int) level;
-	ISEC1_LevelType = GRIB1_LTYPE_ISENTROPIC;
-	ISEC1_Level1    = ilevel;
-	ISEC1_Level2    = 0;
+int modelDef(int instID, int modelgribID, const char *name)
+{
+  model_t *modelptr;
 
-	break;
-      }
-    case ZAXIS_GENERIC:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+  modelInit ();
 
-	ilevel = (int) level;
-	ISEC1_LevelType = ltype;
-	ISEC1_Level1    = ilevel;
-	ISEC1_Level2    = 0;
+  modelptr = modelNewEntry(CDI_UNDEFID, instID, modelgribID, name);
 
-	break;
-      }
-    default:
-      {
-	Error("Unsupported zaxis type: %s", zaxisNamePtr(zaxistype));
-	break;
-      }
-    }
+  return modelptr->self;
 }
 
-static
-void cgribexDefaultSec0(int *isec0)
-{
-  ISEC0_GRIB_Len     = 0;
-  ISEC0_GRIB_Version = 0;
-}
 
-static
-void cgribexDefaultSec1(int *isec1)
+int modelInqInstitut(int modelID)
 {
-  ISEC1_CenterID    = 0;
-  ISEC1_SubCenterID = 0;
-  ISEC1_LocalFLag   = 0;
+  model_t *modelptr = NULL;
+
+  modelInit ();
+
+  if ( modelID != UNDEFID )
+    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+
+  return modelptr ? modelptr->instID : UNDEFID;
 }
 
-static
-void cgribexDefaultSec4(int *isec4)
+
+int modelInqGribID(int modelID)
 {
-  long i;
+  model_t *modelptr = NULL;
 
-  for ( i = 2; i <= 10; ++i ) isec4[i] = 0;
+  modelInit ();
+
+  if ( modelID != UNDEFID )
+    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+
+  return modelptr ? modelptr->modelgribID : UNDEFID;
 }
 
-static
-void cgribexDefEnsembleVar(int *isec1, int vlistID, int varID)
+
+const char *modelInqNamePtr(int modelID)
 {
-  int ensID, ensCount, forecast_type;
+  model_t *modelptr = NULL;
+
+  modelInit ();
+
+  if ( modelID != UNDEFID )
+    modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
+
+  return modelptr ? modelptr->name : NULL;
+}
 
-  /* For Ensemble info  */
 
-  //Put1Byte(isec1[36]);        /* MPIM local GRIB use definition identifier  */
-                                /*    (extension identifier)                  */
-  //Put1Byte(isec1[37]);        /* type of ensemble forecast                  */
-  //Put2Byte(isec1[38]);        /* individual ensemble member                 */
-  //Put2Byte(isec1[39]);        /* number of forecasts in ensemble            */
+static int
+modelCompareP(void *modelptr1, void *modelptr2)
+{
+  model_t *model1 = modelptr1, *model2 = modelptr2;
+  int diff = (namespaceResHDecode(model1->instID).idx
+              != namespaceResHDecode(model2->instID).idx)
+    | (model1->modelgribID != model2->modelgribID)
+    | (strcmp(model1->name, model2->name) != 0);
+  return diff;
+}
 
-  if ( vlistInqVarEnsemble(vlistID, varID, &ensID, &ensCount, &forecast_type) )
-    {
-      if ( ISEC1_CenterID == 252 )
-        {
-          ISEC1_LocalFLag = 1;
-          isec1[36] = 1;
 
-          isec1[37] =  forecast_type;
-          isec1[38] =  ensID;
-          isec1[39] =  ensCount;
-        }
-    }
+void modelDestroyP ( void * modelptr )
+{
+  model_t *mp = (model_t*) modelptr;
+  if (mp->name)
+    free(mp->name);
+  free(mp);
 }
-#endif
 
 
-#if  defined  (HAVE_LIBCGRIBEX)
-size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		     int vdate, int vtime, int tsteptype, int numavg,
-		     long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize)
+void modelPrintP   ( void * modelptr, FILE * fp )
 {
-  size_t nbytes = 0;
-  int gribsize;
-  int iret = 0, iword = 0;
-  int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
-  float fsec2f[512], fsec3f[2];
-  double fsec2[512], fsec3[2];
-  int datatype;
-  int param;
+  model_t *mp = (model_t*) modelptr;
 
-  memset(isec1, 0, 256*sizeof(int));
-  fsec2[0] = 0; fsec2[1] = 0;
-  fsec2f[0] = 0; fsec2f[1] = 0;
+  if ( !mp ) return;
 
-  gribsize = (int)(gribbuffersize / sizeof(int));
-  param    = vlistInqVarParam(vlistID, varID);
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "# modelID %d\n", mp->self);
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "self          = %d\n", mp->self );
+  fprintf ( fp, "used          = %d\n", mp->used );
+  fprintf ( fp, "instID        = %d\n", mp->instID );
+  fprintf ( fp, "modelgribID   = %d\n", mp->modelgribID );
+  fprintf ( fp, "name          = %s\n", mp->name ? mp->name : "NN" );
+}
 
-  cgribexDefaultSec0(isec0);
-  cgribexDefaultSec1(isec1);
-  cgribexDefaultSec4(isec4);
 
-  cgribexDefInstitut(isec1, vlistID, varID);
-  cgribexDefModel(isec1, vlistID, varID);
+static int
+modelTxCode ( void )
+{
+  return MODEL;
+}
 
-  datatype = vlistInqVarDatatype(vlistID, varID);
+enum {
+  model_nints = 4,
+};
 
-  cgribexDefParam(isec1, param);
-  cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
-  cgribexDefGrid(isec1, isec2, isec4, gridID);
-  cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID);
 
-  cgribexDefEnsembleVar(isec1, vlistID, varID);
+static int modelGetSizeP(void * modelptr, void *context)
+{
+  model_t *p = (model_t*)modelptr;
+  size_t txsize = (size_t)serializeGetSize(model_nints, DATATYPE_INT, context)
+    + (size_t)serializeGetSize(p->name?(int)strlen(p->name) + 1:0, DATATYPE_TXT, context);
+  xassert(txsize <= INT_MAX);
+  return (int)txsize;
+}
 
-  ISEC4_NumValues = gridInqSize(gridID);
-  ISEC4_NumBits   = grbBitsPerValue(datatype);
 
-  if ( nmiss > 0 )
-    {
-      FSEC3_MissVal = vlistInqVarMissval(vlistID, varID);
-      ISEC1_Sec2Or3Flag |= 64;
-    }
+static void modelPackP(void * modelptr, void * buf, int size, int *position, void *context)
+{
+  model_t *p = (model_t*) modelptr;
+  int tempbuf[model_nints];
+  tempbuf[0] = p->self;
+  tempbuf[1] = p->instID;
+  tempbuf[2] = p->modelgribID;
+  tempbuf[3] = p->name ? (int)strlen(p->name) + 1 : 0;
+  serializePack(tempbuf, model_nints, DATATYPE_INT, buf, size, position, context);
+  if (p->name)
+    serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
+}
 
-  if ( isec4[2] == 128 && isec4[3] == 64 )
+int
+modelUnpack(void *buf, int size, int *position, int originNamespace, void *context,
+            int force_id)
+{
+  int tempbuf[model_nints];
+  char *name;
+  serializeUnpack(buf, size, position, tempbuf, model_nints, DATATYPE_INT, context);
+  if (tempbuf[3] != 0)
     {
-      isec4[16] = (int) (1000*calculate_pfactor(data, ISEC2_PentaJ, isec4[17]));
-      if ( isec4[16] < -10000 ) isec4[16] = -10000;
-      if ( isec4[16] >  10000 ) isec4[16] =  10000;
+      name = (char *)xmalloc((size_t)tempbuf[3]);
+      serializeUnpack(buf, size, position,
+                      name, tempbuf[3], DATATYPE_TXT, context);
     }
-  //printf("isec4[16] %d\n", isec4[16]);
-
-  if ( memtype == MEMTYPE_FLOAT )
+  else
     {
-      size_t numVCP = ISEC2_NumVCP > 0 ? (size_t)ISEC2_NumVCP : (size_t)0;
-      for ( size_t i = 0; i < numVCP; ++i ) fsec2f[10+i] = (float)fsec2[10+i];
-      fsec3f[ 1] = (float)fsec3[ 1];
+      name = "";
     }
-
-  if ( memtype == MEMTYPE_FLOAT )
-    gribExSP(isec0, isec1, isec2, fsec2f, isec3, fsec3f, isec4, (float*) data,
-             (int)datasize, (int *) gribbuffer, gribsize, &iword, "C", &iret);
-  else
-    gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, (double*) data,
-             (int)datasize, (int *) gribbuffer, gribsize, &iword, "C", &iret);
-
-  if ( iret ) Error("Problem during GRIB encode (errno = %d)!", iret);
-
-  nbytes = (size_t)iword * sizeof (int);
-  return (nbytes);
+  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
+  model_t *mp = modelNewEntry(force_id?targetID:CDI_UNDEFID,
+                              namespaceAdaptKey(tempbuf[1], originNamespace),
+                              tempbuf[2], name);
+  if (tempbuf[3] != 0)
+    free(name);
+  xassert(!force_id
+          || (mp->self == namespaceAdaptKey(tempbuf[0], originNamespace)));
+  return mp->self;
 }
-#endif
+
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -30075,15567 +32415,15775 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
 #if defined (HAVE_CONFIG_H)
 #endif
 
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
+
+#include <limits.h>
+#include <stdlib.h>
 #include <stdio.h>
 
 
+static unsigned nNamespaces = 1;
+static int activeNamespace = 0;
 
-#if  defined  (HAVE_LIBGRIB_API)
-#endif
+#ifdef HAVE_LIBNETCDF
+#define CDI_NETCDF_SWITCHES                     \
+  { .func = (void (*)()) nc__create },          \
+  { .func = (void (*)()) cdf_def_var_serial },  \
+  { .func = (void (*)()) cdfDefTimestep },      \
+  { .func = (void (*)()) cdfDefVars }
 
-extern int cdiInventoryMode;
+#else
+#define CDI_NETCDF_SWITCHES
+#endif
 
-typedef struct {
-  int param;
-  int level1;
-  int level2;
-  int ltype;
-  int tsteptype;
-  char name[32];
-} compvar2_t;
+#define defaultSwitches {                                   \
+    { .func = (void (*)()) cdiAbortC_serial },              \
+    { .func = (void (*)()) cdiWarning },                    \
+    { .func = (void (*)()) serializeGetSizeInCore },        \
+    { .func = (void (*)()) serializePackInCore },           \
+    { .func = (void (*)()) serializeUnpackInCore },         \
+    { .func = (void (*)()) fileOpen_serial },               \
+    { .func = (void (*)()) fileWrite },                     \
+    { .func = (void (*)()) fileClose_serial },              \
+    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },  \
+    { .func = (void (*)()) cdiStreamDefVlist_ },            \
+    { .func = (void (*)()) cdiStreamWriteVar_ },            \
+    { .func = (void (*)()) cdiStreamwriteVarChunk_ },       \
+    { .func = (void (*)()) 0 },                             \
+    { .func = (void (*)()) 0 },                             \
+    { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
+    { .func = (void (*)()) cdiStreamDefTimestep_ }, \
+    { .func = (void (*)()) cdiStreamSync_ },                \
+    CDI_NETCDF_SWITCHES                        \
+    }
 
+#if defined (SX)
+static const union namespaceSwitchValue
+  defaultSwitches_[NUM_NAMESPACE_SWITCH] = defaultSwitches;
+#endif
 
-#if  defined  (HAVE_LIBGRIB_API)
-static
-int my_grib_set_double(grib_handle* h, const char* key, double val)
+static struct Namespace
 {
-  if ( cdiGribApiDebug )
-    fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val);
+  statusCode resStage;
+  union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
+} initialNamespace = {
+  .resStage = STAGE_DEFINITION,
+  .switches = defaultSwitches
+};
 
-  return grib_set_double(h, key, val);
-}
+static struct Namespace *namespaces = &initialNamespace;
 
-static
-int my_grib_set_long(grib_handle* h, const char* key, long val)
-{
-  if ( cdiGribApiDebug )
-    fprintf(stderr, "grib_set_long(  \tgrib_handle* h, \"%s\", %ld)\n", key, val);
+static unsigned namespacesSize = 1;
 
-  return grib_set_long(h, key, val);
-}
+#if  defined  (HAVE_LIBPTHREAD)
+#  include <pthread.h>
 
-static
-int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t* length)
-{
-  if ( cdiGribApiDebug )
-    fprintf(stderr, "grib_set_string(\tgrib_handle* h, \"%s\", \"%s\")\n", key, val);
+static pthread_once_t  namespaceOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t namespaceMutex;
 
-  return grib_set_string(h, key, val, length);
+static void
+namespaceInitialize(void)
+{
+  pthread_mutexattr_t ma;
+  pthread_mutexattr_init(&ma);
+  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  pthread_mutex_init(&namespaceMutex, &ma);
+  pthread_mutexattr_destroy(&ma);
 }
 
-static
-int gribapiGetGridType(grib_handle *gh)
-{
-  int gridtype = GRID_GENERIC;
-  int gribgridtype = -1;
-  long lpar;
+#  define NAMESPACE_LOCK()         pthread_mutex_lock(&namespaceMutex)
+#  define NAMESPACE_UNLOCK()       pthread_mutex_unlock(&namespaceMutex)
+#  define NAMESPACE_INIT()         pthread_once(&namespaceOnce, \
+                                                namespaceInitialize)
 
-    {
-      int status;
-      status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
 
-      if ( status ==  0 ) gribgridtype = (int) lpar;
+#else
+
+#  define NAMESPACE_INIT() do { } while (0)
+#  define NAMESPACE_LOCK()
+#  define NAMESPACE_UNLOCK()
 
-      switch (gribgridtype)
-	{
-	case  GRIB2_GTYPE_LATLON:        { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG ) break;
-                                         }
-	case  GRIB2_GTYPE_LATLON_ROT:    { gridtype = GRID_LONLAT;    break; }
-	case  GRIB2_GTYPE_LCC:           { gridtype = GRID_LCC;       break; }
-	case  GRIB2_GTYPE_GAUSSIAN:      { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG )
-					     gridtype = GRID_GAUSSIAN_REDUCED;
-					   else
-					     gridtype = GRID_GAUSSIAN;
-				  	   break;
-                                         }
-	case  GRIB2_GTYPE_SPECTRAL:      { gridtype = GRID_SPECTRAL;  break; }
-	case  GRIB2_GTYPE_GME:           { gridtype = GRID_GME;       break; }
-	case  GRIB2_GTYPE_UNSTRUCTURED:  { gridtype = GRID_UNSTRUCTURED; break; }
-	}
-    }
+#endif
 
-  return (gridtype);
+
+enum {
+  intbits = sizeof(int) * CHAR_BIT,
+  nspbits = 4,
+  idxbits = intbits - nspbits,
+  nspmask = (( 1 << nspbits ) - 1) << idxbits,
+  idxmask = ( 1 << idxbits ) - 1,
+};
+
+enum {
+  NUM_NAMESPACES = 1 << nspbits,
+  NUM_IDX = 1 << idxbits,
+};
+
+
+int namespaceIdxEncode ( namespaceTuple_t tin )
+{
+  xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
+  return ( tin.nsp << idxbits ) + tin.idx;
 }
 
-static
-int gribapiGetIsRotated(grib_handle *gh)
+int namespaceIdxEncode2 ( int nsp, int idx )
 {
-  int isRotated = 0;
-  int gribgridtype = -1;
-  long lpar;
-  int status;
+  xassert(nsp < NUM_NAMESPACES && idx < NUM_IDX);
+  return ( nsp << idxbits ) + idx;
+}
 
-  status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
 
-  if ( status ==  0 ) gribgridtype = (int) lpar;
+namespaceTuple_t namespaceResHDecode ( int resH )
+{
+  namespaceTuple_t tin;
 
-  if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
+  tin.idx = resH & idxmask;
+  tin.nsp = (int)(((unsigned)( resH & nspmask )) >> idxbits);
 
-  return (isRotated);
+  return tin;
 }
 
-static
-int gribapiGetZaxisType(long editionNumber, int grib_ltype)
+int
+namespaceNew()
 {
-  int zaxistype = ZAXIS_GENERIC;
-
-  if ( editionNumber <= 1 )
+  int newNamespaceID = -1;
+  NAMESPACE_INIT();
+  NAMESPACE_LOCK();
+  if (namespacesSize > nNamespaces)
     {
-      zaxistype = grib1ltypeToZaxisType(grib_ltype);
+      /* namespace is already available and only needs reinitialization */
+      for (unsigned i = 0; i < namespacesSize; ++i)
+        if (namespaces[i].resStage == STAGE_UNUSED)
+          {
+            newNamespaceID = (int)i;
+            break;
+          }
     }
-  else
+  else if (namespacesSize == 1)
     {
-      zaxistype = grib2ltypeToZaxisType(grib_ltype);
+      /* make room for additional namespace */
+      struct Namespace *newNameSpaces
+        = (struct Namespace *)xmalloc(((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
+      memcpy(newNameSpaces, namespaces, sizeof (namespaces[0]));
+      namespaces = newNameSpaces;
+      ++namespacesSize;
+      newNamespaceID = 1;
     }
-
-  return (zaxistype);
-}
-
-static
-int getTimeunits(long unitsOfTime)
-{
-  int timeunits = -1;
-
-  switch (unitsOfTime)
+  else if (namespacesSize < NUM_NAMESPACES)
     {
-    case 13:  timeunits = TUNIT_SECOND;  break;
-    case  0:  timeunits = TUNIT_MINUTE;  break;
-    case  1:  timeunits = TUNIT_HOUR;    break;
-    case 10:  timeunits = TUNIT_3HOURS;  break;
-    case 11:  timeunits = TUNIT_6HOURS;  break;
-    case 12:  timeunits = TUNIT_12HOURS; break;
-    case  2:  timeunits = TUNIT_DAY;     break;
-    default:  timeunits = TUNIT_HOUR;    break;
+      /* make room for additional namespace */
+      newNamespaceID = (int)namespacesSize;
+      namespaces
+        = (struct Namespace *)xrealloc(namespaces, ((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
+      ++namespacesSize;
     }
-
-  return (timeunits);
-}
-
-static
-double timeunit_factor(int tu1, int tu2)
-{
-  double factor = 1;
-
-  if ( tu2 == TUNIT_HOUR )
+  else /* implicit: namespacesSize >= NUM_NAMESPACES */
     {
-      switch (tu1)
-        {
-        case TUNIT_SECOND:  factor = 3600;   break;
-        case TUNIT_MINUTE:  factor = 60;     break;
-        case TUNIT_HOUR:    factor = 1;      break;
-        case TUNIT_3HOURS:  factor = 1./3;   break;
-        case TUNIT_6HOURS:  factor = 1./6;   break;
-        case TUNIT_12HOURS: factor = 1./12;  break;
-        case TUNIT_DAY:     factor = 1./24;  break;
-        }
+      NAMESPACE_UNLOCK();
+      return -1;
     }
+  xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
+  ++nNamespaces;
+  namespaces[newNamespaceID].resStage = STAGE_DEFINITION;
+#if defined (SX)
+  memcpy(namespaces[newNamespaceID].switches,
+         defaultSwitches_,
+         sizeof (namespaces[newNamespaceID].switches));
+#else
+  memcpy(namespaces[newNamespaceID].switches,
+         (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
+         sizeof (namespaces[newNamespaceID].switches));
+#endif
+  reshListCreate(newNamespaceID);
+  NAMESPACE_UNLOCK();
+  return newNamespaceID;
+}
 
-  return (factor);
+void
+namespaceDelete(int namespaceID)
+{
+  NAMESPACE_INIT();
+  NAMESPACE_LOCK();
+  xassert(namespaceID >= 0 && (unsigned)namespaceID < namespacesSize
+          && nNamespaces);
+  reshListDestruct(namespaceID);
+  namespaces[namespaceID].resStage = STAGE_UNUSED;
+  --nNamespaces;
+  NAMESPACE_UNLOCK();
 }
 
-static
-int gribapiGetTimeUnits(grib_handle *gh)
+int namespaceGetNumber ()
 {
-  int timeunits = -1;
-  long unitsOfTime = -1;
+  return (int)nNamespaces;
+}
 
-  grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime);
 
-  GRIB_CHECK(my_grib_set_long(gh, "stepUnits", unitsOfTime), 0);
+void namespaceSetActive ( int nId )
+{
+  xassert((unsigned)nId < namespacesSize
+          && namespaces[nId].resStage != STAGE_UNUSED);
+  activeNamespace = nId;
+}
 
-  timeunits = getTimeunits(unitsOfTime);
 
-  return (timeunits);
+int namespaceGetActive ()
+{
+  return activeNamespace;
 }
 
-static
-int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
+int namespaceAdaptKey ( int originResH, int originNamespace )
 {
-  int endStep = startStep;
-  int timeunits2 = timeunits;
+  namespaceTuple_t tin;
+  int nsp;
 
-  long unitsOfTime;
-  int status = grib_get_long(gh, "stepUnits", &unitsOfTime);
-  if ( status == 0 ) timeunits2 = getTimeunits(unitsOfTime);
-  //timeunits2 = gribapiGetTimeUnits(gh);
+  if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
 
-  long lpar;
-  status = grib_get_long(gh, "endStep", &lpar);
+  tin.idx = originResH & idxmask;
+  tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
 
-  if ( status == 0 )
-    endStep = (int) (((double)lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
-  // printf("%d %d %d %d %d %g\n", startStep, endStep, lpar, timeunits, timeunits2, timeunit_factor(timeunits, timeunits2));
+  xassert ( tin.nsp == originNamespace );
 
-  return (endStep);
+  nsp = namespaceGetActive ();
+
+  return namespaceIdxEncode2 ( nsp, tin.idx );
 }
 
-static
-int gribapiTimeIsFC(grib_handle *gh)
-{
-  long editionNumber;
-  int isFC = TRUE;
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+int namespaceAdaptKey2 ( int originResH )
+{
+  namespaceTuple_t tin;
+  int nsp;
 
-  if ( editionNumber > 1 )
-    {
-      long sigofrtime;
+  if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
 
-      GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
+  tin.idx = originResH & idxmask;
+  tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
 
-      if ( sigofrtime == 3 ) isFC = FALSE;
-    }
+  nsp = namespaceGetActive ();
 
-  return (isFC);
+  return namespaceIdxEncode2 ( nsp, tin.idx );
 }
 
-static
-int gribapiGetTsteptype(grib_handle *gh)
-{
-  int tsteptype = TSTEP_INSTANT;
-  static int lprint = TRUE;
-
-  if ( gribapiTimeIsFC(gh) )
-    {
-      int status;
-      size_t len = 256;
-      char stepType[256];
 
-      status = grib_get_string(gh, "stepType", stepType, &len);
-      if ( status == 0 && len > 1 && len < 256 )
-	{
-	  if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
-	  else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
-	  else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
-	  else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
-	  else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
-	  else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
-	  else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
-	  else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
-	  else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
-	  else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
-	  else if ( lprint )
-	    {
-	      Message("Time stepType %s unsupported, set to instant!", stepType);
-	      lprint = FALSE;
-	    }
+void namespaceDefResStatus ( statusCode argResStatus )
+{
+  int nsp = namespaceGetActive ();
+  namespaces[nsp].resStage = argResStatus;
+}
 
-	  // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
-	}
-    }
 
-  return (tsteptype);
+statusCode namespaceInqResStatus ( void )
+{
+  int nsp = namespaceGetActive ();
+  return namespaces[nsp].resStage;
 }
 
-static
-void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
+void namespaceSwitchSet(enum namespaceSwitch sw, union namespaceSwitchValue value)
 {
-  long lpar;
+  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
+  int nsp = namespaceGetActive();
+  namespaces[nsp].switches[sw] = value;
+}
 
-  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-  *datadate = (int) lpar;
-  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-  *datatime = (int) lpar*100;
+union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
+{
+  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
+  int nsp = namespaceGetActive();
+  return namespaces[nsp].switches[sw];
 }
 
-static
-void gribapiSetDataDateTime(grib_handle *gh, int datadate, int datatime)
+void cdiReset(void)
 {
-  GRIB_CHECK(my_grib_set_long(gh, "dataDate", datadate), 0);
-  GRIB_CHECK(my_grib_set_long(gh, "dataTime", datatime/100), 0);
+  NAMESPACE_INIT();
+  NAMESPACE_LOCK();
+  for (unsigned namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
+    if (namespaces[namespaceID].resStage != STAGE_UNUSED)
+      namespaceDelete((int)namespaceID);
+  if (namespaces != &initialNamespace)
+    {
+      free(namespaces);
+      namespaces = &initialNamespace;
+    }
+  namespacesSize = 1;
+  nNamespaces = 1;
+  activeNamespace = 0;
+  NAMESPACE_UNLOCK();
 }
 
-static
-int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
-{
-  int rdate, rtime;
-  int timeUnits, startStep = 0, endStep;
-  int tstepRange = 0;
-  int range;
-  int status;
-  long lpar;
-  long sigofrtime = 3;
-  long editionNumber;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
 
-  if ( editionNumber > 1 )
+char* myStrDup(const char* string)
+{
+  char* result = xmalloc(strlen(string) + 1);
+  if(result)
     {
-      GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
+      strcpy(result, string);
     }
   else
     {
-      GRIB_CHECK(grib_get_long(gh, "timeRangeIndicator", &sigofrtime), 0);
+      errno = ENOMEM;
     }
+  return result;
+}
 
-  if ( sigofrtime == 3 )
+char* myAsprintf(char* format, ...)
+{
+  va_list args;
+  int size = 64;
+  char *buffer = xmalloc(size);
+  int nchars;
+  //Try to print in the allocated space.
+  va_start(args, format);
+  nchars = vsnprintf(buffer, size, format, args);
+  va_end(args);
+  if (nchars >= size)
     {
-      gribapiGetDataDateTime(gh, vdate, vtime);
+      //Reallocate buffer now that we know how much space is needed.
+      size = nchars + 1;
+      buffer = xrealloc(buffer, size);
+      va_start(args, format);
+      vsnprintf(buffer, size, format, args);
+      va_end(args);
     }
-  else
-    {
-      gribapiGetDataDateTime(gh, &rdate, &rtime);
+  return buffer;
+}
 
-      status = grib_get_long(gh, "forecastTime", &lpar);
-      if ( status == 0 ) startStep = (int) lpar;
-      timeUnits = gribapiGetTimeUnits(gh);
-      endStep = gribapiGetEndStep(gh, startStep, timeUnits);
 
-      range = endStep - startStep;
 
-      if ( range > 0 )
-	{
-	  if ( startStep == 0 ) tstepRange = -1;
-	  else                  tstepRange =  1;
-	}
+void cdiRefObject_construct(CdiReferencedObject* me)
+{
+  me->destructor = cdiRefObject_destruct;
+  me->refCount = 1;
+}
 
-      {
-	static int lprint = TRUE;
-	extern int grib_calendar;
-	int ryear, rmonth, rday, rhour, rminute, rsecond;
-	int julday, secofday;
-	int64_t time_period = endStep;
-        int64_t addsec;
+void cdiRefObject_retain(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount++;
+  xassert(oldCount && "A reference counted object was used after it was destructed.");
+}
 
-	cdiDecodeDate(rdate, &ryear, &rmonth, &rday);
-	cdiDecodeTime(rtime, &rhour, &rminute, &rsecond);
+void cdiRefObject_release(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount--;
+  xassert(oldCount && "A reference counted object was released too often.");
+  if(oldCount == 1)
+    {
+      me->destructor(me);
+      free(me);
+    }
+}
 
-        if ( rday > 0 )
-          {
-            encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, rsecond, &julday, &secofday);
+void cdiRefObject_destruct(CdiReferencedObject* me) { /* Empty for now, but that's no reason not to call it! */ }
+#ifndef MODEL_H
+#define MODEL_H
 
-            addsec = 0;
-            switch ( timeUnits )
-              {
-              case TUNIT_SECOND:  addsec =         time_period; break;
-              case TUNIT_MINUTE:  addsec =    60 * time_period; break;
-              case TUNIT_HOUR:    addsec =  3600 * time_period; break;
-              case TUNIT_3HOURS:  addsec = 10800 * time_period; break;
-              case TUNIT_6HOURS:  addsec = 21600 * time_period; break;
-              case TUNIT_12HOURS: addsec = 43200 * time_period; break;
-              case TUNIT_DAY:     addsec = 86400 * time_period; break;
-              default:
-                if ( lprint )
-                  {
-                    Warning("Time unit %d unsupported", timeUnits);
-                    lprint = FALSE;
-                  }
-                break;
-              }
+int
+modelUnpack(void *buf, int size, int *position,
+            int originNamespace, void *context, int force_id);
 
-            julday_add_seconds(addsec, &julday, &secofday);
+void modelDefaultEntries(void);
 
-            decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &rsecond);
-          }
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-	*vdate = cdiEncodeDate(ryear, rmonth, rday);
-	*vtime = cdiEncodeTime(rhour, rminute, rsecond);
-      }
-    }
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
 
-  return (tstepRange);
-}
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#if defined (HAVE_EXECINFO_H)
+#include <execinfo.h>
+#endif
 
 static
-void gribapiGetGrid(grib_handle *gh, grid_t *grid)
+void show_stackframe()
 {
-  long editionNumber;
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+#if defined HAVE_EXECINFO_H && defined backtrace_size_t && defined HAVE_BACKTRACE
+  void *trace[16];
+  backtrace_size_t trace_size = backtrace(trace, 16);
+  char **messages = backtrace_symbols(trace, trace_size);
 
-  int gridtype = gribapiGetGridType(gh);
-  /*
-  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      gridtype = GRID_GAUSSIAN;
-      ISEC2_NumLon = 2*ISEC2_NumLat;
-      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
-    }
-  */
-  memset(grid, 0, sizeof(grid_t));
+  fprintf(stderr, "[bt] Execution path:\n");
+  if ( messages ) {
+    for ( backtrace_size_t i = 0; i < trace_size; ++i )
+      fprintf(stderr, "[bt] %s\n", messages[i]);
+    free(messages);
+  }
+#endif
+}
 
-  size_t datasize;
-  GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
-  long numberOfPoints;
-  GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
 
-  switch (gridtype)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-      {
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlon = (int)lpar;
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
+enum { MIN_LIST_SIZE = 128 };
 
-	if ( gridtype == GRID_GAUSSIAN )
-          {
-            GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-            grid->np = (int)lpar;
-          }
+static void listInitialize(void);
 
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
+typedef struct listElem {
+  union
+  {
+    /* free-list management data */
+    struct
+    {
+      int next, prev;
+    } free;
+    /* holding an actual value */
+    struct
+    {
+      const resOps *ops;
+      void         *val;//ptr
+    } v;
+  } res;
+  int           status;
+} listElem_t;
 
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
-	grid->xinc  = 0;
-	grid->yinc  = 0;
-	grid->xdef  = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
-	if ( gridtype == GRID_LONLAT )
-	  GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &grid->yinc), 0);
+struct resHList_t
+{
+  int size, freeHead, hasDefaultRes;
+  listElem_t *resources;
+};
 
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+static struct resHList_t *resHList;
 
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+static int resHListSize = 0;
 
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
+#if  defined  (HAVE_LIBPTHREAD)
+#  include <pthread.h>
 
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_GAUSSIAN_REDUCED:
-      {
-	size_t dummy;
-	long *pl;
+static pthread_once_t  listInitThread = PTHREAD_ONCE_INIT;
+static pthread_mutex_t listMutex;
 
-        long lpar;
-        GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-        grid->np = (int)lpar;
+#  define LIST_LOCK()         pthread_mutex_lock(&listMutex)
+#  define LIST_UNLOCK()       pthread_mutex_unlock(&listMutex)
+#  define LIST_INIT(init0)         do {                         \
+    pthread_once(&listInitThread, listInitialize);              \
+    pthread_mutex_lock(&listMutex);                             \
+    if ((init0) && (!resHList || !resHList[0].resources))       \
+      reshListCreate(0);                                        \
+    pthread_mutex_unlock(&listMutex);                           \
+  } while (0)
 
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
 
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size   = (int)numberOfPoints;
 
-        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
-        pl          = (long *) malloc((size_t)nlat * sizeof (long));
-	dummy       = (size_t)nlat;
-	GRIB_CHECK(grib_get_long_array(gh, "pl", pl, &dummy), 0);
-        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
-	for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
-	free(pl);
+#else
 
-	grid->ysize  = nlat;
-	grid->xinc   = 0;
-	grid->yinc   = 0;
-	grid->xdef   = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
+static int listInit = 0;
 
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+#  define LIST_LOCK()
+#  define LIST_UNLOCK()
+#  define LIST_INIT(init0)        do {                          \
+  if ( !listInit )                                              \
+    {                                                           \
+      listInitialize();                                         \
+      if ((init0) && (!resHList || !resHList[0].resources))     \
+        reshListCreate(0);                                      \
+      listInit = 1;                                             \
+    }                                                           \
+  } while(0)
 
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+#endif
 
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
+/**************************************************************/
 
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef  = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_LCC:
-      {
-	int nlon, nlat;
-        long lpar;
+static void
+listInitResources(int nsp)
+{
+  xassert(nsp < resHListSize && nsp >= 0);
+  int size = resHList[nsp].size = MIN_LIST_SIZE;
+  xassert(resHList[nsp].resources == NULL);
+  resHList[nsp].resources = (listElem_t*) xcalloc(MIN_LIST_SIZE, sizeof(listElem_t));
+  listElem_t *p = resHList[nsp].resources;
 
-	GRIB_CHECK(grib_get_long(gh, "Nx", &lpar), 0);
-	nlon = lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ny", &lpar), 0);
-	nlat = lpar;
+  for (int i = 0; i < size; i++ )
+    {
+      p[i].res.free.next = i + 1;
+      p[i].res.free.prev = i - 1;
+      p[i].status = RESH_UNUSED;
+    }
 
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+  p[size-1].res.free.next = -1;
+  resHList[nsp].freeHead = 0;
+  int oldNsp = namespaceGetActive();
+  namespaceSetActive(nsp);
+  instituteDefaultEntries();
+  modelDefaultEntries();
+  namespaceSetActive(oldNsp);
+}
 
-	grid->size  = numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
+static inline void
+reshListClearEntry(int i)
+{
+  resHList[i].size = 0;
+  resHList[i].resources = NULL;
+  resHList[i].freeHead = -1;
+}
 
-	GRIB_CHECK(grib_get_double(gh, "DxInMetres", &grid->lcc_xinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "DyInMetres", &grid->lcc_yinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat), 0);
-	GRIB_CHECK(grib_get_double(gh, "LoVInDegrees", &grid->lcc_lonParY), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin1InDegrees", &grid->lcc_lat1), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin2InDegrees", &grid->lcc_lat2), 0);
+void
+reshListCreate(int namespaceID)
+{
+  LIST_INIT(namespaceID != 0);
+  LIST_LOCK();
+  if (resHListSize <= namespaceID)
+    {
+      resHList = (struct resHList_t *)xrealloc(resHList, (size_t)(namespaceID + 1) * sizeof (resHList[0]));
+      for (int i = resHListSize; i <= namespaceID; ++i)
+        reshListClearEntry(i);
+      resHListSize = namespaceID + 1;
+    }
+  listInitResources(namespaceID);
+  LIST_UNLOCK();
+}
 
-        if ( editionNumber <= 1 )
-          {
-            GRIB_CHECK(grib_get_long(gh, "projectionCenterFlag", &lpar), 0);
-            grid->lcc_projflag  = (int) lpar;
-            GRIB_CHECK(grib_get_long(gh, "scanningMode", &lpar), 0);
-            grid->lcc_scanflag  = (int) lpar;
-          }
 
-	grid->xdef   = 0;
-	grid->ydef   = 0;
+/**************************************************************/
 
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	size_t len = 256;
-	char typeOfPacking[256];
-	GRIB_CHECK(grib_get_string(gh, "packingType", typeOfPacking, &len), 0);
-	grid->lcomplex = 0;
-	if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
+void
+reshListDestruct(int namespaceID)
+{
+  LIST_LOCK();
+  xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
+  int callerNamespaceID = namespaceGetActive();
+  namespaceSetActive(namespaceID);
+  if (resHList[namespaceID].resources)
+    {
+      for ( int j = 0; j < resHList[namespaceID].size; j++ )
+        {
+          listElem_t *listElem = resHList[namespaceID].resources + j;
+          if (listElem->status & RESH_IN_USE_BIT)
+            listElem->res.v.ops->valDestroy(listElem->res.v.val);
+        }
+      free(resHList[namespaceID].resources);
+      resHList[namespaceID].resources = NULL;
+      reshListClearEntry(namespaceID);
+    }
+  if (resHList[callerNamespaceID].resources)
+    namespaceSetActive(callerNamespaceID);
+  LIST_UNLOCK();
+}
 
-        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
-	grid->size  = (int)datasize;
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "J", &lpar), 0);
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	grid->trunc = (int)lpar;
 
-	break;
-      }
-    case GRID_GME:
-      {
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-        long lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
+static void listDestroy ( void )
+{
+  LIST_LOCK();
+  for (int i = resHListSize; i > 0; --i)
+    if (resHList[i-1].resources)
+      namespaceDelete(i-1);
+  resHListSize = 0;
+  free(resHList);
+  resHList = NULL;
+  cdiReset();
+  LIST_UNLOCK();
+}
 
-	break;
-      }
-    case GRID_UNSTRUCTURED:
-      {
-        unsigned char uuid[CDI_UUID_SIZE];
-    	/*
-        char reference_link[8192];
-        size_t len = sizeof(reference_link);
-        reference_link[0] = 0;
-         */
+/**************************************************************/
 
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-    	grid->size  = (int)numberOfPoints;
-        long lpar;
-        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-          {
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            grid->number   = (int)lpar;
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
-              grid->position = (int)lpar;
-            /*
-            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
-              {
-                if ( strncmp(reference_link, "file://", 7) == 0 )
-                  grid->reference = strdupx(reference_link);
-              }
-            */
-            size_t len = (size_t)CDI_UUID_SIZE;
-            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
-              {
-                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
-              }
-          }
-	break;
-      }
-    case GRID_GENERIC:
-      {
-	int nlon = 0, nlat = 0;
-        long lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+static
+void listInitialize ( void )
+{
+#if  defined  (HAVE_LIBPTHREAD)
+  pthread_mutexattr_t ma;
+  pthread_mutexattr_init(&ma);
+  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  /* initialize global API mutex lock */
+  pthread_mutex_init ( &listMutex, &ma);
+  pthread_mutexattr_destroy(&ma);
+#endif
+  /* file is special and has its own table, which needs to be
+   * created, before we register the listDestroy exit handler */
+  {
+    int null_id;
+    null_id = fileOpen_serial("/dev/null", "r");
+    if (null_id != -1)
+      fileClose_serial(null_id);
+  }
+  atexit ( listDestroy );
+}
 
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
+/**************************************************************/
 
-	if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
-	  {
-	    grid->xsize = nlon;
-	    grid->ysize = nlat;
-	  }
-	else
-	  {
-	    grid->xsize = 0;
-	    grid->ysize = 0;
-	  }
+static
+void listSizeExtend()
+{
+  int nsp = namespaceGetActive ();
+  int oldSize = resHList[nsp].size;
+  size_t newListSize = (size_t)oldSize + MIN_LIST_SIZE;
 
-	break;
-      }
-    default:
-      {
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-	break;
-      }
-    }
+  resHList[nsp].resources = (listElem_t*) xrealloc(resHList[nsp].resources,
+                                                   newListSize * sizeof(listElem_t));
 
-  grid->isRotated = FALSE;
-  if ( gribapiGetIsRotated(gh) )
+  listElem_t *r = resHList[nsp].resources;
+  for (size_t i = (size_t)oldSize; i < newListSize; ++i)
     {
-      grid->isRotated = TRUE;
-      GRIB_CHECK(grib_get_double(gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole), 0);
-      GRIB_CHECK(grib_get_double(gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole), 0);
-      GRIB_CHECK(grib_get_double(gh, "angleOfRotation", &grid->angle), 0);
-      /* change from south to north pole */
-      grid->ypole = -grid->ypole;
-      grid->xpole =  grid->xpole - 180;
+      r[i].res.free.next = (int)i + 1;
+      r[i].res.free.prev = (int)i - 1;
+      r[i].status = RESH_UNUSED;
     }
 
-  grid->xvals = NULL;
-  grid->yvals = NULL;
-  grid->type  = gridtype;
+  if (resHList[nsp].freeHead != -1)
+    r[resHList[nsp].freeHead].res.free.prev = (int)newListSize - 1;
+  r[newListSize-1].res.free.next = resHList[nsp].freeHead;
+  r[oldSize].res.free.prev = -1;
+  resHList[nsp].freeHead = oldSize;
+  resHList[nsp].size = (int)newListSize;
+}
+
+/**************************************************************/
+
+static void
+reshPut_(int nsp, int entry, void *p, const resOps *ops)
+{
+  listElem_t *newListElem = resHList[nsp].resources + entry;
+  int next = newListElem->res.free.next,
+    prev = newListElem->res.free.prev;
+  if (next != -1)
+    resHList[nsp].resources[next].res.free.prev = prev;
+  if (prev != -1)
+    resHList[nsp].resources[prev].res.free.next = next;
+  else
+    resHList[nsp].freeHead = next;
+  newListElem->res.v.val = p;
+  newListElem->res.v.ops = ops;
+  newListElem->status = RESH_DESYNC_IN_USE;
 }
 
-static
-void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
+int reshPut ( void *p, const resOps *ops )
 {
-  *leveltype = 0;
-  *lbounds   = 0;
-  *level1    = 0;
-  *level2    = 0;
+  xassert ( p && ops );
 
-  long lpar;
-  int status = grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar);
-  if ( status == 0 )
-    {
-      *leveltype = (int) lpar;
+  LIST_INIT(1);
 
-      switch (*leveltype)
-	{
-	case GRIB1_LTYPE_SIGMA_LAYER:
-	case GRIB1_LTYPE_HYBRID_LAYER:
-	case GRIB1_LTYPE_LANDDEPTH_LAYER:
-	  { *lbounds = 1; break; }
-	}
+  LIST_LOCK();
 
-      if ( *lbounds == 0 )
-	{
-          double dlevel;
-	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
-	  if ( *leveltype == 100 ) dlevel *= 100;
-	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
+  int nsp = namespaceGetActive ();
 
-	  *level1 = (int) dlevel;
-	  *level2 = 0;
-	}
-      else
-	{
-	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);
-	  *level1 = (int)lpar;
-	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);
-	  *level2 = (int)lpar;
-	}
-    }
-}
+  if ( resHList[nsp].freeHead == -1) listSizeExtend();
+  int entry = resHList[nsp].freeHead;
+  cdiResH resH = namespaceIdxEncode2(nsp, entry);
+  reshPut_(nsp, entry, p, ops);
 
-static
-double grib2ScaleFactor(long factor)
-{
-  double scaleFactor = 0;
+  LIST_UNLOCK();
+
+  return resH;
+}
 
-  if      ( factor == 0 ) scaleFactor =    1;
-  else if ( factor == 1 ) scaleFactor =    0.1;
-  else if ( factor == 2 ) scaleFactor =    0.01;
-  else if ( factor == 3 ) scaleFactor =    0.001;
-  else if ( factor == 4 ) scaleFactor =    0.0001;
-  else if ( factor == 5 ) scaleFactor =    0.00001;
-  else if ( factor == 6 ) scaleFactor =    0.000001;
-  else if ( factor == 7 ) scaleFactor =    0.0000001;
-  else if ( factor == 8 ) scaleFactor =    0.00000001;
-  else if ( factor == 9 ) scaleFactor =    0.000000001;
+/**************************************************************/
 
-  return (scaleFactor);
+static void
+reshRemove_(int nsp, int idx)
+{
+  int curFree = resHList[nsp].freeHead;
+  listElem_t *r = resHList[nsp].resources;
+  r[idx].res.free.next = curFree;
+  r[idx].res.free.prev = -1;
+  if (curFree != -1)
+    r[curFree].res.free.prev = idx;
+  r[idx].status = RESH_DESYNC_DELETED;
+  resHList[nsp].freeHead = idx;
 }
 
-static
-void grib2GetLevel(grib_handle *gh, int *leveltype1, int *leveltype2, int *lbounds, int *level1, 
-                   int *level2, int *level_sf, int *level_unit)
+void reshDestroy(cdiResH resH)
 {
-  int status;
-  long lpar;
-  long factor;
+  int nsp;
+  namespaceTuple_t nspT;
 
-  *leveltype1 = 0;
-  *leveltype2 = -1;
-  *lbounds    = 0;
-  *level1     = 0;
-  *level2     = 0;
-  *level_sf   = 0;
-  *level_unit = 0;
+  LIST_LOCK();
 
-  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
-  if ( status == 0 )
-    {
-      long llevel;
-      double dlevel1 = 0, dlevel2 = 0;
+  nsp = namespaceGetActive ();
 
-      *leveltype1 = (int) lpar;
+  nspT = namespaceResHDecode ( resH );
 
-      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar);
-      /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-      if ( status == 0 ) *leveltype2 = (int)lpar;
+  xassert ( nspT.nsp == nsp
+            && nspT.idx >= 0
+            && nspT.idx < resHList[nsp].size
+            && resHList[nsp].resources[nspT.idx].res.v.ops);
 
-      if ( *leveltype1 != 255 && *leveltype2 != 255 && *leveltype2 > 0 ) *lbounds = 1;
-      if ( *leveltype1 == GRIB2_LTYPE_REFERENCE && *leveltype2 == 1 ) *lbounds = 0;
+  if (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
+    reshRemove_(nsp, nspT.idx);
 
-      if ( *leveltype1 == GRIB2_LTYPE_LANDDEPTH )
-        {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_M;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_ISOBARIC )
-        {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_PA;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_SIGMA )
-        {
-          *level_sf = 1000;
-          *level_unit = 0;
-        }
+  LIST_UNLOCK();
+}
 
-      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);
-      if ( llevel != GRIB_MISSING_LONG )
-        {
-          if ( factor != GRIB_MISSING_LONG )
-            dlevel1 = (double)llevel * grib2ScaleFactor(factor);
-          else
-            dlevel1 = (double)llevel;
-        }
+void reshRemove ( cdiResH resH, const resOps * ops )
+{
+  int nsp;
+  namespaceTuple_t nspT;
 
-      if ( *level_sf != 0 ) dlevel1 *= (double)(*level_sf);
+  LIST_LOCK();
 
-      if ( *lbounds == 1 )
-	{
-          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
-          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0);
-          if ( llevel != GRIB_MISSING_LONG )
-            {
-              if ( factor != GRIB_MISSING_LONG )
-                dlevel2 = (double)llevel * grib2ScaleFactor(factor);
-              else
-                dlevel2 = (double)llevel;
-            }
+  nsp = namespaceGetActive ();
 
-          if ( *level_sf != 0 ) dlevel2 *= (*level_sf);
-        }
+  nspT = namespaceResHDecode ( resH );
 
-      *level1 = (int) dlevel1;
-      *level2 = (int) dlevel2;
-    }
-}
+  xassert ( nspT.nsp == nsp
+            && nspT.idx >= 0
+            && nspT.idx < resHList[nsp].size
+            && (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
+            && resHList[nsp].resources[nspT.idx].res.v.ops
+            && resHList[nsp].resources[nspT.idx].res.v.ops == ops );
 
-static
-void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t length)
-{
-  string[0] = 0;
+  reshRemove_(nsp, nspT.idx);
 
-  GRIB_CHECK(grib_get_string(gh, key, string, &length), 0);
-  if      ( length == 8 && memcmp(string, "unknown", length) == 0 ) string[0] = 0;
-  else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
+  LIST_UNLOCK();
 }
 
-#if  defined  (HAVE_LIBGRIB_API)
-static
-void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
-		      size_t recsize, off_t position, int datatype, int comptype, size_t len, const char *varname,
-                      int leveltype1, int leveltype2, int lbounds, int level1, int level2, int level_sf, int level_unit)
+/**************************************************************/
+
+void reshReplace(cdiResH resH, void *p, const resOps *ops)
 {
-  long editionNumber;
-  int zaxistype;
-  int gridID = CDI_UNDEFID, varID;
-  int levelID = 0;
-  int tsID, recID;
-  int numavg;
-  int tsteptype;
-  record_t *record;
-  grid_t grid;
-  int vlistID;
-  long lpar;
-  int status;
-  char stdname[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
-  size_t vlen;
-  long ens_index = 0, ens_count = 0, ens_forecast_type = 0;
+  xassert(p && ops);
+  LIST_INIT(1);
+  LIST_LOCK();
+  int nsp = namespaceGetActive();
+  namespaceTuple_t nspT = namespaceResHDecode(resH);
+  while (resHList[nsp].size <= nspT.idx)
+    listSizeExtend();
+  listElem_t *q = resHList[nsp].resources + nspT.idx;
+  if (q->status & RESH_IN_USE_BIT)
+    {
+      q->res.v.ops->valDestroy(q->res.v.val);
+      reshRemove_(nsp, nspT.idx);
+    }
+  reshPut_(nsp, nspT.idx, p, ops);
+  LIST_UNLOCK();
+}
 
-  vlistID = streamptr->vlistID;
-  tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamptr, tsID);
-  record  = &streamptr->tsteps[tsID].records[recID];
 
-  tsteptype = gribapiGetTsteptype(gh);
-  // numavg  = ISEC1_AvgNum;
-  numavg  = 0;
+static listElem_t *
+reshGetElem(const char *caller, const char* expressionString, cdiResH resH, const resOps *ops)
+{
+  listElem_t *listElem;
+  int nsp;
+  namespaceTuple_t nspT;
+  xassert ( ops );
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+  LIST_INIT(1);
 
-  // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
+  LIST_LOCK();
 
-  (*record).size      = recsize;
-  (*record).position  = position;
-  (*record).param     = param;
-  (*record).ilevel    = level1;
-  (*record).ilevel2   = level2;
-  (*record).ltype     = leveltype1;
-  (*record).tsteptype = tsteptype;
-  memcpy((*record).varname, varname, len);
+  nsp = namespaceGetActive ();
 
-  gribapiGetGrid(gh, &grid);
+  nspT = namespaceResHDecode ( resH );
+  assert(nspT.idx >= 0);
 
-  gridID = varDefGrid(vlistID, &grid, 0);
+  if (nspT.nsp == nsp &&
+      nspT.idx < resHList[nsp].size)
+    {
+      listElem = resHList[nsp].resources + nspT.idx;
+      LIST_UNLOCK();
+    }
+  else
+    {
+      LIST_UNLOCK();
+      show_stackframe();
 
-  zaxistype = gribapiGetZaxisType(editionNumber, leveltype1);
+      if ( resH == CDI_UNDEFID )
+        {
+          xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is CDI_UNDEFID (= %d).\n\tThis is most likely the result of a failed earlier call. Please check the IDs returned by CDI.", expressionString, caller, resH);
+        }
+      else
+        {
+          xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is garbage (= %d, which resolves to namespace = %d, index = %d).\n\tThis is either the result of using an uninitialized variable,\n\tof using a value as an ID that is not an ID,\n\tor of using an ID after it has been invalidated.", expressionString, caller, resH, nspT.nsp, nspT.idx);
+        }
+    }
 
-  switch (zaxistype)
+  if ( !(listElem && listElem->res.v.ops == ops) )
     {
-    case ZAXIS_HYBRID:
-    case ZAXIS_HYBRID_HALF:
-      {
-        int vctsize;
-        size_t dummy;
-        double *vctptr;
-
-        GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-        vctsize = (int)lpar;
-        if ( vctsize > 0 )
-          {
-            vctptr = (double *) malloc(vctsize*sizeof(double));
-            dummy = (size_t)vctsize;
-            GRIB_CHECK(grib_get_double_array(gh, "pv", vctptr, &dummy), 0);
-            varDefVCT((size_t)vctsize, vctptr);
-            free(vctptr);
-          }
-        break;
-      }
-    case ZAXIS_REFERENCE:
-      {
-        size_t len;
-        unsigned char uuid[CDI_UUID_SIZE];
-        long ltmp;
-        long nhlev, nvgrid;
+      show_stackframe();
 
-        GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
-        if ( lpar != 6 )
-          {
-            fprintf(stderr, "Warning ...\n");
-          }
-        GRIB_CHECK(grib_get_long(gh, "nlev", &ltmp), 0);
-        nhlev = ltmp;
-        GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &ltmp), 0);
-        nvgrid = ltmp;
-        len = (size_t)CDI_UUID_SIZE;
-        memset(uuid, 0, CDI_UUID_SIZE);
-        GRIB_CHECK(grib_get_bytes(gh, "uuidOfVGrid", uuid, &len), 0);
-        varDefZAxisReference((int) nhlev, (int) nvgrid, uuid);
-        break;
-      }
+      xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: list element not found. The failed ID is %d", expressionString, caller, (int)resH);
     }
 
-  // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
-  if ( datatype <  0 ) datatype = DATATYPE_PACK;
-
-  stdname[0] = 0;
-  longname[0] = 0;
-  units[0] = 0;
+  return listElem;
+}
 
-  if ( varname[0] != 0 )
-    {
-      vlen = CDI_MAX_NAME;
-      gribapiGetString(gh, "name", longname, vlen);
-      vlen = CDI_MAX_NAME;
-      gribapiGetString(gh, "units", units, vlen);
 
-      {
-        vlen = CDI_MAX_NAME;
-        status = grib_get_string(gh, "cfName", stdname, &vlen);
-        if ( status != 0 || vlen <= 1 ) stdname[0] = 0;
-        else if ( strncmp(stdname, "unknown", 7) == 0 ) stdname[0] = 0;
-      }
-    }
-  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
+void *reshGetValue(const char * caller, const char* expressionString, cdiResH resH, const resOps * ops)
+{
+  return reshGetElem(caller, expressionString, resH, ops)->res.v.val;
+}
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf, level_unit,
-	       datatype, &varID, &levelID, tsteptype, numavg, leveltype1, leveltype2,
-	       varname, stdname, longname, units);
+/**************************************************************/
 
-  (*record).varID   = (short)varID;
-  (*record).levelID = (short)levelID;
+void reshGetResHListOfType(unsigned numIDs, int resHs[numIDs], const resOps *ops)
+{
+  xassert ( resHs && ops );
 
-  varDefCompType(varID, comptype);
+  LIST_INIT(1);
 
-  /*
-    Get the ensemble Info from the grib-2 Tables and update the intermediate datastructure.
-    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdi_generate_vars"
-  */
-  status = grib_get_long(gh, "typeOfEnsembleForecast", &ens_forecast_type );
-  if ( status == 0 )
-    {
-      GRIB_CHECK(grib_get_long(gh, "numberOfForecastsInEnsemble", &ens_count ), 0);
-      GRIB_CHECK(grib_get_long(gh, "perturbationNumber", &ens_index ), 0);
-    }
+  LIST_LOCK();
 
-  if ( ens_index > 0 )
-    varDefEnsembleInfo(varID, (int)ens_index, (int)ens_count, (int)ens_forecast_type);
+  int nsp = namespaceGetActive();
+  unsigned j = 0;
+  for (int i = 0; i < resHList[nsp].size && j < numIDs; i++ )
+    if ((resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
+        && resHList[nsp].resources[i].res.v.ops == ops)
+      resHs[j++] = namespaceIdxEncode2(nsp, i);
 
-  long typeOfGeneratingProcess = 0;
-  status = grib_get_long(gh, "typeOfGeneratingProcess", &typeOfGeneratingProcess);
-  if ( status == 0 )
-    varDefTypeOfGeneratingProcess(varID, (int) typeOfGeneratingProcess);
+  LIST_UNLOCK();
+}
 
-  long productDefinitionTemplate = 0;
-  status = grib_get_long(gh, "productDefinitionTemplateNumber", &productDefinitionTemplate);
-  if ( status == 0 )
-    varDefProductDefinitionTemplate(varID, (int) productDefinitionTemplate);
+enum cdiApplyRet
+cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
+                                      void *data), void *data)
+{
+  xassert(func);
 
-  int    i;
-  long   lval;
-  double dval;
+  LIST_INIT(1);
 
-  /* we read the additional keys for the first variable record only. */
-  int linitial_field = (varOptGribNentries(varID) == 0);
+  LIST_LOCK();
 
-  for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
-    {
-      if ( linitial_field )
-	{
-	  if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
-            varDefOptGribInt(varID, lval, cdiAdditionalGRIBKeys[i]);
-	}
-      if ( linitial_field )
-	{
-	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
-            varDefOptGribDbl(varID, dval, cdiAdditionalGRIBKeys[i]);
-	}
-      /* note: if the key is not defined, we do not throw an error! */
-    }
+  int nsp = namespaceGetActive ();
+  enum cdiApplyRet ret = CDI_APPLY_GO_ON;
+  for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
+    if (resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
+      ret = func(namespaceIdxEncode2(nsp, i),
+                 resHList[nsp].resources[i].res.v.val,
+                 resHList[nsp].resources[i].res.v.ops, data);
+  LIST_UNLOCK();
+  return ret;
+}
 
-  if ( varInqInst(varID) == CDI_UNDEFID )
-    {
-      long center, subcenter;
-      int instID;
-      GRIB_CHECK(grib_get_long(gh, "centre", &center), 0);
-      GRIB_CHECK(grib_get_long(gh, "subCentre", &subcenter), 0);
-      instID    = institutInq((int)center, (int)subcenter, NULL, NULL);
-      if ( instID == CDI_UNDEFID )
-	instID = institutDef((int)center, (int)subcenter, NULL, NULL);
-      varDefInst(varID, instID);
-    }
 
-  if ( varInqModel(varID) == CDI_UNDEFID )
-    {
-      int modelID;
-      long processID;
-      status = grib_get_long(gh, "generatingProcessIdentifier", &processID);
-      if ( status == 0 )
-	{
-          /* FIXME: assert(processID >= INT_MIN && processID <= INT_MAX) */
-	  modelID = modelInq(varInqInst(varID), (int)processID, NULL);
-	  if ( modelID == CDI_UNDEFID )
-	    modelID = modelDef(varInqInst(varID), (int)processID, NULL);
-	  varDefModel(varID, modelID);
-	}
-    }
+enum cdiApplyRet
+cdiResHFilterApply(const resOps *p,
+                   enum cdiApplyRet (*func)(int id, void *res, void *data),
+                   void *data)
+{
+  xassert(p && func);
 
-  if ( varInqTable(varID) == CDI_UNDEFID )
-    {
-      int pdis, pcat, pnum;
+  LIST_INIT(1);
 
-      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  LIST_LOCK();
 
-      if ( pdis == 255 )
-	{
-	  int tableID;
-	  int tabnum = pcat;
+  int nsp = namespaceGetActive ();
+  enum cdiApplyRet ret = CDI_APPLY_GO_ON;
+  listElem_t *r = resHList[nsp].resources;
+  for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
+    if ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == p)
+      ret = func(namespaceIdxEncode2(nsp, i), r[i].res.v.val,
+                 data);
+  LIST_UNLOCK();
+  return ret;
+}
 
-	  tableID = tableInq(varInqModel(varID), tabnum, NULL);
 
-	  if ( tableID == CDI_UNDEFID )
-	    tableID = tableDef(varInqModel(varID), tabnum, NULL);
-	  varDefTable(varID, tableID);
-	}
-    }
 
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
 
-  if ( CDI_Debug )
-    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
-	    varID, param, zaxistype, gridID, levelID);
-}
-#endif
+/**************************************************************/
 
-static
-int gribapiGetParam(grib_handle *gh)
+unsigned reshCountType(const resOps *ops)
 {
-  int pdis = 0, pcat = 0, pnum = 0;
-  int param = 0;
-  int status;
-  long lpar;
+  unsigned countType = 0;
+
+  xassert(ops);
+
+  LIST_INIT(1);
 
-  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-  pdis = (int) lpar;
+  LIST_LOCK();
 
-  status = grib_get_long(gh, "parameterCategory", &lpar);
-  if ( status == 0 ) pcat = (int) lpar;
+  int nsp = namespaceGetActive ();
 
-  status = grib_get_long(gh, "parameterNumber", &lpar);
-  if ( status == 0 ) pnum = (int) lpar;
+  listElem_t *r = resHList[nsp].resources;
+  size_t len = (size_t)resHList[nsp].size;
+  for (size_t i = 0; i < len; i++ )
+    countType += ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == ops);
 
-  param = cdiEncodeParam(pnum, pcat, pdis);
+  LIST_UNLOCK();
 
-  return (param);
+  return countType;
 }
 
-static
-compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype, char *name)
-{
-  compvar2_t compVar;
-  size_t maxlen = sizeof(compVar.name);
-  size_t len = strlen(name);
-  if ( len > maxlen ) len = maxlen;
+/**************************************************************/
 
-  compVar.param     = param;
-  compVar.level1    = level1;
-  compVar.level2    = level2;
-  compVar.ltype     = leveltype;
-  compVar.tsteptype = tsteptype;
-  memset(compVar.name, 0, maxlen);
-  memcpy(compVar.name, name, len);
+int
+reshResourceGetPackSize_intern(int resH, const resOps *ops, void *context, const char* caller, const char* expressionString)
+{
+  listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
+  return curr->res.v.ops->valGetPackSize(curr->res.v.val, context);
+}
 
-  return (compVar);
+void
+reshPackResource_intern(int resH, const resOps *ops, void *buf, int buf_size, int *position, void *context,
+                        const char* caller, const char* expressionString)
+{
+  listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
+  curr->res.v.ops->valPack(curr->res.v.val, buf, buf_size, position, context);
 }
 
-static
-int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
+enum {
+  resHPackHeaderNInt = 2,
+  resHDeleteNInt = 2,
+};
+
+static int getPackBufferSize(void *context)
 {
-  compvar2_t compVar0;
-  size_t maxlen = sizeof(compVar.name);
+  int intpacksize, packBufferSize = 0;
 
-  compVar0.param     = record.param;
-  compVar0.level1    = record.ilevel;
-  compVar0.level2    = record.ilevel2;
-  compVar0.ltype     = record.ltype;
-  compVar0.tsteptype = record.tsteptype;
-  memcpy(compVar0.name, record.varname, maxlen);
+  int nsp = namespaceGetActive ();
 
-  if ( flag == 0 )
-    {
-      if ( compVar0.tsteptype == TSTEP_INSTANT  && compVar.tsteptype == TSTEP_INSTANT3 ) compVar0.tsteptype = TSTEP_INSTANT3;
-      if ( compVar0.tsteptype == TSTEP_INSTANT3 && compVar.tsteptype == TSTEP_INSTANT  ) compVar0.tsteptype = TSTEP_INSTANT;
-    }
+  /* pack start marker, namespace and sererator marker */
+  packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, DATATYPE_INT, context));
 
-  int rstatus = memcmp(&compVar0, &compVar, sizeof(compvar2_t));
+  /* pack resources, type marker and seperator marker */
+  listElem_t *r = resHList[nsp].resources;
+  for ( int i = 0; i < resHList[nsp].size; i++)
+    if (r[i].status & RESH_SYNC_BIT)
+      {
+        if (r[i].status == RESH_DESYNC_DELETED)
+          {
+            packBufferSize += resHDeleteNInt * intpacksize;
+          }
+        else if (r[i].status == RESH_DESYNC_IN_USE)
+          {
+            xassert ( r[i].res.v.ops );
+            /* packed resource plus 1 int for type */
+            packBufferSize +=
+              r[i].res.v.ops->valGetPackSize(r[i].res.v.val, context)
+              + intpacksize;
+          }
+      }
+  /* end marker */
+  packBufferSize += intpacksize;
 
-  return (rstatus);
+  return packBufferSize;
 }
-#endif
 
-#define gribWarning(text, nrecs, timestep, varname, paramstr, level1, level2) \
-            Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text)
+/**************************************************************/
 
-int gribapiScanTimestep1(stream_t * streamptr)
+void reshPackBufferDestroy ( char ** buffer )
 {
-#if  defined  (HAVE_LIBGRIB_API)
-  off_t recpos = 0;
-  unsigned char *gribbuffer = NULL;
-  size_t buffersize = 0;
-  int rstatus;
-  int status;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0;
-  int vdate = 0, vtime = 0;
-  int param = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  size_t readsize;
-  int nrecords, nrecs, recID;
-  int nrecs_scanned = 0;
-  int datatype;
-  size_t recsize = 0;
-  int warn_time = TRUE;
-  // int warn_numavg = TRUE;
-  int taxisID = -1;
-  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
-  taxis_t *taxis;
-  int vlistID;
-  int comptype;
-  long unzipsize;
-  compvar2_t compVar;
-  grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  long editionNumber;
-  long lpar;
-  size_t len;
-  int bitsPerValue;
-  int lieee = FALSE;
-  int lbounds;
-  int level_sf, level_unit;
-  int tsteptype;
-  char paramstr[32];
-  char varname[256];
+  if ( buffer ) free ( *buffer );
+}
 
-  streamptr->curTsID = 0;
+/**************************************************************/
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+void reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
+{
+  int i, packBufferPos = 0;
+  int end = END;
 
-  if ( tsID != 0 )
-    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+  xassert ( packBuffer );
 
-  fileID = streamptr->fileID;
+  LIST_LOCK();
 
-  nrecs = 0;
-  while ( TRUE )
-    {
-      level1 = 0;
-      level2 = 0;
-      recsize = (size_t)gribGetSize(fileID);
-      recpos  = fileGetPos(fileID);
+  int nsp = namespaceGetActive ();
 
-      if ( recsize == 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
+  int pBSize = *packBufferSize = getPackBufferSize(context);
+  char *pB = *packBuffer = (char *)xcalloc(1, (size_t)pBSize);
 
-      readsize = recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
-      if ( rstatus ) break;
+  {
+    int header[resHPackHeaderNInt] = { START, nsp };
+    serializePack(header, resHPackHeaderNInt,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+  }
 
-      lieee = FALSE;
+  listElem_t *r = resHList[nsp].resources;
+  for ( i = 0; i < resHList[nsp].size; i++ )
+    if (r[i].status & RESH_SYNC_BIT)
+      {
+        if (r[i].status == RESH_DESYNC_DELETED)
+          {
+            int temp[resHDeleteNInt]
+              = { RESH_DELETE, namespaceIdxEncode2(nsp, i) };
+            serializePack(temp, resHDeleteNInt, DATATYPE_INT,
+                          pB, pBSize, &packBufferPos, context);
+          }
+        else
+          {
+            listElem_t * curr = r + i;
+            xassert ( curr->res.v.ops );
+            int type = curr->res.v.ops->valTxCode();
+            if ( ! type ) continue;
+            serializePack(&type, 1, DATATYPE_INT, pB,
+                          pBSize, &packBufferPos, context);
+            curr->res.v.ops->valPack(curr->res.v.val,
+                                     pB, pBSize, &packBufferPos, context);
+          }
+        r[i].status &= ~RESH_SYNC_BIT;
+      }
 
-      comptype = COMPRESS_NONE;
+  LIST_UNLOCK();
 
-      nrecs_scanned++;
-      gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
-      GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
+  serializePack(&end, 1,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+}
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+/**************************************************************/
 
-      if ( editionNumber <= 1 )
-	{
-          if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-            {
-              comptype = COMPRESS_SZIP;
-              unzipsize += 100;
-              if ( buffersize < (size_t)unzipsize )
-                {
-                  buffersize = (size_t)unzipsize;
-                  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-                }
-            }
+/* for thread safety this feature would have to be integrated in reshPut */
 
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
+void reshSetStatus ( cdiResH resH, const resOps * ops, int status )
+{
+  int nsp;
+  namespaceTuple_t nspT;
+  listElem_t * listElem;
 
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
+  xassert(ops && (status & RESH_IN_USE_BIT));
 
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  size_t len = 256;
-	  char typeOfPacking[256];
+  LIST_INIT(1);
 
-	  status = grib_get_string(gh, "packingType", typeOfPacking, &len);
-	  if ( status == 0 )
-	    {
-	      // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
-	      if      ( strncmp(typeOfPacking, "grid_jpeg", len)  == 0 ) comptype = COMPRESS_JPEG;
-	      else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) comptype = COMPRESS_SZIP;
-	      else if ( strncmp(typeOfPacking, "grid_ieee", len)  == 0 ) lieee = TRUE;
-	    }
+  LIST_LOCK();
 
-	  param = gribapiGetParam(gh);
+  nsp = namespaceGetActive ();
 
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
+  nspT = namespaceResHDecode ( resH );
 
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+  xassert ( nspT.nsp == nsp &&
+            nspT.idx >= 0 &&
+            nspT.idx < resHList[nsp].size );
 
-      varname[0] = 0;
-      gribapiGetString(gh, "shortName", varname, sizeof(varname));
-      len = strlen(varname);
-      if ( len > 32 ) len = 32;
-      //printf("param = %s  name = %s   l1 = %d  l2 = %d\n", paramstr, varname, level1, level2);
+  xassert ( resHList[nsp].resources );
+  listElem = resHList[nsp].resources + nspT.idx;
 
-      tsteptype = gribapiGetTsteptype(gh);
-      gribapiGetValidityDateTime(gh, &vdate, &vtime);
-      /*
-      printf("%d %d %d\n", vdate, vtime, leveltype1);
-      */
-      if ( lieee )
-        {
-          datatype = DATATYPE_FLT64;
-          status = grib_get_long(gh, "precision", &lpar);
-          if ( status == 0 && lpar == 1 ) datatype = DATATYPE_FLT32;
-        }
-      else
-        {
-          datatype = DATATYPE_PACK;
-          status = grib_get_long(gh, "bitsPerValue", &lpar);
-          if ( status == 0 )
-            {
-              bitsPerValue = (int) lpar;
-              if ( bitsPerValue > 0 && bitsPerValue <= 32 )
-                datatype = bitsPerValue;
-            }
-        }
+  xassert ( listElem->res.v.ops == ops );
 
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
+  listElem->status = status;
 
-          gribapiGetDataDateTime(gh, &rdate, &rtime);
+  LIST_UNLOCK();
+}
 
-	  fcast = gribapiTimeIsFC(gh);
-	  if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-	}
-      else
-	{
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+/**************************************************************/
 
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+int reshGetStatus ( cdiResH resH, const resOps * ops )
+{
+  int nsp;
+  namespaceTuple_t nspT;
 
-	  for ( recID = 0; recID < nrecs; recID++ )
-            if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
+  xassert ( ops );
 
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      if ( recID < nrecs ) break;
-	      if ( warn_time )
-		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
-		  {
-                    if ( datetime0.date == 10101 && datetime0.time == 0 )
-                      {
-                        datetime0.date = datetime.date;
-                        datetime0.time = datetime.time;
+  LIST_INIT(1);
 
-                        gribapiGetDataDateTime(gh, &rdate, &rtime);
+  LIST_LOCK();
 
-                        fcast = gribapiTimeIsFC(gh);
-                        if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-                      }
-                    else
-                      {
-                        gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-                        warn_time = FALSE;
-                      }
-                  }
-	    }
-	  else
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+  nsp = namespaceGetActive ();
 
-	      if ( recID < nrecs )
-		{
-		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-		  continue;
-		}
-	    }
-	}
-      /*
-      if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
-	    {
-	      Message("Change numavg from %d to %d not allowed!",
-		      taxis->numavg, ISEC1_AvgNum);
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
-      */
-      nrecs++;
+  nspT = namespaceResHDecode ( resH );
 
-      if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
-                nrecs, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+  xassert ( nspT.nsp == nsp &&
+            nspT.idx >= 0 &&
+            nspT.idx < resHList[nsp].size );
 
-      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
-                       leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
+  listElem_t *listElem = resHList[nsp].resources + nspT.idx;
 
-      grib_handle_delete(gh);
-      gh = NULL;
-    }
+  const resOps *elemOps = listElem->res.v.ops;
 
-  if ( gh ) grib_handle_delete(gh);
+  LIST_UNLOCK();
 
-  streamptr->rtsteps = 1;
+  xassert(listElem && elemOps == ops);
 
-  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
+  return listElem->status;
+}
 
-  cdi_generate_vars(streamptr);
+/**************************************************************/
 
-  if ( fcast )
-    {
-      taxisID = taxisCreate(TAXIS_RELATIVE);
-      taxis->type  = TAXIS_RELATIVE;
-      taxis->rdate = rdate;
-      taxis->rtime = rtime;
-      taxis->unit  = tunit;
-    }
-  else
-    {
-      taxisID = taxisCreate(TAXIS_ABSOLUTE);
-      taxis->type  = TAXIS_ABSOLUTE;
-    }
+void reshLock ()
+{
+  LIST_LOCK();
+}
 
-  taxis->vdate = (int)datetime0.date;
-  taxis->vtime = (int)datetime0.time;
+/**************************************************************/
 
-  vlistID = streamptr->vlistID;
-  vlistDefTaxis(vlistID, taxisID);
+void reshUnlock ()
+{
+  LIST_UNLOCK();
+}
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  if ( nrecords < streamptr->tsteps[0].recordSize )
-    {
-      streamptr->tsteps[0].recordSize = nrecords;
-      streamptr->tsteps[0].records =
-      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
-    }
+/**************************************************************/
 
-  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
-  streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[0].recIDs[recID] = recID;
+int reshListCompare ( int nsp0, int nsp1 )
+{
+  LIST_INIT(1);
+  LIST_LOCK();
 
-  streamptr->record->buffer     = gribbuffer;
-  streamptr->record->buffersize = buffersize;
+  xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
+          nsp0 >= 0 && nsp1 >= 0);
 
-  if ( streamptr->ntsteps == -1 )
+  int valCompare = 0;
+  int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
+    ? resHList[nsp0].size : resHList[nsp1].size;
+  listElem_t *resources0 = resHList[nsp0].resources,
+    *resources1 = resHList[nsp1].resources;
+  for (i = 0; i < listSizeMin; i++)
     {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
-
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
+      int occupied0 = (resources0[i].status & RESH_IN_USE_BIT) != 0,
+        occupied1 = (resources1[i].status & RESH_IN_USE_BIT) != 0;
+      /* occupation mismatch ? */
+      int diff = occupied0 ^ occupied1;
+      valCompare |= (diff << cdiResHListOccupationMismatch);
+      if (!diff && occupied0)
+        {
+          /* both occupied, do resource types match? */
+          diff = (resources0[i].res.v.ops != resources1[i].res.v.ops
+                  || resources0[i].res.v.ops == NULL);
+          valCompare |= (diff << cdiResHListResourceTypeMismatch);
+          if (!diff)
+            {
+              /* types match, does content match also? */
+              diff
+                = resources0[i].res.v.ops->valCompare(resources0[i].res.v.val,
+                                                      resources1[i].res.v.val);
+              valCompare |= (diff << cdiResHListResourceContentMismatch);
+            }
+        }
     }
+  /* find resources in nsp 0 beyond end of nsp 1 */
+  for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
+    valCompare |= (((resources0[j].status & RESH_IN_USE_BIT) != 0)
+                   << cdiResHListOccupationMismatch);
+  /* find resources in nsp 1 beyond end of nsp 0 */
+  for (; i < resHList[nsp1].size; ++i)
+    valCompare |= (((resources1[i].status & RESH_IN_USE_BIT) != 0)
+                   << cdiResHListOccupationMismatch);
 
-  if ( streamptr->ntsteps == 1 )
-    {
-      if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
-    }
-#else
-  (void)streamptr;
-  Error("GRIB_API support not compiled in!");
-#endif
+  LIST_UNLOCK();
 
-  return (0);
+  return valCompare;
 }
 
+/**************************************************************/
 
-#ifdef HAVE_LIBGRIB_API
-int gribapiScanTimestep2(stream_t * streamptr)
+void reshListPrint(FILE *fp)
 {
-  int rstatus = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer = NULL;
-  size_t buffersize = 0;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  // int gridID;
-  size_t readsize;
-  int nrecords, nrecs, recID, rindex;
-  int nrecs_scanned = 0;
-  size_t recsize = 0;
-  //  int warn_numavg = TRUE;
-  int tsteptype;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  long unzipsize;
-  compvar2_t compVar;
-  grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
-
-  streamptr->curTsID = 1;
+  int i, j, temp;
+  listElem_t * curr;
 
-  fileID  = streamptr->fileID;
-  vlistID = streamptr->vlistID;
-  taxisID = vlistInqTaxis(vlistID);
+  LIST_INIT(1);
 
-  gribbuffer = (unsigned char *) streamptr->record->buffer;
-  buffersize = streamptr->record->buffersize;
 
-  tsID = streamptr->rtsteps;
-  if ( tsID != 1 )
-    Error("Internal problem! unexpected timestep %d", tsID+1);
+  temp = namespaceGetActive ();
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+  fprintf ( fp, "\n\n##########################################\n#\n#  print " \
+            "global resource list \n#\n" );
 
-  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+  for ( i = 0; i < namespaceGetNumber (); i++ )
+    {
+      namespaceSetActive ( i );
 
-  cdi_create_records(streamptr, tsID);
+      fprintf ( fp, "\n" );
+      fprintf ( fp, "##################################\n" );
+      fprintf ( fp, "#\n" );
+      fprintf ( fp, "# namespace=%d\n", i );
+      fprintf ( fp, "#\n" );
+      fprintf ( fp, "##################################\n\n" );
 
-  nrecords = streamptr->tsteps[tsID].nallrecs;
-  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
-  streamptr->tsteps[1].nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[1].recIDs[recID] = -1;
+      fprintf ( fp, "resHList[%d].size=%d\n", i, resHList[i].size );
 
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = streamptr->tsteps[0].records[recID].size;
+      for ( j = 0; j < resHList[i].size; j++ )
+        {
+          curr = resHList[i].resources + j;
+          if (!(curr->status & RESH_IN_USE_BIT))
+            {
+              curr->res.v.ops->valPrint(curr->res.v.val, fp);
+              fprintf ( fp, "\n" );
+            }
+        }
     }
+  fprintf ( fp, "#\n#  end global resource list" \
+            "\n#\n##########################################\n\n" );
 
-  nrecs_scanned = nrecords;
-  rindex = 0;
-  while ( TRUE )
-    {
-      if ( rindex > nrecords ) break;
+  namespaceSetActive ( temp );
+}
 
-      recsize = (size_t)gribGetSize(fileID);
-      recpos  = fileGetPos(fileID);
-      if ( recsize == 0 )
-	{
-	  streamptr->ntsteps = 2;
-	  break;
-	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
 
-      readsize = recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
-      if ( rstatus ) break;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#include <inttypes.h>
+#include <limits.h>
+#include <string.h>
 
-      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	{
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < (size_t)unzipsize )
-	    {
-	      buffersize = (size_t)unzipsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
-	}
 
-      nrecs_scanned++;
-      gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
-      GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
+int
+serializeGetSize(int count, int datatype, void *context)
+{
+  int (*serialize_get_size_p)(int count, int datatype, void *context)
+    = (int (*)(int, int, void *))
+    namespaceSwitchGet(NSSWITCH_SERIALIZE_GET_SIZE).func;
+  return serialize_get_size_p(count, datatype, context);
+}
+
+void serializePack(const void *data, int count, int datatype,
+                   void *buf, int buf_size, int *position, void *context)
+{
+  void (*serialize_pack_p)(const void *data, int count, int datatype,
+                           void *buf, int buf_size, int *position, void *context)
+    = (void (*)(const void *, int, int, void *, int, int *, void *))
+    namespaceSwitchGet(NSSWITCH_SERIALIZE_PACK).func;
+  serialize_pack_p(data, count, datatype, buf, buf_size, position, context);
+}
+
+void serializeUnpack(const void *buf, int buf_size, int *position,
+                     void *data, int count, int datatype, void *context)
+{
+  void (*serialize_unpack_p)(const void *buf, int buf_size, int *position,
+                             void *data, int count, int datatype, void *context)
+    = (void (*)(const void *, int, int *, void *, int, int, void *))
+    namespaceSwitchGet(NSSWITCH_SERIALIZE_UNPACK).func;
+  serialize_unpack_p(buf, buf_size, position, data, count, datatype, context);
+}
+
+
+
+int
+serializeGetSizeInCore(int count, int datatype, void *context)
+{
+  int elemSize;
+  (void)context;
+  switch (datatype)
+  {
+  case DATATYPE_INT8:
+    elemSize = sizeof (int8_t);
+    break;
+  case DATATYPE_INT16:
+    elemSize = sizeof (int16_t);
+    break;
+  case DATATYPE_UINT32:
+    elemSize = sizeof (uint32_t);
+    break;
+  case DATATYPE_INT:
+    elemSize = sizeof (int);
+    break;
+  case DATATYPE_FLT:
+  case DATATYPE_FLT64:
+    elemSize = sizeof (double);
+    break;
+  case DATATYPE_TXT:
+  case DATATYPE_UCHAR:
+    elemSize = 1;
+    break;
+  case DATATYPE_LONG:
+    elemSize = sizeof (long);
+    break;
+  default:
+    xabort("Unexpected datatype");
+  }
+  return count * elemSize;
+}
+
+void serializePackInCore(const void *data, int count, int datatype,
+                         void *buf, int buf_size, int *position, void *context)
+{
+  int size = serializeGetSize(count, datatype, context);
+  int pos = *position;
+  xassert(INT_MAX - pos >= size && buf_size - pos >= size);
+  memcpy((unsigned char *)buf + pos, data, (size_t)size);
+  pos += size;
+  *position = pos;
+}
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+void serializeUnpackInCore(const void *buf, int buf_size, int *position,
+                           void *data, int count, int datatype, void *context)
+{
+  int size = serializeGetSize(count, datatype, context);
+  int pos = *position;
+  xassert(INT_MAX - pos >= size && buf_size - pos >= size);
+  memcpy(data, (unsigned char *)buf + pos, (size_t)size);
+  pos += size;
+  *position = pos;
+}
+#if defined (HAVE_CONFIG_H)
+#endif
 
-      if ( editionNumber <= 1 )
-	{
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
+#ifdef HAVE_LIBSERVICE
 
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
 
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  param = gribapiGetParam(gh);
 
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
 
-      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-      varname[0] = 0;
-      gribapiGetString(gh, "shortName", varname, sizeof(varname));
+enum {
+  SRV_HEADER_LEN = 8,
+};
 
-      gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
-      if ( rindex == 0 )
-	{
-	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
-	    {
-	      taxis->type  = TAXIS_RELATIVE;
+static int initSrvLib      = 0;
+static int srvDefaultHprec = 0;
+static int srvDefaultDprec = 0;
 
-              gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
 
-	      taxis->unit  = gribapiGetTimeUnits(gh);
-	    }
-	  else
-	    {
-	      taxis->type  = TAXIS_ABSOLUTE;
-	    }
-	  taxis->vdate = vdate;
-	  taxis->vtime = vtime;
+/*
+ * A version string.
+ */
 
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	}
+#undef  LIBVERSION
+#define LIBVERSION      1.3.2
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
+static const char srv_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
 
-      tsteptype = gribapiGetTsteptype(gh);
-      /*
-      if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg &&
-		(taxis->numavg != ISEC1_AvgNum) )
-	    {
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
-      */
-      datetime.date  = vdate;
-      datetime.time  = vtime;
+const char *srvLibraryVersion(void)
+{
+  return (srv_libvers);
+}
 
-      compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
-      for ( recID = 0; recID < nrecords; recID++ )
-        if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
+int SRV_Debug = 0;    /* If set to 1, debugging */
 
-      if ( recID == nrecords )
-	{
-	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-	  return (CDI_EUFSTRUCT);
-	}
 
-      if ( streamptr->tsteps[tsID].records[recID].used )
-        {
-          if ( cdiInventoryMode == 1 ) break;
-          else
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+void srvDebug(int debug)
+{
+  SRV_Debug = debug;
 
-              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-	      continue;
-	    }
-	}
+  if ( SRV_Debug )
+    Message("debug level %d", debug);
+}
 
-      streamptr->tsteps[tsID].records[recID].used = TRUE;
-      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
-      if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
-                nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+void srvLibInit()
+{
+  char *envString;
+  char *envName = "SRV_PRECISION";
 
-      streamptr->tsteps[tsID].records[recID].size = recsize;
 
-      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
-	{
-	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		  tsID, recID,
-		  streamptr->tsteps[tsID].records[recID].param, param,
-		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
-	  return (CDI_EUFSTRUCT);
-	}
+  envString = getenv(envName);
+  if ( envString )
+    {
+      int pos;
+      int nrun;
+      if ( strlen(envString) == 2 ) nrun = 1;
+      else                          nrun = 2;
 
-      streamptr->tsteps[1].records[recID].position = recpos;
-      varID = streamptr->tsteps[tsID].records[recID].varID;
-      /*
-      gridID = vlistInqVarGrid(vlistID, varID);
-      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
+      pos = 0;
+      while ( nrun-- )
 	{
-	  if ( IS_NOT_EQUAL(gridInqXval(gridID, 0),ISEC2_FirstLon*0.001) ||
-	       IS_NOT_EQUAL(gridInqYval(gridID, 0),ISEC2_FirstLat*0.001) )
-	    gridChangeType(gridID, GRID_TRAJECTORY);
+	  switch ( tolower((int) envString[pos]) )
+	    {
+	    case 'i':
+	      {
+		switch ( (int) envString[pos+1] )
+		  {
+		  case '4': srvDefaultHprec = SINGLE_PRECISION; break;
+		  case '8': srvDefaultHprec = DOUBLE_PRECISION; break;
+		  default:
+		    Message("Invalid digit in %s: %s", envName, envString);
+		  }
+		break;
+	      }
+	    case 'r':
+	      {
+		switch ( (int) envString[pos+1] )
+		  {
+		  case '4': srvDefaultDprec = SINGLE_PRECISION; break;
+		  case '8': srvDefaultDprec = DOUBLE_PRECISION; break;
+		  default:
+		    Message("Invalid digit in %s: %s", envName, envString);
+		  }
+		break;
+	      }
+	    default:
+              {
+                Message("Invalid character in %s: %s", envName, envString);
+                break;
+              }
+            }
+	  pos += 2;
 	}
-      */
-      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
-	vlistDefVarTsteptype(vlistID, varID, tsteptype);
+    }
 
-      grib_handle_delete(gh);
-      gh = NULL;
+  initSrvLib = 1;
+}
 
-      rindex++;
-    }
 
-  if ( gh ) grib_handle_delete(gh);
+void srvInit(srvrec_t *srvp)
+{
+  srvp->checked    = 0;
+  srvp->byteswap   = 0;
+  srvp->hprec      = 0;
+  srvp->dprec      = 0;
+  srvp->datasize   = 0;
+  srvp->buffersize = 0;
+  srvp->buffer     = NULL;
+}
 
-  nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      if ( ! streamptr->tsteps[tsID].records[recID].used )
-	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
-	  vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	}
-      else
-	{
-	  nrecs++;
-	}
-    }
-  streamptr->tsteps[tsID].nrecs = nrecs;
 
-  streamptr->rtsteps = 2;
+srvrec_t *srvNew(void)
+{
+  srvrec_t *srvp;
 
-  if ( streamptr->ntsteps == -1 )
-    {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+  if ( ! initSrvLib ) srvLibInit();
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
-    }
+  srvp = (srvrec_t *) malloc(sizeof(srvrec_t));
 
-  streamptr->record->buffer     = gribbuffer;
-  streamptr->record->buffersize = buffersize;
+  srvInit(srvp);
 
-  return (rstatus);
+  return (srvp);
 }
-#endif
 
 
-#if  defined  (HAVE_LIBGRIB_API)
-int gribapiScanTimestep(stream_t * streamptr)
+void srvDelete(srvrec_t *srvp)
 {
-  int rstatus = 0;
-  size_t recsize = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer;
-  size_t buffersize = 0;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int vrecID, recID;
-  //int warn_numavg = TRUE;
-  size_t readsize;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  int rindex, nrecs = 0;
-  int nrecs_scanned;
-  long unzipsize;
-  compvar2_t compVar;
-  grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
-
-  vlistID = streamptr->vlistID;
-
-  if ( CDI_Debug )
+  if ( srvp )
     {
-      Message("streamID = %d", streamptr->self);
-      Message("cts = %d", streamptr->curTsID);
-      Message("rts = %d", streamptr->rtsteps);
-      Message("nts = %d", streamptr->ntsteps);
+      if ( srvp->buffer ) free(srvp->buffer);
+      free(srvp);
     }
+}
 
-  tsID  = streamptr->rtsteps;
-  taxis = &streamptr->tsteps[tsID].taxis;
-
-  if ( streamptr->tsteps[tsID].recordSize == 0 )
-    {
-      gribbuffer = (unsigned char *) streamptr->record->buffer;
-      buffersize = streamptr->record->buffersize;
-
-      cdi_create_records(streamptr, tsID);
-
-      nrecs = streamptr->tsteps[1].nrecs;
-
-      streamptr->tsteps[tsID].nrecs = nrecs;
-      streamptr->tsteps[tsID].recIDs = (int *) malloc(nrecs*sizeof(int));
-      for ( recID = 0; recID < nrecs; recID++ )
-	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamptr->fileID;
+int srvCheckFiletype(int fileID, int *swap)
+{
+  size_t blocklen = 0;
+  size_t sblocklen = 0;
+  size_t data = 0;
+  size_t dimx = 0, dimy = 0;
+  size_t fact = 0;
+  int found = 0;
+  unsigned char buffer[72], *pbuf;
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+  if ( fileRead(fileID, buffer, 4) != 4 ) return (found);
 
-      nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
-      rindex = 0;
-      while ( TRUE )
-	{
-	  if ( rindex > nrecs ) break;
+  blocklen  = (size_t) get_UINT32(buffer);
+  sblocklen = (size_t) get_SUINT32(buffer);
 
-	  recsize = (size_t)gribGetSize(fileID);
-	  recpos  = fileGetPos(fileID);
-	  if ( recsize == 0 )
-	    {
-	      streamptr->ntsteps = streamptr->rtsteps + 1;
-	      break;
-	    }
+  if ( SRV_Debug )
+    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
 
-	  if ( rindex >= nrecs ) break;
+  if ( blocklen == 32 )
+    {
+     *swap = 0;
+      fact = blocklen>>3;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
+      pbuf = buffer+4*fact;      dimx = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+5*fact;      dimy = (size_t) get_UINT32(pbuf);
+      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
+    }
+  else if ( blocklen == 64 )
+    {
+     *swap = 0;
+      fact = blocklen>>3;
+      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
+      pbuf = buffer+4*fact;      dimx = (size_t) get_UINT64(pbuf);
+      pbuf = buffer+5*fact;      dimy = (size_t) get_UINT64(pbuf);
+      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
+    }
+  else if ( sblocklen == 32 )
+    {
+     *swap = 1;
+      fact = sblocklen>>3;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
+      pbuf = buffer+4*fact;       dimx = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+5*fact;       dimy = (size_t) get_SUINT32(pbuf);
+      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
+    }
+  else if ( sblocklen == 64 )
+    {
+     *swap = 1;
+      fact = sblocklen>>3;
+      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
+      pbuf = buffer+4*fact;       dimx = (size_t) get_SUINT64(pbuf);
+      pbuf = buffer+5*fact;       dimy = (size_t) get_SUINT64(pbuf);
+      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
+    }
 
-	  if ( recsize > buffersize )
-	    {
-	      buffersize = recsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
+  fileRewind(fileID);
 
-	  readsize = recsize;
-	  rstatus = gribRead(fileID, gribbuffer, &readsize);
-	  if ( rstatus )
-	    {
-	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
-		      streamptr->tsteps[tsID].recordSize);
-	      break;
-	    }
+  if      ( data && dimx*dimy*fact == data ) found = 1;
+  else if ( data && dimx*dimy*8    == data ) found = 1;
 
-	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	    {
-	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	      if ( buffersize < (size_t)unzipsize )
-		{
-		  buffersize = (size_t)unzipsize;
-		  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-		}
-	    }
+  if ( SRV_Debug )
+    {
+      Message("swap = %d fact = %d", *swap, fact);
+      Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
+    }
 
-          nrecs_scanned++;
-	  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
-	  GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
+  return (found);
+}
 
-	  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-	  if ( editionNumber <= 1 )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	      rtabnum = (int) lpar;
-	      GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	      rcode = (int) lpar;
+int srvInqHeader(srvrec_t *srvp, int *header)
+{
+  size_t i;
 
-	      param = cdiEncodeParam(rcode, rtabnum, 255);
+  for ( i = 0; i < SRV_HEADER_LEN; i++ )
+    header[i] = srvp->header[i];
+  
+  if ( SRV_Debug )
+    Message("datasize = %lu", srvp->datasize);
 
-	      grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-              level_sf = 0;
-              level_unit = 0;
-	    }
-	  else
-	    {
-	      param = gribapiGetParam(gh);
+  return (0);
+}
 
-	      grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	    }
 
-          cdiParamToString(param, paramstr, sizeof(paramstr));
+int srvDefHeader(srvrec_t *srvp, const int *header)
+{
+  size_t i;
 
-          varname[0] = 0;
-	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
+  for ( i = 0; i < SRV_HEADER_LEN; i++ )
+    srvp->header[i] = header[i];
 
-	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
+  srvp->datasize = (size_t)(header[4] * header[5]);
 
-	  if ( rindex == nrecs ) break;
+  if ( SRV_Debug )
+    Message("datasize = %lu", srvp->datasize);
 
-	  if ( rindex == 0 )
-	    {
-	      taxisID = vlistInqTaxis(vlistID);
-	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
-		{
-		  taxis->type  = TAXIS_RELATIVE;
+  return (0);
+}
 
-                  gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
 
-		  taxis->unit  = gribapiGetTimeUnits(gh);
-		}
-	      else
-		{
-		  taxis->type  = TAXIS_ABSOLUTE;
-		}
-	      taxis->vdate = vdate;
-	      taxis->vtime = vtime;
+int srvInqData(srvrec_t *srvp, int prec, void *data)
+{
+  size_t datasize;
+  size_t i;
+  int ierr = 0;
+  int dprec;
+  void *buffer;
+  int byteswap = srvp->byteswap;
 
-	      datetime0.date = vdate;
-	      datetime0.time = vtime;
-	    }
-	  /*
-	  if ( ISEC1_AvgNum )
-	    {
-	      if (  taxis->numavg && warn_numavg &&
-		   (taxis->numavg != ISEC1_AvgNum) )
-		{
-		  warn_numavg = FALSE;
-		}
-	      else
-		{
-		  taxis->numavg = ISEC1_AvgNum;
-		}
-	    }
-	  */
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+  datasize = srvp->datasize;
 
-          int tsteptype = gribapiGetTsteptype(gh);
+  buffer = srvp->buffer;
 
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+  dprec = srvp->dprec;
 
-	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
-	    {
-	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
-	    }
+  switch ( dprec )
+    {
+    case SINGLE_PRECISION:
+      {
+	if ( sizeof(FLT32) == 4 )
+	  {
+	    if ( byteswap ) swap4byte(buffer, datasize);
 
-	  if ( vrecID == nrecs )
-	    {
-	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+	    if ( dprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT32));
+	    else
+	      for (i = 0; i < datasize; i++)
+		((double *) data)[i] = (double) ((float *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT32));
+	  }
+	break;
+      }
+    case DOUBLE_PRECISION:
+	if ( sizeof(FLT64) == 8 )
+	  {
+	    if ( byteswap ) swap8byte(buffer, datasize);
 
-	      if ( cdiInventoryMode == 1 )
-		return (CDI_EUFSTRUCT);
-	      else
-		continue;
-	    }
+	    if ( dprec == prec )
+	      memcpy(data, buffer, datasize*sizeof(FLT64));
+	    else
+	      for (i = 0; i < datasize; i++)
+		((float *) data)[i] = (float) ((double *) buffer)[i];
+	  }
+	else
+	  {
+	    Error("not implemented for %d byte float", sizeof(FLT64));
+	  }
+	break;
+    default:
+      {
+	Error("unexpected data precision %d", dprec);
+        break;
+      }
+    }
 
-	  if ( cdiInventoryMode != 1 )
-	    {
-	      if ( streamptr->tsteps[tsID].records[recID].used )
-		{
-		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+  return (ierr);
+}
 
-		  if ( CDI_Debug )
-                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
 
-		  continue;
-		}
-	    }
+int srvInqDataSP(srvrec_t *srvp, float *data)
+{
+  return (srvInqData(srvp, SINGLE_PRECISION, (void *) data));
+}
 
-          streamptr->tsteps[tsID].records[recID].used = TRUE;
-          streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
-	  if ( CDI_Debug )
-	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
+int srvInqDataDP(srvrec_t *srvp, double *data)
+{
+  return (srvInqData(srvp, DOUBLE_PRECISION, (void *) data));
+}
 
-	  if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
-	    {
-	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		      tsID, recID,
-		      streamptr->tsteps[tsID].records[recID].param, param,
-		      streamptr->tsteps[tsID].records[recID].ilevel, level1);
-	      Error("Invalid, unsupported or inconsistent record structure");
-	    }
 
-	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = recsize;
+int srvDefData(srvrec_t *srvp, int prec, const void *data)
+{
+  size_t datasize;
+  size_t blocklen;
+  size_t buffersize;
+  size_t i;
+  int dprec, hprec;
+  int *header;
+  void *buffer;
 
-	  if ( CDI_Debug )
-	    Message("%4d %8d %4d %8d %8d %6d", rindex, (int)recpos, param, level1, vdate, vtime);
+  if ( srvDefaultDprec ) dprec = srvDefaultDprec;
+  else                   dprec = srvp->dprec;
 
-	  grib_handle_delete(gh);
-	  gh = NULL;
+  if ( ! dprec ) dprec = prec;
 
-	  rindex++;
-	}
+  srvp->dprec = dprec;
 
-      if ( gh ) grib_handle_delete(gh);
+  if ( srvDefaultHprec ) hprec = srvDefaultHprec;
+  else                   hprec = srvp->hprec;
 
-      for ( vrecID = 0; vrecID < nrecs; vrecID++ )
-	{
-	  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-	  if ( ! streamptr->tsteps[tsID].records[recID].used ) break;
-	}
+  if ( ! hprec ) hprec = dprec;
 
-      if ( vrecID < nrecs )
-	{
-	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
-	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, paramstr,
-                      streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
-	  return (CDI_EUFSTRUCT);
-	}
+  srvp->hprec = hprec;
 
-      streamptr->rtsteps++;
+  header = srvp->header;
 
-      if ( streamptr->ntsteps != streamptr->rtsteps )
-	{
-	  tsID = tstepsNewEntry(streamptr);
-	  if ( tsID != streamptr->rtsteps )
-	    Error("Internal error. tsID = %d", tsID);
+  datasize = (size_t)(header[4] * header[5]);
+  blocklen = datasize * (size_t)dprec;
 
-	  streamptr->tsteps[tsID-1].next   = 1;
-	  streamptr->tsteps[tsID].position = recpos;
-	}
+  srvp->datasize = datasize;
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
-      streamptr->tsteps[tsID].position = recpos;
+  buffersize = srvp->buffersize;
 
-      streamptr->record->buffer     = gribbuffer;
-      streamptr->record->buffersize = buffersize;
+  if ( buffersize != blocklen )
+    {
+      buffersize = blocklen;
+      buffer = srvp->buffer;
+      buffer = realloc(buffer, buffersize);
+      srvp->buffer = buffer;
+      srvp->buffersize = buffersize;
     }
+  else
+    buffer = srvp->buffer;
 
-  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+  switch ( dprec )
     {
-      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
-      streamptr->ntsteps = tsID;
+    case SINGLE_PRECISION:
+      {
+	if ( dprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT32));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((float *) buffer)[i] = (float) ((double *) data)[i];
+
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	if ( dprec == prec )
+	  memcpy(buffer, data, datasize*sizeof(FLT64));
+	else
+	  for (i = 0; i < datasize; i++)
+	    ((double *) buffer)[i] = (double) ((float *) data)[i];
+
+	break;
+      }
+    default:
+      {
+	Error("unexpected data precision %d", dprec);
+        break;
+      }
     }
 
-  rstatus = (int)streamptr->ntsteps;
-  return (rstatus);
+  return (0);
 }
-#endif
 
-#ifdef gribWarning
-#undef gribWarning
-#endif
 
-#ifdef HAVE_LIBGRIB_API
-int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, double missval, int vlistID, int varID)
+int srvDefDataSP(srvrec_t *srvp, const float *data)
 {
-  int status = 0;
-  long lpar;
-  long editionNumber, numberOfPoints;
-  size_t datasize, dummy, recsize;
-  grib_handle *gh = NULL;
+  return (srvDefData(srvp, SINGLE_PRECISION, (void *) data));
+}
 
-  UNUSED(vlistID);
-  UNUSED(varID);
 
-  if ( unreduced )
-    {
-      static int lwarn = 1;
+int srvDefDataDP(srvrec_t *srvp, const double *data)
+{
+  return (srvDefData(srvp, DOUBLE_PRECISION, (void *) data));
+}
 
-      if ( lwarn )
-	{
-	  lwarn = 0;
-	  Warning("Conversion of gaussian reduced grids unsupported!");
-	}
+
+int srvRead(int fileID, srvrec_t *srvp)
+{
+  size_t datasize;
+  size_t blocklen, blocklen2;
+  size_t i;
+  char tempheader[64];
+  void *buffer;
+  int byteswap;
+  int status;
+
+  if ( ! srvp->checked )
+    {
+      status = srvCheckFiletype(fileID, &srvp->byteswap);
+      if ( status == 0 ) Error("Not a SERVICE file!");
+      srvp->checked = 1;
     }
 
-  recsize = (size_t)gribsize;
-  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
-  GRIB_CHECK(my_grib_set_double(gh, "missingValue", missval), 0);
+  byteswap = srvp->byteswap;
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
+  /* read header record */
+  blocklen = binReadF77Block(fileID, byteswap);
 
-  /* get the size of the values array*/
-  GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
-  GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
+  if ( fileEOF(fileID) ) return (-1);
 
-  // printf("values_size = %d  numberOfPoints = %ld\n", datasize, numberOfPoints);
+  if ( SRV_Debug )
+    Message("blocklen = %lu", blocklen);
 
-  if ( gridsize != (int) datasize )
-    Error("Internal problem: gridsize(%d) != datasize(%d)!", gridsize, datasize);
-  dummy = datasize;
-  GRIB_CHECK(grib_get_double_array(gh, "values", data, &dummy), 0);
+  size_t hprec = blocklen / SRV_HEADER_LEN;
 
-  int gridtype;
-  GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
-  gridtype = (int) lpar;
+  srvp->hprec = (int)hprec;
 
-  *nmiss = 0;
-  if ( gridtype < 50 || gridtype > 53 )
+  switch ( hprec )
     {
-      GRIB_CHECK(grib_get_long(gh, "numberOfMissing", &lpar), 0);
-      *nmiss = (int) lpar;
-      // printf("gridtype %d, nmiss %d\n", gridtype, nmiss);
-    }
+    case SINGLE_PRECISION:
+      {
+	binReadInt32(fileID, byteswap, SRV_HEADER_LEN, (INT32 *) tempheader);
 
-  grib_handle_delete(gh);
+	for ( i = 0; i < SRV_HEADER_LEN; i++ )
+          srvp->header[i] = (int) ((INT32 *) tempheader)[i];
 
-  return (status);
-}
-#endif
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	binReadInt64(fileID, byteswap, SRV_HEADER_LEN, (INT64 *) tempheader);
 
+	for ( i = 0; i < SRV_HEADER_LEN; i++ )
+          srvp->header[i] = (int) ((INT64 *) tempheader)[i];
 
-#if  defined  (HAVE_LIBGRIB_API)
-static
-void gribapiDefInstitut(grib_handle *gh, int vlistID, int varID)
-{
-  int instID;
+	break;
+      }
+    default:
+      {
+	Error("Unexpected header precision %d", hprec);
+        break;
+      }
+    }
 
-  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
-    instID = vlistInqInstitut(vlistID);
-  else
-    instID = vlistInqVarInstitut(vlistID, varID);
+  blocklen2 = binReadF77Block(fileID, byteswap);
 
-  if ( instID != CDI_UNDEFID )
+  if ( blocklen2 != blocklen )
     {
-      long center, subcenter;
-      long center0, subcenter0;
+      Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+      if ( blocklen2 != 0 ) return (-1);
+    }
 
-      center    = institutInqCenter(instID);
-      subcenter = institutInqSubcenter(instID);
+  srvp->datasize = (size_t)(srvp->header[4] * srvp->header[5]);
 
-      GRIB_CHECK(grib_get_long(gh, "centre", &center0), 0);
-      GRIB_CHECK(grib_get_long(gh, "subCentre", &subcenter0), 0);
+  if ( SRV_Debug )
+    Message("datasize = %lu", srvp->datasize);
 
-      if ( center != center0 )
-	GRIB_CHECK(my_grib_set_long(gh, "centre", center), 0);
-      if ( subcenter != subcenter0 )
-	GRIB_CHECK(my_grib_set_long(gh, "subCentre", subcenter), 0);
-    }
-}
+  blocklen = binReadF77Block(fileID, byteswap);
 
-static
-void gribapiDefModel(grib_handle *gh, int vlistID, int varID)
-{
-  int modelID;
+  size_t buffersize = srvp->buffersize;
 
-  if ( vlistInqModel(vlistID) != CDI_UNDEFID )
-    modelID = vlistInqModel(vlistID);
+  if ( buffersize < blocklen )
+    {
+      buffersize = blocklen;
+      buffer = srvp->buffer;
+      buffer = realloc(buffer, buffersize);
+      srvp->buffer = buffer;
+      srvp->buffersize = buffersize;
+    }
   else
-    modelID = vlistInqVarModel(vlistID, varID);
+    buffer = srvp->buffer;
 
-  if ( modelID != CDI_UNDEFID )
-    GRIB_CHECK(my_grib_set_long(gh, "generatingProcessIdentifier", modelInqGribID(modelID)), 0);
-}
+  datasize = srvp->datasize;
 
-static
-void gribapiDefParam(int editionNumber, grib_handle *gh, int param, const char *name)
-{
-  int pdis, pcat, pnum;
+  size_t dprec = blocklen / datasize;
 
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  srvp->dprec = (int)dprec;
 
-  if ( pnum < 0 )
+  if ( dprec != SINGLE_PRECISION && dprec != DOUBLE_PRECISION )
     {
-      size_t len;
-      int status;
-      len = strlen(name);
-      status = my_grib_set_string(gh, "shortName", name, &len);
-      if ( status != 0 )
-	Warning("grib_api: No match for shortName=%s", name);
+      Warning("Unexpected data precision %d", dprec);
+      return (-1);
     }
-  else
-    {
-      if ( pnum < 0 ) pnum = -pnum;
 
-      if ( editionNumber <= 1 )
-	{
-	  if ( pdis != 255 )
-	    {
-	      char paramstr[32];
-	      cdiParamToString(param, paramstr, sizeof(paramstr));
-	      Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
-	    }
+  fileRead(fileID, buffer, blocklen);
 
-	  GRIB_CHECK(my_grib_set_long(gh, "table2Version",        pcat), 0);
-	  GRIB_CHECK(my_grib_set_long(gh, "indicatorOfParameter", pnum), 0);
-	}
-      else
-	{
-	  GRIB_CHECK(my_grib_set_long(gh, "discipline",        pdis), 0);
-	  GRIB_CHECK(my_grib_set_long(gh, "parameterCategory", pcat), 0);
-	  GRIB_CHECK(my_grib_set_long(gh, "parameterNumber",   pnum), 0);
-	}
+  blocklen2 = binReadF77Block(fileID, byteswap);
+
+  if ( blocklen2 != blocklen )
+    {
+      Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
+      if ( blocklen2 != 0 ) return (-1);
     }
 
-  // printf("param: %d.%d.%d %s\n", pnum, pcat, pdis, name);
+  return (0);
 }
 
-static
-int getTimeunitFactor(int timeunit)
+
+void srvWrite(int fileID, srvrec_t *srvp)
 {
-  int factor = 1;
+  size_t datasize;
+  size_t blocklen;
+  size_t i;
+  int dprec, hprec;
+  char tempheader[64];
+  int *header;
+  void *buffer;
+  int byteswap = srvp->byteswap;
 
-  switch (timeunit)
-    {
-    case TUNIT_SECOND:  factor =     1;  break;
-    case TUNIT_MINUTE:  factor =    60;  break;
-    case TUNIT_HOUR:    factor =  3600;  break;
-    case TUNIT_3HOURS:  factor = 10800;  break;
-    case TUNIT_6HOURS:  factor = 21600;  break;
-    case TUNIT_12HOURS: factor = 43200;  break;
-    case TUNIT_DAY:     factor = 86400;  break;
-    default:            factor =  3600;  break;
-    }
+  dprec  = srvp->dprec;
+  hprec  = srvp->hprec;
+  header = srvp->header;
 
-  return (factor);
-}
+  /* write header record */
+  blocklen = SRV_HEADER_LEN * (size_t)hprec;
 
-static
-void gribapiDefStepUnits(grib_handle *gh, int timeunit, int proDefTempNum, int gcinit)
-{
-  long unitsOfTime;
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  switch (timeunit)
+  switch ( hprec )
     {
-    case TUNIT_SECOND:  unitsOfTime = 13;  break;
-    case TUNIT_MINUTE:  unitsOfTime =  0;  break;
-    case TUNIT_HOUR:    unitsOfTime =  1;  break;
-    case TUNIT_3HOURS:  unitsOfTime = 10;  break;
-    case TUNIT_6HOURS:  unitsOfTime = 11;  break;
-    case TUNIT_12HOURS: unitsOfTime = 12;  break;
-    case TUNIT_DAY:     unitsOfTime =  2;  break;
-    default:            unitsOfTime =  1;  break;
-    }
+    case SINGLE_PRECISION:
+      {
+	for (i = 0; i < SRV_HEADER_LEN; i++)
+          ((INT32 *) tempheader)[i] = (INT32) header[i];
 
-  if ( !gcinit )
-    {
-      GRIB_CHECK(my_grib_set_long(gh, "stepUnits", unitsOfTime), 0);
-      if ( proDefTempNum == 8 || proDefTempNum == 11 )
-        GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitForTimeRange", unitsOfTime), 0);
-      GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
-    }
-}
+	binWriteInt32(fileID, byteswap, SRV_HEADER_LEN, (INT32 *) tempheader);
 
-static
-int gribapiDefSteptype(int editionNumber, grib_handle *gh, int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int gcinit)
-{
-  long proDefTempNum = 0;
-  size_t len = 64;
-  char stepType[len];
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	for (i = 0; i < SRV_HEADER_LEN; i++)
+          ((INT64 *) tempheader)[i] = (INT64) header[i];
 
-  switch ( tsteptype )
-    {
-    case TSTEP_AVG:      strcpy(stepType, "avg");     proDefTempNum = 8; break;
-    case TSTEP_ACCUM:    strcpy(stepType, "accum");   proDefTempNum = 8; break;
-    case TSTEP_MAX:      strcpy(stepType, "max");     proDefTempNum = 8; break;
-    case TSTEP_MIN:      strcpy(stepType, "min");     proDefTempNum = 8; break;
-    case TSTEP_DIFF:     strcpy(stepType, "diff");    proDefTempNum = 8; break;
-    case TSTEP_RMS:      strcpy(stepType, "rms");     proDefTempNum = 8; break;
-    case TSTEP_SD:       strcpy(stepType, "sd");      proDefTempNum = 8; break;
-    case TSTEP_COV:      strcpy(stepType, "cov");     proDefTempNum = 8; break;
-    case TSTEP_RATIO:    strcpy(stepType, "ratio");   proDefTempNum = 8; break;
-    case TSTEP_INSTANT:  strcpy(stepType, "instant"); proDefTempNum = 0; break;
-    default:             strcpy(stepType, "instant"); proDefTempNum = 0; break;
-    }
+	binWriteInt64(fileID, byteswap, SRV_HEADER_LEN, (INT64 *) tempheader);
 
-  if ( typeOfGeneratingProcess == 4 )
-    {
-      if ( proDefTempNum == 8 ) proDefTempNum = 11;
-      else                      proDefTempNum = 1;
+	break;
+      }
+    default:
+      {
+	Error("unexpected header precision %d", hprec);
+        break;
+      }
     }
 
-  if ( productDefinitionTemplate != -1 ) proDefTempNum = productDefinitionTemplate;
+  binWriteF77Block(fileID, byteswap, blocklen);
 
-  if ( !gcinit )
+  datasize = (size_t)(header[4] * header[5]);
+  blocklen = datasize * (size_t)dprec;
+
+  binWriteF77Block(fileID, byteswap, blocklen);
+
+  srvp->datasize = datasize;
+
+  buffer = srvp->buffer;
+
+  switch ( dprec )
     {
-      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "productDefinitionTemplateNumber", proDefTempNum), 0);
-      len = strlen(stepType);
-      GRIB_CHECK(my_grib_set_string(gh, "stepType", stepType, &len), 0);
+    case SINGLE_PRECISION:
+      {
+	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
+	break;
+      }
+    case DOUBLE_PRECISION:
+      {
+	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
+	break;
+      }
+    default:
+      {
+	Error("unexpected data precision %d", dprec);
+        break;
+      }
     }
 
-  return ((int)proDefTempNum);
+  binWriteF77Block(fileID, byteswap, blocklen);
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#endif  /* HAVE_LIBSERVICE */
+#ifndef _STREAM_SRV_H
+#define _STREAM_SRV_H
+
+#ifndef _SERVICE_H
+#endif
+
+int    srvInqContents(stream_t *streamptr);
+int    srvInqTimestep(stream_t *streamptr, int tsID);
+
+int    srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void   srvDefRecord(stream_t *streamptr);
+void   srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void   srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   srvWriteRecord(stream_t *streamptr, const double *data);
+
+void   srvReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
+
+void   srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
+
+#endif  /* _STREAM_SRV_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_EXT_H
+#define _STREAM_EXT_H
+
+#ifndef _EXTRA_H
+#endif
+
+int    extInqContents(stream_t *streamptr);
+int    extInqTimestep(stream_t *streamptr, int tsID);
+
+int    extInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void   extDefRecord(stream_t *streamptr);
+void   extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void   extReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   extWriteRecord(stream_t *streamptr, const double *data);
+
+void   extReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   extWriteVarDP(stream_t *streamptr, int varID, const double *data);
+
+void   extReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
-static
-void gribapiDefDateTimeAbs(int editionNumber, grib_handle *gh, int date, int time, int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int gcinit)
-{
-  (void ) gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
+#endif  /* _STREAM_EXT_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_IEG_H
+#define _STREAM_IEG_H
 
-  if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "significanceOfReferenceTime", 0), 0);
-  if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "stepRange", 0), 0);
+#ifndef _IEG_H
+#endif
 
-  if ( date == 0 ) date = 10101;
-  gribapiSetDataDateTime(gh, date, time);
-}
+int    iegInqContents(stream_t *streamptr);
+int    iegInqTimestep(stream_t *streamptr, int tsID);
 
-static
-int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rtime, int vdate, int vtime,
-                          int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int timeunit, int calendar, int gcinit)
-{
-  int status = -1;
-  int year, month, day, hour, minute, second;
-  int julday1, secofday1, julday2, secofday2, days, secs;
-  int factor;
-  long startStep = 0, endStep;
+int    iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
+void   iegDefRecord(stream_t *streamptr);
+void   iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+void   iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   iegWriteRecord(stream_t *streamptr, const double *data);
 
-  cdiDecodeDate(rdate, &year, &month, &day);
-  cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
+void   iegReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-  if ( vdate == 0 && vtime == 0 ) { vdate = rdate; vtime = rtime; }
+void   iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
-  cdiDecodeDate(vdate, &year, &month, &day);
-  cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
+#endif  /* _STREAM_IEG_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
 
-  factor = getTimeunitFactor(timeunit);
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
 
-  if ( !(int) fmod(days*86400.0 + secs, factor) )
-    {
-      int proDefTempNum = gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
 
-      gribapiDefStepUnits(gh, timeunit, proDefTempNum, gcinit);
 
-      endStep = (int) ((days*86400.0 + secs)/factor);
 
-      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "significanceOfReferenceTime", 1), 0);
-      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "stepRange", 0), 0);
+static stream_t *stream_new_entry(int resH);
+static void stream_delete_entry(stream_t *streamptr);
+static int streamCompareP(void * streamptr1, void * streamptr2);
+static void streamDestroyP(void * streamptr);
+static void streamPrintP(void * streamptr, FILE * fp);
+static int streamGetPackSize(void * streamptr, void *context);
+static void streamPack(void * streamptr, void * buff, int size, int * position, void *context);
+static int streamTxCode(void);
 
-      if ( rdate == 0 ) rdate = 10101;
-      gribapiSetDataDateTime(gh, rdate, rtime);
+const resOps streamOps = {
+  streamCompareP,
+  streamDestroyP,
+  streamPrintP,
+  streamGetPackSize,
+  streamPack,
+  streamTxCode
+};
 
-      // printf(">>>>> tsteptype %d  startStep %ld  endStep %ld\n", tsteptype, startStep, endStep);
 
-      if ( proDefTempNum == 0 ) startStep = endStep;
 
-      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "forecastTime", startStep), 0);
-      GRIB_CHECK(my_grib_set_long(gh, "endStep", endStep), 0);
 
-      status = 0;
-    }
+#undef  IsBigendian
+#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
 
-  return (status);
-}
 
 static
-void gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOfGeneratingProcess, grib_handle *gh,
-                    int vdate, int vtime, int tsteptype, int numavg, int taxisID, int gcinit)
+int getByteorder(int byteswap)
 {
-  int taxistype = -1;
-
-  UNUSED(numavg);
-
-  if ( taxisID != -1 ) taxistype = taxisInqType(taxisID);
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
+  int byteorder = -1;
 
-  if ( typeOfGeneratingProcess == 196 )
+  if ( IsBigendian() )
     {
-      vdate = 10101;
-      vtime = 0;
-      taxistype = TAXIS_ABSOLUTE;
+      if ( byteswap ) byteorder = CDI_LITTLEENDIAN;
+      else            byteorder = CDI_BIGENDIAN;
     }
-  /*
-  else if ( typeOfGeneratingProcess == 9 )
+  else
     {
+      if ( byteswap ) byteorder = CDI_BIGENDIAN;
+      else            byteorder = CDI_LITTLEENDIAN;
     }
-  */
 
-  if ( taxistype == TAXIS_RELATIVE )
-    {
-      int status;
-      int calendar = taxisInqCalendar(taxisID);
-      int rdate    = taxisInqRdate(taxisID);
-      int rtime    = taxisInqRtime(taxisID);
-      int timeunit = taxisInqTunit(taxisID);
+  return (byteorder);
+}
 
-      status = gribapiDefDateTimeRel(editionNumber, gh, rdate, rtime, vdate, vtime,
-                                     productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, timeunit, calendar, gcinit);
+// used also in CDO
+int cdiGetFiletype(const char *filename, int *byteorder)
+{
+  int filetype = CDI_EUFTYPE;
+  int swap = 0;
+  int version;
+  long recpos;
+  char buffer[8];
 
-      if ( status != 0 ) taxistype = TAXIS_ABSOLUTE;
-    }
+  int fileID = fileOpen(filename, "r");
 
-  if ( taxistype == TAXIS_ABSOLUTE )
+  if ( fileID == CDI_UNDEFID )
     {
-      gribapiDefDateTimeAbs(editionNumber, gh, vdate, vtime, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
+      if ( strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0 )
+	return (FILETYPE_NC);
+      else
+	return (CDI_ESYSTEM);
     }
-}
-
-static
-void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, int lieee, int datatype, int nmiss, int gcinit)
-{
-  int gridtype;
-  int status;
-  static short lwarn = TRUE;
-  size_t len;
-  char *mesg;
-
-  UNUSED(nmiss);
 
-  gridtype = gridInqType(gridID);
+  if ( fileRead(fileID, buffer, 8) != 8 ) return (CDI_EUFTYPE);
 
-  if ( editionNumber <= 1 )
-    if ( gridtype == GRID_GME || gridtype == GRID_UNSTRUCTURED )
-      gridtype = -1;
+  fileRewind(fileID);
 
-  if ( gridtype == GRID_GENERIC )
+  if ( memcmp(buffer, "GRIB", 4) == 0 )
     {
-      int xsize, ysize, gridsize;
-
-      gridsize = gridInqSize(gridID);
-      xsize = gridInqXsize(gridID);
-      ysize = gridInqYsize(gridID);
-
-      if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
-	    ysize ==  96 || ysize == 160 || ysize == 192 ||
-	    ysize == 240 || ysize == 320 || ysize == 384 ||
-	    ysize == 480 || ysize == 768 ) &&
-	   (xsize == 2*ysize || xsize == 1) )
-	{
-	  gridtype = GRID_GAUSSIAN;
-	  gridChangeType(gridID, gridtype);
-	}
-      else if ( gridsize == 1 )
+      version = buffer[7];
+      if ( version <= 1 )
 	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
+	  filetype = FILETYPE_GRB;
+	  if ( CDI_Debug ) Message("found GRIB file = %s, version %d", filename, version);
 	}
-      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
+      else if ( version == 2 )
 	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
+	  filetype = FILETYPE_GRB2;
+	  if ( CDI_Debug ) Message("found GRIB2 file = %s", filename);
 	}
     }
-  else if ( gridtype == GRID_CURVILINEAR )
+  else if ( memcmp(buffer, "CDF\001", 4) == 0 )
     {
-      if ( lwarn && gridInqSize(gridID) > 1 )
-	{
-	  lwarn = FALSE;
-	  Warning("Curvilinear grids are unsupported in GRIB format! Created wrong GDS!");
-	}
-      gridtype = GRID_LONLAT;
+      filetype = FILETYPE_NC;
+      if ( CDI_Debug ) Message("found CDF1 file = %s", filename);
     }
-
-  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
+  else if ( memcmp(buffer, "CDF\002", 4) == 0 )
     {
-      if ( editionNumber != 2 || lieee ) { comptype = 0; }
-
-      if ( comptype )
-        {
-          if ( comptype == COMPRESS_JPEG )
-            {
-              mesg = "grid_jpeg"; len = strlen(mesg);
-              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-            }
-          else if ( comptype == COMPRESS_SZIP )
-            {
-              mesg = "grid_ccsds"; len = strlen(mesg);
-              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-            }
-          else
-            {
-              mesg = "grid_simple"; len = strlen(mesg);
-              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-            }
-        }
+      filetype = FILETYPE_NC2;
+      if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
     }
-
-  if ( gcinit ) return;
-
-  switch (gridtype)
+  else if ( memcmp(buffer+1, "HDF", 3) == 0 )
     {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_GAUSSIAN_REDUCED:
-    case GRID_TRAJECTORY:
-      {
-	int nlon = 0, nlat;
-	double xfirst = 0, xlast = 0, xinc = 0;
-	double yfirst = 0, ylast = 0, yinc = 0;
-	double latIncr;
-
-	if ( gridtype == GRID_GAUSSIAN )
-	  {
-	    mesg = "regular_gg"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-	  }
-	else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-	  {
-	    mesg = "reduced_gg"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-	  }
-	else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
-	  {
-	    mesg = "rotated_ll"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-	  }
-	else
-	  {
-	    mesg = "regular_ll"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-	  }
-
-	nlon = gridInqXsize(gridID);
-	nlat = gridInqYsize(gridID);
-
-	if ( gridtype == GRID_GAUSSIAN_REDUCED )
-	  {
-	    int *rowlon, i;
-	    long *pl = NULL;
-
-	    nlon = 0;
-
-	    rowlon = (int *) malloc(nlat*sizeof(int));
-	    pl     = (long *) malloc(nlat*sizeof(long));
-	    gridInqRowlon(gridID, rowlon);
-	    for ( i = 0; i < nlat; ++i ) pl[i] = rowlon[i];
-
-	    // GRIB_CHECK(my_grib_set_long_array(gh, "pl", pl, nlat), 0);
-
-	    free(pl);
-	    free(rowlon);
-	  }
-	else
-	  {
-	    if ( nlon == 0 )
-	      {
-		nlon = 1;
-	      }
-	    else
-	      {
-		xfirst = gridInqXval(gridID,      0);
-		xlast  = gridInqXval(gridID, nlon-1);
-		xinc   = gridInqXinc(gridID);
-	      }
-	  }
-
-	if ( nlat == 0 )
-	  {
-	    nlat = 1;
-	  }
-	else
-	  {
-	    yfirst = gridInqYval(gridID,      0);
-	    ylast  = gridInqYval(gridID, nlat-1);
-	    yinc   = gridInqYinc(gridID);
-	  }
-
-	GRIB_CHECK(my_grib_set_long(gh, "Ni", nlon), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "Nj", nlat), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", xfirst), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfLastGridPointInDegrees",  xlast), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees",  yfirst), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees",   ylast), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "iDirectionIncrementInDegrees", xinc), 0);
-
-        {
-          long jscan = 0;
-          if ( yfirst < ylast ) jscan = 1;
-          GRIB_CHECK(my_grib_set_long(gh, "jScansPositively", jscan), 0);
-        }
-	/*
-	if ( fabs(xinc*1000 - ISEC2_LonIncr) > FLT_EPSILON )
-	  ISEC2_LonIncr = 0;
-	*/
-	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
-          {
-            int np = gridInqNP(gridID);
-            if ( np == 0 ) np = nlat/2;
-            GRIB_CHECK(my_grib_set_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", np), 0);
-          }
-	else
-	  {
-	    latIncr = yinc;
-	    if ( latIncr < 0 ) latIncr = -latIncr;
-	    GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", latIncr), 0);
-	    /*
-	    if ( fabs(yinc*1000 - ISEC2_LatIncr) > FLT_EPSILON )
-	      ISEC2_LatIncr = 0;
-	    */
-	  }
-	/*
-	if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
-	  if ( ISEC2_LonIncr != 0 && ISEC2_LatIncr == 0 ) ISEC2_LatIncr = ISEC2_LonIncr;
-
-	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
-	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
-
-	if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
-	  ISEC2_ResFlag = 0;
-	else
-	  ISEC2_ResFlag = 128;
-	*/
-	if ( gridIsRotated(gridID) )
-	  {
-	    double xpole, ypole, angle;
-	    xpole = gridInqXpole(gridID);
-	    ypole = gridInqYpole(gridID);
-	    angle = gridInqAngle(gridID);
-	    /* change from north to south pole */
-	    ypole = -ypole;
-	    xpole =  xpole + 180;
-	    GRIB_CHECK(my_grib_set_double(gh, "latitudeOfSouthernPoleInDegrees",  ypole), 0);
-	    GRIB_CHECK(my_grib_set_double(gh, "longitudeOfSouthernPoleInDegrees", xpole), 0);
-	    GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0);
-	  }
+      filetype = FILETYPE_NC4;
+      if ( CDI_Debug ) Message("found HDF file = %s", filename);
+    }
+#if  defined  (HAVE_LIBSERVICE)
+  else if ( srvCheckFiletype(fileID, &swap) )
+    {
+      filetype = FILETYPE_SRV;
+      if ( CDI_Debug ) Message("found SRV file = %s", filename);
+    }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+  else if ( extCheckFiletype(fileID, &swap) )
+    {
+      filetype = FILETYPE_EXT;
+      if ( CDI_Debug ) Message("found EXT file = %s", filename);
+    }
+#endif
+#if  defined  (HAVE_LIBIEG)
+  else if ( iegCheckFiletype(fileID, &swap) )
+    {
+      filetype = FILETYPE_IEG;
+      if ( CDI_Debug ) Message("found IEG file = %s", filename);
+    }
+#endif
+  else if ( gribCheckSeek(fileID, &recpos, &version) == 0 )
+    {
+      if ( version <= 1 )
+	{
+	  filetype = FILETYPE_GRB;
+	  if ( CDI_Debug ) Message("found seeked GRIB file = %s", filename);
+	}
+      else if ( version == 2 )
+	{
+	  filetype = FILETYPE_GRB2;
+	  if ( CDI_Debug ) Message("found seeked GRIB2 file = %s", filename);
+	}
+    }
 
-	/* East -> West */
-	//if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
+  fileClose(fileID);
 
-	/* South -> North */
-	//if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
+  *byteorder = getByteorder(swap);
 
-        if ( editionNumber != 2 ) { lieee = 0; comptype = 0; }
+  return (filetype);
+}
 
-        if ( lieee )
-          {
-            mesg = "grid_ieee"; len = strlen(mesg);
-            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+/*
+ at Function  streamInqFiletype
+ at Title     Get the filetype
 
-	    if ( datatype == DATATYPE_FLT64 )
-	      GRIB_CHECK(my_grib_set_long(gh, "precision", 2), 0);
-	    else
-	      GRIB_CHECK(my_grib_set_long(gh, "precision", 1), 0);
-          }
-        else
-	  {
-            if ( comptype == COMPRESS_JPEG )
-              {
-                mesg = "grid_jpeg"; len = strlen(mesg);
-                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-              }
-            else if ( comptype == COMPRESS_SZIP )
-              {
-                mesg = "grid_ccsds"; len = strlen(mesg);
-                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-              }
-            else
-              {
-                mesg = "grid_simple"; len = strlen(mesg);
-                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-              }
-	  }
+ at Prototype int streamInqFiletype(int streamID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
 
-	break;
-      }
-    case GRID_LCC:
-      {
-	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
-	int xsize, ysize;
-	int projflag, scanflag;
+ at Description
+The function @func{streamInqFiletype} returns the filetype of a stream.
 
-	xsize = gridInqXsize(gridID);
-	ysize = gridInqYsize(gridID);
+ at Result
+ at func{streamInqFiletype} returns the type of the file format,
+one of the set of predefined CDI file format types.
+The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC}, @func{FILETYPE_NC2},
+ at func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV}, @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
 
-	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
-		   &projflag, &scanflag);
+ at EndFunction
+*/
+int streamInqFiletype(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-        mesg = "lambert"; len = strlen(mesg);
-        GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+  stream_check_ptr(__func__, streamptr);
 
-	GRIB_CHECK(my_grib_set_long(gh, "Nx", xsize), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "Ny", ysize), 0);
+  return (streamptr->filetype);
+}
 
-	GRIB_CHECK(my_grib_set_double(gh, "DxInMetres", lround(xincm)), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "DyInMetres", lround(yincm)), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", originLon), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", originLat), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "LoVInDegrees", lonParY), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "Latin1InDegrees", lat1), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat2), 0);
 
-        if ( editionNumber <= 1 )
-          {
-            GRIB_CHECK(my_grib_set_long(gh, "projectionCenterFlag", projflag), 0);
-            GRIB_CHECK(my_grib_set_long(gh, "scanningMode", scanflag), 0);
-          }
-        /*
-	ISEC2_Lambert_LatSP  = 0;
-	ISEC2_Lambert_LatSP  = 0;
-        */
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	int trunc = gridInqTrunc(gridID);
+int getByteswap(int byteorder)
+{
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
+  int byteswap = 0;
 
-	mesg = "sh"; len = strlen(mesg);
-	GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+  if ( IsBigendian() )
+    {
+      if ( byteorder == CDI_LITTLEENDIAN ) byteswap = TRUE;
+    }
+  else
+    {
+      if ( byteorder == CDI_BIGENDIAN ) byteswap = TRUE;
+    }
 
-	GRIB_CHECK(my_grib_set_long(gh, "J", trunc), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "K", trunc), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "M", trunc), 0);
+  return (byteswap);
+}
 
-	// GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridInqSize(gridID)), 0);
-        /*
-        if ( lieee )
-          {
-            printf("spectral_ieee\n");
-            if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridInqSize(gridID)), 0);
-            mesg = "spectral_ieee"; len = strlen(mesg);
-            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-          }
-        else */ if ( gridInqComplexPacking(gridID) )
-	  {
-	    if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridInqSize(gridID)), 0);
-	    mesg = "spectral_complex"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+/*
+ at Function  streamDefByteorder
+ at Title     Define the byte order
 
-	    GRIB_CHECK(my_grib_set_long(gh, "JS", 20), 0);
-	    GRIB_CHECK(my_grib_set_long(gh, "KS", 20), 0);
-	    GRIB_CHECK(my_grib_set_long(gh, "MS", 20), 0);
-	  }
-	else
-	  {
-	    mesg = "spectral_simple"; len = strlen(mesg);
-	    GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-	  }
+ at Prototype void streamDefByteorder(int streamID, int byteorder)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  byteorder The byte order of a dataset, one of the CDI constants @func{CDI_BIGENDIAN} and
+                     @func{CDI_LITTLEENDIAN}.
 
-	break;
-      }
-    case GRID_GME:
-      {
-	GRIB_CHECK(my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_GME), 0);
+ at Description
+The function @func{streamDefByteorder} defines the byte order of a binary dataset
+with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
 
-	GRIB_CHECK(my_grib_set_long(gh, "nd", gridInqGMEnd(gridID)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "Ni", gridInqGMEni(gridID)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "n2", gridInqGMEni2(gridID)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "n3", gridInqGMEni3(gridID)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "latitudeOfThePolePoint", 90000000), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "longitudeOfThePolePoint", 0), 0);
+ at EndFunction
+*/
+void streamDefByteorder(int streamID, int byteorder)
+{
+  int filetype;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-	GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridInqSize(gridID)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", gridInqSize(gridID)), 0);
+  stream_check_ptr(__func__, streamptr);
 
-        if ( comptype == COMPRESS_SZIP )
-          {
-            mesg = "grid_ccsds"; len = strlen(mesg);
-            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-          }
+  streamptr->byteorder = byteorder;
+  filetype = streamptr->filetype;
+
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+	srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+	srvp->byteswap = getByteswap(byteorder);
 
 	break;
       }
-    case GRID_UNSTRUCTURED:
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
       {
-	static int warning = 1;
-
-	status = my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_UNSTRUCTURED);
-	if ( status != 0 && warning )
-	  {
-	    warning = 0;
-	    Warning("Can't write reference grid!");
-	    Warning("gridDefinitionTemplateNumber %d not found (grib2/template.3.%d.def)!",
-		    GRIB2_GTYPE_UNSTRUCTURED, GRIB2_GTYPE_UNSTRUCTURED);
-	  }
-	else
-	  {
-            unsigned char uuid[CDI_UUID_SIZE];
-            int position = gridInqPosition(gridID);
-            int number = gridInqNumber(gridID);
-            if ( position < 0 ) position = 0;
-            if ( number < 0 ) number = 0;
-	    GRIB_CHECK(my_grib_set_long(gh, "numberOfGridUsed", number), 0);
-	    GRIB_CHECK(my_grib_set_long(gh, "numberOfGridInReference", position), 0);
-            len = CDI_UUID_SIZE;
-            gridInqUUID(gridID, uuid);
-	    if (grib_set_bytes(gh, "uuidOfHGrid", uuid, &len) != 0)
-	      Warning("Can't write UUID!");
-	  }
-
-        if ( comptype == COMPRESS_SZIP )
-          {
-            mesg = "grid_ccsds"; len = strlen(mesg);
-            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-          }
+	extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+	extp->byteswap = getByteswap(byteorder);
 
 	break;
       }
-    default:
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
       {
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+	iegp->byteswap = getByteswap(byteorder);
+
 	break;
       }
+#endif
     }
+  reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
 }
 
-static
-void getLevelFactor(double level, long *factor, long *out_scaled_value)
+/*
+ at Function  streamInqByteorder
+ at Title     Get the byte order
+
+ at Prototype int streamInqByteorder(int streamID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+
+ at Description
+The function @func{streamInqByteorder} returns the byte order of a binary dataset
+with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
+
+ at Result
+ at func{streamInqByteorder} returns the type of the byte order.
+The valid CDI byte order types are @func{CDI_BIGENDIAN} and @func{CDI_LITTLEENDIAN}
+
+ at EndFunction
+*/
+int streamInqByteorder(int streamID)
 {
-  double scaled_value  = level;
-  /* FIXME: lround might be better here */
-  long   iscaled_value = (long) round(scaled_value);
-  long   i;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  const double eps = 1.e-8;
-  for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
-    {
-      scaled_value *= 10.;
-      /* FIXME: lround might be better here */
-      iscaled_value = (long)round(scaled_value);
-    }
+  stream_check_ptr(__func__, streamptr);
 
-  (*factor)           = i;
-  (*out_scaled_value) = iscaled_value;
+  return (streamptr->byteorder);
 }
 
-static
-void gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
+
+const char *streamFilesuffix(int filetype)
 {
-  if ( !gcinit ) GRIB_CHECK(my_grib_set_long(gh, keyname, leveltype), 0);
+  // static char *fileSuffix[] = {"", ".grb", ".g2", ".nc", ".nc", ".nc4", ".nc4", ".srv", ".ext", ".ieg"};
+  /* note: the 2nd dimenstion of the fileSuffix array must be equal to or
+   * larger than the length of the longest suffix (dot and \0 terminator
+   * included) */
+  static const char fileSuffix[][5] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
+  int size = (int)(sizeof(fileSuffix)/sizeof(fileSuffix[0]));
+
+  if ( filetype > 0 && filetype < size )
+    return (fileSuffix[filetype]);
+  else
+    return (fileSuffix[0]);
+}
+
+
+const char *streamFilename(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+
+  stream_check_ptr(__func__, streamptr);
+
+  return (streamptr->filename);
 }
 
 static
-void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2, int lbounds, double level, double dlevel1, double dlevel2)
+long cdiInqTimeSize(int streamID)
 {
-  long scaled_level;
-  long factor;
+  int tsID = 0, nrecs;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", leveltype1);
-  if ( lbounds ) gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", leveltype2);
+  stream_check_ptr(__func__, streamptr);
 
-  if ( !lbounds ) dlevel1 = level;
+  long ntsteps = streamptr->ntsteps;
 
-  getLevelFactor(dlevel1, &factor, &scaled_level);
-  GRIB_CHECK(my_grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
-  GRIB_CHECK(my_grib_set_long(gh, "scaledValueOfFirstFixedSurface", scaled_level), 0);
+  if ( ntsteps == (long)CDI_UNDEFID )
+    while ( (nrecs = streamInqTimestep(streamID, tsID++)) )
+      ntsteps = streamptr->ntsteps;
 
-  if ( lbounds )
-    {
-      getLevelFactor(dlevel2, &factor, &scaled_level);
-      GRIB_CHECK(my_grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
-      GRIB_CHECK(my_grib_set_long(gh, "scaledValueOfSecondFixedSurface", scaled_level), 0);
-    }
+  return (ntsteps);
 }
 
-int zaxisInqLtype2(int zaxisID);
-
 static
-void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
+int cdiInqContents(stream_t * streamptr)
 {
-  int lbounds = 0;
-  static int warning = 1;
-  double dlevel1 = 0, dlevel2 = 0;
-
-  int zaxistype = zaxisInqType(zaxisID);
-  int ltype = zaxisInqLtype(zaxisID);
-  int ltype2 = zaxisInqLtype2(zaxisID);
-  double level = zaxisInqLevel(zaxisID, levelID);
-
-  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-    {
-      lbounds = 1;
-      dlevel1 = zaxisInqLbound(zaxisID, levelID);
-      dlevel2 = zaxisInqUbound(zaxisID, levelID);
-    }
-  else
-    {
-      dlevel1 = level;
-      dlevel2 = 0;
-    }
+  int status = 0;
 
-  if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
-    {
-      Message("Changed zaxis type from %s to %s", zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
-      zaxistype = ZAXIS_PRESSURE;
-      zaxisChangeType(zaxisID, zaxistype);
-      zaxisDefUnits(zaxisID, "Pa");
-    }
+  int filetype = streamptr->filetype;
 
-  switch (zaxistype)
+  switch (filetype)
     {
-    case ZAXIS_SURFACE:
-    case ZAXIS_MEANSEA:
-    case ZAXIS_HEIGHT:
-    case ZAXIS_ALTITUDE:
-    case ZAXIS_SIGMA:
-    case ZAXIS_DEPTH_BELOW_SEA:
-    case ZAXIS_ISENTROPIC:
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
-	if ( editionNumber <= 1 )
-          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
-        else
-          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-
-        GRIB_CHECK(my_grib_set_long(gh, "level", (long)level), 0);
-
+        status = grbInqContents(streamptr);
 	break;
       }
-    case ZAXIS_CLOUD_BASE:
-    case ZAXIS_CLOUD_TOP:
-    case ZAXIS_ISOTHERM_ZERO:
-    case ZAXIS_TOA:
-    case ZAXIS_SEA_BOTTOM:
-    case ZAXIS_LAKE_BOTTOM:
-    case ZAXIS_SEDIMENT_BOTTOM:
-    case ZAXIS_SEDIMENT_BOTTOM_TA:
-    case ZAXIS_SEDIMENT_BOTTOM_TW:
-    case ZAXIS_MIX_LAYER:
-    case ZAXIS_ATMOSPHERE:
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
       {
-        if ( lbounds )
-          {
-            if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
-            else
-              {
-                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-                gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-              }
-
-            GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
-            GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
-          }
-        else
-          {
-            if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
-            else
-              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-
-            GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
-          }
-
-        break;
+        status = srvInqContents(streamptr);
+	break;
       }
-    case ZAXIS_HYBRID:
-    case ZAXIS_HYBRID_HALF:
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
       {
-	if ( lbounds )
-	  {
-	    if ( editionNumber <= 1 )
-	      gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
-            else
-	      {
-		gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
-		gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID);
-	      }
-
-	    GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
-	    GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
-	  }
-	else
-	  {
-	    if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
-            else
-              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
-
-	    GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
-	  }
-
-        if ( !gcinit )
-          {
-            int vctsize = zaxisInqVctSize(zaxisID);
-            if ( vctsize == 0 && warning )
-              {
-                char paramstr[32];
-                cdiParamToString(param, paramstr, sizeof(paramstr));
-                Warning("VCT missing ( param = %s, zaxisID = %d )", paramstr, zaxisID);
-                warning = 0;
-              }
-            GRIB_CHECK(my_grib_set_long(gh, "PVPresent", 1), 0);
-            GRIB_CHECK(grib_set_double_array(gh, "pv", zaxisInqVctPtr(zaxisID), (size_t)vctsize), 0);
-          }
-
+        status = extInqContents(streamptr);
 	break;
       }
-    case ZAXIS_PRESSURE:
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
       {
-	double dum;
-	char units[128];
-
-	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
-
-	zaxisInqUnits(zaxisID, units);
-	if ( memcmp(units, "Pa", 2) != 0 )
-          {
-            level   *= 100;
-            dlevel1 *= 100;
-            dlevel2 *= 100;
-          }
-
-        if ( editionNumber <= 1 )
-          {
-            long leveltype = GRIB1_LTYPE_ISOBARIC;
-
-            if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-              leveltype = GRIB1_LTYPE_99;
-            else
-              level /= 100;
-
-            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", leveltype);
-            GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
-	  }
-	else
-	  {
-            if ( ltype2 == -1 ) ltype2 = GRIB2_LTYPE_ISOBARIC;
-            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_ISOBARIC, ltype2, lbounds, level, dlevel1, dlevel2);
-	  }
-
+        status = iegInqContents(streamptr);
 	break;
       }
-    case ZAXIS_SNOW:
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
-        if ( editionNumber <= 1 )
-          ; // not available
-	else
-          {
-            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_SNOW, GRIB2_LTYPE_SNOW, lbounds, level, dlevel1, dlevel2);
-          }
-
+        status = cdfInqContents(streamptr);
 	break;
       }
-    case ZAXIS_DEPTH_BELOW_LAND:
+#endif
+    default:
       {
-	char units[128];
-
-	zaxisInqUnits(zaxisID, units);
-
-	if ( editionNumber <= 1 )
-	  {
-            double scalefactor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor =   0.1;
-	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor =   1; // cm
-	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor =  10;
-	    else                                    scalefactor = 100;
+	if ( CDI_Debug )
+	  Message("%s support not compiled in!", strfiletype(filetype));
 
-	    gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH);
-	    GRIB_CHECK(my_grib_set_double(gh, "level", level*scalefactor), 0);
-	  }
-	else
-	  {
-            double scalefactor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor = 0.001;
-	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor = 0.01;
-	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor = 0.1;
-	    else                                    scalefactor = 1; // meter
+	status = CDI_ELIBNAVAIL;
+        break;
+      }
+    }
 
-            level   *= scalefactor;
-            dlevel1 *= scalefactor;
-            dlevel2 *= scalefactor;
+  if ( status == 0 )
+    {
+      int vlistID = streamptr->vlistID;
+      int taxisID = vlistInqTaxis(vlistID);
+      if ( taxisID != CDI_UNDEFID )
+        {
+          taxis_t *taxisptr1 = &streamptr->tsteps[0].taxis;
+          taxis_t *taxisptr2 = taxisPtr(taxisID);
+          ptaxisCopy(taxisptr2, taxisptr1);
+        }
+    }
 
-            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_LANDDEPTH, GRIB2_LTYPE_LANDDEPTH, lbounds, level, dlevel1, dlevel2);
-	  }
+  return (status);
+}
 
-	break;
+int cdiStreamOpenDefaultDelegate(const char *filename, const char *filemode,
+                                 int filetype, stream_t *streamptr,
+                                 int recordBufIsToBeCreated)
+{
+  int fileID;
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        fileID = gribOpen(filename, filemode);
+        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+        if (recordBufIsToBeCreated)
+          {
+            streamptr->record = (Record *) malloc(sizeof(Record));
+            streamptr->record->buffer = NULL;
+          }
+        break;
       }
-    case ZAXIS_REFERENCE:
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
       {
-        unsigned char uuid[CDI_UUID_SIZE];
-
-        if ( !gcinit )
+        fileID = fileOpen(filename, filemode);
+        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+        if (recordBufIsToBeCreated)
           {
-            GRIB_CHECK(my_grib_set_long(gh, "genVertHeightCoords", 1), 0);
+            streamptr->record = (Record *) malloc(sizeof(Record));
+            streamptr->record->buffer = NULL;
+            streamptr->record->exsep  = srvNew();
           }
-
-        if ( lbounds )
+        break;
+      }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        fileID = fileOpen(filename, filemode);
+        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+        if (recordBufIsToBeCreated)
           {
-            if ( editionNumber <= 1 )
-              ; // not available
-            else
-              {
-                int number = zaxisInqNumber(zaxisID);
-                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
-                gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_REFERENCE);
-                GRIB_CHECK(my_grib_set_long(gh, "NV", 6), 0);
-                GRIB_CHECK(my_grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
-                GRIB_CHECK(my_grib_set_long(gh, "numberOfVGridUsed", number), 0);
-                size_t len = CDI_UUID_SIZE;
-                zaxisInqUUID(zaxisID, uuid);
-                if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
-                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
-                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
-              }
+            streamptr->record = (Record *) malloc(sizeof(Record));
+            streamptr->record->buffer = NULL;
+            streamptr->record->exsep  = extNew();
           }
-        else
+        break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        fileID = fileOpen(filename, filemode);
+        if ( fileID < 0 ) fileID = CDI_ESYSTEM;
+        if (recordBufIsToBeCreated)
           {
-            if ( editionNumber <= 1 )
-              ; // not available
-            else
-              {
-                int number = zaxisInqNumber(zaxisID);
-                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
-                GRIB_CHECK(my_grib_set_long(gh, "NV", 6), 0);
-                GRIB_CHECK(my_grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
-                GRIB_CHECK(my_grib_set_long(gh, "numberOfVGridUsed", number), 0);
-                size_t len = CDI_UUID_SIZE;
-                zaxisInqUUID(zaxisID, uuid);
-                if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
-                GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
-              }
+            streamptr->record = (Record *) malloc(sizeof(Record));
+            streamptr->record->buffer = NULL;
+            streamptr->record->exsep   = iegNew();
           }
-
         break;
       }
-    case ZAXIS_GENERIC:
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
       {
-	if ( editionNumber <= 1 )
-          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", ltype);
-        else
-          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", ltype);
-
-	GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
-
-	break;
+        fileID = cdfOpen(filename, filemode);
+        break;
       }
-    default:
+    case FILETYPE_NC2:
       {
-	Error("Unsupported zaxis type: %s", zaxisNamePtr(zaxistype));
-	break;
+        fileID = cdfOpen64(filename, filemode);
+        break;
+      }
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+        fileID = cdf4Open(filename, filemode, &filetype);
+        break;
       }
-    }
-}
-#endif
-
-/* #define GRIBAPIENCODETEST 1 */
-
-#ifdef HAVE_LIBGRIB_API
-size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		     int vdate, int vtime, int tsteptype, int numavg,
-		     long datasize, const double *data, int nmiss, unsigned char **gribbuffer, size_t *gribbuffersize,
-		     int comptype, void *gribContainer)
-{
-  size_t recsize = 0;
-  void *dummy = NULL;
-  int datatype;
-  int param;
-  int lieee = FALSE;
-  /*  int ensID, ensCount, forecast_type; *//* Ensemble Data */
-  int typeOfGeneratingProcess;
-  int productDefinitionTemplate;
-  long bitsPerValue;
-  long editionNumber = 2;
-  char name[256];
-  gribContainer_t *gc = (gribContainer_t *) gribContainer;
-  // extern unsigned char _grib_template_GRIB2[];
-
-  param    = vlistInqVarParam(vlistID, varID);
-  datatype = vlistInqVarDatatype(vlistID, varID);
-  typeOfGeneratingProcess = vlistInqVarTypeOfGeneratingProcess(vlistID, varID);
-  productDefinitionTemplate = vlistInqVarProductDefinitionTemplate(vlistID, varID);
-
-  vlistInqVarName(vlistID, varID, name);
-
-#if defined(GRIBAPIENCODETEST)
-  grib_handle *gh = (grib_handle *) gribHandleNew(editionNumber);
-#else
-  grib_handle *gh = gc->gribHandle;
 #endif
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-  if ( editionNumber == 2 )
-    {
-      if ( typeOfGeneratingProcess == -1 ) typeOfGeneratingProcess = 0;
-      if ( ! gc->init ) GRIB_CHECK(my_grib_set_long(gh, "typeOfGeneratingProcess", typeOfGeneratingProcess), 0);
-    }
-
-  /*
-  if( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
-    {
-      GRIB_CHECK(my_grib_set_long(gh, "typeOfEnsembleForecast", forecast_type ), 0);
-      GRIB_CHECK(my_grib_set_long(gh, "numberOfForecastsInEnsemble", ensCount ), 0);
-      GRIB_CHECK(my_grib_set_long(gh, "perturbationNumber", ensID ), 0);
+    default:
+      {
+        if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
+        return (CDI_ELIBNAVAIL);
+      }
     }
-  */
-
-  gribapiDefTime((int)editionNumber, productDefinitionTemplate, typeOfGeneratingProcess, gh, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID), gc->init);
 
-  if ( ! gc->init ) gribapiDefInstitut(gh, vlistID, varID);
-  if ( ! gc->init ) gribapiDefModel(gh, vlistID, varID);
+  streamptr->filetype = filetype;
 
-  if ( ! gc->init ) gribapiDefParam(editionNumber, gh, param, name);
+  return fileID;
+}
 
-  if ( editionNumber == 2 && (datatype == DATATYPE_FLT32 || datatype == DATATYPE_FLT64) ) lieee = TRUE;
 
-  /* bitsPerValue have to be defined before call to DefGrid (complex packing) */
-  //  if ( lieee == FALSE )
-    {
-      bitsPerValue = grbBitsPerValue(datatype);
-      GRIB_CHECK(my_grib_set_long(gh, "bitsPerValue", bitsPerValue), 0);
-    }
+static int
+streamOpenID(const char *filename, const char *filemode, int filetype,
+             int resH)
+{
+  int fileID = CDI_UNDEFID;
+  int status;
 
-  gribapiDefGrid((int)editionNumber, gh, gridID, comptype, lieee, datatype, nmiss, gc->init);
+  if ( CDI_Debug )
+    Message("Open %s mode %c file %s", strfiletype(filetype), (int) *filemode,
+            filename?filename:"(NUL)");
 
-  gribapiDefLevel((int)editionNumber, gh, param, zaxisID, levelID, gc->init);
+  if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
 
-  /* ---------------------------------- */
-  /* Local change: 2013-01-28, FP (DWD) */
-  /* ---------------------------------- */
+  stream_t *streamptr = stream_new_entry(resH);
+  int streamID = CDI_ESYSTEM;
 
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  //if (!gc->init)
   {
-    for ( int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++ )
-      {
-        if ( vlistptr->vars[varID].opt_grib_dbl_update[i] )
-          {
-            //DR: Fix for multi-level fields (otherwise only the 1st level is correct)
-            if ( zaxisInqSize(zaxisID)==(levelID+1) ) vlistptr->vars[varID].opt_grib_dbl_update[i] = FALSE;
-            int ret = my_grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
-                                         vlistptr->vars[varID].opt_grib_dbl_val[i]);
-            if (ret != 0) {
-              fprintf(stderr, "key \"%s\"  :   value = %g\n",
-                      vlistptr->vars[varID].opt_grib_dbl_keyword[i],
-                      vlistptr->vars[varID].opt_grib_dbl_val[i]);
-            }
-            GRIB_CHECK(ret, 0);
-          }
-      }
-    for ( int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++ )
-      {
-        if ( vlistptr->vars[varID].opt_grib_int_update[i] )
-          {
-            //DR: Fix for multi-level fields (otherwise only the 1st level is correct)
-            if ( zaxisInqSize(zaxisID)==(levelID+1) ) vlistptr->vars[varID].opt_grib_int_update[i] = FALSE;
-            int ret = my_grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
-                                       vlistptr->vars[varID].opt_grib_int_val[i]);
-            if (ret != 0) {
-              fprintf(stderr, "key \"%s\"  :   value = %d\n",
-                      vlistptr->vars[varID].opt_grib_int_keyword[i],
-                      vlistptr->vars[varID].opt_grib_int_val[i]);
-            }
-            GRIB_CHECK(ret, 0);
-          }
-      }
-  }
+    int (*streamOpenDelegate)(const char *filename, const char *filemode,
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
+      namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
 
+    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
+  }
 
-  if ( nmiss > 0 )
+  if (fileID < 0)
     {
-      GRIB_CHECK(my_grib_set_long(gh, "bitmapPresent", 1), 0);
-      GRIB_CHECK(my_grib_set_double(gh, "missingValue", vlistInqVarMissval(vlistID, varID)), 0);
+      free(streamptr->record);
+      stream_delete_entry(streamptr);
+      streamID = fileID;
     }
+  else
+    {
+      streamID  = streamptr->self;
 
-  GRIB_CHECK(grib_set_double_array(gh, "values", data, (size_t)datasize), 0);
-
-  /* get the size of coded message  */
-  GRIB_CHECK(grib_get_message(gh, (const void **)&dummy, &recsize), 0);
-  recsize += 512; /* add some space for possible filling */
-  *gribbuffersize = recsize;
-  *gribbuffer = (unsigned char *) malloc(*gribbuffersize);
+      if ( streamID < 0 ) return (CDI_ELIMIT);
 
-  /* get a copy of the coded message */
-  GRIB_CHECK(grib_get_message_copy(gh, *gribbuffer, &recsize), 0);
+      streamptr->filemode = tolower(*filemode);
+      streamptr->filename = strdupx(filename);
+      streamptr->fileID   = fileID;
 
-#if defined(GRIBAPIENCODETEST)
-  gribHandleDelete(gh);
-#endif
+      if ( streamptr->filemode == 'r' )
+	{
+	  int vlistID = vlistCreate();
+	  if ( vlistID < 0 ) return(CDI_ELIMIT);
 
-  gc->init = TRUE;
+	  streamptr->vlistID = vlistID;
+	  /* cdiReadByteorder(streamID); */
+	  status = cdiInqContents(streamptr);
+	  if ( status < 0 ) return (status);
+	  vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
+	  vlistptr->ntsteps = streamptr->ntsteps;
+	}
+    }
 
-  return (recsize);
+  return (streamID);
 }
-#endif
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <stdlib.h>
 
-
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
-                       const char *container_name)
+int streamOpen(const char *filename, const char *filemode, int filetype)
 {
+  return streamOpenID(filename, filemode, filetype, CDI_UNDEFID);
+}
 
-  int fileID1 = streamptr1->fileID;
-  int fileID2 = streamptr2->fileID;
-
-  int tsID    = streamptr1->curTsID;
-  int vrecID  = streamptr1->tsteps[tsID].curRecID;
-  int recID   = streamptr1->tsteps[tsID].recIDs[vrecID];
-  off_t recpos  = streamptr1->tsteps[tsID].records[recID].position;
-  size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
+static int streamOpenA(const char *filename, const char *filemode, int filetype)
+{
+  int fileID = CDI_UNDEFID;
+  int streamID = CDI_ESYSTEM;
+  int status;
+  stream_t *streamptr = stream_new_entry(CDI_UNDEFID);
+  vlist_t *vlistptr;
 
-  if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
-    Error("Cannot seek input file for %s record copy!", container_name);
+  if ( CDI_Debug )
+    Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
+  if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
 
-  char *buffer = xmalloc(recsize);
+  if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
 
-  if (fileRead(fileID1, buffer, recsize) != recsize)
-    Error("Failed to read record from %s file for copying!", container_name);
+  {
+    int (*streamOpenDelegate)(const char *filename, const char *filemode,
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
+      namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
 
-  if (fileWrite(fileID2, buffer, recsize) != recsize)
-    Error("Failed to write record to %s file when copying!", container_name);
+    fileID = streamOpenDelegate(filename, "r", filetype, streamptr, 1);
+  }
 
-  free(buffer);
-}
+  if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return (fileID);
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  streamID = streamptr->self;
 
-#include <stdio.h>
-#include <string.h>
+  streamptr->filemode = tolower(*filemode);
+  streamptr->filename = strdupx(filename);
+  streamptr->fileID   = fileID;
 
+  streamptr->vlistID = vlistCreate();
+  /* cdiReadByteorder(streamID); */
+  status = cdiInqContents(streamptr);
+  if ( status < 0 ) return (status);
+  vlistptr = vlist_to_pointer(streamptr->vlistID);
+  vlistptr->ntsteps = (int)cdiInqTimeSize(streamID);
 
+  {
+    void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
+      = (void (*)(stream_t *, int))
+      namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
 
-int grib1ltypeToZaxisType(int grib_ltype)
-{
-  int zaxistype = ZAXIS_GENERIC;
+    streamCloseDelegate(streamptr, 0);
+  }
 
-  switch ( grib_ltype )
+  switch (filetype)
     {
-    case GRIB1_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;                break; }
-    case GRIB1_LTYPE_CLOUD_BASE:         { zaxistype = ZAXIS_CLOUD_BASE;             break; }
-    case GRIB1_LTYPE_CLOUD_TOP:          { zaxistype = ZAXIS_CLOUD_TOP;              break; }
-    case GRIB1_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;          break; }
-    case GRIB1_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;                    break; }
-    case GRIB1_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;             break; }
-    case GRIB1_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;             break; }
-    case GRIB1_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;                break; }
-    case GRIB1_LTYPE_99:
-    case GRIB1_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;               break; }
-    case GRIB1_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;                 break; }
-    case GRIB1_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;	             break; }
-    case GRIB1_LTYPE_SIGMA:
-    case GRIB1_LTYPE_SIGMA_LAYER:        { zaxistype = ZAXIS_SIGMA;	             break; }
-    case GRIB1_LTYPE_HYBRID:
-    case GRIB1_LTYPE_HYBRID_LAYER:       { zaxistype = ZAXIS_HYBRID;	             break; }
-    case GRIB1_LTYPE_LANDDEPTH:
-    case GRIB1_LTYPE_LANDDEPTH_LAYER:    { zaxistype = ZAXIS_DEPTH_BELOW_LAND;       break; }
-    case GRIB1_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;             break; }
-    case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;        break; }
-    case GRIB1_LTYPE_LAKE_BOTTOM:        { zaxistype = ZAXIS_LAKE_BOTTOM;            break; }
-    case GRIB1_LTYPE_SEDIMENT_BOTTOM:    { zaxistype = ZAXIS_SEDIMENT_BOTTOM;        break; }
-    case GRIB1_LTYPE_SEDIMENT_BOTTOM_TA: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;     break; }
-    case GRIB1_LTYPE_SEDIMENT_BOTTOM_TW: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;     break; }
-    case GRIB1_LTYPE_MIX_LAYER:          { zaxistype = ZAXIS_MIX_LAYER;              break; }
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        fileID = gribOpen(filename, filemode);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        fileID = fileOpen(filename, filemode);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        fileID = fileOpen(filename, filemode);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        fileID = fileOpen(filename, filemode);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+      {
+	fileID = cdfOpen(filename, filemode);
+	streamptr->ncmode = 2;
+	break;
+      }
+    case FILETYPE_NC2:
+      {
+	fileID = cdfOpen64(filename, filemode);
+	streamptr->ncmode = 2;
+	break;
+      }
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+	fileID = cdf4Open(filename, filemode, &filetype);
+	streamptr->ncmode = 2;
+	break;
+      }
+#endif
+    default:
+      {
+	if ( CDI_Debug ) Message("%s support not compiled in!", strfiletype(filetype));
+	return (CDI_ELIBNAVAIL);
+      }
     }
 
-  return (zaxistype);
-}
-
-
-int grib2ltypeToZaxisType(int grib_ltype)
-{
-  int zaxistype = ZAXIS_GENERIC;
-
-  switch ( grib_ltype )
-    {
-    case GRIB2_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;                break; }
-    case GRIB2_LTYPE_CLOUD_BASE:         { zaxistype = ZAXIS_CLOUD_BASE;             break; }
-    case GRIB2_LTYPE_CLOUD_TOP:          { zaxistype = ZAXIS_CLOUD_TOP;              break; }
-    case GRIB2_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;          break; }
-    case GRIB2_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;                    break; }
-    case GRIB2_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;             break; }
-    case GRIB2_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;             break; }
-    case GRIB2_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;                break; }
-    case GRIB2_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;               break; }
-    case GRIB2_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;                 break; }
-    case GRIB2_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;               break; }
-    case GRIB2_LTYPE_SIGMA:              { zaxistype = ZAXIS_SIGMA;                  break; }
-    case GRIB2_LTYPE_HYBRID:
- /* case GRIB2_LTYPE_HYBRID_LAYER: */    { zaxistype = ZAXIS_HYBRID;                 break; }
-    case GRIB2_LTYPE_LANDDEPTH:
- /* case GRIB2_LTYPE_LANDDEPTH_LAYER: */ { zaxistype = ZAXIS_DEPTH_BELOW_LAND;       break; }
-    case GRIB2_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;             break; }
-    case GRIB2_LTYPE_SNOW:               { zaxistype = ZAXIS_SNOW;                   break; }
-    case GRIB2_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;        break; }
-    case GRIB2_LTYPE_LAKE_BOTTOM:        { zaxistype = ZAXIS_LAKE_BOTTOM;            break; }
-    case GRIB2_LTYPE_SEDIMENT_BOTTOM:    { zaxistype = ZAXIS_SEDIMENT_BOTTOM;        break; }
-    case GRIB2_LTYPE_SEDIMENT_BOTTOM_TA: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;     break; }
-    case GRIB2_LTYPE_SEDIMENT_BOTTOM_TW: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;     break; }
-    case GRIB2_LTYPE_MIX_LAYER:          { zaxistype = ZAXIS_MIX_LAYER;              break; }
-    case GRIB2_LTYPE_REFERENCE:          { zaxistype = ZAXIS_REFERENCE;              break; }
-    }
+  if ( fileID == CDI_UNDEFID )
+    streamID = CDI_UNDEFID;
+  else
+    streamptr->fileID = fileID;
 
-  return (zaxistype);
+  return (streamID);
 }
 
+/*
+ at Function  streamOpenRead
+ at Title     Open a dataset for reading
 
-int zaxisTypeToGrib1ltype(int zaxistype)
-{
-  int grib_ltype = -1;
-
-  switch (zaxistype)
-    {
-    case ZAXIS_SURFACE:               { grib_ltype = GRIB1_LTYPE_SURFACE;            break; }
-    case ZAXIS_MEANSEA:               { grib_ltype = GRIB1_LTYPE_MEANSEA;            break; }
-    case ZAXIS_HEIGHT:                { grib_ltype = GRIB1_LTYPE_HEIGHT;             break; }
-    case ZAXIS_ALTITUDE:              { grib_ltype = GRIB1_LTYPE_ALTITUDE;           break; }
-    case ZAXIS_SIGMA:                 { grib_ltype = GRIB1_LTYPE_SIGMA;              break; }
-    case ZAXIS_DEPTH_BELOW_SEA:       { grib_ltype = GRIB1_LTYPE_SEADEPTH;           break; }
-    case ZAXIS_ISENTROPIC:            { grib_ltype = GRIB1_LTYPE_ISENTROPIC;         break; }
-    case ZAXIS_CLOUD_BASE:            { grib_ltype = GRIB1_LTYPE_CLOUD_BASE;         break; }
-    case ZAXIS_CLOUD_TOP:             { grib_ltype = GRIB1_LTYPE_CLOUD_TOP;          break; }
-    case ZAXIS_ISOTHERM_ZERO:         { grib_ltype = GRIB1_LTYPE_ISOTHERM0;          break; }
-    case ZAXIS_TOA:                   { grib_ltype = GRIB1_LTYPE_TOA;                break; }
-    case ZAXIS_SEA_BOTTOM:            { grib_ltype = GRIB1_LTYPE_SEA_BOTTOM;         break; }
-    case ZAXIS_LAKE_BOTTOM:           { grib_ltype = GRIB1_LTYPE_LAKE_BOTTOM;        break; }
-    case ZAXIS_SEDIMENT_BOTTOM:       { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM;    break; }
-    case ZAXIS_SEDIMENT_BOTTOM_TA:    { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM_TA; break; }
-    case ZAXIS_SEDIMENT_BOTTOM_TW:    { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM_TW; break; }
-    case ZAXIS_MIX_LAYER:             { grib_ltype = GRIB1_LTYPE_MIX_LAYER;          break; }
-    case ZAXIS_ATMOSPHERE:            { grib_ltype = GRIB1_LTYPE_ATMOSPHERE;         break; }
-    }
+ at Prototype int streamOpenRead(const char *path)
+ at Parameter
+    @Item  path  The name of the dataset to be read.
 
-  return (grib_ltype);
-}
+ at Description
+The function @func{streamOpenRead} opens an existing dataset for reading.
 
+ at Result
+Upon successful completion @func{streamOpenRead} returns an identifier to the
+open stream. Otherwise, a negative number with the error status is returned.
 
-int zaxisTypeToGrib2ltype(int zaxistype)
-{
-  int grib_ltype = -1;
+ at Errors
+ at List
+   @Item  CDI_ESYSTEM     Operating system error.
+   @Item  CDI_EINVAL      Invalid argument.
+   @Item  CDI_EUFILETYPE  Unsupported file type.
+   @Item  CDI_ELIBNAVAIL  Library support not compiled in.
+ at EndList
 
-  switch (zaxistype)
-    {
-    case ZAXIS_SURFACE:               { grib_ltype = GRIB2_LTYPE_SURFACE;            break; }
-    case ZAXIS_MEANSEA:               { grib_ltype = GRIB2_LTYPE_MEANSEA;            break; }
-    case ZAXIS_HEIGHT:                { grib_ltype = GRIB2_LTYPE_HEIGHT;             break; }
-    case ZAXIS_ALTITUDE:              { grib_ltype = GRIB2_LTYPE_ALTITUDE;           break; }
-    case ZAXIS_SIGMA:                 { grib_ltype = GRIB2_LTYPE_SIGMA;              break; }
-    case ZAXIS_DEPTH_BELOW_SEA:       { grib_ltype = GRIB2_LTYPE_SEADEPTH;           break; }
-    case ZAXIS_ISENTROPIC:            { grib_ltype = GRIB2_LTYPE_ISENTROPIC;         break; }
-    case ZAXIS_CLOUD_BASE:            { grib_ltype = GRIB2_LTYPE_CLOUD_BASE;         break; }
-    case ZAXIS_CLOUD_TOP:             { grib_ltype = GRIB2_LTYPE_CLOUD_TOP;          break; }
-    case ZAXIS_ISOTHERM_ZERO:         { grib_ltype = GRIB2_LTYPE_ISOTHERM0;          break; }
-    case ZAXIS_TOA:                   { grib_ltype = GRIB2_LTYPE_TOA;                break; }
-    case ZAXIS_SEA_BOTTOM:            { grib_ltype = GRIB2_LTYPE_SEA_BOTTOM;         break; }
-    case ZAXIS_LAKE_BOTTOM:           { grib_ltype = GRIB2_LTYPE_LAKE_BOTTOM;        break; }
-    case ZAXIS_SEDIMENT_BOTTOM:       { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM;    break; }
-    case ZAXIS_SEDIMENT_BOTTOM_TA:    { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM_TA; break; }
-    case ZAXIS_SEDIMENT_BOTTOM_TW:    { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM_TW; break; }
-    case ZAXIS_MIX_LAYER:             { grib_ltype = GRIB2_LTYPE_MIX_LAYER;          break; }
-    case ZAXIS_ATMOSPHERE:            { grib_ltype = GRIB2_LTYPE_ATMOSPHERE;         break; }
-    }
+ at Example
+Here is an example using @func{streamOpenRead} to open an existing netCDF
+file named @func{foo.nc} for reading:
 
-  return (grib_ltype);
-}
+ at Source
+   ...
+int streamID;
+   ...
+streamID = streamOpenRead("foo.nc");
+if ( streamID < 0 ) handle_error(streamID);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int streamOpenRead(const char *filename)
+{
+  cdiInitialize();
 
+  int byteorder = 0;
+  int filetype = cdiGetFiletype(filename, &byteorder);
 
-int grbBitsPerValue(int datatype)
-{
-  int bitsPerValue = 16;
+  if ( filetype < 0 ) return (filetype);
 
-  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    Error("CDI/GRIB library does not support complex numbers!");
+  int streamID = streamOpen(filename, "r", filetype);
 
-  if ( datatype != CDI_UNDEFID )
+  if ( streamID >= 0 )
     {
-      if ( datatype > 0 && datatype <= 32 )
-	bitsPerValue = datatype;
-      else if ( datatype == DATATYPE_FLT64 )
-	bitsPerValue = 24;
-      else
-	bitsPerValue = 16;
+      stream_t *streamptr = stream_to_pointer(streamID);
+      streamptr->byteorder = byteorder;
     }
 
-  return (bitsPerValue);
+  return (streamID);
 }
 
 
-/*
-int grbInqRecord(stream_t * streamptr, int *varID, int *levelID)
+int streamOpenAppend(const char *filename)
 {
-  int status;
-
-  status = cgribexInqRecord(streamptr, varID, levelID);
+  cdiInitialize();
 
-  return (status);
-}
-*/
+  int byteorder = 0;
+  int filetype = cdiGetFiletype(filename, &byteorder);
 
-void grbDefRecord(stream_t * streamptr)
-{
-  UNUSED(streamptr);
-}
+  if ( filetype < 0 ) return (filetype);
 
-static
-int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-	      int unreduced, int *nmiss, double missval, int vlistID, int varID)
-{
-  int status = 0;
+  int streamID = streamOpenA(filename, "a", filetype);
 
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
-    {
-#if  defined  (HAVE_LIBGRIB_API)
-      extern int cdiNAdditionalGRIBKeys;
-      if ( cdiNAdditionalGRIBKeys > 0 )
-	Error("CGRIBEX decode does not support reading of additional GRIB keys!");
-#endif
-      status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, missval);
-    }
-  else
-#endif
-#ifdef HAVE_LIBGRIB_API
-    status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, missval, vlistID, varID);
-#else
+  if ( streamID >= 0 )
     {
-      (void)vlistID; (void)varID;
-      Error("GRIB_API support not compiled in!");
+      stream_t *streamptr = stream_to_pointer(streamID);
+      streamptr->byteorder = byteorder;
     }
-#endif
 
-  return (status);
+  return (streamID);
 }
 
+/*
+ at Function  streamOpenWrite
+ at Title     Create a new dataset
 
-int grbUnzipRecord(unsigned char *gribbuffer, size_t *gribsize)
+ at Prototype int streamOpenWrite(const char *path, int filetype)
+ at Parameter
+    @Item  path      The name of the new dataset.
+    @Item  filetype  The type of the file format, one of the set of predefined CDI file format types.
+                     The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC},
+                     @func{FILETYPE_NC2}, @func{FILETYPE_NC4}, @func{FILETYPE_NC4C}, @func{FILETYPE_SRV},
+                     @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
+
+ at Description
+The function @func{streamOpenWrite} creates a new datset.
+ at Result
+Upon successful completion @func{streamOpenWrite} returns an identifier to the
+open stream. Otherwise, a negative number with the error status is returned.
+
+ at Errors
+ at List
+   @Item  CDI_ESYSTEM     Operating system error.
+   @Item  CDI_EINVAL      Invalid argument.
+   @Item  CDI_EUFILETYPE  Unsupported file type.
+   @Item  CDI_ELIBNAVAIL  Library support not compiled in.
+ at EndList
+
+ at Example
+Here is an example using @func{streamOpenWrite} to create a new netCDF file named @func{foo.nc} for writing:
+
+ at Source
+   ...
+int streamID;
+   ...
+streamID = streamOpenWrite("foo.nc", FILETYPE_NC);
+if ( streamID < 0 ) handle_error(streamID);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int streamOpenWrite(const char *filename, int filetype)
 {
-  int zip = 0;
-  int izip;
-  size_t igribsize;
-  size_t ogribsize;
-  long unzipsize;
+  cdiInitialize();
 
-  igribsize = *gribsize;
-  ogribsize = *gribsize;
+  return (streamOpen(filename, "w", filetype));
+}
 
-  if ( (izip = gribGetZip((long)igribsize, gribbuffer, &unzipsize)) > 0 )
-    {
-      zip = izip;
-      if ( izip == 128 ) /* szip */
-	{
-	  unsigned char *itmpbuffer = NULL;
-	  size_t itmpbuffersize = 0;
+static
+void streamDefaultValue ( stream_t * streamptr )
+{
+  int i;
 
-	  if ( unzipsize < (long) igribsize )
-	    {
-	      fprintf(stderr, "Decompressed size smaller than compressed size (in %ld; out %ld)!\n", (long)igribsize, unzipsize);
-	      return (0);
-	    }
+  streamptr->self              = CDI_UNDEFID;
+  streamptr->accesstype        = CDI_UNDEFID;
+  streamptr->accessmode        = 0;
+  streamptr->filetype          = FILETYPE_UNDEF;
+  streamptr->byteorder         = CDI_UNDEFID;
+  streamptr->fileID            = 0;
+  streamptr->filemode          = 0;
+  streamptr->numvals           = 0;
+  streamptr->filename          = NULL;
+  streamptr->record            = NULL;
+  streamptr->varsAllocated     = 0;
+  streamptr->nrecs             = 0;
+  streamptr->nvars             = 0;
+  streamptr->vars              = NULL;
+  streamptr->ncmode            = 0;
+  streamptr->curTsID           = CDI_UNDEFID;
+  streamptr->rtsteps           = 0;
+  streamptr->ntsteps           = CDI_UNDEFID;
+  streamptr->tsteps            = NULL;
+  streamptr->tstepsTableSize   = 0;
+  streamptr->tstepsNextID      = 0;
+  streamptr->historyID         = CDI_UNDEFID;
+  streamptr->vlistID           = CDI_UNDEFID;
+  streamptr->globalatts        = 0;
+  streamptr->localatts         = 0;
+  streamptr->vct.ilev          = 0;
+  streamptr->vct.mlev          = 0;
+  streamptr->vct.ilevID        = CDI_UNDEFID;
+  streamptr->vct.mlevID        = CDI_UNDEFID;
+  streamptr->unreduced         = cdiDataUnreduced;
+  streamptr->sortname          = cdiSortName;
+  streamptr->have_missval      = cdiHaveMissval;
+  streamptr->comptype          = COMPRESS_NONE;
+  streamptr->complevel         = 0;
 
-	  if ( itmpbuffersize < igribsize )
-	    {
-	      itmpbuffersize = igribsize;
-	      itmpbuffer = (unsigned char *) realloc(itmpbuffer, itmpbuffersize);
-	    }
+  basetimeInit(&streamptr->basetime);
 
-	  memcpy(itmpbuffer, gribbuffer, itmpbuffersize);
+  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->xdimID[i]   = CDI_UNDEFID;
+  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ydimID[i]   = CDI_UNDEFID;
+  for ( i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i]  = CDI_UNDEFID;
+  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncxvarID[i] = CDI_UNDEFID;
+  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncyvarID[i] = CDI_UNDEFID;
+  for ( i = 0; i < MAX_GRIDS_PS; i++ ) streamptr->ncavarID[i] = CDI_UNDEFID;
 
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
+  streamptr->gribContainers    = NULL;
+  streamptr->vlistIDorig       = CDI_UNDEFID;
+}
 
-	  ogribsize = (size_t)gribUnzip(gribbuffer, unzipsize, itmpbuffer, (long)igribsize);
 
-	  free(itmpbuffer);
+static stream_t *stream_new_entry(int resH)
+{
+  stream_t *streamptr;
 
-	  if ( ogribsize <= 0 ) Error("Decompression problem!");
-	}
-      else
-	{
-	  Error("Decompression for %d not implemented!", izip);
-	}
-    }
+  cdiInitialize(); /* ***************** make MT version !!! */
 
-  *gribsize = ogribsize;
+  streamptr = (stream_t *) xmalloc(sizeof(stream_t));
+  streamDefaultValue ( streamptr );
+  if (resH == CDI_UNDEFID)
+    streamptr->self = reshPut(streamptr, &streamOps);
+  else
+    {
+      streamptr->self = resH;
+      reshReplace(resH, streamptr, &streamOps);
+    }
 
-  return zip;
+  return streamptr;
 }
 
 
-void grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
+void
+cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
 {
+  int fileID   = streamptr->fileID;
   int filetype = streamptr->filetype;
+  if ( fileID == CDI_UNDEFID )
+    Warning("File %s not open!", streamptr->filename);
+  else
+    switch (filetype)
+      {
+#if  defined  (HAVE_LIBGRIB)
+      case FILETYPE_GRB:
+      case FILETYPE_GRB2:
+        {
+          gribClose(fileID);
+          if (recordBufIsToBeDeleted)
+            gribContainersDelete(streamptr);
+          break;
+        }
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+      case FILETYPE_SRV:
+        {
+          fileClose(fileID);
+          if (recordBufIsToBeDeleted)
+            srvDelete(streamptr->record->exsep);
+          break;
+        }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+      case FILETYPE_EXT:
+        {
+          fileClose(fileID);
+          if (recordBufIsToBeDeleted)
+            extDelete(streamptr->record->exsep);
+          break;
+        }
+#endif
+#if  defined  (HAVE_LIBIEG)
+      case FILETYPE_IEG:
+        {
+          fileClose(fileID);
+          if (recordBufIsToBeDeleted)
+            iegDelete(streamptr->record->exsep);
+          break;
+        }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+      case FILETYPE_NC:
+      case FILETYPE_NC2:
+      case FILETYPE_NC4:
+      case FILETYPE_NC4C:
+        {
+          cdfClose(fileID);
+          break;
+        }
+#endif
+      default:
+        {
+          Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
+          break;
+        }
+      }
+}
 
-  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
-
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-  int tsID    = streamptr->curTsID;
-  int vrecID  = streamptr->tsteps[tsID].curRecID;
-  int recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-  off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
-  size_t recsize = streamptr->tsteps[tsID].records[recID].size;
-  int varID   = streamptr->tsteps[tsID].records[recID].varID;
 
-  int gridID   = vlistInqVarGrid(vlistID, varID);
-  int gridsize = gridInqSize(gridID);
+/*
+ at Function  streamClose
+ at Title     Close an open dataset
 
-  streamptr->numvals += gridsize;
+ at Prototype  void streamClose(int streamID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
 
-  fileSetPos(fileID, recpos, SEEK_SET);
+ at Description
+The function @func{streamClose} closes an open dataset.
 
-  if (fileRead(fileID, gribbuffer, recsize) != recsize)
-    Error("Failed to read GRIB record");
+ at EndFunction
+*/
+void streamClose(int streamID)
+{
+  int index;
+  int vlistID;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
+  stream_check_ptr(__func__, streamptr);
 
-  streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
+  if ( CDI_Debug )
+    Message("streamID = %d filename = %s", streamID, streamptr->filename);
 
-  grbDecode(filetype, gribbuffer, (int)recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
-}
+  vlistID  = streamptr->vlistID;
 
-static
-int grbScanTimestep1(stream_t * streamptr)
-{
-  int status;
-  int filetype;
+  void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
+    = (void (*)(stream_t *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
 
-  filetype  = streamptr->filetype;
+  if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
 
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
+  if ( streamptr->record )
     {
-      status = cgribexScanTimestep1(streamptr);
+      if ( streamptr->record->buffer )
+        free(streamptr->record->buffer);
+
+      free(streamptr->record);
     }
-  else
-#endif
+
+  streamptr->filetype = 0;
+  if ( streamptr->filename ) free(streamptr->filename);
+
+  for ( index = 0; index < streamptr->nvars; index++ )
     {
-      status = gribapiScanTimestep1(streamptr);
+      if ( streamptr->vars[index].level )
+	free(streamptr->vars[index].level);
+      if ( streamptr->vars[index].lindex )
+	free(streamptr->vars[index].lindex);
     }
+  free(streamptr->vars);
 
-  return (status);
-}
+  for ( index = 0; index < streamptr->ntsteps; ++index )
+    {
+      if ( streamptr->tsteps[index].records )
+	free(streamptr->tsteps[index].records);
+      if ( streamptr->tsteps[index].recIDs )
+	free(streamptr->tsteps[index].recIDs);
+      taxisDestroyKernel(&streamptr->tsteps[index].taxis);
+    }
 
-static
-int grbScanTimestep2(stream_t * streamptr)
-{
-  int status = 0;
-  int filetype;
+  if ( streamptr->tsteps ) free(streamptr->tsteps);
 
-  filetype  = streamptr->filetype;
+  if ( streamptr->basetime.timevar_cache ) free(streamptr->basetime.timevar_cache);
 
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
+  if ( vlistID != -1 )
     {
-      status = cgribexScanTimestep2(streamptr);
+      if ( streamptr->filemode != 'w' )
+	if ( vlistInqTaxis(vlistID) != -1 )
+	  {
+	    taxisDestroy(vlistInqTaxis(vlistID));
+	  }
+
+      vlist_unlock(vlistID);
+      vlistDestroy(vlistID);
     }
-#endif
-#if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
-  else
-#endif
-#ifdef HAVE_LIBGRIB_API
-    status = gribapiScanTimestep2(streamptr);
-#endif
 
-  return (status);
+  stream_delete_entry(streamptr);
 }
 
-static
-int grbScanTimestep(stream_t * streamptr)
+static void stream_delete_entry(stream_t *streamptr)
 {
-  int status = CDI_EUFTYPE;
-  int filetype;
+  int idx;
 
-  filetype  = streamptr->filetype;
+  xassert ( streamptr );
 
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
-    {
-      status = cgribexScanTimestep(streamptr);
-    }
-  else
-#endif
-#ifdef HAVE_LIBGRIB_API
-    status = gribapiScanTimestep(streamptr);
-#else
-    Error("Sufficient GRIB support unavailable!");
-#endif
+  idx = streamptr->self;
+  free ( streamptr );
+  reshRemove ( idx, &streamOps );
 
-  return (status);
+  if ( CDI_Debug )
+    Message("Removed idx %d from stream list", idx);
 }
 
 
-int grbInqContents(stream_t * streamptr)
+void cdiStreamSync_(stream_t *streamptr)
 {
-  int fileID;
-  int status = 0;
+  int fileID   = streamptr->fileID;
+  int filetype = streamptr->filetype;
+  int vlistID  = streamptr->vlistID;
+  int nvars    = vlistNvars(vlistID);
 
-  fileID = streamptr->fileID;
+  if ( fileID == CDI_UNDEFID )
+    Warning("File %s not open!", streamptr->filename);
+  else if ( vlistID == CDI_UNDEFID )
+    Warning("Vlist undefined for file %s!", streamptr->filename);
+  else if ( nvars == 0 )
+    Warning("No variables defined!");
+  else
+    {
+      if ( streamptr->filemode == 'w' || streamptr->filemode == 'a' )
+	{
+	  switch (filetype)
+	    {
+#if  defined  (HAVE_LIBNETCDF)
+	    case FILETYPE_NC:
+	    case FILETYPE_NC2:
+	    case FILETYPE_NC4:
+	    case FILETYPE_NC4C:
+	      {
+		void cdf_sync(int ncid);
+		if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
+		break;
+	      }
+#endif
+	    default:
+	      {
+		fileFlush(fileID);
+		break;
+	      }
+	    }
+	}
+    }
+}
 
-  streamptr->curTsID = 0;
+/*
+ at Function  streamSync
+ at Title     Synchronize an Open Dataset to Disk
 
-  status = grbScanTimestep1(streamptr);
+ at Prototype  void streamSync(int streamID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
 
-  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
+ at Description
+The function @func{streamSync} offers a way to synchronize the disk copy of a dataset with in-memory buffers.
 
-  fileSetPos(fileID, 0, SEEK_SET);
+ at EndFunction
+*/
+void streamSync(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  return (status);
+  stream_check_ptr(__func__, streamptr);
+
+  void (*myStreamSync_)(stream_t *streamptr)
+    = (void (*)(stream_t *))namespaceSwitchGet(NSSWITCH_STREAM_SYNC).func;
+  myStreamSync_(streamptr);
 }
 
 
-int grbInqTimestep(stream_t * streamptr, int tsID)
+int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
 {
-  int ntsteps, nrecs;
-
-  if ( tsID == 0 && streamptr->rtsteps == 0 )
-    Error("Call to cdiInqContents missing!");
+  int taxisID;
 
   if ( CDI_Debug )
-    Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
+    Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
-  ntsteps = CDI_UNDEFID;
-  while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
+  stream_check_ptr(__func__, streamptr);
+
+  int vlistID = streamptr->vlistID;
+
+  int time_is_varying = vlistHasTime(vlistID);
+
+  if ( time_is_varying )
     {
-      ntsteps = grbScanTimestep(streamptr);
-      if ( ntsteps == CDI_EUFSTRUCT )
-	{
-	  streamptr->ntsteps = streamptr->rtsteps;
-	  break;
-	}
+      taxisID = vlistInqTaxis(vlistID);
+      if ( taxisID == CDI_UNDEFID )
+        {
+          Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
+          taxisID = taxisCreate(TAXIS_ABSOLUTE);
+          vlistDefTaxis(vlistID, taxisID);
+        }
     }
 
-  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+  int newtsID = tstepsNewEntry(streamptr);
+
+  if ( tsID != newtsID )
+    Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
+
+  streamptr->curTsID = tsID;
+
+  if ( time_is_varying )
     {
-      nrecs = 0;
+      taxis_t *taxisptr1 = taxisPtr(taxisID);
+      taxis_t *taxisptr2 = &streamptr->tsteps[tsID].taxis;
+      ptaxisCopy(taxisptr2, taxisptr1);
     }
-  else
+
+  streamptr->ntsteps = tsID + 1;
+
+#ifdef HAVE_LIBNETCDF
+  if ((streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C)
+      && vlistHasTime(vlistID))
     {
-      streamptr->curTsID = tsID;
-      nrecs = streamptr->tsteps[tsID].nrecs;
+      void (*myCdfDefTimestep)(stream_t *streamptr, int tsID)
+        = (void (*)(stream_t *, int))
+        namespaceSwitchGet(NSSWITCH_CDF_DEF_TIMESTEP).func;
+      myCdfDefTimestep(streamptr, tsID);
     }
+#endif
 
-  return (nrecs);
+  cdi_create_records(streamptr, tsID);
+
+  return (int)streamptr->ntsteps;
 }
 
+/*
+ at Function  streamDefTimestep
+ at Title     Define time step
 
-void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
-{
-  int filetype = streamptr->filetype;
+ at Prototype int streamDefTimestep(int streamID, int tsID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  tsID      Timestep identifier.
 
-  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
+ at Description
+The function @func{streamDefTimestep} defines the time step of a stream.
 
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-  int tsID    = streamptr->curTsID;
+ at Result
+ at func{streamDefTimestep} returns the number of records of the time step.
 
-  int nlevs    = streamptr->vars[varID].nlevs;
-  int gridID   = vlistInqVarGrid(vlistID, varID);
-  int gridsize = gridInqSize(gridID);
+ at EndFunction
+*/
+int streamDefTimestep(int streamID, int tsID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+  int (*myStreamDefTimestep_)(stream_t *streamptr, int tsID)
+    = (int (*)(stream_t *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_DEF_TIMESTEP_).func;
+  return myStreamDefTimestep_(streamptr, tsID);
+}
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+int streamInqCurTimestepID(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+  return streamptr->curTsID;
+}
 
-  off_t currentfilepos = fileGetPos(fileID);
 
-  *nmiss = 0;
-  for (int levelID = 0; levelID < nlevs; levelID++ )
-    {
-      int recID   = streamptr->vars[varID].level[levelID];
-      off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
-      size_t recsize = streamptr->tsteps[tsID].records[recID].size;
+/*
+ at Function  streamInqTimestep
+ at Title     Get time step
 
-      fileSetPos(fileID, recpos, SEEK_SET);
+ at Prototype int streamInqTimestep(int streamID, int tsID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
+    @Item  tsID      Timestep identifier.
 
-      fileRead(fileID, gribbuffer, recsize);
+ at Description
+The function @func{streamInqTimestep} returns the time step of a stream.
 
-      double missval = vlistInqVarMissval(vlistID, varID);
+ at Result
+ at func{streamInqTimestep} returns the number of records of the time step.
 
-      int imiss;
+ at EndFunction
+*/
+int streamInqTimestep(int streamID, int tsID)
+{
+  int nrecs = 0;
+  int taxisID;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-      streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
+  stream_check_ptr(__func__, streamptr);
 
-      grbDecode(filetype, gribbuffer, (int)recsize, &data[levelID*gridsize], gridsize,
-		streamptr->unreduced, &imiss, missval, vlistID, varID);
+  int vlistID = streamptr->vlistID;
 
-      *nmiss += imiss;
-    }
+  if ( tsID < streamptr->rtsteps )
+    {
+      streamptr->curTsID = tsID;
+      nrecs = streamptr->tsteps[tsID].nrecs;
+      streamptr->tsteps[tsID].curRecID = CDI_UNDEFID;
+      taxisID = vlistInqTaxis(vlistID);
+      if ( taxisID == -1 )
+	Error("Timestep undefined for fileID = %d", streamID);
+      ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
 
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
-}
+      return (nrecs);
+    }
 
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      return (0);
+    }
 
-void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss)
-{
   int filetype = streamptr->filetype;
 
-  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
-
-  int vlistID = streamptr->vlistID;
-  int gridID   = vlistInqVarGrid(vlistID, varID);
-  int gridsize = gridInqSize(gridID);
-  int tsID = streamptr->curTsID;
-
   if ( CDI_Debug )
-    Message("gridID = %d gridsize = %d", gridID, gridsize);
-
-  int fileID = streamptr->fileID;
+    Message("streamID = %d  tsID = %d  filetype = %d", streamID, tsID, filetype);
 
-  off_t currentfilepos = fileGetPos(fileID);
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        nrecs = grbInqTimestep(streamptr, tsID);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        nrecs = srvInqTimestep(streamptr, tsID);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        nrecs = extInqTimestep(streamptr, tsID);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        nrecs = iegInqTimestep(streamptr, tsID);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+        nrecs = cdfInqTimestep(streamptr, tsID);
+	break;
+      }
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+	break;
+      }
+    }
 
-  int recID   = streamptr->vars[varID].level[levelID];
-  off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
-  size_t recsize = streamptr->tsteps[tsID].records[recID].size;
+  taxisID = vlistInqTaxis(vlistID);
+  if ( taxisID == -1 )
+    Error("Timestep undefined for fileID = %d", streamID);
 
-  if ( recsize == 0 )
-    Error("Internal problem! Recordsize is zero for record %d at timestep %d",
-	  recID+1, tsID+1);
+  ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis);
 
-  fileSetPos(fileID, recpos, SEEK_SET);
+  return (nrecs);
+}
 
-  fileRead(fileID, gribbuffer, recsize);
+/* the single image implementation */
+static
+void cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmiss)
+{
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamID, varID);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
+  check_parg(data);
+  check_parg(nmiss);
 
-  streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  grbDecode(filetype, gribbuffer, (int)recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+  stream_check_ptr(__func__, streamptr);
 
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
-}
+  int filetype = streamptr->filetype;
 
-static
-size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		 int date, int time, int tsteptype, int numavg,
-		 size_t datasize, const double *data, int nmiss, unsigned char **gribbuffer,
-		 int comptype, void *gribContainer)
-{
-  size_t nbytes = 0;
+  *nmiss = 0;
 
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
+  switch (filetype)
     {
-      size_t gribbuffersize = datasize*4+3000;
-      *gribbuffer = (unsigned char *) malloc(gribbuffersize);
-
-      nbytes = cgribexEncode(memtype, varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg,
-			     (long)datasize, data, nmiss, *gribbuffer, gribbuffersize);
-    }
-  else
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("grbReadVar not implemented for memtype float!");
+        grbReadVarDP(streamptr, varID, data, nmiss);
+	break;
+      }
 #endif
-#ifdef HAVE_LIBGRIB_API
-    {
-      if ( memtype == MEMTYPE_FLOAT ) Error("gribapiEncode() not implemented for memtype float!");
-
-      size_t gribbuffersize;
-      nbytes = gribapiEncode(varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg,
-			     (long)datasize, data, nmiss, gribbuffer, &gribbuffersize,
-			     comptype, gribContainer);
-    }
-#else
-    Error("GRIB_API support not compiled in!");
-    (void)gribContainer;
-    (void)comptype;
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("srvReadVar not implemented for memtype float!");
+        srvReadVarDP(streamptr, varID, data, nmiss);
+	break;
+      }
 #endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("extReadVar not implemented for memtype float!");
+        extReadVarDP(streamptr, varID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("iegReadVar not implemented for memtype float!");
+        iegReadVarDP(streamptr, varID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+        if ( memtype == MEMTYPE_FLOAT )
+          cdfReadVarSP(streamptr, varID, data, nmiss);
+        else
+          cdfReadVarDP(streamptr, varID, data, nmiss);
 
-
-  return (nbytes);
+	break;
+      }
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+	break;
+      }
+    }
 }
 
-static
-size_t grbSzip(int filetype, unsigned char *gribbuffer, size_t gribbuffersize)
-{
-  size_t nbytes = 0;
-  unsigned char *buffer;
-  size_t buffersize;
-  static int lszip_warn = 1;
+/*
+ at Function  streamReadVar
+ at Title     Read a variable
 
-  buffersize = gribbuffersize + 1000; /* compressed record can be greater than source record */
-  buffer = (unsigned char *) malloc(buffersize);
+ at Prototype void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
+    @Item  varID     Variable identifier.
+    @Item  data      Pointer to the location into which the data values are read.
+                     The caller must allocate space for the returned values.
+    @Item  nmiss     Number of missing values.
 
-  /*  memcpy(buffer, gribbuffer, gribbuffersize); */
+ at Description
+The function streamReadVar reads all the values of one time step of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVar(int streamID, int varID, double *data, int *nmiss)
+{
+  cdiStreamReadVar(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
+}
 
-  if ( filetype == FILETYPE_GRB )
-    {
-      nbytes = (size_t)gribZip(gribbuffer, (long) gribbuffersize, buffer, (long) buffersize);
-    }
-  else
-    {
-      if ( lszip_warn ) Warning("Szip compression of GRIB2 records not implemented!");
-      lszip_warn = 0;
-      nbytes = gribbuffersize;
-    }
+/*
+ at Function  streamReadVarF
+ at Title     Read a variable
 
-  free(buffer);
+ at Prototype void streamReadVar(int streamID, int varID, float *data, int *nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
+    @Item  varID     Variable identifier.
+    @Item  data      Pointer to the location into which the data values are read.
+                     The caller must allocate space for the returned values.
+    @Item  nmiss     Number of missing values.
 
-  return (nbytes);
+ at Description
+The function streamReadVar reads all the values of one time step of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarF(int streamID, int varID, float *data, int *nmiss)
+{
+  cdiStreamReadVar(streamID, varID, MEMTYPE_FLOAT, data, nmiss);
 }
 
-
-void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
+/* the single image implementation */
+void cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, int nmiss)
 {
-  size_t nwrite;
-  int fileID;
-  int gridID;
-  int zaxisID;
-  unsigned char *gribbuffer = NULL;
-  int tsID;
-  int vlistID;
-  int date, time;
-  int tsteptype;
-  int numavg = 0;
-  size_t nbytes;
-  int filetype;
-  void *gc = NULL;
+  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
 
-  filetype  = streamptr->filetype;
-  fileID    = streamptr->fileID;
-  vlistID   = streamptr->vlistID;
-  gridID    = vlistInqVarGrid(vlistID, varID);
-  zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  check_parg(data);
 
-  int comptype  = streamptr->comptype;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  tsID      = streamptr->curTsID;
-  date      = streamptr->tsteps[tsID].taxis.vdate;
-  time      = streamptr->tsteps[tsID].taxis.vtime;
-  if ( vlistInqVarTimave(vlistID, varID) )
-    numavg = streamptr->tsteps[tsID].taxis.numavg;
+  stream_check_ptr(__func__, streamptr);
 
-  if ( CDI_Debug )
-    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
 
-  size_t datasize = (size_t)gridInqSize(gridID);
-  /*
-  gribbuffersize = datasize*4+3000;
-  gribbuffer = (unsigned char *) malloc(gribbuffersize);
-  */
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == FILETYPE_GRB )
+  int filetype = streamptr->filetype;
+
+  switch (filetype)
     {
-    }
-  else
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        grb_write_var(streamptr, varID, memtype, data, nmiss);
+	break;
+      }
 #endif
-    {
-#if defined (GRIBCONTAINER2D)
-      gribContainer_t **gribContainers =  (gribContainer_t **) streamptr->gribContainers;
-      gc = (void *) &gribContainers[varID][levelID];
-#else
-      gribContainer_t *gribContainers =  (gribContainer_t *) streamptr->gribContainers;
-      gc = (void *) &gribContainers[varID];
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVar not implemented for memtype float!");
+        srvWriteVarDP(streamptr, varID, data);
+	break;
+      }
 #endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVar not implemented for memtype float!");
+        extWriteVarDP(streamptr, varID, data);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVar not implemented for memtype float!");
+        iegWriteVarDP(streamptr, varID, data);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+        cdf_write_var(streamptr, varID, memtype, data, nmiss);
+	break;
+      }
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+	break;
+      }
     }
+}
 
-  if ( comptype != COMPRESS_JPEG && comptype != COMPRESS_SZIP ) comptype = COMPRESS_NONE;
-
-  if ( filetype == FILETYPE_GRB && comptype == COMPRESS_JPEG )
-    {
-      static int ljpeg_warn = 1;
-      if ( ljpeg_warn ) Warning("JPEG compression of GRIB1 records not available!");
-      ljpeg_warn = 0;
-    }
-
-  nbytes = grbEncode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
-		     datasize, (const double*) data, nmiss, &gribbuffer, comptype, gc);
-
-  if ( filetype == FILETYPE_GRB && streamptr->comptype == COMPRESS_SZIP )
-    nbytes = grbSzip(filetype, gribbuffer, nbytes);
-
-  {
-    size_t (*myFileWrite)(int fileID, const void *restrict buffer,
-                          size_t len, int tsID)
-      = (size_t (*)(int, const void *restrict, size_t, int))
-      namespaceSwitchGet(NSSWITCH_FILE_WRITE).func;
-    nwrite = myFileWrite(fileID, gribbuffer, nbytes, tsID);
-  }
+/*
+ at Function  streamWriteVar
+ at Title     Write a variable
 
-  if ( nwrite != nbytes )
-    {
-      perror(__func__);
-      Error("Failed to write GRIB slice!");
-    }
+ at Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  varID     Variable identifier.
+    @Item  data      Pointer to a block of double precision floating point data values to be written.
+    @Item  nmiss     Number of missing values.
 
-  if ( gribbuffer ) free(gribbuffer);
+ at Description
+The function streamWriteVar writes the values of one time step of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
+{
+  void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
+                               const void *data, int nmiss)
+    = (void (*)(int, int, int, const void *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
+  myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
 }
 
+/*
+ at Function  streamWriteVarF
+ at Title     Write a variable
 
-void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
-{
-  int vlistID, gridID, zaxisID, levelID, nlevs;
-  int gridsize;
-
-  vlistID  = streamptr->vlistID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  nlevs    = zaxisInqSize(zaxisID);
+ at Prototype void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  varID     Variable identifier.
+    @Item  data      Pointer to a block of single precision floating point data values to be written.
+    @Item  nmiss     Number of missing values.
 
-  for ( levelID = 0; levelID < nlevs; levelID++ )
-    {
-      if ( memtype == MEMTYPE_FLOAT )
-        grb_write_var_slice(streamptr, varID, levelID, memtype, ((float*)data)+levelID*gridsize, nmiss);
-      else
-        grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
-    }
+ at Description
+The function streamWriteVarF writes the values of one time step of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+Only support for netCDF was implemented in this function.
+ at EndFunction
+*/
+void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
+{
+  void (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
+                               const void *data, int nmiss)
+    = (void (*)(int, int, int, const void *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
+  myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, data, nmiss);
 }
 
-
-void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
+static
+int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *data, int *nmiss)
 {
-  int filetype = streamptr1->filetype;
-
-  int fileID1 = streamptr1->fileID;
-  int fileID2 = streamptr2->fileID;
+  // May fail if memtype == MEMTYPE_FLOAT and the file format does not support single precision reading.
+  // A value > 0 is returned in this case, otherwise it returns zero.
+  int status = 0;
 
-  int tsID    = streamptr1->curTsID;
-  int vrecID  = streamptr1->tsteps[tsID].curRecID;
-  int recID   = streamptr1->tsteps[tsID].recIDs[vrecID];
-  off_t recpos  = streamptr1->tsteps[tsID].records[recID].position;
-  size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamID, varID);
 
-  fileSetPos(fileID1, recpos, SEEK_SET);
+  check_parg(data);
+  check_parg(nmiss);
 
-  /* round up recsize to next multiple of 8 */
-  size_t gribbuffersize = ((recsize + 7U) & ~7U);
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  unsigned char *gribbuffer = xmalloc(gribbuffersize);
+  stream_check_ptr(__func__, streamptr);
 
-  if (fileRead(fileID1, gribbuffer, recsize) != recsize)
-    Error("Could not read GRIB record for copying!");
+  int filetype = streamptr->filetype;
 
-  size_t nbytes = recsize;
+  *nmiss = 0;
 
-  if ( filetype == FILETYPE_GRB )
+  switch (filetype)
     {
-      long unzipsize;
-      int izip = gribGetZip((long)recsize, gribbuffer, &unzipsize);
-
-      if ( izip == 0 )
-        if ( streamptr2->comptype == COMPRESS_SZIP )
-          nbytes = grbSzip(filetype, gribbuffer, nbytes);
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) return 1;
+        grbReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) return 1;
+        srvReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) return 1;
+        extReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) return 1;
+        iegReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+        if ( memtype == MEMTYPE_FLOAT )
+          cdfReadVarSliceSP(streamptr, varID, levelID, data, nmiss);
+        else
+          cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+        break;
+      }
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+        status = 2;
+	break;
+      }
     }
 
-  while ( nbytes & 7 ) gribbuffer[nbytes++] = 0;
+  return status;
+}
 
-  size_t nwrite = fileWrite(fileID2, gribbuffer, nbytes);
-  if ( nwrite != nbytes )
+/*
+ at Function  streamReadVarSlice
+ at Title     Read a horizontal slice of a variable
+
+ at Prototype void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
+    @Item  varID     Variable identifier.
+    @Item  levelID   Level identifier.
+    @Item  data      Pointer to the location into which the data values are read.
+                     The caller must allocate space for the returned values.
+    @Item  nmiss     Number of missing values.
+
+ at Description
+The function streamReadVarSlice reads all the values of a horizontal slice of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int *nmiss)
+{
+  if ( cdiStreamReadVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss) )
     {
-      perror(__func__);
-      Error("Could not write record for copying!");
+      Warning("Unexpected error returned from cdiStreamReadVarSlice()!");
+      size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+      memset(data, 0, elementCount * sizeof(*data));
     }
-
-  free(gribbuffer);
 }
 
+/*
+ at Function  streamReadVarSliceF
+ at Title     Read a horizontal slice of a variable
 
-void grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss)
-{
-  int varID, levelID;
-
-  varID   = streamptr->record->varID;
-  levelID = streamptr->record->levelID;
+ at Prototype void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead}.
+    @Item  varID     Variable identifier.
+    @Item  levelID   Level identifier.
+    @Item  data      Pointer to the location into which the data values are read.
+                     The caller must allocate space for the returned values.
+    @Item  nmiss     Number of missing values.
 
-  grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+ at Description
+The function streamReadVarSliceF reads all the values of a horizontal slice of a variable
+from an open dataset.
+ at EndFunction
+*/
+void streamReadVarSliceF(int streamID, int varID, int levelID, float *data, int *nmiss)
+{
+  if ( cdiStreamReadVarSlice(streamID, varID,levelID, MEMTYPE_FLOAT, data, nmiss) )
+    {
+      // In case the file format does not support single precision reading,
+      // we fall back to double precision reading, converting the data on the fly.
+      size_t elementCount = (size_t)gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+      double* conversionBuffer = malloc(elementCount * sizeof(*conversionBuffer));
+      streamReadVarSlice(streamID, varID, levelID, conversionBuffer, nmiss);
+      for (size_t i = elementCount; i--; ) data[i] = (float)conversionBuffer[i];
+      free(conversionBuffer);
+    }
 }
 
-
-void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
+static
+void cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
+  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+
+  check_parg(data);
+
   stream_t *streamptr = stream_to_pointer(streamID);
 
   stream_check_ptr(__func__, streamptr);
 
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+
   int filetype = streamptr->filetype;
 
-  if ( filetype == FILETYPE_GRB )
+  switch (filetype)
     {
-      int tsID     = streamptr->curTsID;
-      int vrecID   = streamptr->tsteps[tsID].curRecID;
-      int recID    = streamptr->tsteps[tsID].recIDs[vrecID];
-      off_t recpos = streamptr->tsteps[tsID].records[recID].position;
-      int zip      = streamptr->tsteps[tsID].records[recID].zip;
-
-      void *gribbuffer = streamptr->record->buffer;
-      size_t gribbuffersize = streamptr->record->buffersize;
-
-      if ( zip > 0 )
-	Error("Compressed GRIB records unsupported!");
-      else
-        grib_info_for_grads(recpos, (long)gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum, bignum);
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      {
+        grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVarSlice not implemented for memtype float!");
+        srvWriteVarSliceDP(streamptr, varID, levelID, data);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVarSlice not implemented for memtype float!");
+        extWriteVarSliceDP(streamptr, varID, levelID, data);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      {
+        if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVarSlice not implemented for memtype float!");
+        iegWriteVarSliceDP(streamptr, varID, levelID, data);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+      cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+      break;
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+	break;
+      }
     }
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-
 
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
-
-#define SINGLE_PRECISION  4
-#define DOUBLE_PRECISION  8
+/*
+ at Function  streamWriteVarSlice
+ at Title     Write a horizontal slice of a variable
 
-#if defined (HAVE_LIBSERVICE)
+ at Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  varID     Variable identifier.
+    @Item  levelID   Level identifier.
+    @Item  data      Pointer to a block of double precision floating point data values to be written.
+    @Item  nmiss     Number of missing values.
 
+ at Description
+The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
+{
+  cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss);
+}
 
-typedef struct {
-  int param;
-  int level;
-} SRVCOMPVAR;
+/*
+ at Function  streamWriteVarSliceF
+ at Title     Write a horizontal slice of a variable
 
+ at Prototype void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  varID     Variable identifier.
+    @Item  levelID   Level identifier.
+    @Item  data      Pointer to a block of single precision floating point data values to be written.
+    @Item  nmiss     Number of missing values.
 
-int srvInqDatatype(int prec)
+ at Description
+The function streamWriteVarSliceF writes the values of a horizontal slice of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+Only support for netCDF was implemented in this function.
+ at EndFunction
+*/
+void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *data, int nmiss)
 {
-  int datatype;
-
-  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
-  else                            datatype = DATATYPE_FLT32;
-
-  return (datatype);
+  cdiStreamWriteVarSlice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss);
 }
 
 
-int srvDefDatatype(int datatype)
+void
+streamWriteVarChunk(int streamID, int varID,
+                    const int rect[][2], const double *data, int nmiss)
 {
-  int prec;
-
-  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    Error("CDI/SERVICE library does not support complex numbers!");
-
-  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
-    datatype = DATATYPE_FLT32;
-
-  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
-  else                              prec = SINGLE_PRECISION;
-
-  return (prec);
+  void (*myCdiStreamWriteVarChunk_)(int streamID, int varID, int memtype,
+                                    const int rect[][2], const void *data,
+                                    int nmiss)
+    = (void (*)(int, int, int, const int [][2], const void *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_CHUNK_).func;
+  myCdiStreamWriteVarChunk_(streamID, varID, MEMTYPE_DOUBLE, rect, data, nmiss);
 }
 
-/* not used
-int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
+/* single image implementation */
+void
+cdiStreamwriteVarChunk_(int streamID, int varID, int memtype,
+                        const int rect[][2], const void *data, int nmiss)
 {
-  int status;
-  int fileID;
-  int icode, ilevel;
-  int zaxisID = -1;
-  int header[8];
-  int vlistID;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-
-  *varID   = -1;
-  *levelID = -1;
+  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
 
-  status = srvRead(fileID, srvp);
-  if ( status != 0 ) return (0);
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  srvInqHeader(srvp, header);
+  stream_check_ptr(__func__, streamptr);
 
-  icode  = header[0];
-  ilevel = header[1];
+  // streamDefineTaxis(streamID);
 
-  *varID = vlistInqVarID(vlistID, icode);
+  int filetype = streamptr->filetype;
 
-  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+  switch (filetype)
+    {
+#if defined (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+#endif
+#if defined (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+#endif
+#if defined (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+#endif
+#if defined (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+#endif
+#if  defined (HAVE_LIBGRIB) || defined (HAVE_LIBSERVICE)      \
+  || defined (HAVE_LIBEXTRA) || defined (HAVE_LIBIEG)
+      xabort("streamWriteVarChunk not implemented for filetype %s!",
+             strfiletype(filetype));
+      break;
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+      cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
+      break;
+#endif
+    default:
+      Error("%s support not compiled in!", strfiletype(filetype));
+      break;
+    }
+}
 
-  zaxisID = vlistInqVarZaxis(vlistID, *varID);
+void streamWriteContents(int streamID, char *cname)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
+  stream_check_ptr(__func__, streamptr);
 
-  return (1);
-}
-*/
+  int vlistID = streamptr->vlistID;
 
-void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
-{
-  int vlistID, fileID;
-  int status;
-  int recID, vrecID, tsID;
-  off_t recpos;
-  int header[8];
-  int varID, gridID;
-  int i, size;
-  double missval;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+  FILE *cnp = fopen(cname, "w");
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-  tsID    = streamptr->curTsID;
-  vrecID  = streamptr->tsteps[tsID].curRecID;
-  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-  recpos  = streamptr->tsteps[tsID].records[recID].position;
-  varID   = streamptr->tsteps[tsID].records[recID].varID;
+  if ( cnp == NULL ) SysError(cname);
 
-  fileSetPos(fileID, recpos, SEEK_SET);
+  fprintf(cnp, "#CDI library version %s\n", cdiLibraryVersion());
+  fprintf(cnp, "#\n");
 
-  status = srvRead(fileID, srvp);
-  if ( status != 0 )
-    Error("Failed to read record from SRV file");
+  fprintf(cnp, "filename: %s\n", streamptr->filename);
+  int filetype = streamptr->filetype;
+  fprintf(cnp, "filetype: %s\n", strfiletype(filetype));
 
-  srvInqHeader(srvp, header);
-  srvInqDataDP(srvp, data);
+  fprintf(cnp, "#\n");
+  fprintf(cnp, "#grids:\n");
 
-  missval = vlistInqVarMissval(vlistID, varID);
-  gridID  = vlistInqVarGrid(vlistID, varID);
-  size    = gridInqSize(gridID);
+  int ngrids = vlistNgrids(vlistID);
+  for ( int i = 0; i < ngrids; i++ )
+    {
+      int gridID   = vlistGrid(vlistID, i);
+      int gridtype = gridInqType(gridID);
+      int xsize    = gridInqXsize(gridID);
+      int ysize    = gridInqYsize(gridID);
+      fprintf(cnp, "%4d:%4d:%4d:%4d\n", i+1, gridtype, xsize, ysize);
+    }
 
-  streamptr->numvals += size;
+  fprintf(cnp, "#\n");
 
-  *nmiss = 0;
-  for ( i = 0; i < size; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
-}
+  fprintf(cnp, "varID:code:gridID:zaxisID:tsteptype:datatype\n");
 
+  int nvars = vlistNvars(vlistID);
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      int code      = vlistInqVarCode(vlistID, varID);
+      int gridID    = vlistInqVarGrid(vlistID, varID);
+      int zaxisID   = vlistInqVarZaxis(vlistID, varID);
+      int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+      int datatype  = vlistInqVarDatatype(vlistID, varID);
+      fprintf(cnp, "%4d:%4d:%4d:%4d:%4d:%4d:\n",
+	      varID+1, code, gridID, zaxisID, tsteptype, datatype);
+    }
 
-void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
-{
-  streamFCopyRecord(streamptr2, streamptr1, "SRV");
-}
+  fprintf(cnp, "#\n");
 
+  fprintf(cnp, "tsID:nrecs:date:time\n");
 
-void srvDefRecord(stream_t *streamptr)
-{
-  int gridID;
-  int header[8];
-  int xsize, ysize;
-  int datatype;
-  int pdis, pcat, pnum;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+  int tsID = 0;
+  while (1)
+    {
+      int nrecs      = streamptr->tsteps[tsID].nallrecs;
+      int date       = streamptr->tsteps[tsID].taxis.vdate;
+      int time       = streamptr->tsteps[tsID].taxis.vtime;
+      off_t position = streamptr->tsteps[tsID].position;
 
-  gridID = streamptr->record->gridID;
+      fprintf(cnp, "%4d:%4d:%4d:%4d:%ld\n",
+	      tsID, nrecs, date, time, (long) position);
 
-  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
-  header[0] = pnum;
-  header[1] = streamptr->record->level;
-  header[2] = streamptr->record->date;
-  header[3] = streamptr->record->time;
+      if ( streamptr->tsteps[tsID].next )
+	tsID++;
+      else
+	break;
+    }
 
-  xsize = gridInqXsize(gridID);
-  ysize = gridInqYsize(gridID);
-  if ( xsize == 0 || ysize == 0 )
+  fprintf(cnp, "#\n");
+
+  fprintf(cnp, "tsID:recID:varID:levID:size:pos\n");
+
+  tsID = 0;
+  while (1)
     {
-      xsize = gridInqSize(gridID);
-      ysize = 1;
+      int nrecs = streamptr->tsteps[tsID].nallrecs;
+      for ( int recID = 0; recID < nrecs; recID++ )
+	{
+	  int varID   = streamptr->tsteps[tsID].records[recID].varID;
+	  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
+	  off_t recpos = streamptr->tsteps[tsID].records[recID].position;
+	  long recsize = (long)streamptr->tsteps[tsID].records[recID].size;
+	  fprintf(cnp, "%4d:%4d:%4d:%4d:%4ld:%ld\n",
+		  tsID, recID, varID, levelID, recsize, (long) recpos);
+	}
+
+      if ( streamptr->tsteps[tsID].next )
+	tsID++;
+      else
+	break;
     }
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
-  if ( gridInqSize(gridID) != xsize*ysize )
-    Error("Internal problem with gridsize!");
 
-  header[4] = xsize;
-  header[5] = ysize;
-  header[6] = 0;
-  header[7] = 0;
+  fclose(cnp);
+}
 
-  datatype = streamptr->record->prec;
+// This function is used in CDO!
+off_t streamNvals(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  srvp->dprec = srvDefDatatype(datatype);
+  stream_check_ptr(__func__, streamptr);
 
-  srvDefHeader(srvp, header);
+  return (streamptr->numvals);
 }
 
+/*
+ at Function  streamDefVlist
+ at Title     Define the variable list
 
-void srvWriteRecord(stream_t *streamptr, const double *data)
-{
-  int fileID = streamptr->fileID;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+ at Prototype void streamDefVlist(int streamID, int vlistID)
+ at Parameter
+    @Item  streamID Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
 
-  srvDefDataDP(srvp, data);
+ at Description
+The function @func{streamDefVlist} defines the variable list of a stream.
 
-  srvWrite(fileID, srvp);
+ at EndFunction
+*/
+void streamDefVlist(int streamID, int vlistID)
+{
+  void (*myStreamDefVlist)(int streamID, int vlistID)
+    = (void (*)(int, int))namespaceSwitchGet(NSSWITCH_STREAM_DEF_VLIST_).func;
+  myStreamDefVlist(streamID, vlistID);
 }
 
-static
-void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
-                    size_t recsize, off_t position, int prec)
+/* the single image implementation of streamDefVlist */
+void
+cdiStreamDefVlist_(int streamID, int vlistID)
 {
-  int leveltype;
-  int gridID = CDI_UNDEFID;
-  int levelID = 0;
-  int tsID, recID, varID;
-  int datatype;
-  record_t *record;
-  grid_t grid;
-  int vlistID;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamptr->vlistID;
-  tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamptr, tsID);
-  record  = &streamptr->tsteps[tsID].records[recID];
+  stream_check_ptr(__func__, streamptr);
 
-  (*record).size     = recsize;
-  (*record).position = position;
-  (*record).param    = param;
-  (*record).ilevel   = level;
+  if ( streamptr->vlistID == CDI_UNDEFID )
+    cdiStreamSetupVlist(streamptr, vlistDuplicate(vlistID), vlistID);
+  else
+    Warning("vlist already defined for %s!", streamptr->filename);
+}
 
-  memset(&grid, 0, sizeof(grid_t));
-  grid.type  = GRID_GENERIC;
-  grid.size  = xsize*ysize;
-  grid.xsize = xsize;
-  grid.ysize = ysize;
-  grid.xvals = NULL;
-  grid.yvals = NULL;
-  gridID = varDefGrid(vlistID, &grid, 0);
-  /*
-  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
-  else              leveltype = ZAXIS_GENERIC;
-  */
-  leveltype = ZAXIS_GENERIC;
+/*
+ at Function  streamInqVlist
+ at Title     Get the variable list
 
-  datatype = srvInqDatatype(prec);
+ at Prototype int streamInqVlist(int streamID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
-	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
+ at Description
+The function @func{streamInqVlist} returns the variable list of a stream.
 
-  xassert(varID <= SHRT_MAX && levelID <= SHRT_MAX);
-  (*record).varID   = (short)varID;
-  (*record).levelID = (short)levelID;
+ at Result
+ at func{streamInqVlist} returns an identifier to the variable list.
 
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
+ at EndFunction
+*/
+int streamInqVlist(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d",
-	    varID, gridID, levelID);
+  stream_check_ptr(__func__, streamptr);
+
+  return (streamptr->vlistID);
 }
 
-static
-void srvScanTimestep1(stream_t *streamptr)
+
+int streamInqVlistIDorig(int streamID)
 {
-  int header[8];
-  int prec = 0;
-  int status;
-  int fileID;
-  int rxsize = 0, rysize = 0;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  off_t recpos;
-  int nrecords, nrecs, recID;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  SRVCOMPVAR compVar, compVar0;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  streamptr->curTsID = 0;
+  stream_check_ptr(__func__, streamptr);
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+  return (streamptr->vlistIDorig);
+}
 
-  if ( tsID != 0 )
-    Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamptr->fileID;
+void streamDefCompType(int streamID, int comptype)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  nrecs = 0;
-  while ( TRUE )
-    {
-      recpos = fileGetPos(fileID);
-      status = srvRead(fileID, srvp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+  stream_check_ptr(__func__, streamptr);
 
-      srvInqHeader(srvp, header);
+  if (streamptr->comptype != comptype)
+    {
+      streamptr->comptype = comptype;
+      reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-      prec   = srvp->dprec;
-      rcode  = header[0];
-      rlevel = header[1];
-      vdate  = header[2];
-      vtime  = header[3];
-      rxsize = header[4];
-      rysize = header[5];
 
-      param = cdiEncodeParam(rcode, 255, 255);
+void streamDefCompLevel(int streamID, int complevel)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	}
-      else
-	{
-	  datetime.date = vdate;
-	  datetime.time = vtime;
-	  compVar.param = param;
-          compVar.level = rlevel;
-	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      compVar0.param = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
+  stream_check_ptr(__func__, streamptr);
 
-	      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 ) break;
-	    }
-	  if ( recID < nrecs ) break;
-	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
-	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
-	}
+  if (streamptr->complevel != complevel)
+    {
+      streamptr->complevel = complevel;
+      reshSetStatus(streamID, &streamOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-      nrecs++;
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
+int streamInqCompType(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
-    }
+  stream_check_ptr(__func__, streamptr);
 
-  streamptr->rtsteps = 1;
+  return (streamptr->comptype);
+}
 
-  cdi_generate_vars(streamptr);
 
-  taxisID = taxisCreate(TAXIS_ABSOLUTE);
-  taxis->type  = TAXIS_ABSOLUTE;
-  taxis->vdate = (int)datetime0.date;
-  taxis->vtime = (int)datetime0.time;
+int streamInqCompLevel(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamptr->vlistID;
-  vlistDefTaxis(vlistID, taxisID);
+  stream_check_ptr(__func__, streamptr);
 
-  vlist_check_contents(vlistID);
+  return (streamptr->complevel);
+}
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  if ( nrecords < streamptr->tsteps[0].recordSize )
-    {
-      streamptr->tsteps[0].recordSize = nrecords;
-      streamptr->tsteps[0].records =
-	(record_t *)xrealloc(streamptr->tsteps[0].records,
-                             (size_t)nrecords * sizeof(record_t));
-    }
+int streamInqFileID(int streamID)
+{
+  stream_t *streamptr;
 
-  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
-  streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[0].recIDs[recID] = recID;
+  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
 
-  if ( streamptr->ntsteps == -1 )
-    {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+  return (streamptr->fileID);
+}
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
-    }
+void cdiDefAccesstype(int streamID, int type)
+{
+  stream_t *streamptr = reshGetVal(streamID, &streamOps);
 
-  if ( streamptr->ntsteps == 1 )
+  if ( streamptr->accesstype == CDI_UNDEFID )
     {
-      if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
+      streamptr->accesstype = type;
     }
+  else if ( streamptr->accesstype != type )
+    Error("Changing access type from %s not allowed!",
+          streamptr->accesstype == TYPE_REC ? "REC to VAR" : "VAR to REC");
 }
 
-static
-int srvScanTimestep2(stream_t *streamptr)
-{
-  int header[8];
-  int status;
-  int fileID;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  int tsID;
-  int varID;
-  off_t recpos = 0;
-  int nrecords, nrecs, recID, rindex;
-  int nextstep;
-  taxis_t *taxis;
-  int vlistID;
-  SRVCOMPVAR compVar, compVar0;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-
-  streamptr->curTsID = 1;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
 
-  tsID = streamptr->rtsteps;
-  if ( tsID != 1 )
-    Error("Internal problem! unexpected timestep %d", tsID+1);
+int cdiInqAccesstype(int streamID)
+{
+  stream_t *streamptr;
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
 
-  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+  return (streamptr->accesstype);
+}
 
-  cdi_create_records(streamptr, tsID);
+static
+int streamTxCode(void)
+{
+  return STREAM;
+}
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
-  streamptr->tsteps[1].nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[1].recIDs[recID] = -1;
 
-  for ( recID = 0; recID < nrecords; recID++ )
+void cdiStreamSetupVlist(stream_t *streamptr, int vlistID, int vlistIDorig)
+{
+  vlist_lock(vlistID);
+  int nvars = vlistNvars(vlistID);
+  streamptr->vlistID = vlistID;
+  streamptr->vlistIDorig = vlistIDorig;
+  for (int varID = 0; varID < nvars; varID++ )
     {
-      varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position =
-	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     =
-	streamptr->tsteps[0].records[recID].size;
+      int gridID  = vlistInqVarGrid(vlistID, varID);
+      int zaxisID = vlistInqVarZaxis(vlistID, varID);
+      stream_new_var(streamptr, gridID, zaxisID);
+      if ( streamptr->have_missval )
+        vlistDefVarMissval(vlistID, varID,
+                           vlistInqVarMissval(vlistID, varID));
     }
 
-  for ( rindex = 0; rindex <= nrecords; rindex++ )
-    {
-      recpos = fileGetPos(fileID);
-      status = srvRead(fileID, srvp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 2;
-	  break;
-	}
-      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+  if (streamptr->filemode == 'w' )
+    switch (streamptr->filetype)
+      {
+#ifdef HAVE_LIBNETCDF
+      case FILETYPE_NC:
+      case FILETYPE_NC2:
+      case FILETYPE_NC4:
+      case FILETYPE_NC4C:
+        {
+          void (*myCdfDefVars)(stream_t *streamptr)
+            = (void (*)(stream_t *))
+            namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
+          myCdfDefVars(streamptr);
+        }
+        break;
+#endif
+      case FILETYPE_GRB:
+      case FILETYPE_GRB2:
+        gribContainersNew(streamptr);
+        break;
+      }
+}
 
-      srvInqHeader(srvp, header);
 
-      rcode  = header[0];
-      rlevel = header[1];
-      vdate  = header[2];
-      vtime  = header[3];
+void cdiStreamGetIndexList(unsigned numIDs, int IDs[numIDs])
+{
+  reshGetResHListOfType(numIDs, IDs, &streamOps);
+}
 
-      param = cdiEncodeParam(rcode, 255, 255);
+int streamInqNvars ( int streamID )
+{
+  stream_t *streamptr = reshGetVal(streamID, &streamOps);
+  return streamptr->nvars;
+}
 
-      if ( rindex == 0 )
-	{
-	  taxis->type  = TAXIS_ABSOLUTE;
-	  taxis->vdate = vdate;
-	  taxis->vtime = vtime;
-	}
 
-      compVar.param = param;
-      compVar.level = rlevel;
-      nextstep = FALSE;
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+static int streamCompareP(void * streamptr1, void * streamptr2)
+{
+  stream_t * s1 = ( stream_t * ) streamptr1;
+  stream_t * s2 = ( stream_t * ) streamptr2;
+  enum {
+    differ = -1,
+    equal  = 0,
+  };
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 )
-	    {
-	      if ( streamptr->tsteps[tsID].records[recID].used )
-		{
-		  nextstep = TRUE;
-		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
-	      break;
-	    }
-	}
-      if ( recID == nrecords )
-	{
-	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
-	  return (CDI_EUFSTRUCT);
-	}
+  xassert ( s1 );
+  xassert ( s2 );
 
-      if ( nextstep ) break;
+  if ( s1->filetype  != s2->filetype  ) return differ;
+  if (  namespaceAdaptKey2 ( s1->vlistIDorig ) !=
+	namespaceAdaptKey2 ( s2->vlistIDorig )) return differ;
+  if ( s1->byteorder != s2->byteorder ) return differ;
+  if ( s1->comptype  != s2->comptype  ) return differ;
+  if ( s1->complevel != s2->complevel ) return differ;
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);
+  if ( s1->filename )
+    {
+      if (strcmp(s1->filename, s2->filename))
+	return differ;
+    }
+  else if ( s2->filename )
+    return differ;
 
-      streamptr->tsteps[tsID].records[recID].size = recsize;
+  return equal;
+}
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
-	{
-	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		  tsID, recID,
-		  streamptr->tsteps[tsID].records[recID].param, param,
-		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	  return (CDI_EUFSTRUCT);
-	}
+void streamDestroyP ( void * streamptr )
+{
+  stream_t * sp = ( stream_t * ) streamptr;
 
-      streamptr->tsteps[1].records[recID].position = recpos;
-    }
+  xassert ( sp );
 
-  nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      if ( ! streamptr->tsteps[tsID].records[recID].used )
-	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	}
-      else
-	{
-	  nrecs++;
-	}
-    }
-  streamptr->tsteps[tsID].nrecs = nrecs;
+  int id = sp->self;
+  streamClose ( id );
+}
 
-  streamptr->rtsteps = 2;
 
-  if ( streamptr->ntsteps == -1 )
-    {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+void streamPrintP   ( void * streamptr, FILE * fp )
+{
+  stream_t * sp = ( stream_t * ) streamptr;
+
+  if ( !sp ) return;
+
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "# streamID %d\n", sp->self);
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "self          = %d\n", sp->self );
+  fprintf ( fp, "accesstype    = %d\n", sp->accesstype );
+  fprintf ( fp, "accessmode    = %d\n", sp->accessmode );
+  fprintf ( fp, "filetype      = %d\n", sp->filetype );
+  fprintf ( fp, "byteorder     = %d\n", sp->byteorder );
+  fprintf ( fp, "fileID        = %d\n", sp->fileID );
+  fprintf ( fp, "filemode      = %d\n", sp->filemode );
+  fprintf ( fp, "//off_t numvals;\n" );
+  fprintf ( fp, "filename      = %s\n", sp->filename );
+  fprintf ( fp, "//Record   *record;\n" );
+  fprintf ( fp, "nrecs         = %d\n", sp->nrecs );
+  fprintf ( fp, "nvars         = %d\n", sp->nvars );
+  fprintf ( fp, "//svarinfo_t *vars;\n" );
+  fprintf ( fp, "varsAllocated = %d\n", sp->varsAllocated );
+  fprintf ( fp, "curTsID       = %d\n", sp->curTsID );
+  fprintf ( fp, "rtsteps       = %d\n", sp->rtsteps );
+  fprintf ( fp, "//long ntsteps;\n" );
+  fprintf ( fp, "//  tsteps_t   *tsteps;\n" );
+  fprintf ( fp, "tstepsTableSize= %d\n", sp->tstepsTableSize );
+  fprintf ( fp, "tstepsNextID  = %d\n", sp->tstepsNextID );
+  fprintf ( fp, "//basetime_t  basetime;\n" );
+  fprintf ( fp, "ncmode        = %d\n", sp->ncmode );
+  fprintf ( fp, "vlistID       = %d\n", sp->vlistID );
+  fprintf ( fp, "//  int       xdimID[MAX_GRIDS_PS];\n" );
+  fprintf ( fp, "//  int       ydimID[MAX_GRIDS_PS];\n" );
+  fprintf ( fp, "//  int       zaxisID[MAX_ZAXES_PS];\n" );
+  fprintf ( fp, "//  int       ncxvarID[MAX_GRIDS_PS];\n" );
+  fprintf ( fp, "//  int       ncyvarID[MAX_GRIDS_PS];\n" );
+  fprintf ( fp, "//  int       ncavarID[MAX_GRIDS_PS];\n" );
+  fprintf ( fp, "historyID     = %d\n", sp->historyID );
+  fprintf ( fp, "globalatts    = %d\n", sp->globalatts );
+  fprintf ( fp, "localatts     = %d\n", sp->localatts );
+  fprintf ( fp, "//  VCT       vct;\n" );
+  fprintf ( fp, "unreduced     = %d\n", sp->unreduced );
+  fprintf ( fp, "sortname      = %d\n", sp->sortname );
+  fprintf ( fp, "have_missval  = %d\n", sp->have_missval );
+  fprintf ( fp, "ztype         = %d\n", sp->comptype );
+  fprintf ( fp, "zlevel        = %d\n", sp->complevel );
+  fprintf ( fp, "//  void    **gribContainers;\n" );
+  fprintf ( fp, "vlistIDorig   = %d\n", sp->vlistIDorig );
+}
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
-    }
+enum {
+  streamNint = 11,
+};
 
-  return (0);
+static int
+streamGetPackSize(void * voidP, void *context)
+{
+  stream_t * streamP = ( stream_t * ) voidP;
+  int packBufferSize
+    = serializeGetSize(streamNint, DATATYPE_INT, context)
+    + serializeGetSize(2, DATATYPE_UINT32, context)
+    + serializeGetSize((int)strlen(streamP->filename) + 1,
+                       DATATYPE_TXT, context)
+    + serializeGetSize(1, DATATYPE_FLT64, context);
+  return packBufferSize;
 }
 
 
-int srvInqContents(stream_t *streamptr)
+static void
+streamPack(void * streamptr, void * packBuffer, int packBufferSize,
+           int * packBufferPos, void *context)
 {
-  int fileID;
-  int status = 0;
+  stream_t * streamP = ( stream_t * ) streamptr;
+  int intBuffer[streamNint];
 
-  fileID = streamptr->fileID;
+  intBuffer[0]  = streamP->self;
+  intBuffer[1]  = streamP->filetype;
+  intBuffer[2]  = (int)strlen(streamP->filename) + 1;
+  intBuffer[3]  = streamP->vlistID;
+  intBuffer[4]  = streamP->vlistIDorig;
+  intBuffer[5]  = streamP->byteorder;
+  intBuffer[6]  = streamP->comptype;
+  intBuffer[7]  = streamP->complevel;
+  intBuffer[8]  = streamP->unreduced;
+  intBuffer[9]  = streamP->sortname;
+  intBuffer[10] = streamP->have_missval;
 
-  streamptr->curTsID = 0;
+  serializePack(intBuffer, streamNint, DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
+  uint32_t d = cdiCheckSum(DATATYPE_INT, streamNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
 
-  srvScanTimestep1(streamptr);
+  serializePack(&cdiDefaultMissval, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+  serializePack(streamP->filename, intBuffer[2], DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
+  d = cdiCheckSum(DATATYPE_TXT, intBuffer[2], streamP->filename);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+}
 
-  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
+struct streamAssoc
+streamUnpack(char * unpackBuffer, int unpackBufferSize,
+             int * unpackBufferPos, int originNamespace, void *context)
+{
+  int intBuffer[streamNint], streamID;
+  uint32_t d;
+  char filename[CDI_MAX_NAME];
 
-  fileSetPos(fileID, 0, SEEK_SET);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  intBuffer, streamNint, DATATYPE_INT, context);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
 
-  return (status);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &filename, intBuffer[2], DATATYPE_TXT, context);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(d == cdiCheckSum(DATATYPE_TXT, intBuffer[2], filename));
+  int targetStreamID = namespaceAdaptKey(intBuffer[0], originNamespace);
+  streamID = streamOpenID(filename, "w", intBuffer[1], targetStreamID);
+  xassert(streamID >= 0 && targetStreamID == streamID);
+  streamDefByteorder(streamID, intBuffer[5]);
+  streamDefCompType(streamID, intBuffer[6]);
+  streamDefCompLevel(streamID, intBuffer[7]);
+  stream_t *streamptr = stream_to_pointer(streamID);
+  streamptr->unreduced = intBuffer[8];
+  streamptr->sortname = intBuffer[9];
+  streamptr->have_missval = intBuffer[10];
+  struct streamAssoc retval = { streamID, intBuffer[3], intBuffer[4] };
+  return retval;
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _VARSCAN_H
+#define _VARSCAN_H
 
-static
-long srvScanTimestep(stream_t *streamptr)
-{
-  int header[8];
-  int status;
-  int fileID;
-  /* int rxsize = 0, rysize = 0; */
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  off_t recpos = 0;
-  int recID;
-  int rindex, nrecs = 0;
-  SRVCOMPVAR compVar, compVar0;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-  /*
-  if ( CDI_Debug )
-    {
-      Message("streamID = %d", streamptr->self);
-      Message("cts = %d", streamptr->curTsID);
-      Message("rts = %d", streamptr->rtsteps);
-      Message("nts = %d", streamptr->ntsteps);
-    }
-  */
+#ifndef _GRID_H
+#endif
 
-  int tsID  = streamptr->rtsteps;
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-  if ( streamptr->tsteps[tsID].recordSize == 0 )
-    {
-      cdi_create_records(streamptr, tsID);
+void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
+		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
+		  const char *name, const char *stdname, const char *longname, const char *units);
 
-      nrecs = streamptr->tsteps[1].nrecs;
+void varDefVCT(size_t vctsize, double *vctptr);
+void varDefZAxisReference(int nlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]);
 
-      streamptr->tsteps[tsID].nrecs = nrecs;
-      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
-      for ( recID = 0; recID < nrecs; recID++ )
-	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
+int  varDefGrid(int vlistID, const grid_t *grid, int mode);
+int  varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
+		 double *levels1, double *levels2, int vctsize, double *vct, char *name,
+		 char *longname, char *units, int prec, int mode, int ltype);
 
-      fileID = streamptr->fileID;
+void varDefMissval(int varID, double missval);
+void varDefCompType(int varID, int comptype);
+void varDefInst(int varID, int instID);
+int  varInqInst(int varID);
+void varDefModel(int varID, int modelID);
+int  varInqModel(int varID);
+void varDefTable(int varID, int tableID);
+int  varInqTable(int varID);
+void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess);
+void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate);
 
-      for ( rindex = 0; rindex <= nrecs; rindex++ )
-	{
-	  recpos = fileGetPos(fileID);
-	  status = srvRead(fileID, srvp);
-	  if ( status != 0 )
-	    {
-	      streamptr->ntsteps = streamptr->rtsteps + 1;
-	      break;
-	    }
-	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-	  srvInqHeader(srvp, header);
+void varDefOptGribInt(int varID, long lval, const char *keyword);
+void varDefOptGribDbl(int varID, double dval, const char *keyword);
+int varOptGribNentries(int varID);
 
-	  rcode  = header[0];
-	  rlevel = header[1];
-	  vdate  = header[2];
-	  vtime  = header[3];
-          /* rxsize = header[4]; */
-          /* rysize = header[5]; */
+int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, char *longname, char *units, int ltype);
 
-	  param = cdiEncodeParam(rcode, 255, 255);
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
-	  if ( rindex == nrecs ) continue;
-	  recID = streamptr->tsteps[tsID].recIDs[rindex];
+#ifdef HAVE_LIBNETCDF
 
-	  if ( rindex == 0 )
-	    {
-	      taxis->type  = TAXIS_ABSOLUTE;
-	      taxis->vdate = vdate;
-	      taxis->vtime = vtime;
-	    }
+//#define TEST_GROUPS 1
 
-	  compVar.param  = param;
-          compVar.level  = rlevel;
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <float.h>
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
-	    {
-	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		      tsID, recID,
-		      streamptr->tsteps[tsID].records[recID].param, param,
-		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	      Error("Invalid, unsupported or inconsistent record structure!");
-	    }
+#include <netcdf.h>
 
-	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = recsize;
 
-	  if ( CDI_Debug )
-	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
-	}
+//#define PROJECTION_TEST
 
-      streamptr->rtsteps++;
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
 
-      if ( streamptr->ntsteps != streamptr->rtsteps )
-	{
-	  tsID = tstepsNewEntry(streamptr);
-	  if ( tsID != streamptr->rtsteps )
-	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = 1;
-	  streamptr->tsteps[tsID].position = recpos;
-	}
+#if defined HAVE_LIBNETCDF
+static void cdfDefGlobalAtts(stream_t *streamptr);
+static void cdfDefLocalAtts(stream_t *streamptr);
+#endif
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
-      streamptr->tsteps[tsID].position = recpos;
-    }
+#define  X_AXIS  1
+#define  Y_AXIS  2
+#define  Z_AXIS  3
+#define  T_AXIS  4
 
-  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
-    {
-      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
-      streamptr->ntsteps = tsID;
-    }
+#define  POSITIVE_UP    1
+#define  POSITIVE_DOWN  2
 
-  return (streamptr->ntsteps);
+typedef struct {
+  int     ncvarid;
+  int     dimtype;
+  size_t  len;
+  char    name[CDI_MAX_NAME];
 }
+ncdim_t;
 
+#define  MAX_COORDVARS  4
+#define  MAX_AUXVARS    4
 
-int srvInqTimestep(stream_t *streamptr, int tsID)
-{
-  long ntsteps;
-  int nrecs;
-
-  if ( tsID == 0 && streamptr->rtsteps == 0 )
-    Error("Call to cdiInqContents missing!");
+typedef struct {
+  int      ncid;
+  int      ignore;
+  int      isvar;
+  int      islon;
+  int      islat;
+  int      islev;
+  int      istime;
+  int      warn;
+  int      tsteptype;
+  int      param;
+  int      code;
+  int      tabnum;
+  int      climatology;
+  int      bounds;
+  int      gridID;
+  int      zaxisID;
+  int      gridtype;
+  int      zaxistype;
+  int      xdim;
+  int      ydim;
+  int      zdim;
+  int      xvarid;
+  int      yvarid;
+  int      zvarid;
+  int      tvarid;
+  int      ncoordvars;
+  int      coordvarids[MAX_COORDVARS];
+  int      nauxvars;
+  int      auxvarids[MAX_AUXVARS];
+  int      cellarea;
+  int      calendar;
+  int      tableID;
+  int      truncation;
+  int      position;
+  int      defmissval;
+  int      deffillval;
+  int      xtype;
+  int      ndims;
+  int      gmapid;
+  int      positive;
+  int      dimids[8];
+  int      dimtype[8];
+  int      chunks[8];
+  int      chunked;
+  int      chunktype;
+  int      natts;
+  int     *atts;
+  int      deflate;
+  int      lunsigned;
+  int      lvalidrange;
+  size_t   vlen;
+  double  *vdata;
+  double   missval;
+  double   fillval;
+  double   addoffset;
+  double   scalefactor;
+  double   validrange[2];
+  char     name[CDI_MAX_NAME];
+  char     longname[CDI_MAX_NAME];
+  char     stdname[CDI_MAX_NAME];
+  char     units[CDI_MAX_NAME];
+  char     extra[CDI_MAX_NAME];
+  ensinfo_t   *ensdata;    /* Ensemble information */
+}
+ncvar_t;
 
-  if ( CDI_Debug )
-    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
+static
+void strtolower(char *str)
+{
+  if ( str )
+    for (size_t i = 0; str[i]; ++i)
+      str[i] = (char)tolower((int)str[i]);
+}
 
-  ntsteps = UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = srvScanTimestep(streamptr);
+static
+int get_timeunit(size_t len, const char *ptu)
+{
+  int timeunit = -1;
 
-  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != UNDEFID )
+  if ( len > 2 )
     {
-      nrecs = 0;
+      if      ( memcmp(ptu, "sec",    3) == 0 )          timeunit = TUNIT_SECOND;
+      else if ( memcmp(ptu, "minute", 6) == 0 )          timeunit = TUNIT_MINUTE;
+      else if ( memcmp(ptu, "hour",   4) == 0 )          timeunit = TUNIT_HOUR;
+      else if ( memcmp(ptu, "day",    3) == 0 )          timeunit = TUNIT_DAY;
+      else if ( memcmp(ptu, "month",  5) == 0 )          timeunit = TUNIT_MONTH;
+      else if ( memcmp(ptu, "calendar_month", 14) == 0 ) timeunit = TUNIT_MONTH;
+      else if ( memcmp(ptu, "year",   4) == 0 )          timeunit = TUNIT_YEAR;
     }
-  else
+  else if ( len == 1 )
     {
-      streamptr->curTsID = tsID;
-      nrecs = streamptr->tsteps[tsID].nrecs;
+      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
     }
 
-  return (nrecs);
+  return (timeunit);
 }
 
-
-void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+static
+int isTimeUnits(const char *timeunits)
 {
-  int vlistID, fileID;
-  int levID, nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int header[8];
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
-
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
-
-  currentfilepos = fileGetPos(fileID);
+  int status = 0;
 
-  for (levID = 0; levID < nlevs; levID++)
-    {
-      recID = streamptr->vars[varID].level[levID];
-      recpos = streamptr->tsteps[tsid].records[recID].position;
-      fileSetPos(fileID, recpos, SEEK_SET);
-      if (srvRead(fileID, srvp) < 0)
-        abort();
-      srvInqHeader(srvp, header);
-      srvInqDataDP(srvp, &data[levID*gridsize]);
-    }
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
+  if ( strncmp(timeunits, "sec",    3) == 0 ||
+       strncmp(timeunits, "minute", 6) == 0 ||
+       strncmp(timeunits, "hour",   4) == 0 ||
+       strncmp(timeunits, "day",    3) == 0 ||
+       strncmp(timeunits, "month",  5) == 0 ) status = 1;
 
-  *nmiss = 0;
-  for ( i = 0; i < nlevs*gridsize; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
+  return (status);
 }
 
-
-void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+static
+int isTimeAxisUnits(const char *timeunits)
 {
-  int vlistID, fileID;
-  int nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int header[8];
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
-
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d",
-	     nlevs, gridID, gridsize);
-
-  currentfilepos = fileGetPos(fileID);
-
-  recID = streamptr->vars[varID].level[levID];
-  recpos = streamptr->tsteps[tsid].records[recID].position;
-  fileSetPos(fileID, recpos, SEEK_SET);
-  if (srvRead(fileID, srvp) < 0)
-    abort();
-  srvInqHeader(srvp, header);
-  srvInqDataDP(srvp, data);
-
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
+  char *ptu, *tu;
+  int timetype = -1;
+  int timeunit;
+  int status = FALSE;
 
-  *nmiss = 0;
-  for ( i = 0; i < gridsize; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
-}
+  size_t len = strlen(timeunits);
+  tu = xmalloc((len+1)*sizeof(char));
+  memcpy(tu, timeunits, (len+1) * sizeof(char));
+  ptu = tu;
 
+  for (size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
 
-void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
-{
-  int fileID;
-  int levID, nlevs, gridID, gridsize;
-  int zaxisID;
-  double level;
-  int header[8];
-  int xsize, ysize;
-  int datatype;
-  int tsID;
-  int vlistID;
-  int pdis, pcat, pnum;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+  timeunit = get_timeunit(len, ptu);
+  if ( timeunit != -1 )
+    {
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamptr->self, varID);
+      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+      if ( *ptu )
+        {
+          while ( isspace(*ptu) ) ptu++;
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  tsID     = streamptr->curTsID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  nlevs    = zaxisInqSize(zaxisID);
+          if ( memcmp(ptu, "as", 2) == 0 )
+            timetype = TAXIS_ABSOLUTE;
+          else if ( memcmp(ptu, "since", 5) == 0 )
+            timetype = TAXIS_RELATIVE;
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+          if ( timetype != -1 ) status = TRUE;
+        }
+    }
 
-  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+  free(tu);
 
-  header[0] = pnum;
-  header[2] = streamptr->tsteps[tsID].taxis.vdate;
-  header[3] = streamptr->tsteps[tsID].taxis.vtime;
+  return (status);
+}
 
-  xsize = gridInqXsize(gridID);
-  ysize = gridInqYsize(gridID);
-  if ( xsize == 0 || ysize == 0 )
+static
+void scanTimeString(const char *ptu, int *rdate, int *rtime)
+{
+  int year = 1, month = 1, day = 1;
+  int hour = 0, minute = 0, second = 0;
+  int v1 = 1, v2 = 1, v3 = 1;
+
+  *rdate = 0;
+  *rtime = 0;
+
+  if ( *ptu )
     {
-      xsize = gridInqSize(gridID);
-      ysize = 1;
+      v1 = atoi(ptu);
+      if ( v1 < 0 ) ptu++;
+      while ( isdigit((int) *ptu) ) ptu++;
+      if ( *ptu )
+        {
+          v2 = atoi(++ptu);
+          while ( isdigit((int) *ptu) ) ptu++;
+          if ( *ptu )
+            {
+              v3 = atoi(++ptu);
+              while ( isdigit((int) *ptu) ) ptu++;
+            }
+        }
     }
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
-  if ( gridInqSize(gridID) != xsize*ysize )
-    Error("Internal problem with gridsize!");
-
-  header[4] = xsize;
-  header[5] = ysize;
-  header[6] = 0;
-  header[7] = 0;
 
-  datatype = vlistInqVarDatatype(vlistID, varID);
+  if ( v3 > 999 && v1 < 32 )
+    { year = v3; month = v2; day = v1; }
+  else
+    { year = v1; month = v2; day = v3; }
 
-  srvp->dprec = srvDefDatatype(datatype);
+  while ( isspace((int) *ptu) ) ptu++;
 
-  for ( levID = 0; levID < nlevs; levID++ )
+  if ( *ptu )
     {
-      level = zaxisInqLevel(zaxisID, levID);
+      while ( ! isdigit((int) *ptu) ) ptu++;
 
-      header[1] = (int) level;
-      srvDefHeader(srvp, header);
-      srvDefDataDP(srvp, &data[levID*gridsize]);
-      srvWrite(fileID, srvp);
+      hour = atoi(ptu);
+      while ( isdigit((int) *ptu) ) ptu++;
+      if ( *ptu == ':' )
+        {
+          ptu++;
+          minute = atoi(ptu);
+          while ( isdigit((int) *ptu) ) ptu++;
+          if ( *ptu == ':' )
+            {
+              ptu++;
+              second = atoi(ptu);
+            }
+        }
     }
-}
 
+  *rdate = cdiEncodeDate(year, month, day);
+  *rtime = cdiEncodeTime(hour, minute, second);
+}
 
-void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+static
+int scanTimeUnit(const char *unitstr)
 {
-  int fileID;
-  int gridID;
-  int zaxisID;
-  double level;
-  int header[8];
-  int xsize, ysize;
-  int datatype;
-  int tsID;
-  int vlistID;
-  int pdis, pcat, pnum;
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+  int timeunit = -1;
+  size_t len = strlen(unitstr);
+  timeunit = get_timeunit(len, unitstr);
+  if ( timeunit == -1 )
+    Message("Unsupported TIMEUNIT: %s!", unitstr);
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  tsID     = streamptr->curTsID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  level    = zaxisInqLevel(zaxisID, levID);
+  return (timeunit);
+}
 
-  if ( CDI_Debug )
-    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
+static
+void setForecastTime(const char *timestr, taxis_t *taxis)
+{
+  int len;
 
-  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+  (*taxis).fdate = 0;
+  (*taxis).ftime = 0;
 
-  header[0] = pnum;
-  header[1] = (int) level;
-  header[2] = streamptr->tsteps[tsID].taxis.vdate;
-  header[3] = streamptr->tsteps[tsID].taxis.vtime;
+  len = (int) strlen(timestr);
+  if ( len == 0 ) return;
 
-  xsize = gridInqXsize(gridID);
-  ysize = gridInqYsize(gridID);
-  if ( xsize == 0 || ysize == 0 )
-    {
-      xsize = gridInqSize(gridID);
-      ysize = 1;
-    }
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
-  if ( gridInqSize(gridID) != xsize*ysize )
-    Error("Internal problem with gridsize!");
+  int fdate = 0, ftime = 0;
+  scanTimeString(timestr, &fdate, &ftime);
 
-  header[4] = xsize;
-  header[5] = ysize;
-  header[6] = 0;
-  header[7] = 0;
+  (*taxis).fdate = fdate;
+  (*taxis).ftime = ftime;
+}
 
-  datatype = vlistInqVarDatatype(vlistID, varID);
+static
+int setBaseTime(const char *timeunits, taxis_t *taxis)
+{
+  char *ptu, *tu;
+  int timetype = TAXIS_ABSOLUTE;
+  int rdate = -1, rtime = -1;
+  int timeunit;
 
-  srvp->dprec = srvDefDatatype(datatype);
+  size_t len = strlen(timeunits);
+  tu = xmalloc((len+1) * sizeof (char));
+  memcpy(tu, timeunits, (len+1) * sizeof (char));
+  ptu = tu;
 
-  srvDefHeader(srvp, header);
-  srvDefDataDP(srvp, data);
-  srvWrite(fileID, srvp);
-}
+  for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int) ptu[i]);
 
-#endif /* HAVE_LIBSERVICE */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  timeunit = get_timeunit(len, ptu);
+  if ( timeunit == -1 )
+    {
+      Message("Unsupported TIMEUNIT: %s!", timeunits);
+      return (1);
+    }
 
-#include <stdio.h>
-#include <string.h>
+  while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+  if ( *ptu )
+    {
+      while ( isspace(*ptu) ) ptu++;
+
+      if ( memcmp(ptu, "as", 2) == 0 )
+        timetype = TAXIS_ABSOLUTE;
+      else if ( memcmp(ptu, "since", 5) == 0 )
+        timetype = TAXIS_RELATIVE;
 
+      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+      if ( *ptu )
+        {
+          while ( isspace(*ptu) ) ptu++;
 
+          if ( timetype == TAXIS_ABSOLUTE )
+            {
+              if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
+                {
+                  Message("Unsupported format %s for TIMEUNIT day!", ptu);
+                  timeunit = -1;
+                }
+              else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
+                {
+                  Message("Unsupported format %s for TIMEUNIT month!", ptu);
+                  timeunit = -1;
+                }
+            }
+          else if ( timetype == TAXIS_RELATIVE )
+            {
+              scanTimeString(ptu, &rdate, &rtime);
 
+              (*taxis).rdate = rdate;
+              (*taxis).rtime = rtime;
 
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
+              if ( CDI_Debug )
+                Message("rdate = %d  rtime = %d", rdate, rtime);
+            }
+        }
+    }
 
-#define SINGLE_PRECISION  4
-#define DOUBLE_PRECISION  8
+  (*taxis).type = timetype;
+  (*taxis).unit = timeunit;
 
-#if defined (HAVE_LIBEXTRA)
+  free(tu);
 
+  if ( CDI_Debug )
+    Message("timetype = %d  unit = %d", timetype, timeunit);
 
-typedef struct {
-  int param;
-  int level;
-} extcompvar_t;
+  return (0);
+}
 
 static
-int extInqDatatype(int prec, int number)
+void cdfGetAttInt(int fileID, int ncvarid, char *attname, int attlen, int *attint)
 {
-  int datatype;
+  nc_type atttype;
+  size_t nc_attlen;
 
-  if ( number == 2 )
-    {
-      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_CPX64;
-      else                            datatype = DATATYPE_CPX32;
-    }
-  else
+  *attint = 0;
+
+  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+
+  if ( atttype != NC_CHAR )
     {
-      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
-      else                            datatype = DATATYPE_FLT32;
-    }
+      int *pintatt = NULL;
 
-  return (datatype);
+      if ( (int)nc_attlen > attlen )
+        pintatt = (int *) malloc(nc_attlen * sizeof (int));
+      else
+        pintatt = attint;
+
+      cdf_get_att_int(fileID, ncvarid, attname, pintatt);
+
+      if ( (int)nc_attlen > attlen )
+        {
+          memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
+          free(pintatt);
+        }
+    }
 }
 
 static
-void extDefDatatype(int datatype, int *prec, int *number)
+void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
 {
+  nc_type atttype;
+  size_t nc_attlen;
 
-  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 &&
-       datatype != DATATYPE_CPX32 && datatype != DATATYPE_CPX64 )
-    datatype = DATATYPE_FLT32;
+  *attdouble = 0;
 
-  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    *number = 2;
-  else
-    *number = 1;
+  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  if ( datatype == DATATYPE_FLT64 || datatype == DATATYPE_CPX64 )
-    *prec = DOUBLE_PRECISION;
-  else 
-    *prec = SINGLE_PRECISION;
+  if ( atttype != NC_CHAR )
+    {
+      double *pdoubleatt = NULL;
+
+      if ( (int)nc_attlen > attlen )
+        pdoubleatt = (double *) malloc(nc_attlen * sizeof (double));
+      else
+        pdoubleatt = attdouble;
+
+      cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
+
+      if ( (int)nc_attlen > attlen )
+        {
+          memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
+          free(pdoubleatt);
+        }
+    }
 }
 
-/* not used
-int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
+static
+void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *atttext)
 {
-  int status;
-  int fileID;
-  int icode, ilevel;
-  int zaxisID = -1;
-  int header[4];
-  int vlistID;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  nc_type atttype;
+  size_t nc_attlen;
 
-  *varID   = -1;
-  *levelID = -1;
+  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
+  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  status = extRead(fileID, extp);
-  if ( status != 0 ) return (0);
+  if ( atttype == NC_CHAR )
+    {
+      char attbuf[65636];
+      if ( nc_attlen < sizeof(attbuf) )
+        {
+          cdf_get_att_text(fileID, ncvarid, attname, attbuf);
 
-  extInqHeader(extp, header);
+          if ( (int) nc_attlen > (attlen-1) ) nc_attlen = (size_t)(attlen-1);
 
-  icode  = header[1];
-  ilevel = header[2];
+          attbuf[nc_attlen++] = 0;
+          memcpy(atttext, attbuf, nc_attlen);
+        }
+      else
+        {
+          atttext[0] = 0;
+        }
+    }
+#if  defined  (HAVE_NETCDF4)
+  else if ( atttype == NC_STRING )
+    {
+      if ( nc_attlen == 1 )
+        {
+          char *attbuf = NULL;
+          cdf_get_att_string(fileID, ncvarid, attname, &attbuf);
 
-  *varID = vlistInqVarID(vlistID, icode);
+          size_t ssize = strlen(attbuf) + 1;
 
-  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+          if ( ssize > (size_t)attlen ) ssize = (size_t)attlen;
+          memcpy(atttext, attbuf, ssize);
+          atttext[ssize - 1] = 0;
+          free(attbuf);
+        }
+      else
+        {
+          atttext[0] = 0;
+        }
+    }
+#endif
+}
 
-  zaxisID = vlistInqVarZaxis(vlistID, *varID);
+static
+int xtypeIsText(int xtype)
+{
+  int isText = FALSE;
 
-  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
+  if ( xtype == NC_CHAR )
+    isText = TRUE;
+#if  defined  (HAVE_NETCDF4)
+  else if ( xtype == NC_STRING )
+    isText = TRUE;
+#endif
 
-  return (1);
+  return (isText);
 }
-*/
 
-void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
+static
+int xtypeIsFloat(int xtype)
 {
-  int vlistID, fileID;
-  int status;
-  int recID, vrecID, tsID;
-  off_t recpos;
-  int header[4];
-  int varID, gridID;
-  int i, size;
-  double missval;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+  int isFloat = FALSE;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-  tsID    = streamptr->curTsID;
-  vrecID  = streamptr->tsteps[tsID].curRecID;
-  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-  recpos  = streamptr->tsteps[tsID].records[recID].position;
-  varID   = streamptr->tsteps[tsID].records[recID].varID;
+  if ( xtype == NC_FLOAT || xtype == NC_DOUBLE ) isFloat = TRUE;
 
-  fileSetPos(fileID, recpos, SEEK_SET);
+  return isFloat;
+}
 
-  status = extRead(fileID, extp);
-  if ( status != 0 )
-    Error("Failed to read EXTRA record");
+static
+int cdfInqDatatype(int xtype, int lunsigned)
+{
+  int datatype = -1;
 
-  extInqHeader(extp, header);
-  extInqDataDP(extp, data);
+#if  defined  (HAVE_NETCDF4)
+  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
+#endif
 
-  missval = vlistInqVarMissval(vlistID, varID);
-  gridID  = vlistInqVarGrid(vlistID, varID);
-  size    = gridInqSize(gridID);
+  if      ( xtype == NC_BYTE   )  datatype = DATATYPE_INT8;
+  /* else if ( xtype == NC_CHAR   )  datatype = DATATYPE_UINT8; */
+  else if ( xtype == NC_SHORT  )  datatype = DATATYPE_INT16;
+  else if ( xtype == NC_INT    )  datatype = DATATYPE_INT32;
+  else if ( xtype == NC_FLOAT  )  datatype = DATATYPE_FLT32;
+  else if ( xtype == NC_DOUBLE )  datatype = DATATYPE_FLT64;
+#if  defined  (HAVE_NETCDF4)
+  else if ( xtype == NC_UBYTE  )  datatype = DATATYPE_UINT8;
+  else if ( xtype == NC_LONG   )  datatype = DATATYPE_INT32;
+  else if ( xtype == NC_USHORT )  datatype = DATATYPE_UINT16;
+  else if ( xtype == NC_UINT   )  datatype = DATATYPE_UINT32;
+  else if ( xtype == NC_INT64  )  datatype = DATATYPE_FLT64;
+  else if ( xtype == NC_UINT64 )  datatype = DATATYPE_FLT64;
+#endif
 
-  streamptr->numvals += size;
+  return (datatype);
+}
 
-  *nmiss = 0;
-  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
+static
+int cdfDefDatatype(int datatype, int filetype)
+{
+  int xtype;
+
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    Error("CDI/netCDF library does not support complex numbers!");
+
+  if ( filetype == FILETYPE_NC4 )
     {
-      for ( i = 0; i < size; i++ )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
+      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
+      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
+      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
+#if  defined  (HAVE_NETCDF4)
+      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_UBYTE;
+      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
+      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
+#else
+      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
+      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
+      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
+#endif
+      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
+      else                                    xtype = NC_FLOAT;
     }
   else
     {
-      for ( i = 0; i < 2*size; i+=2 )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
+      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
+      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
+      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
+      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
+      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
+      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
+      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
+      else                                    xtype = NC_FLOAT;
     }
-}
 
+  return (xtype);
+}
 
-void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+static inline void *
+resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
 {
-  streamFCopyRecord(streamptr2, streamptr1, "EXTRA");
+  if (reqSize > *bufSize)
+    {
+      *buf = xrealloc(*buf, reqSize);
+      *bufSize = reqSize;
+    }
+  return *buf;
 }
 
-
-void extDefRecord(stream_t *streamptr)
+static
+void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
 {
-  int gridID;
-  int header[4];
-  int pdis, pcat, pnum;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+  int natts, iatt;
+  int atttype, attlen;
+  size_t len;
+  char attname[CDI_MAX_NAME+1];
+  void *attBuf = NULL;
+  size_t attBufSize = 0;
 
-  gridID   = streamptr->record->gridID;
+  vlistInqNatts(vlistID, varID, &natts);
 
-  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
-  header[0] = streamptr->record->date;
-  header[1] = pnum;
-  header[2] = streamptr->record->level;
-  header[3] = gridInqSize(gridID);
+  for ( iatt = 0; iatt < natts; iatt++ )
+    {
+      vlistInqAtt(vlistID, varID, iatt, attname, &atttype, &attlen);
 
-  extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
+      if ( attlen == 0 ) continue;
 
-  extDefHeader(extp, header);
+      if ( atttype == DATATYPE_TXT )
+        {
+          size_t attSize = (size_t)attlen*sizeof(char);
+          char *atttxt = (char *)resizeBuf(&attBuf, &attBufSize, attSize);
+          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
+          len = (size_t)attlen;
+          cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
+        }
+      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
+        {
+          size_t attSize = (size_t)attlen*sizeof(int);
+          int *attint = (int *)resizeBuf(&attBuf, &attBufSize, attSize);
+          vlistInqAttInt(vlistID, varID, attname, attlen, &attint[0]);
+          len = (size_t)attlen;
+          cdf_put_att_int(fileID, ncvarID, attname, atttype == DATATYPE_INT16 ? NC_SHORT : NC_INT, len, attint);
+        }
+      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
+        {
+          size_t attSize = (size_t)attlen * sizeof(double);
+          double *attflt = (double *)resizeBuf(&attBuf, &attBufSize, attSize);
+          vlistInqAttFlt(vlistID, varID, attname, attlen, attflt);
+          len = (size_t)attlen;
+          cdf_put_att_double(fileID, ncvarID, attname, atttype == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE, len, attflt);
+        }
+    }
+  free(attBuf);
 }
 
 
-void extWriteRecord(stream_t *streamptr, const double *data)
+void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
-  int fileID = streamptr->fileID;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+  int memtype  = MEMTYPE_DOUBLE;
+  int vlistID1 = streamptr1->vlistID;
+  int tsID     = streamptr1->curTsID;
+  int vrecID   = streamptr1->tsteps[tsID].curRecID;
+  int recID    = streamptr1->tsteps[tsID].recIDs[vrecID];
+  int ivarID   = streamptr1->tsteps[tsID].records[recID].varID;
+  int gridID   = vlistInqVarGrid(vlistID1, ivarID);
+  int datasize = gridInqSize(gridID);
 
-  extDefDataDP(extp, data);
-  extWrite(fileID, extp);
+  double *data = xmalloc((size_t)datasize * sizeof (double));
+
+  int nmiss;
+  cdfReadRecord(streamptr1, data, &nmiss);
+  cdf_write_record(streamptr2, memtype, data, nmiss);
+
+  free(data);
 }
 
-static
-void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
-		  size_t recsize, off_t position, int prec, int number)
+/* not used
+int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
-  int leveltype;
-  int gridID = CDI_UNDEFID;
-  int levelID = 0;
-  int tsID, recID, varID;
-  record_t *record;
-  grid_t grid;
-  int vlistID;
+  int tsID, recID;
 
-  vlistID = streamptr->vlistID;
-  tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamptr, tsID);
-  record  = &streamptr->tsteps[tsID].records[recID];
+  recID = streamptr->tsteps[0].curRecID++;
+  printf("cdfInqRecord recID %d %d\n", recID, streamptr->tsteps[0].curRecID);
+  printf("cdfInqRecord tsID %d\n", streamptr->curTsID);
 
-  (*record).size     = recsize;
-  (*record).position = position;
-  (*record).param     = param;
-  (*record).ilevel   = level;
+  if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
+    {
+      streamptr->tsteps[0].curRecID = 0;
+    }
 
-  memset(&grid, 0, sizeof(grid_t));
-  grid.type  = GRID_GENERIC;
-  grid.size  = xysize;
-  grid.xsize = xysize;
-  grid.ysize = 0;
-  grid.xvals = NULL;
-  grid.yvals = NULL;
-  gridID = varDefGrid(vlistID, &grid, 0);
-  /*
-  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
-  else              leveltype = ZAXIS_GENERIC;
-  */
-  leveltype = ZAXIS_GENERIC;
+  *varID   = streamptr->tsteps[0].records[recID].varID;
+  *levelID = streamptr->tsteps[0].records[recID].levelID;
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
-	       extInqDatatype(prec, number), &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
+  streamptr->record->varID   = *varID;
+  streamptr->record->levelID = *levelID;
 
-  (*record).varID   = (short)varID;
-  (*record).levelID = (short)levelID;
+  if ( CDI_Debug )
+    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
 
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
+  return (recID+1);
+}
+*/
 
-  if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d",
-	    varID, gridID, levelID);
+
+void cdfDefRecord(stream_t *streamptr)
+{
+  (void)streamptr;
 }
 
+
 static
-void extScanTimestep1(stream_t *streamptr)
+void cdfWriteGridTraj(stream_t *streamptr, int gridID)
 {
-  int header[4];
-  int status;
-  int fileID;
-  int rxysize = 0;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  long recsize;
-  off_t recpos;
-  int nrecords, nrecs, recID;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  extcompvar_t compVar, compVar0;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
-  streamptr->curTsID = 0;
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  int lonID = streamptr->xdimID[gridindex],
+    latID = streamptr->ydimID[gridindex];
 
-  if ( tsID != 0 )
-    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+  double xlon = gridInqXval(gridID, 0),
+    xlat = gridInqYval(gridID, 0);
+  int tsID = streamptr->curTsID;
+  size_t index = (size_t)tsID;
 
-  fileID = streamptr->fileID;
+  cdf_put_var1_double(fileID, lonID, &index, &xlon);
+  cdf_put_var1_double(fileID, latID, &index, &xlat);
+}
 
-  nrecs = 0;
-  while ( TRUE )
-    {
-      recpos = fileGetPos(fileID);
-      status = extRead(fileID, extp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      recsize = fileGetPos(fileID) - recpos;
+static
+void cdfReadGridTraj(stream_t *streamptr, int gridID)
+{
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-      extInqHeader(extp, header);
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  int lonID = streamptr->xdimID[gridindex];
+  int latID = streamptr->ydimID[gridindex];
 
-      vdate   = header[0];
-      vtime   = 0;
-      rcode   = header[1];
-      rlevel  = header[2];
-      rxysize = header[3];
+  int tsID = streamptr->curTsID;
+  size_t index = (size_t)tsID;
 
-      param = cdiEncodeParam(rcode, 255, 255);
+  double xlon, xlat;
+  cdf_get_var1_double(fileID, lonID, &index, &xlon);
+  cdf_get_var1_double(fileID, latID, &index, &xlat);
 
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	}
-      else
-	{
-	  datetime.date = vdate;
-	  datetime.time = vtime;
-	  compVar.param = param;
-          compVar.level = rlevel;
-	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
+  gridDefXvals(gridID, &xlon);
+  gridDefYvals(gridID, &xlat);
+}
 
-	      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 ) break;
-	    }
-	  if ( recID < nrecs ) break;
-	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
-	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
-	}
 
-      nrecs++;
+static
+void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
+{
+#if  defined  (HAVE_NETCDF4)
+  int retval;
+  /* Set chunking, shuffle, and deflate. */
+  int shuffle = 1;
+  int deflate = 1;
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
+  if ( deflate_level < 1 || deflate_level > 9 ) deflate_level = 1;
 
-      extAddRecord(streamptr, param, rlevel, rxysize, (size_t)recsize, recpos, extp->prec, extp->number);
+  if ((retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)))
+    {
+      Error("nc_def_var_deflate failed, status = %d", retval);
     }
+#else
+  static int lwarn = TRUE;
 
-  streamptr->rtsteps = 1;
-
-  cdi_generate_vars(streamptr);
-
-  taxisID = taxisCreate(TAXIS_ABSOLUTE);
-  taxis->type  = TAXIS_ABSOLUTE;
-  taxis->vdate = (int)datetime0.date;
-  taxis->vtime = (int)datetime0.time;
-
-  vlistID = streamptr->vlistID;
-  vlistDefTaxis(vlistID, taxisID);
-
-  vlist_check_contents(vlistID);
-
-  nrecords = streamptr->tsteps[0].nallrecs;
-  if ( nrecords < streamptr->tsteps[0].recordSize )
+  if ( lwarn )
     {
-      streamptr->tsteps[0].recordSize = nrecords;
-      streamptr->tsteps[0].records =
-        (record_t *)xrealloc(streamptr->tsteps[0].records, (size_t)nrecords * sizeof (record_t));
+      lwarn = FALSE;
+      Warning("Deflate compression failed, netCDF4 not available!");
     }
+#endif
+}
 
-  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
-  streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[0].recIDs[recID] = recID;
-
-  if ( streamptr->ntsteps == -1 )
-    {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
-    }
+#if defined(NC_SZIP_NN_OPTION_MASK)
+static
+void cdfDefVarSzip(int ncid, int ncvarid)
+{
+  int retval;
+  /* Set options_mask and bits_per_pixel. */
+  int options_mask = NC_SZIP_NN_OPTION_MASK;
+  int bits_per_pixel = 16;
 
-  if ( streamptr->ntsteps == 1 )
+  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
     {
-      if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
+      if ( retval == NC_EINVAL )
+        {
+          static int lwarn = TRUE;
+
+          if ( lwarn )
+            {
+              lwarn = FALSE;
+              Warning("netCDF4/Szip compression not compiled in!");
+            }
+        }
+      else
+        Error("nc_def_var_szip failed, status = %d", retval);
     }
 }
+#endif
 
 static
-int extScanTimestep2(stream_t *streamptr)
+void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 {
-  int header[4];
-  int status;
-  int fileID;
-  // int rxysize = 0;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  int tsID;
-  int varID;
-  off_t recpos = 0;
-  int nrecords, nrecs, recID, rindex;
-  int nextstep;
-  taxis_t *taxis;
-  int vlistID;
-  extcompvar_t compVar, compVar0;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
-  streamptr->curTsID = 1;
+  if ( streamptr->vars[varID].defmiss == FALSE )
+    {
+      int fileID;
+      int ncvarid;
+      double missval;
+      int vlistID;
+      int xtype;
 
-  fileID  = streamptr->fileID;
-  vlistID = streamptr->vlistID;
+      vlistID = streamptr->vlistID;
+      fileID  = streamptr->fileID;
+      ncvarid = streamptr->vars[varID].ncvarid;
+      missval = vlistInqVarMissval(vlistID, varID);
 
-  tsID = streamptr->rtsteps;
-  if ( tsID != 1 )
-    Error("Internal problem! unexpected timestep %d", tsID+1);
+      if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+      xtype = cdfDefDatatype(dtype, streamptr->filetype);
 
-  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
 
-  cdi_create_records(streamptr, tsID);
+      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  streamptr->tsteps[1].recIDs = xmalloc((size_t)nrecords * sizeof (int));
-  streamptr->tsteps[1].nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[1].recIDs[recID] = -1;
+      if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position =
-	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     =
-	streamptr->tsteps[0].records[recID].size;
+      streamptr->vars[varID].defmiss = TRUE;
     }
+}
 
-  for ( rindex = 0; rindex <= nrecords; rindex++ )
-    {
-      recpos = fileGetPos(fileID);
-      status = extRead(fileID, extp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 2;
-	  break;
-	}
-      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
-
-      extInqHeader(extp, header);
-
-      vdate  = header[0];
-      vtime  = 0;
-      rcode  = header[1];
-      rlevel = header[2];
-      // rxysize = header[3];
 
-      param = cdiEncodeParam(rcode, 255, 255);
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+{
+  int varID;
+  int levelID;
 
-      if ( rindex == 0 )
-	{
-	  taxis->type  = TAXIS_ABSOLUTE;
-	  taxis->vdate = vdate;
-	  taxis->vtime = vtime;
-	}
+  varID   = streamptr->record->varID;
+  levelID = streamptr->record->levelID;
 
-      compVar.param = param;
-      compVar.level = rlevel;
-      nextstep = FALSE;
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 )
-	    {
-	      if ( streamptr->tsteps[tsID].records[recID].used )
-		{
-		  nextstep = TRUE;
-		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
-	      break;
-	    }
-	}
-      if ( recID == nrecords )
-	{
-	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
-	  return (CDI_EUFSTRUCT);
-	}
+  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
+}
 
-      if ( nextstep ) break;
+void cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
+{
+  if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);
+  int tsID    = streamptr->curTsID;
+  int vrecID  = streamptr->tsteps[tsID].curRecID;
+  int recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+  int varID   = streamptr->tsteps[tsID].records[recID].varID;
+  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
 
-      streamptr->tsteps[tsID].records[recID].size = recsize;
+  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
+}
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+static
+void cdfDefTimeValue(stream_t *streamptr, int tsID)
+{
+  int fileID = streamptr->fileID;
 
-      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
-	{
-	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		  tsID, recID,
-		  streamptr->tsteps[tsID].records[recID].param, param,
-		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	  return (CDI_EUFSTRUCT);
-	}
+  if ( CDI_Debug )
+    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
-      streamptr->tsteps[1].records[recID].position = recpos;
-    }
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-  nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
+  if ( streamptr->ncmode == 1 )
     {
-      if ( ! streamptr->tsteps[tsID].records[recID].used )
-	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	}
-      else
-	{
-	  nrecs++;
-	}
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
-  streamptr->tsteps[tsID].nrecs = nrecs;
 
-  streamptr->rtsteps = 2;
+  size_t index = (size_t)tsID;
 
-  if ( streamptr->ntsteps == -1 )
+  double timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
+  if ( CDI_Debug ) Message("tsID = %d  timevalue = %f", tsID, timevalue);
+
+  int ncvarid = streamptr->basetime.ncvarid;
+  cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+
+  if ( taxis->has_bounds )
     {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+      size_t start[2], count[2];
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
+      ncvarid = streamptr->basetime.ncvarboundsid;
+
+      timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
+      start[0] = (size_t)tsID; count[0] = 1; start[1] = 0; count[1] = 1;
+      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+
+      timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
+      start[0] = (size_t)tsID; count[0] = 1; start[1] = 1; count[1] = 1;
+      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
     }
 
-  return (0);
-}
+  ncvarid = streamptr->basetime.leadtimeid;
+  if ( taxis->type == TAXIS_FORECAST && ncvarid != UNDEFID )
+    {
+      timevalue = taxis->fc_period;
+      cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+    }
 
+  /*
+printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
+  */
+}
 
-int extInqContents(stream_t *streamptr)
+static
+int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, char* taxis_name, taxis_t* taxis)
 {
-  int fileID;
-  int status = 0;
+  int time_bndsid = -1;
+  int dims[2];
+  char tmpstr[CDI_MAX_NAME];
+
+  dims[0] = nctimedimid;
 
-  fileID = streamptr->fileID;
+  /* fprintf(stderr, "time has bounds\n"); */
 
-  streamptr->curTsID = 0;
+  if ( nc_inq_dimid(fileID, "bnds", &dims[1]) != NC_NOERR )
+    cdf_def_dim(fileID, "bnds", 2, &dims[1]);
 
-  extScanTimestep1(streamptr);
+  if ( taxis->climatology )
+    {
+      strcpy(tmpstr, "climatology");
+      strcat(tmpstr, "_bnds");
+      cdf_def_var(fileID, tmpstr, NC_DOUBLE, 2, dims, &time_bndsid);
 
-  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
+      cdf_put_att_text(fileID, nctimevarid, "climatology", strlen(tmpstr), tmpstr);
+    }
+  else
+    {
+      strcpy(tmpstr, taxis_name);
+      strcat(tmpstr, "_bnds");
+      cdf_def_var(fileID, tmpstr, NC_DOUBLE, 2, dims, &time_bndsid);
 
-  fileSetPos(fileID, 0, SEEK_SET);
+      cdf_put_att_text(fileID, nctimevarid, "bounds", strlen(tmpstr), tmpstr);
+    }
 
-  return (status);
+  return (time_bndsid);
 }
 
 static
-long extScanTimestep(stream_t *streamptr)
+void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
 {
-  int header[4];
-  int status;
-  int fileID;
-  // int rxysize = 0;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  off_t recpos = 0;
-  int recID;
-  int rindex, nrecs = 0;
-  extcompvar_t compVar, compVar0;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-  /*
-  if ( CDI_Debug )
+  unitstr[0] = 0;
+
+  if ( taxis0->type == TAXIS_ABSOLUTE )
     {
-      Message("streamID = %d", streamptr->self);
-      Message("cts = %d", streamptr->curTsID);
-      Message("rts = %d", streamptr->rtsteps);
-      Message("nts = %d", streamptr->ntsteps);
+      if ( taxis0->unit == TUNIT_YEAR )
+        sprintf(unitstr, "year as %s", "%Y.%f");
+      else if ( taxis0->unit == TUNIT_MONTH )
+        sprintf(unitstr, "month as %s", "%Y%m.%f");
+      else
+        sprintf(unitstr, "day as %s", "%Y%m%d.%f");
     }
-  */
+  else
+    {
+      int year, month, day, hour, minute, second;
+      int rdate, rtime;
+      int timeunit;
 
-  int tsID  = streamptr->rtsteps;
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+      timeunit = taxis->unit;
+      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
+      rdate    = taxis->rdate;
+      rtime    = taxis->rtime;
+      if ( rdate == -1 )
+        {
+          rdate  = taxis->vdate;
+          rtime  = taxis->vtime;
+        }
 
-  if ( streamptr->tsteps[tsID].recordSize == 0 )
-    {
-      cdi_create_records(streamptr, tsID);
+      cdiDecodeDate(rdate, &year, &month, &day);
+      cdiDecodeTime(rtime, &hour, &minute, &second);
 
-      nrecs = streamptr->tsteps[1].nrecs;
+      if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
+      if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
+      if ( timeunit == TUNIT_3HOURS  ||
+	   timeunit == TUNIT_6HOURS  ||
+	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
 
-      streamptr->tsteps[tsID].nrecs = nrecs;
-      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
-      for ( recID = 0; recID < nrecs; recID++ )
-	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
+      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
+              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
+    }
+}
 
-      fileID = streamptr->fileID;
+static
+void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
+{
+  unitstr[0] = 0;
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+  if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
 
-      for ( rindex = 0; rindex <= nrecs; rindex++ )
-	{
-	  recpos = fileGetPos(fileID);
-	  status = extRead(fileID, extp);
-	  if ( status != 0 )
-	    {
-	      streamptr->ntsteps = streamptr->rtsteps + 1;
-	      break;
-	    }
-	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+  if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
+  if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
+  if ( timeunit == TUNIT_3HOURS  ||
+       timeunit == TUNIT_6HOURS  ||
+       timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
 
-	  extInqHeader(extp, header);
+  sprintf(unitstr, "%s", tunitNamePtr(timeunit));
+}
 
-	  vdate  = header[0];
-	  vtime  = 0;
-	  rcode  = header[1];
-	  rlevel = header[2];
-	  // rxysize = header[3];
+static
+void cdfDefCalendar(int fileID, int ncvarid, int calendar)
+{
+  size_t len;
+  char calstr[80];
 
-	  param = cdiEncodeParam(rcode, 255, 255);
+  calstr[0] = 0;
 
-	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
-	  if ( rindex == nrecs ) continue;
-	  recID = streamptr->tsteps[tsID].recIDs[rindex];
+  if      ( calendar == CALENDAR_STANDARD )  strcpy(calstr, "standard");
+  else if ( calendar == CALENDAR_PROLEPTIC ) strcpy(calstr, "proleptic_gregorian");
+  else if ( calendar == CALENDAR_NONE )      strcpy(calstr, "none");
+  else if ( calendar == CALENDAR_360DAYS )   strcpy(calstr, "360_day");
+  else if ( calendar == CALENDAR_365DAYS )   strcpy(calstr, "365_day");
+  else if ( calendar == CALENDAR_366DAYS )   strcpy(calstr, "366_day");
 
-	  if ( rindex == 0 )
-	    {
-	      taxis->type  = TAXIS_ABSOLUTE;
-	      taxis->vdate = vdate;
-	      taxis->vtime = vtime;
-	    }
+  len = strlen(calstr);
 
-	  compVar.param  = param;
-          compVar.level  = rlevel;
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+  if ( len ) cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
+}
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
-	    {
-	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		      tsID, recID,
-		      streamptr->tsteps[tsID].records[recID].param, param,
-		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	      Error("Invalid, unsupported or inconsistent record structure!");
-	    }
+static
+void cdfDefTime(stream_t* streamptr)
+{
+  int fileID;
+  int time_varid;
+  int time_dimid;
+  int time_bndsid = -1;
+  char unitstr[CDI_MAX_NAME];
+  char tmpstr[CDI_MAX_NAME];
+  char default_name[] = "time";
+  char* taxis_name = default_name;
+  size_t len;
+  taxis_t* taxis;
 
-	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = recsize;
+  if ( streamptr->basetime.ncvarid != UNDEFID ) return;
 
-	  if ( CDI_Debug )
-	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
-	}
+  fileID = streamptr->fileID;
 
-      streamptr->rtsteps++;
+  if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
 
-      if ( streamptr->ntsteps != streamptr->rtsteps )
-	{
-	  tsID = tstepsNewEntry(streamptr);
-	  if ( tsID != streamptr->rtsteps )
-	    Error("Internal error. tsID = %d", tsID);
+  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-	  streamptr->tsteps[tsID-1].next   = 1;
-	  streamptr->tsteps[tsID].position = recpos;
-	}
+  taxis = &streamptr->tsteps[0].taxis;
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
-      streamptr->tsteps[tsID].position = recpos;
-    }
+  if ( taxis->name && taxis->name[0] ) taxis_name = taxis->name;
 
-  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
-    {
-      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
-      streamptr->ntsteps = tsID;
-    }
+  cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
+  streamptr->basetime.ncdimid = time_dimid;
 
-  return (streamptr->ntsteps);
-}
+  cdf_def_var(fileID, taxis_name, NC_DOUBLE, 1, &time_dimid, &time_varid);
 
+  streamptr->basetime.ncvarid = time_varid;
 
-int extInqTimestep(stream_t *streamptr, int tsID)
-{
-  int nrecs;
-  long ntsteps;
+  strcpy(tmpstr, "time");
+  cdf_put_att_text(fileID, time_varid, "standard_name", strlen(tmpstr), tmpstr);
 
-  if ( tsID == 0 && streamptr->rtsteps == 0 )
-    Error("Call to cdiInqContents missing!");
+  if ( taxis->longname && taxis->longname[0] )
+    cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
 
-  if ( CDI_Debug )
-    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
+  if ( taxis->has_bounds )
+    {
+      time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
+      streamptr->basetime.ncvarboundsid = time_bndsid;
+    }
 
-  ntsteps = UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = extScanTimestep(streamptr);
+  cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
 
-  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+  len = strlen(unitstr);
+  if ( len )
     {
-      nrecs = 0;
+      cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
+      /*
+      if ( taxis->has_bounds )
+        cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
+      */
     }
-  else
+
+  if ( taxis->calendar != -1 )
     {
-      streamptr->curTsID = tsID;
-      nrecs = streamptr->tsteps[tsID].nrecs;
+      cdfDefCalendar(fileID, time_varid, taxis->calendar);
+      /*
+      if ( taxis->has_bounds )
+        cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
+      */
     }
 
-  return (nrecs);
-}
+  if ( taxis->type == TAXIS_FORECAST )
+    {
+      int leadtimeid;
 
+      cdf_def_var(fileID, "leadtime", NC_DOUBLE, 1, &time_dimid, &leadtimeid);
 
-void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
-{
-  int vlistID, fileID;
-  int levID, nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int header[4];
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+      streamptr->basetime.leadtimeid = leadtimeid;
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
+      strcpy(tmpstr, "forecast_period");
+      cdf_put_att_text(fileID, leadtimeid, "standard_name", strlen(tmpstr), tmpstr);
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+      strcpy(tmpstr, "Time elapsed since the start of the forecast");
+      cdf_put_att_text(fileID, leadtimeid, "long_name", strlen(tmpstr), tmpstr);
 
-  currentfilepos = fileGetPos(fileID);
+      cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
 
-  for (levID = 0; levID < nlevs; levID++)
-    {
-      recID = streamptr->vars[varID].level[levID];
-      recpos = streamptr->tsteps[tsid].records[recID].position;
-      fileSetPos(fileID, recpos, SEEK_SET);
-      extRead(fileID, extp);
-      extInqHeader(extp, header);
-      extInqDataDP(extp, &data[levID*gridsize]);
+      len = strlen(unitstr);
+      if ( len ) cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
     }
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  *nmiss = 0;
-  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
-    {
-      for ( i = 0; i < nlevs*gridsize; i++ )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
-    }
-  else
-    {
-      for ( i = 0; i < 2*nlevs*gridsize; i+=2 )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
-    }
+  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
 }
 
 
-void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void cdfDefTimestep(stream_t *streamptr, int tsID)
 {
-  int vlistID, fileID;
-  int nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int header[4];
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
+  int vlistID = streamptr->vlistID;
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d",
-	     nlevs, gridID, gridsize);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  currentfilepos = fileGetPos(fileID);
+  cdfDefTimeValue(streamptr, tsID);
+}
 
-  recID = streamptr->vars[varID].level[levID];
-  recpos = streamptr->tsteps[tsid].records[recID].position;
-  fileSetPos(fileID, recpos, SEEK_SET);
-  extRead(fileID, extp);
-  extInqHeader(extp, header);
-  extInqDataDP(extp, data);
+static
+void cdfDefComplex(stream_t *streamptr, int gridID)
+{
+  char axisname[] = "nc2";
+  int dimID = UNDEFID;
+  int gridID0, gridtype0;
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
+  int ngrids = vlistNgrids(vlistID);
 
-  *nmiss = 0;
-  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
+  for ( int index = 0; index < ngrids; index++ )
     {
-      for ( i = 0; i < gridsize; i++ )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
+            {
+              dimID = streamptr->xdimID[index];
+              break;
+            }
+        }
     }
-  else
+
+  if ( dimID == UNDEFID )
     {
-      for ( i = 0; i < 2*gridsize; i+=2 )
-	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-	  {
-	    data[i] = missval;
-	    (*nmiss)++;
-	  }
+      size_t dimlen = 2;
+
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
+
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->xdimID[gridindex] = dimID;
 }
 
 
-void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
+static
+void cdfDefSP(stream_t *streamptr, int gridID)
 {
+  /*
+  char longname[] = "Spherical harmonic coefficient";
+  */
+  char axisname[5] = "nspX";
+  int index, iz = 0;
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int ngrids;
   int fileID;
-  int levID, nlevs, gridID, gridsize;
-  int zaxisID;
-  double level;
-  int header[4];
-  int tsID;
   int vlistID;
-  int pdis, pcat, pnum;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  tsID     = streamptr->curTsID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  nlevs    = zaxisInqSize(zaxisID);
+  ngrids = vlistNgrids(vlistID);
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+  size_t dimlen = (size_t)gridInqSize(gridID)/2;
 
-  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->ydimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_SPECTRAL )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
+              if ( dimlen == dimlen0 )
+                {
+                  dimID = streamptr->ydimID[index];
+                  break;
+                }
+              else
+                iz++;
+            }
+        }
+    }
 
-  header[0] = streamptr->tsteps[tsID].taxis.vdate;
-  header[1] = pnum;
-  header[3] = gridInqSize(gridID);
+  if ( dimID == UNDEFID )
+    {
+      if ( iz == 0 ) axisname[3] = '\0';
+      else           sprintf(&axisname[3], "%1d", iz+1);
 
-  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  for ( levID = 0;  levID < nlevs; levID++ )
-    {
-      level = zaxisInqLevel(zaxisID, levID);
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-      header[2] = (int) level;
-      extDefHeader(extp, header);
-      extDefDataDP(extp, &data[levID*gridsize]);
-      extWrite(fileID, extp);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
+
+  gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->ydimID[gridindex] = dimID;
 }
 
 
-void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+static
+void cdfDefFC(stream_t *streamptr, int gridID)
 {
+  char axisname[5] = "nfcX";
+  int index, iz = 0;
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int ngrids;
   int fileID;
-  int gridID;
-  int zaxisID;
-  double level;
-  int header[4];
-  int tsID;
   int vlistID;
-  int pdis, pcat, pnum;
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  tsID     = streamptr->curTsID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  level    = zaxisInqLevel(zaxisID, levID);
-
-  if ( CDI_Debug )
-    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
-
-  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
-
-  header[0] = streamptr->tsteps[tsID].taxis.vdate;
-  header[1] = pnum;
-  header[2] = (int) level;
-  header[3] = gridInqSize(gridID);
-
-  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
-
-  extDefHeader(extp, header);
-  extDefDataDP(extp, data);
-  extWrite(fileID, extp);
-}
-
-#endif /* HAVE_LIBEXTRA */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <float.h>
-#include <math.h>
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
+  ngrids = vlistNgrids(vlistID);
 
+  size_t dimlen = (size_t)gridInqSize(gridID)/2;
 
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->ydimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_FOURIER )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
+              if ( dimlen == dimlen0 )
+                {
+                  dimID = streamptr->ydimID[index];
+                  break;
+                }
+              else
+                iz++;
+            }
+        }
+    }
 
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
+  if ( dimID == UNDEFID )
+    {
+      if ( iz == 0 ) axisname[3] = '\0';
+      else           sprintf(&axisname[3], "%1d", iz+1);
 
-#define SINGLE_PRECISION  4
-#define DOUBLE_PRECISION  8
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-#if defined (HAVE_LIBIEG)
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-typedef struct {
-  int param;
-  int level;
-} IEGCOMPVAR;
+  gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->ydimID[gridindex] = dimID;
+}
 
 
-int iegInqDatatype(int prec)
+static
+void cdfDefTrajLon(stream_t *streamptr, int gridID)
 {
-  int datatype;
+  char units[CDI_MAX_NAME];
+  char longname[CDI_MAX_NAME];
+  char stdname[CDI_MAX_NAME];
+  char axisname[CDI_MAX_NAME];
+  int gridtype, gridindex;
+  int dimID = UNDEFID;
+  int fileID;
+  int dimlen;
+  size_t len;
+  int ncvarid;
+  int vlistID;
+  int xtype = NC_DOUBLE;
 
-  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
-  else                            datatype = DATATYPE_FLT32;
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  return (datatype);
-}
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
+  gridtype = gridInqType(gridID);
+  dimlen = gridInqXsize(gridID);
+  if ( dimlen != 1 ) Error("Xsize isn't 1 for %s grid!", gridNamePtr(gridtype));
 
-int iegDefDatatype(int datatype)
-{
-  int prec;
+  gridindex = vlistGridIndex(vlistID, gridID);
+  ncvarid = streamptr->xdimID[gridindex];
 
-  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    Error("CDI/IEG library does not support complex numbers!");
+  gridInqXname(gridID, axisname);
+  gridInqXlongname(gridID, longname);
+  gridInqXstdname(gridID, stdname);
+  gridInqXunits(gridID, units);
 
-  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
-    datatype = DATATYPE_FLT32;
+  if ( ncvarid == UNDEFID )
+    {
+      dimID = streamptr->basetime.ncvarid;
 
-  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
-  else                              prec = SINGLE_PRECISION;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  return (prec);
+      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
+
+      if ( (len = strlen(stdname)) )
+        cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+      if ( (len = strlen(longname)) )
+        cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+      if ( (len = strlen(units)) )
+        cdf_put_att_text(fileID, ncvarid, "units", len, units);
+
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
+
+  streamptr->xdimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
 }
 
-/* not used
-int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
+
+static
+void cdfDefTrajLat(stream_t *streamptr, int gridID)
 {
-  int status;
+  char units[] = "degrees_north";
+  char longname[] = "latitude";
+  char stdname[] = "latitude";
+  char axisname[] = "tlat";
+  int gridtype, gridindex;
+  int dimID = UNDEFID;
   int fileID;
-  int icode, ilevel;
-  int zaxisID = -1;
+  int dimlen;
+  size_t len;
+  int ncvarid;
   int vlistID;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+  int xtype = NC_DOUBLE;
+
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
   vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  fileID = streamptr->fileID;
 
-  *varID   = -1;
-  *levelID = -1;
+  gridtype = gridInqType(gridID);
+  dimlen = gridInqYsize(gridID);
+  if ( dimlen != 1 ) Error("Ysize isn't 1 for %s grid!", gridNamePtr(gridtype));
 
-  status = iegRead(fileID, iegp);
-  if ( status != 0 ) return (0);
+  gridindex = vlistGridIndex(vlistID, gridID);
+  ncvarid = streamptr->ydimID[gridindex];
 
-  icode  = IEG_P_Parameter(iegp->ipdb);
-  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
-    ilevel = IEG_P_Level1(iegp->ipdb);
-  else
-    ilevel = IEG_P_Level2(iegp->ipdb);
+  gridInqYname(gridID, axisname);
+  gridInqYlongname(gridID, longname);
+  gridInqYstdname(gridID, stdname);
+  gridInqYunits(gridID, units);
 
-  *varID = vlistInqVarID(vlistID, icode);
+  if ( ncvarid == UNDEFID )
+    {
+      dimID = streamptr->basetime.ncvarid;
 
-  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  zaxisID = vlistInqVarZaxis(vlistID, *varID);
+      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
 
-  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
+      if ( (len = strlen(stdname)) )
+        cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+      if ( (len = strlen(longname)) )
+        cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+      if ( (len = strlen(units)) )
+        cdf_put_att_text(fileID, ncvarid, "units", len, units);
 
-  return (1);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
+
+  streamptr->ydimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
 }
-*/
 
-void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
+
+static
+int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID, int ngrids, int mode)
 {
-  int vlistID, fileID;
+  int iz, index;
+  int gridID0;
+  int ncdimid;
+  char axisname0[CDI_MAX_NAME];
+  char axisname2[CDI_MAX_NAME];
+  int checkname;
   int status;
-  int recID, vrecID, tsID;
-  off_t recpos;
-  int varID, gridID;
-  int i, size;
-  double missval;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-  tsID    = streamptr->curTsID;
-  vrecID  = streamptr->tsteps[tsID].curRecID;
-  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-  recpos  = streamptr->tsteps[tsID].records[recID].position;
-  varID   = streamptr->tsteps[tsID].records[recID].varID;
+  /* check that the name is not already defined */
+  checkname = TRUE;
+  iz = 0;
 
-  fileSetPos(fileID, recpos, SEEK_SET);
+  do
+    {
+      strcpy(axisname2, axisname);
+      if ( iz ) sprintf(&axisname2[strlen(axisname2)], "_%d", iz+1);
 
-  status = iegRead(fileID, iegp);
-  if ( status != 0 )
-    Error("Could not read IEG record!");
+      //status = nc_inq_varid(fileID, axisname2, &ncvarid);
+      if ( type == 'V' ) /* type Var oder Dim */
+        status = nc_inq_varid(fileID, axisname2, &ncdimid);
+      else
+        status = nc_inq_dimid(fileID, axisname2, &ncdimid);
 
-  iegInqDataDP(iegp, data);
+      if ( status != NC_NOERR )
+        {
+          if ( iz )
+            {
+              /* check that the name does not exist for other grids */
+              for ( index = 0; index < ngrids; index++ )
+                {
+                  gridID0 = vlistGrid(vlistID, index);
+                  if ( gridID != gridID0 )
+                    {
+                      if ( mode == 'X' ) /* mode X or Y */
+                        gridInqXname(gridID0, axisname0);
+                      else
+                        gridInqYname(gridID0, axisname0);
 
-  missval = vlistInqVarMissval(vlistID, varID);
-  gridID  = vlistInqVarGrid(vlistID, varID);
-  size    = gridInqSize(gridID);
+                      if ( strcmp(axisname0, axisname2) == 0 ) break;
+                    }
+                }
+              if ( index == ngrids ) checkname = FALSE;
+            }
+          else
+            {
+              checkname = FALSE;
+            }
+        }
 
-  streamptr->numvals += size;
+      if ( checkname ) iz++;
+    }
+  while (checkname && iz <= 99);
 
-  *nmiss = 0;
-  for ( i = 0; i < size; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
+
+  if ( iz ) sprintf(&axisname[strlen(axisname)], "_%d", iz+1);
+
+  return (iz);
 }
 
+
 static
-int iegGetZaxisType(int iegleveltype)
+void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
 {
-  int leveltype = 0;
-
-  switch ( iegleveltype )
-    {
-    case IEG_LTYPE_SURFACE:
-      {
-	leveltype = ZAXIS_SURFACE;
-	break;
-      }
-    case IEG_LTYPE_99:
-    case IEG_LTYPE_ISOBARIC:
-      {
-	leveltype = ZAXIS_PRESSURE;
-	break;
-      }
-    case IEG_LTYPE_HEIGHT:
-      {
-	leveltype = ZAXIS_HEIGHT;
-	break;
-      }
-    case IEG_LTYPE_ALTITUDE:
-      {
-	leveltype = ZAXIS_ALTITUDE;
-	break;
-      }
-    case IEG_LTYPE_HYBRID:
-    case IEG_LTYPE_HYBRID_LAYER:
-      {
-	leveltype = ZAXIS_HYBRID;
-	break;
-      }
-    case IEG_LTYPE_LANDDEPTH:
-    case IEG_LTYPE_LANDDEPTH_LAYER:
-      {
-	leveltype = ZAXIS_DEPTH_BELOW_LAND;
-	break;
-      }
-    case IEG_LTYPE_SEADEPTH:
-      {
-	leveltype = ZAXIS_DEPTH_BELOW_SEA;
-	break;
-      }
-    default:
-      {
-	leveltype = ZAXIS_GENERIC;
-	break;
-      }
-    }
+  char units[CDI_MAX_NAME];
+  char longname[CDI_MAX_NAME];
+  char stdname[CDI_MAX_NAME];
+  char axisname[CDI_MAX_NAME];
+  int index;
+  /*  int index2; */
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int dimIDs[2];
+  int ngrids = 0;
+  int fileID;
+  size_t len;
+  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  int vlistID;
+  int xtype = NC_DOUBLE;
 
-  return (leveltype);
-}
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-void iegDefTime(int *pdb, int date, int time, int taxisID)
-{
-  int year, month, day, hour, minute, second;
-  int timetype = -1;
+  if ( ndims ) ngrids = vlistNgrids(vlistID);
 
-  if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
+  size_t dimlen = (size_t)gridInqXsize(gridID);
+  gridindex = vlistGridIndex(vlistID, gridID);
 
-  if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
-    {
-      cdiDecodeDate(date, &year, &month, &day);
-      cdiDecodeTime(time, &hour, &minute, &second);
+  gridInqXname(gridID, axisname);
+  gridInqXlongname(gridID, longname);
+  gridInqXstdname(gridID, stdname);
+  gridInqXunits(gridID, units);
 
-      IEG_P_Year(pdb)     = year;
-      IEG_P_Month(pdb)    = month;
-      IEG_P_Day(pdb)      = day;
-      IEG_P_Hour(pdb)     = hour;
-      IEG_P_Minute(pdb)   = minute;
+  if ( axisname[0] == 0 ) Error("axis name undefined!");
 
-      pdb[15] = 1;
-      pdb[16] = 0;
-      pdb[17] = 0;
-      pdb[18] = 10;
-      pdb[36] = 1;
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN    ||
+               gridtype0 == GRID_LONLAT      ||
+               gridtype0 == GRID_CURVILINEAR ||
+               gridtype0 == GRID_GENERIC )
+            {
+              size_t dimlen0 = (size_t)gridInqXsize(gridID0);
+              if ( dimlen == dimlen0 )
+                if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
+                     IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) )
+                  {
+                    dimID = streamptr->xdimID[index];
+                    break;
+                  }
+              /*
+              for ( index2 = 0; index2 < index; index2++ )
+                if ( streamptr->xdimID[index] == streamptr->xdimID[index2] )
+                  break;
+              if ( index2 == index ) iz++;
+              */
+            }
+        }
     }
 
-  pdb[5] = 128;
-}
+  if ( dimID == UNDEFID )
+    {
+      int status;
+      status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'X');
+      if ( status == 0 && ndims )
+        status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
 
-static
-int calc_resfac(double xfirst, double xlast, double xinc, double yfirst, double ylast, double yinc)
-{
-  int i, j;
-  int iresfac = 1000;
-  int ifact;
-  int ifacarr[5] = {1000, 10000, 100000, 1000000, 10000000};
-  double vals[6] = {xfirst, xlast, xinc, yfirst, ylast, yinc};
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  for ( j = 0; j < 5; ++j )
-    {
-      ifact = ifacarr[j];
-      for ( i = 0; i < 6; ++i )
+      if ( ndims )
         {
-          if ( fabs(vals[i]*ifact - round(vals[i]*ifact)) > FLT_EPSILON ) break;
+          cdf_def_dim(fileID, axisname, dimlen, &dimID);
+
+          if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
+            {
+              size_t nvertex = 2;
+              if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+                cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
+            }
         }
-      if ( i == 6 )
+
+      if ( gridInqXvalsPtr(gridID) )
         {
-          iresfac = ifact;
-          break;
+          cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
+
+          if ( (len = strlen(stdname)) )
+            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+          if ( (len = strlen(longname)) )
+            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+          if ( (len = strlen(units)) )
+            cdf_put_att_text(fileID, ncvarid, "units", len, units);
+
+          cdf_put_att_text(fileID, ncvarid, "axis", 1, "X");
+
+          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              strcat(axisname, "_bnds");
+              dimIDs[0] = dimID;
+              dimIDs[1] = nvdimID;
+              cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
+              cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
+            }
+          /*
+          if ( gridIsRotated(gridID) )
+            {
+              double north_pole = gridInqXpole(gridID);
+              cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
+            }
+          */
         }
+
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+
+      if ( ncvarid  != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqXvalsPtr(gridID));
+      if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqXboundsPtr(gridID));
+
+      if ( ndims == 0 ) streamptr->ncxvarID[gridindex] = ncvarid;
     }
 
-  return (iresfac);
+  streamptr->xdimID[gridindex] = dimID;
 }
 
+
 static
-void iegDefGrid(int *gdb, int gridID)
+void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
 {
-  int gridtype;
+  char units[CDI_MAX_NAME];
+  char longname[CDI_MAX_NAME];
+  char stdname[CDI_MAX_NAME];
+  char axisname[CDI_MAX_NAME];
+  int index;
+  /*  int index2; */
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int dimIDs[2];
+  int ngrids = 0;
+  int fileID;
+  size_t len;
+  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  int vlistID;
+  int xtype = NC_DOUBLE;
 
-  gridtype = gridInqType(gridID);
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  if ( gridtype == GRID_GENERIC )
-    {
-      int xsize, ysize;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-      xsize = gridInqXsize(gridID);
-      ysize = gridInqYsize(gridID);
+  if ( ndims ) ngrids = vlistNgrids(vlistID);
 
-      if ( (ysize == 32  || ysize == 48 || ysize == 64 ||
-	    ysize == 96  || ysize == 160) &&
-	   (xsize == 2*ysize || xsize == 1) )
-	{
-	  gridtype = GRID_GAUSSIAN;
-	  gridChangeType(gridID, gridtype);
-	}
-      else if ( (xsize == 1 && ysize == 1) || (xsize == 0 && ysize == 0) )
-	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
-	}
-      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
-	{
-	  gridtype = GRID_LONLAT;
-	  gridChangeType(gridID, gridtype);
-	}
-    }
-  else if ( gridtype == GRID_CURVILINEAR )
+  size_t dimlen = (size_t)gridInqYsize(gridID);
+  gridindex = vlistGridIndex(vlistID, gridID);
+
+  gridInqYname(gridID, axisname);
+  gridInqYlongname(gridID, longname);
+  gridInqYstdname(gridID, stdname);
+  gridInqYunits(gridID, units);
+
+  if ( axisname[0] == 0 ) Error("axis name undefined!");
+
+  for ( index = 0; index < ngrids; index++ )
     {
-      gridtype = GRID_LONLAT;
+      if ( streamptr->ydimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN    ||
+               gridtype0 == GRID_LONLAT      ||
+               gridtype0 == GRID_CURVILINEAR ||
+               gridtype0 == GRID_GENERIC )
+            {
+              size_t dimlen0 = (size_t)gridInqYsize(gridID0);
+              if ( dimlen == dimlen0 )
+                if ( IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
+                     IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
+                  {
+                    dimID = streamptr->ydimID[index];
+                    break;
+                  }
+              /*
+              for ( index2 = 0; index2 < index; index2++ )
+                if ( streamptr->ydimID[index] == streamptr->ydimID[index2] )
+                  break;
+              if ( index2 == index ) iz++;
+              */
+            }
+        }
     }
 
-  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
+  if ( dimID == UNDEFID )
     {
-      double xfirst = 0, xlast = 0, xinc = 0;
-      double yfirst = 0, ylast = 0, yinc = 0;
+      int status;
+      status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'Y');
+      if ( status == 0 && ndims )
+        status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'Y');
 
-      int nlon = gridInqXsize(gridID),
-        nlat = gridInqYsize(gridID);
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      if ( nlon == 0 )
-	{
-	  nlon = 1;
-	}
-      else
-	{
-	  xfirst = gridInqXval(gridID,      0);
-	  xlast  = gridInqXval(gridID, nlon-1);
-	  xinc   = gridInqXinc(gridID);
-	}
+      if ( ndims )
+        {
+          cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-      if ( nlat == 0 )
-	{
-	  nlat = 1;
-	}
-      else
-	{
-	  yfirst = gridInqYval(gridID,      0);
-	  ylast  = gridInqYval(gridID, nlat-1);
-	  yinc   = gridInqYinc(gridID);
-	}
+          if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
+            {
+              size_t nvertex = 2;
+              if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+                cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
+            }
+        }
 
-      if ( gridtype == GRID_GAUSSIAN )
-	IEG_G_GridType(gdb) = 4;
-      else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
-	IEG_G_GridType(gdb) = 10;
-      else
-	IEG_G_GridType(gdb) = 0;
+      if ( gridInqYvalsPtr(gridID) )
+        {
+          cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
 
-      int iresfac = calc_resfac(xfirst, xlast, xinc, yfirst, ylast, yinc);
-      double resfac = (double) iresfac;
-      if ( iresfac == 1000 ) iresfac = 0;
+          if ( (len = strlen(stdname)) )
+            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+          if ( (len = strlen(longname)) )
+            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+          if ( (len = strlen(units)) )
+            cdf_put_att_text(fileID, ncvarid, "units", len, units);
 
-      IEG_G_ResFac(gdb)   = iresfac;
+          cdf_put_att_text(fileID, ncvarid, "axis", 1, "Y");
 
-      IEG_G_NumLon(gdb)   = nlon;
-      IEG_G_NumLat(gdb)   = nlat;
-      IEG_G_FirstLat(gdb) = (int)lround(yfirst*resfac);
-      IEG_G_LastLat(gdb)  = (int)lround(ylast*resfac);
-      IEG_G_FirstLon(gdb) = (int)lround(xfirst*resfac);
-      IEG_G_LastLon(gdb)  = (int)lround(xlast*resfac);
-      IEG_G_LonIncr(gdb)  = (int)lround(xinc*resfac);
-      if ( fabs(xinc*resfac - IEG_G_LonIncr(gdb)) > FLT_EPSILON )
-	IEG_G_LonIncr(gdb) = 0;
+          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              strcat(axisname, "_bnds");
+              dimIDs[0] = dimID;
+              dimIDs[1] = nvdimID;
+              cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
+              cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
+            }
+          /*
+          if ( gridIsRotated(gridID) )
+            {
+              double north_pole = gridInqYpole(gridID);
+              cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
+            }
+          */
+        }
 
-      if ( gridtype == GRID_GAUSSIAN )
-	IEG_G_LatIncr(gdb) = nlat/2;
-      else
-	{
-	  IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
-	  if ( fabs(yinc*resfac - IEG_G_LatIncr(gdb)) > FLT_EPSILON )
-	    IEG_G_LatIncr(gdb) = 0;
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-	  if ( IEG_G_LatIncr(gdb) < 0 ) IEG_G_LatIncr(gdb) = -IEG_G_LatIncr(gdb);
-	}
+      if ( ncvarid  != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqYvalsPtr(gridID));
+      if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqYboundsPtr(gridID));
 
-      if ( IEG_G_NumLon(gdb) > 1 && IEG_G_NumLat(gdb) == 1 )
-	if ( IEG_G_LonIncr(gdb) != 0 && IEG_G_LatIncr(gdb) == 0 ) IEG_G_LatIncr(gdb) = IEG_G_LonIncr(gdb);
+      if ( ndims == 0 ) streamptr->ncyvarID[gridindex] = ncvarid;
+    }
 
-      if ( IEG_G_NumLon(gdb) == 1 && IEG_G_NumLat(gdb) > 1 )
-	if ( IEG_G_LonIncr(gdb) == 0 && IEG_G_LatIncr(gdb) != 0 ) IEG_G_LonIncr(gdb) = IEG_G_LatIncr(gdb);
+  streamptr->ydimID[gridindex] = dimID;
+}
 
-      if ( IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0 )
-	IEG_G_ResFlag(gdb) = 0;
-      else
-	IEG_G_ResFlag(gdb) = 128;
 
-      if ( gridIsRotated(gridID) )
-	{
-	  IEG_G_LatSP(gdb) = - (int)lround(gridInqYpole(gridID) * resfac);
-	  IEG_G_LonSP(gdb) =   (int)lround((gridInqXpole(gridID) + 180) * resfac);
-	  IEG_G_Size(gdb)  = 42;
-	}
-      else
-	{
-	  IEG_G_Size(gdb)  = 32;
-	}
-    }
-  else
+static
+void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
+{
+#if  defined  (HAVE_NETCDF4)
+  if ( gridsize > 1 && comptype == COMPRESS_ZIP && (filetype == FILETYPE_NC4 || filetype == FILETYPE_NC4C) )
     {
-      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+      nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
+      cdfDefVarDeflate(fileID, ncvarid, 1);
     }
-
-  IEG_G_ScanFlag(gdb) = 64;
+#endif
 }
 
+
 static
-void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
+void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 {
-  double level;
-  int ilevel, leveltype;
-  static int warning = 1;
-  static int vct_warning = 1;
+  char xunits[CDI_MAX_NAME];
+  char xlongname[CDI_MAX_NAME];
+  char xstdname[CDI_MAX_NAME];
+  char yunits[CDI_MAX_NAME];
+  char ylongname[CDI_MAX_NAME];
+  char ystdname[CDI_MAX_NAME];
+  char xaxisname[CDI_MAX_NAME];
+  char yaxisname[CDI_MAX_NAME];
+  char xdimname[4] = "x";
+  char ydimname[4] = "y";
+  int index;
+  int gridID0, gridtype0, gridindex;
+  int xdimID = UNDEFID;
+  int ydimID = UNDEFID;
+  int dimIDs[3];
+  int ngrids;
+  int fileID;
+  size_t len;
+  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
+  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  int vlistID;
+  int xtype = NC_DOUBLE;
 
-  leveltype = zaxisInqType(zaxisID);
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  if ( leveltype == ZAXIS_GENERIC )
-    {
-      Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(leveltype),
-	      zaxisNamePtr(ZAXIS_PRESSURE));
-      leveltype = ZAXIS_PRESSURE;
-      zaxisChangeType(zaxisID, leveltype);
-      zaxisDefUnits(zaxisID, "Pa");
-    }
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  /*  IEG_G_NumVCP(gdb) = 0; */
+  ngrids = vlistNgrids(vlistID);
 
-  switch (leveltype)
-    {
-    case ZAXIS_SURFACE:
-      {
-	IEG_P_LevelType(pdb) = IEG_LTYPE_SURFACE;
-	IEG_P_Level1(pdb)    = 0;
-	IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
-	break;
-      }
-    case ZAXIS_HYBRID:
-      {
-	int vctsize;
+  size_t xdimlen = (size_t)gridInqXsize(gridID);
+  size_t ydimlen = (size_t)gridInqYsize(gridID);
+  gridindex = vlistGridIndex(vlistID, gridID);
 
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-	  {
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID_LAYER;
-	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
-	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
-	  }
-	else
-	  {
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID;
-	    IEG_P_Level1(pdb)    = 0;
-	    IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
-	  }
+  gridInqXname(gridID, xaxisname);
+  gridInqXlongname(gridID, xlongname);
+  gridInqXstdname(gridID, xstdname);
+  gridInqXunits(gridID, xunits);
+  gridInqYname(gridID, yaxisname);
+  gridInqYlongname(gridID, ylongname);
+  gridInqYstdname(gridID, ystdname);
+  gridInqYunits(gridID, yunits);
 
-	vctsize = zaxisInqVctSize(zaxisID);
-	if ( vctsize == 0 && warning )
-	  {
-	    Warning("VCT missing. ( code = %d, zaxisID = %d )",
-		    IEG_P_Parameter(pdb), zaxisID);
-	    warning = 0;
-	  }
-	if ( vctsize > 100 )
-	  {
-	    /*	    IEG_G_NumVCP(gdb) = 0; */
-	    if ( vct_warning )
-	      {
-		Warning("VCT size of %d is too large (maximum is 100). Set to 0!", vctsize);
-		vct_warning = 0;
-	      }
-	  }
-	else
-	  {
-	    IEG_G_Size(gdb) += (vctsize*4);
-	    memcpy(vct, zaxisInqVctPtr(zaxisID), (size_t)vctsize/2*sizeof(double));
-	    memcpy(vct+50, zaxisInqVctPtr(zaxisID)+vctsize/2, (size_t)vctsize/2*sizeof(double));
-	  }
-	break;
-      }
-    case ZAXIS_PRESSURE:
-      {
-	double dum;
-	char units[128];
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN    ||
+               gridtype0 == GRID_LONLAT      ||
+               gridtype0 == GRID_CURVILINEAR ||
+               gridtype0 == GRID_GENERIC )
+            {
+              size_t dimlen0 = (size_t)gridInqXsize(gridID0);
+              if ( xdimlen == dimlen0 )
+                if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
+                     IS_EQUAL(gridInqXval(gridID0, (int)xdimlen-1), gridInqXval(gridID, (int)xdimlen-1)) )
+                  {
+                    xdimID = streamptr->xdimID[index];
+                    ncxvarid = streamptr->ncxvarID[index];
+                    break;
+                  }
+              dimlen0 = (size_t)gridInqYsize(gridID0);
+              if ( ydimlen == dimlen0 )
+                if ( IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
+                     IS_EQUAL(gridInqYval(gridID0, (int)xdimlen-1), gridInqYval(gridID, (int)xdimlen-1)) )
+                  {
+                    ydimID = streamptr->ydimID[index];
+                    ncyvarid = streamptr->ncyvarID[index];
+                    break;
+                  }
+            }
+        }
+    }
 
-	level = zaxisInqLevel(zaxisID, levelID);
-	if ( level < 0 )
-	  Warning("pressure level of %f Pa is below 0.", level);
+  if ( xdimID == UNDEFID || ydimID == UNDEFID )
+    {
+      checkGridName('V', xaxisname, fileID, vlistID, gridID, ngrids, 'X');
+      checkGridName('V', yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
+      checkGridName('D', xdimname, fileID, vlistID, gridID, ngrids, 'X');
+      checkGridName('D', ydimname, fileID, vlistID, gridID, ngrids, 'Y');
 
-	zaxisInqUnits(zaxisID, units);
-	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
-	  level = level*100;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-	ilevel = (int) level;
-	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-	  {
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_99;
-	    IEG_P_Level1(pdb)    = 0;
-	    IEG_P_Level2(pdb)    = ilevel;
-	  }
-	else
-	  {
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_ISOBARIC;
-	    IEG_P_Level1(pdb)    = 0;
-	    IEG_P_Level2(pdb)    = ilevel/100;
-	  }
-	break;
-      }
-    case ZAXIS_HEIGHT:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+      cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
+      cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
 
-	ilevel = (int) level;
-	IEG_P_LevelType(pdb) = IEG_LTYPE_HEIGHT;
-	IEG_P_Level1(pdb)    = 0;
-	IEG_P_Level2(pdb)    = ilevel;
+      if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
+        {
+          size_t nvertex = 4;
+          if ( nc_inq_dimid(fileID, "vertices", &nvdimID) != NC_NOERR )
+            cdf_def_dim(fileID, "vertices", nvertex, &nvdimID);
+        }
 
-	break;
-      }
-    case ZAXIS_ALTITUDE:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+      dimIDs[0] = ydimID;
+      dimIDs[1] = xdimID;
 
-	ilevel = (int) level;
-	IEG_P_LevelType(pdb) = IEG_LTYPE_ALTITUDE;
-	IEG_P_Level1(pdb)    = 0;
-	IEG_P_Level2(pdb)    = ilevel;
+      if ( gridInqXvalsPtr(gridID) )
+        {
+          cdf_def_var(fileID, xaxisname, (nc_type) xtype, 2, dimIDs, &ncxvarid);
+          cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-	break;
-      }
-    case ZAXIS_DEPTH_BELOW_LAND:
-      {
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-	  {
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH_LAYER;
-	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
-	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
-	  }
-	else
-	  {
-	    level = zaxisInqLevel(zaxisID, levelID);
+          if ( (len = strlen(xstdname)) )
+            cdf_put_att_text(fileID, ncxvarid, "standard_name", len, xstdname);
+          if ( (len = strlen(xlongname)) )
+            cdf_put_att_text(fileID, ncxvarid, "long_name", len, xlongname);
+          if ( (len = strlen(xunits)) )
+            cdf_put_att_text(fileID, ncxvarid, "units", len, xunits);
 
-	    ilevel = (int) level;
-	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH;
-	    IEG_P_Level1(pdb)    = 0;
-	    IEG_P_Level2(pdb)    = ilevel;
-	  }
+          /* attribute for Panoply */
+          cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
 
-	break;
-      }
-    case ZAXIS_DEPTH_BELOW_SEA:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              strcat(xaxisname, "_vertices");
+              dimIDs[0] = ydimID;
+              dimIDs[1] = xdimID;
+              dimIDs[2] = nvdimID;
+              cdf_def_var(fileID, xaxisname, (nc_type) xtype, 3, dimIDs, &ncbxvarid);
+              cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-	ilevel = (int) level;
-	IEG_P_LevelType(pdb) = IEG_LTYPE_SEADEPTH;
-	IEG_P_Level1(pdb)    = 0;
-	IEG_P_Level2(pdb)    = ilevel;
+              cdf_put_att_text(fileID, ncxvarid, "bounds", strlen(xaxisname), xaxisname);
+            }
+        }
 
-	break;
-      }
-    case ZAXIS_ISENTROPIC:
-      {
-	level = zaxisInqLevel(zaxisID, levelID);
+      if ( gridInqYvalsPtr(gridID) )
+        {
+          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncyvarid);
+          cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-	ilevel = (int) level;
-	IEG_P_LevelType(pdb) = 113;
-	IEG_P_Level1(pdb)    = 0;
-	IEG_P_Level2(pdb)    = ilevel;
+          if ( (len = strlen(ystdname)) )
+            cdf_put_att_text(fileID, ncyvarid, "standard_name", len, ystdname);
+          if ( (len = strlen(ylongname)) )
+            cdf_put_att_text(fileID, ncyvarid, "long_name", len, ylongname);
+          if ( (len = strlen(yunits)) )
+            cdf_put_att_text(fileID, ncyvarid, "units", len, yunits);
 
-	break;
-      }
-    default:
-      {
-	Error("Unsupported zaxis type: %s", zaxisNamePtr(leveltype));
-	break;
-      }
-    }
-}
+          /* attribute for Panoply */
+          cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
 
+          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              strcat(yaxisname, "_vertices");
+              dimIDs[0] = ydimID;
+              dimIDs[1] = xdimID;
+              dimIDs[2] = nvdimID;
+              cdf_def_var(fileID, yaxisname, (nc_type) xtype, 3, dimIDs, &ncbyvarid);
+              cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
-{
-  streamFCopyRecord(streamptr2, streamptr1, "IEG");
-}
+              cdf_put_att_text(fileID, ncyvarid, "bounds", strlen(yaxisname), yaxisname);
+            }
+        }
 
+      if ( gridInqAreaPtr(gridID) )
+        {
+          char yaxisname[] = "cell_area";
+          char units[] = "m2";
+          char longname[] = "area of grid cell";
+          char stdname[] = "cell_area";
 
-void iegDefRecord(stream_t *streamptr)
-{
-  int vlistID;
-  int gridID;
-  int date, time;
-  int datatype;
-  int i;
-  int param, pdis, pcat, pnum;
-  int varID, levelID, tsID, zaxisID;
-  int byteorder;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncavarid);
 
-  vlistID = streamptr->vlistID;
-  byteorder = streamptr->byteorder;
+          cdf_put_att_text(fileID, ncavarid, "standard_name", strlen(stdname), stdname);
+          cdf_put_att_text(fileID, ncavarid, "long_name", strlen(longname), longname);
+          cdf_put_att_text(fileID, ncavarid, "units", strlen(units), units);
+        }
 
-  varID   = streamptr->record->varID;
-  levelID = streamptr->record->levelID;
-  tsID    = streamptr->curTsID;
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-  gridID  = vlistInqVarGrid(vlistID, varID);
-  zaxisID = vlistInqVarZaxis(vlistID, varID);
+      if ( ncxvarid  != UNDEFID ) cdf_put_var_double(fileID, ncxvarid,  gridInqXvalsPtr(gridID));
+      if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
+      if ( ncyvarid  != UNDEFID ) cdf_put_var_double(fileID, ncyvarid,  gridInqYvalsPtr(gridID));
+      if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
+      if ( ncavarid  != UNDEFID ) cdf_put_var_double(fileID, ncavarid,  gridInqAreaPtr(gridID));
+    }
 
-  iegInitMem(iegp);
-  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+  streamptr->xdimID[gridindex] = xdimID;
+  streamptr->ydimID[gridindex] = ydimID;
+  streamptr->ncxvarID[gridindex] = ncxvarid;
+  streamptr->ncyvarID[gridindex] = ncyvarid;
+  streamptr->ncavarID[gridindex] = ncavarid;
+}
 
-  iegp->byteswap = getByteswap(byteorder);
 
-  param =  vlistInqVarParam(vlistID, varID);
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  IEG_P_Parameter(iegp->ipdb) = pnum;
-  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
-  date     = streamptr->tsteps[tsID].taxis.vdate;
-  time     = streamptr->tsteps[tsID].taxis.vtime;
+static
+void cdfDefRgrid(stream_t *streamptr, int gridID)
+{
+  char axisname[7] = "rgridX";
+  int index, iz = 0;
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int ngrids;
+  int fileID;
+  int vlistID;
+  int lwarn = TRUE;
 
-  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
-  iegDefGrid(iegp->igdb, gridID);
-  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  datatype = streamptr->record->prec;
+  ngrids = vlistNgrids(vlistID);
 
-  iegp->dprec = iegDefDatatype(datatype);
-}
+  size_t dimlen = (size_t)gridInqSize(gridID);
 
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN_REDUCED )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(gridID0);
 
-void iegWriteRecord(stream_t *streamptr, const double *data)
-{
-  int fileID;
-  int i, gridsize, gridID;
-  double refval;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+              if ( dimlen == dimlen0 )
+                {
+                  dimID = streamptr->xdimID[index];
+                  break;
+                }
+              else
+                iz++;
+            }
+        }
+    }
 
-  fileID = streamptr->fileID;
-  gridID = streamptr->record->gridID;
+  if ( dimID == UNDEFID )
+    {
+      if ( lwarn )
+        {
+          Warning("Creating a netCDF file with data on a gaussian reduced grid.");
+          Warning("The further processing of the resulting file is unsupported!");
+          lwarn = FALSE;
+        }
 
-  gridsize = gridInqSize(gridID);
+      if ( iz == 0 ) axisname[5] = '\0';
+      else           sprintf(&axisname[5], "%1d", iz+1);
 
-  refval = data[0];
-  for ( i = 1; i < gridsize; i++ )
-    if ( data[i] < refval ) refval = data[i];
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  iegp->refval = refval;
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-  iegDefDataDP(iegp, data);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-  iegWrite(fileID, iegp);
+  gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->xdimID[gridindex] = dimID;
 }
 
+
 static
-void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
-		  size_t recsize, off_t position, int prec)
+void cdfDefGdim(stream_t *streamptr, int gridID)
 {
-  int leveltype;
-  int gridID = UNDEFID;
-  int levelID = 0;
-  int tsID, recID, varID;
-  int datatype;
-  int level1, level2;
-  int gridtype;
-  int lbounds = 0;
-  record_t *record;
-  grid_t grid;
+  int index, iz = 0;
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int ngrids;
+  int fileID;
   int vlistID;
 
   vlistID = streamptr->vlistID;
-  tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamptr, tsID);
-  record  = &streamptr->tsteps[tsID].records[recID];
-
-  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER )
-    {
-      level1 = IEG_P_Level1(pdb);
-      level2 = IEG_P_Level2(pdb);
-    }
-  else
-    {
-      level1 = IEG_P_Level2(pdb);
-      level2 = 0;
-      if ( IEG_P_LevelType(pdb) == 100 ) level1 *= 100;
-    }
-
-  record->size     = recsize;
-  record->position = position;
-  record->param    = param;
-  record->ilevel   = level1;
-  record->ilevel2  = level2;
-  record->ltype    = IEG_P_LevelType(pdb);
-
-  if ( IEG_G_GridType(gdb) == 0 || IEG_G_GridType(gdb) == 10 )
-    gridtype = GRID_LONLAT;
-  else if ( IEG_G_GridType(gdb) == 4 )
-    gridtype = GRID_GAUSSIAN;
-  else
-    gridtype = GRID_GENERIC;
+  fileID  = streamptr->fileID;
 
-  memset(&grid, 0, sizeof(grid_t));
-  grid.type  = gridtype;
-  grid.size  = IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb);
-  grid.xsize = IEG_G_NumLon(gdb);
-  grid.ysize = IEG_G_NumLat(gdb);
-  grid.xinc  = 0;
-  grid.yinc  = 0;
-  grid.xdef  = 0;
+  ngrids = vlistNgrids(vlistID);
 
-  int iresfac = IEG_G_ResFac(gdb);
-  if ( iresfac == 0 ) iresfac = 1000;
-  double resfac = 1./(double) iresfac;
+  size_t dimlen = (size_t)gridInqSize(gridID);
 
-  /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
-  {
-    if ( grid.xsize > 1 )
+  if ( gridInqYsize(gridID) == 0 )
+    for ( index = 0; index < ngrids; index++ )
       {
-	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
-	  grid.xinc = IEG_G_LonIncr(gdb) * resfac;
-	else
-	  grid.xinc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (grid.xsize - 1);
-
-	/* correct xinc if necessary */
-	if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
-	  {
-	    double xinc = 360. / grid.xsize;
-            /* FIXME: why not use grid.xinc != xinc as condition? */
-	    if ( fabs(grid.xinc-xinc) > 0.0 )
-	      {
-		grid.xinc = xinc;
-		if ( CDI_Debug ) Message("set xinc to %g", grid.xinc);
-	      }
-	  }
+        if ( streamptr->xdimID[index] != UNDEFID )
+          {
+            gridID0 = vlistGrid(vlistID, index);
+            gridtype0 = gridInqType(gridID0);
+            if ( gridtype0 == GRID_GENERIC )
+              {
+                size_t dimlen0 = (size_t)gridInqSize(gridID0);
+                if ( dimlen == dimlen0 )
+                  {
+                    dimID = streamptr->xdimID[index];
+                    break;
+                  }
+                else
+                  iz++;
+              }
+          }
       }
-    grid.xfirst = IEG_G_FirstLon(gdb) * resfac;
-    grid.xlast  = IEG_G_LastLon(gdb)  * resfac;
-    grid.xdef   = 2;
-  }
-  grid.ydef  = 0;
-  /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
-  {
-    if ( grid.ysize > 1 )
+
+  if ( gridInqXsize(gridID) == 0 )
+    for ( index = 0; index < ngrids; index++ )
       {
-	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
-	  grid.yinc = IEG_G_LatIncr(gdb) * resfac;
-	else
-	  grid.yinc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (grid.ysize - 1);
+        if ( streamptr->ydimID[index] != UNDEFID )
+          {
+            gridID0 = vlistGrid(vlistID, index);
+            gridtype0 = gridInqType(gridID0);
+            if ( gridtype0 == GRID_GENERIC )
+              {
+                size_t dimlen0 = (size_t)gridInqSize(gridID0);
+                if ( dimlen == dimlen0 )
+                  {
+                    dimID = streamptr->ydimID[index];
+                    break;
+                  }
+                else
+                  iz++;
+              }
+          }
       }
-    grid.yfirst = IEG_G_FirstLat(gdb) * resfac;
-    grid.ylast  = IEG_G_LastLat(gdb)  * resfac;
-    grid.ydef   = 2;
-  }
-  /*
-  grid.xfirst= IEG_G_FirstLon(gdb) * resfac;
-  grid.xlast = IEG_G_LastLon(gdb) * resfac;
-  grid.xinc  = IEG_G_LonIncr(gdb) * resfac;
-  grid.xdef  = 2;
-  grid.yfirst= IEG_G_FirstLat(gdb) * resfac;
-  grid.ylast = IEG_G_LastLat(gdb) * resfac;
-  grid.yinc  = IEG_G_LatIncr(gdb) * resfac;
-  grid.ydef  = 2;
-  */
-  grid.xvals = NULL;
-  grid.yvals = NULL;
 
-  grid.isRotated = FALSE;
-  if ( IEG_G_GridType(gdb) == 10 )
+  if ( dimID == UNDEFID )
     {
-      grid.isRotated = TRUE;
-      grid.ypole     = - IEG_G_LatSP(gdb) * resfac;
-      grid.xpole     =   IEG_G_LonSP(gdb) * resfac - 180;
-      grid.angle     = 0;
-    }
-
-  gridID = varDefGrid(vlistID, &grid, 0);
-
-  leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
+      char axisname[CDI_MAX_NAME];
+      strcpy(axisname, "gsize");
 
-  if ( leveltype == ZAXIS_HYBRID )
-    {
-      double tmpvct[100];
-      size_t vctsize = (size_t)IEG_G_NumVCP(gdb);
+      checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
+      /*
+      if ( iz == 0 ) axisname[5] = '\0';
+      else           sprintf(&axisname[5], "%1d", iz+1);
+      */
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
-      for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
+      //printf("axisname, dimlen %s %d\n", axisname, dimlen);
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-      varDefVCT(vctsize, tmpvct);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
 
-  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER ) lbounds = 1;
+  gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->xdimID[gridindex] = dimID;
+}
 
-  datatype = iegInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
-	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
+static
+void cdfDefGridReference(stream_t *streamptr, int gridID)
+{
+  int fileID  = streamptr->fileID;
+  int number = gridInqNumber(gridID);
 
-  record->varID   = (short)varID;
-  record->levelID = (short)levelID;
+  if ( number > 0 )
+    {
+      cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
+    }
 
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
+  if ( gridInqReference(gridID, NULL) )
+    {
+      char gridfile[8912];
+      gridInqReference(gridID, gridfile);
 
-  if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d",
-	    varID, gridID, levelID);
+      if ( gridfile[0] != 0 )
+        cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
+    }
 }
 
-#if 0
 static
-void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
-		  int level, int xsize, int ysize)
+void cdfDefGridUUID(stream_t *streamptr, int gridID)
 {
-  int varID = 0;
-  int levelID = 0;
-  record_t *record;
-
-  record  = &streamptr->tsteps[tsID].records[recID];
-
-  if ( param != (*record).param || level != (*record).ilevel )
-    Error("inconsistent timestep");
-
-  (*record).position = position;
-  /*
-  varID   = (*record).varID;
-  levelID = (*record).levelID;
-
-  streamptr->vars[varID].level[levelID] = recID;
+  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
 
-  streamptr->tsteps[tsID].nallrecs++;
-  streamptr->nrecs++;
-  */
-  if ( CDI_Debug )
-    Message("varID = %d levelID = %d", varID, levelID);
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( !cdiUUIDIsNull(uuidOfHGrid) )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          //if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
+          //if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
 }
-#endif
 
-void iegDateTime(int *pdb, int *date, int *time)
+static
+void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
 {
-  int ryear, rmonth, rday, rhour, rminute;
-
-  ryear   = IEG_P_Year(pdb);
-
-  rmonth  = IEG_P_Month(pdb);
-  rday    = IEG_P_Day(pdb);
-
-  rhour   = IEG_P_Hour(pdb);
-  rminute = IEG_P_Minute(pdb);
-
-  if ( rminute == -1 ) rminute = 0;
+  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
+  zaxisInqUUID(zaxisID, uuidOfVGrid);
 
-  *date = cdiEncodeDate(ryear, rmonth, rday);
-  *time = cdiEncodeTime(rhour, rminute, 0);
+  if ( uuidOfVGrid[0] != 0 )
+    {
+      char uuidOfVGridStr[37];
+      uuid2str(uuidOfVGrid, uuidOfVGridStr);
+      if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
+          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
 }
 
 static
-void iegScanTimestep1(stream_t *streamptr)
+void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
-  int prec = 0;
-  int status;
+  char xunits[CDI_MAX_NAME];
+  char xlongname[CDI_MAX_NAME];
+  char xstdname[CDI_MAX_NAME];
+  char yunits[CDI_MAX_NAME];
+  char ylongname[CDI_MAX_NAME];
+  char ystdname[CDI_MAX_NAME];
+  char xaxisname[CDI_MAX_NAME];
+  char yaxisname[CDI_MAX_NAME];
+  int index;
+  int gridID0, gridtype0, gridindex;
+  int dimID = UNDEFID;
+  int ngrids;
   int fileID;
-  int tabnum;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  size_t recsize;
-  off_t recpos;
-  int nrecords, nrecs, recID;
-  int taxisID = -1;
-  taxis_t *taxis;
+  size_t len;
+  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
+  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
+  int nvdimID = UNDEFID;
   int vlistID;
-  IEGCOMPVAR compVar, compVar0;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+  int xtype = NC_DOUBLE;
 
-  streamptr->curTsID = 0;
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  if ( tsID != 0 )
-    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+  ngrids = vlistNgrids(vlistID);
 
-  fileID = streamptr->fileID;
+  size_t dimlen = (size_t)gridInqSize(gridID);
+  gridindex = vlistGridIndex(vlistID, gridID);
 
-  nrecs = 0;
-  while ( TRUE )
+  gridInqXname(gridID, xaxisname);
+  gridInqXlongname(gridID, xlongname);
+  gridInqXstdname(gridID, xstdname);
+  gridInqXunits(gridID, xunits);
+  gridInqYname(gridID, yaxisname);
+  gridInqYlongname(gridID, ylongname);
+  gridInqYstdname(gridID, ystdname);
+  gridInqYunits(gridID, yunits);
+
+  for ( index = 0; index < ngrids; index++ )
     {
-      recpos = fileGetPos(fileID);
-      status = iegRead(fileID, iegp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      recsize = (size_t)(fileGetPos(fileID) - recpos);
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          gridID0 = vlistGrid(vlistID, index);
+          gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_UNSTRUCTURED )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(gridID0);
+              if ( dimlen == dimlen0 )
+		if ( gridInqNvertex(gridID0) == gridInqNvertex(gridID) &&
+		     IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
+                     IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) )
+		  {
+		    dimID = streamptr->xdimID[index];
+                    ncxvarid = streamptr->ncxvarID[index];
+                    ncyvarid = streamptr->ncyvarID[index];
+                    ncavarid = streamptr->ncavarID[index];
+		    break;
+		  }
+            }
+        }
+    }
 
-      prec   = iegp->dprec;
-      rcode  = IEG_P_Parameter(iegp->ipdb);
-      tabnum = IEG_P_CodeTable(iegp->ipdb);
-      param  = cdiEncodeParam(rcode, tabnum, 255);
+  if ( dimID == UNDEFID )
+    {
+      char axisname[CDI_MAX_NAME];
+      char vertname[CDI_MAX_NAME];
+      strcpy(axisname, "ncells");
+      strcpy(vertname, "vertices");
 
-      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
-	rlevel = IEG_P_Level1(iegp->ipdb);
-      else
-	rlevel = IEG_P_Level2(iegp->ipdb);
+      checkGridName('V', xaxisname, fileID, vlistID, gridID, ngrids, 'X');
+      checkGridName('V', yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
+      checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
+      checkGridName('D', vertname, fileID, vlistID, gridID, ngrids, 'X');
 
-      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      iegDateTime(iegp->ipdb, &vdate, &vtime);
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-	}
-      else
-	{
-	  datetime.date = vdate;
-	  datetime.time = vtime;
-	  compVar.param = param;
-          compVar.level = rlevel;
-	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      compVar0.param = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
+      size_t nvertex = (size_t)gridInqNvertex(gridID);
+      if ( nvertex > 0 ) cdf_def_dim(fileID, vertname, nvertex, &nvdimID);
 
-	      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 ) break;
-	    }
-	  if ( recID < nrecs ) break;
-	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
-	    Warning("Inconsistent verification time for param %d level %d", param, rlevel);
-	}
+      cdfDefGridReference(streamptr, gridID);
 
-      nrecs++;
+      cdfDefGridUUID(streamptr, gridID);
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, param, rlevel, vdate, vtime);
+      if ( gridInqXvalsPtr(gridID) )
+        {
+          cdf_def_var(fileID, xaxisname, (nc_type) xtype, 1, &dimID, &ncxvarid);
+          cdfGridCompress(fileID, ncxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
-    }
+          if ( (len = strlen(xstdname)) )
+            cdf_put_att_text(fileID, ncxvarid, "standard_name", len, xstdname);
+          if ( (len = strlen(xlongname)) )
+            cdf_put_att_text(fileID, ncxvarid, "long_name", len, xlongname);
+          if ( (len = strlen(xunits)) )
+            cdf_put_att_text(fileID, ncxvarid, "units", len, xunits);
 
-  streamptr->rtsteps = 1;
+          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              int dimIDs[2];
+              dimIDs[0] = dimID;
+              dimIDs[1] = nvdimID;
+              strcat(xaxisname, "_vertices");
+              cdf_def_var(fileID, xaxisname, (nc_type) xtype, 2, dimIDs, &ncbxvarid);
+              cdfGridCompress(fileID, ncbxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-  cdi_generate_vars(streamptr);
+              cdf_put_att_text(fileID, ncxvarid, "bounds", strlen(xaxisname), xaxisname);
+            }
+        }
 
-  taxisID = taxisCreate(TAXIS_ABSOLUTE);
-  taxis->type  = TAXIS_ABSOLUTE;
-  taxis->vdate = (int)datetime0.date;
-  taxis->vtime = (int)datetime0.time;
+      if ( gridInqYvalsPtr(gridID) )
+        {
+          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 1, &dimID, &ncyvarid);
+          cdfGridCompress(fileID, ncyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+
+          if ( (len = strlen(ystdname)) )
+            cdf_put_att_text(fileID, ncyvarid, "standard_name", len, ystdname);
+          if ( (len = strlen(ylongname)) )
+            cdf_put_att_text(fileID, ncyvarid, "long_name", len, ylongname);
+          if ( (len = strlen(yunits)) )
+            cdf_put_att_text(fileID, ncyvarid, "units", len, yunits);
+
+          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              int dimIDs[2];
+              dimIDs[0] = dimID;
+              dimIDs[1] = nvdimID;
+              strcat(yaxisname, "_vertices");
+              cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncbyvarid);
+              cdfGridCompress(fileID, ncbyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-  vlistID = streamptr->vlistID;
-  vlistDefTaxis(vlistID, taxisID);
+              cdf_put_att_text(fileID, ncyvarid, "bounds", strlen(yaxisname), yaxisname);
+            }
+        }
 
-  vlist_check_contents(vlistID);
+      if ( gridInqAreaPtr(gridID) )
+        {
+          char yaxisname[] = "cell_area";
+          char units[] = "m2";
+          char longname[] = "area of grid cell";
+          char stdname[] = "cell_area";
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  if ( nrecords < streamptr->tsteps[0].recordSize )
-    {
-      streamptr->tsteps[0].recordSize = nrecords;
-      streamptr->tsteps[0].records =
-	(record_t *)xrealloc(streamptr->tsteps[0].records,
-                             (size_t)nrecords * sizeof (record_t));
-    }
+          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 1, &dimID, &ncavarid);
 
-  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
-  streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[0].recIDs[recID] = recID;
+          cdf_put_att_text(fileID, ncavarid, "standard_name", strlen(stdname), stdname);
+          cdf_put_att_text(fileID, ncavarid, "long_name", strlen(longname), longname);
+          cdf_put_att_text(fileID, ncavarid, "units", strlen(units), units);
+        }
 
-  if ( streamptr->ntsteps == -1 )
-    {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
+      if ( ncxvarid  != UNDEFID ) cdf_put_var_double(fileID, ncxvarid,  gridInqXvalsPtr(gridID));
+      if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
+      if ( ncyvarid  != UNDEFID ) cdf_put_var_double(fileID, ncyvarid,  gridInqYvalsPtr(gridID));
+      if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
+      if ( ncavarid  != UNDEFID ) cdf_put_var_double(fileID, ncavarid,  gridInqAreaPtr(gridID));
     }
 
-  if ( streamptr->ntsteps == 1 )
-    {
-      if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
-    }
+  streamptr->xdimID[gridindex] = dimID;
+  streamptr->ncxvarID[gridindex] = ncxvarid;
+  streamptr->ncyvarID[gridindex] = ncyvarid;
+  streamptr->ncavarID[gridindex] = ncavarid;
 }
 
+
 static
-int iegScanTimestep2(stream_t *streamptr)
+void cdfDefVCT(stream_t *streamptr, int zaxisID)
 {
-  int status;
-  int fileID;
-  int tabnum;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  int tsID;
-  int varID;
-  size_t recsize;
-  off_t recpos = 0;
-  int nrecords, nrecs, recID, rindex;
-  int nextstep;
-  taxis_t *taxis;
-  int vlistID;
-  IEGCOMPVAR compVar, compVar0;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
-
-  streamptr->curTsID = 1;
+  int type;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  type = zaxisInqType(zaxisID);
+  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+    {
+      int i;
+      int fileID;
+      int ilev = zaxisInqVctSize(zaxisID)/2;
+      int mlev = ilev - 1;
+      size_t start;
+      size_t count = 1;
+      int ncdimid, ncdimid2;
+      int hyaiid, hybiid, hyamid, hybmid;
+      double mval;
+      char tmpname[CDI_MAX_NAME];
 
-  tsID = streamptr->rtsteps;
-  if ( tsID != 1 )
-    Error("Internal problem! unexpected timestep %d", tsID+1);
+      if ( streamptr->vct.ilev > 0 )
+        {
+          if ( streamptr->vct.ilev != ilev )
+            Error("more than one VCT for each file unsupported!");
+          return;
+        }
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+      if ( ilev == 0 )
+        {
+          Warning("VCT missing");
+          return;
+        }
 
-  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      fileID = streamptr->fileID;
 
-  cdi_create_records(streamptr, tsID);
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof(int));
-  streamptr->tsteps[1].nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
-    streamptr->tsteps[1].recIDs[recID] = -1;
+      cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
+      cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
 
-  for ( recID = 0; recID < nrecords; recID++ )
-    {
-      varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position =
-	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     =
-	streamptr->tsteps[0].records[recID].size;
-    }
+      streamptr->vct.mlev   = mlev;
+      streamptr->vct.ilev   = ilev;
+      streamptr->vct.mlevID = ncdimid;
+      streamptr->vct.ilevID = ncdimid2;
 
-  for ( rindex = 0; rindex <= nrecords; rindex++ )
-    {
-      recpos = fileGetPos(fileID);
-      status = iegRead(fileID, iegp);
-      if ( status != 0 )
-	{
-	  streamptr->ntsteps = 2;
-	  break;
-	}
-      recsize = (size_t)(fileGetPos(fileID) - recpos);
+      cdf_def_var(fileID, "hyai", NC_DOUBLE, 1, &ncdimid2, &hyaiid);
+      cdf_def_var(fileID, "hybi", NC_DOUBLE, 1, &ncdimid2, &hybiid);
+      cdf_def_var(fileID, "hyam", NC_DOUBLE, 1, &ncdimid,  &hyamid);
+      cdf_def_var(fileID, "hybm", NC_DOUBLE, 1, &ncdimid,  &hybmid);
 
-      rcode  = IEG_P_Parameter(iegp->ipdb);
-      tabnum = IEG_P_CodeTable(iegp->ipdb);
-      param  = cdiEncodeParam(rcode, tabnum, 255);
+      strcpy(tmpname, "hybrid A coefficient at layer interfaces");
+      cdf_put_att_text(fileID, hyaiid, "long_name", strlen(tmpname), tmpname);
+      strcpy(tmpname, "Pa");
+      cdf_put_att_text(fileID, hyaiid, "units", strlen(tmpname), tmpname);
+      strcpy(tmpname, "hybrid B coefficient at layer interfaces");
+      cdf_put_att_text(fileID, hybiid, "long_name", strlen(tmpname), tmpname);
+      strcpy(tmpname, "1");
+      cdf_put_att_text(fileID, hybiid, "units", strlen(tmpname), tmpname);
+      strcpy(tmpname, "hybrid A coefficient at layer midpoints");
+      cdf_put_att_text(fileID, hyamid, "long_name", strlen(tmpname), tmpname);
+      strcpy(tmpname, "Pa");
+      cdf_put_att_text(fileID, hyamid, "units", strlen(tmpname), tmpname);
+      strcpy(tmpname, "hybrid B coefficient at layer midpoints");
+      cdf_put_att_text(fileID, hybmid, "long_name", strlen(tmpname), tmpname);
+      strcpy(tmpname, "1");
+      cdf_put_att_text(fileID, hybmid, "units", strlen(tmpname), tmpname);
 
-      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
-	rlevel = IEG_P_Level1(iegp->ipdb);
-      else
-	rlevel = IEG_P_Level2(iegp->ipdb);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+      const double *vctptr = zaxisInqVctPtr(zaxisID);
 
-      iegDateTime(iegp->ipdb, &vdate, &vtime);
+      cdf_put_var_double(fileID, hyaiid, vctptr);
+      cdf_put_var_double(fileID, hybiid, vctptr+ilev);
 
-      if ( rindex == 0 )
-	{
-	  taxis->type  = TAXIS_ABSOLUTE;
-	  taxis->vdate = vdate;
-	  taxis->vtime = vtime;
-	}
+      for ( i = 0; i < mlev; i++ )
+        {
+          start = (size_t)i;
+          mval = (vctptr[i] + vctptr[i+1]) * 0.5;
+          cdf_put_vara_double(fileID, hyamid, &start, &count, &mval);
+          mval = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
+          cdf_put_vara_double(fileID, hybmid, &start, &count, &mval);
+        }
+    }
+}
 
-      compVar.param = param;
-      compVar.level = rlevel;
-      nextstep = FALSE;
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 )
-	    {
-	      if ( streamptr->tsteps[tsID].records[recID].used )
-		{
-		  nextstep = TRUE;
-		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
-	      break;
-	    }
-	}
-      if ( recID == nrecords )
-	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
-	  Warning("param %s level %d not defined at timestep 1", paramstr, rlevel);
-	  return (CDI_EUFSTRUCT);
-	}
+static
+void cdfDefZaxis(stream_t *streamptr, int zaxisID)
+{
+  /*  char zaxisname0[CDI_MAX_NAME]; */
+  char axisname[CDI_MAX_NAME];
+  char stdname[CDI_MAX_NAME];
+  char longname[CDI_MAX_NAME];
+  char units[CDI_MAX_NAME];
+  char tmpname[CDI_MAX_NAME];
+  int index;
+  int zaxisID0;
+  int dimID = UNDEFID;
+  int dimIDs[2];
+  int fileID;
+  size_t len;
+  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  int type;
+  int nzaxis;
+  int ilevel = 0;
+  int vlistID;
+  int zaxisindex;
+  int xtype = NC_DOUBLE;
+  int positive;
 
-      if ( nextstep ) break;
+  if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-      if ( CDI_Debug )
-	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, param, rlevel, vdate, vtime);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-      streamptr->tsteps[tsID].records[recID].size = recsize;
+  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
 
-      compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+  nzaxis = vlistNzaxis(vlistID);
 
-      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
-	{
-	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		  tsID, recID,
-		  streamptr->tsteps[tsID].records[recID].param, param,
-		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	  return (CDI_EUFSTRUCT);
-	}
+  size_t dimlen = (size_t)zaxisInqSize(zaxisID);
+  type   = zaxisInqType(zaxisID);
 
-      streamptr->tsteps[1].records[recID].position = recpos;
-    }
+  if (dimlen == 1)
+    switch (type)
+      {
+      case ZAXIS_SURFACE:
+      case ZAXIS_CLOUD_BASE:
+      case ZAXIS_CLOUD_TOP:
+      case ZAXIS_ISOTHERM_ZERO:
+      case ZAXIS_TOA:
+      case ZAXIS_SEA_BOTTOM:
+      case ZAXIS_ATMOSPHERE:
+      case ZAXIS_MEANSEA:
+      case ZAXIS_LAKE_BOTTOM:
+      case ZAXIS_SEDIMENT_BOTTOM:
+      case ZAXIS_SEDIMENT_BOTTOM_TA:
+      case ZAXIS_SEDIMENT_BOTTOM_TW:
+      case ZAXIS_MIX_LAYER:
+        return;
+      }
 
-  nrecs = 0;
-  for ( recID = 0; recID < nrecords; recID++ )
+  zaxisInqName(zaxisID, axisname);
+  /*
+  for ( index = 0; index < nzaxis; index++ )
     {
-      if ( ! streamptr->tsteps[tsID].records[recID].used )
-	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	}
-      else
-	{
-	  nrecs++;
-	}
+      if ( streamptr->zaxisID[index] != UNDEFID )
+        {
+          zaxisID0 = vlistZaxis(vlistID, index);
+          zaxisInqName(zaxisID0, zaxisname0);
+          if ( strcmp(zaxisname0, axisname) == 0 ) ilevel++;
+        }
     }
-  streamptr->tsteps[tsID].nrecs = nrecs;
-
-  streamptr->rtsteps = 2;
-
-  if ( streamptr->ntsteps == -1 )
+  */
+  if ( dimID == UNDEFID )
     {
-      tsID = tstepsNewEntry(streamptr);
-      if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
-
-      streamptr->tsteps[tsID-1].next   = TRUE;
-      streamptr->tsteps[tsID].position = recpos;
-    }
-
-  return (0);
-}
-
+      char axisname0[CDI_MAX_NAME];
+      char axisname2[CDI_MAX_NAME];
+      int checkname = FALSE;
+      int status;
 
-int iegInqContents(stream_t *streamptr)
-{
-  int fileID;
-  int status = 0;
+      /* check that the name is not already defined */
+      checkname = TRUE;
+      ilevel = 0;
 
-  fileID = streamptr->fileID;
+      while ( checkname )
+        {
+          strcpy(axisname2, axisname);
+          if ( ilevel ) sprintf(&axisname2[strlen(axisname2)], "_%d", ilevel+1);
 
-  streamptr->curTsID = 0;
+          status = nc_inq_varid(fileID, axisname2, &ncvarid);
+          if ( status != NC_NOERR )
+            {
+              if ( ilevel )
+                {
+                  /* check that the name does not exist for other grids */
+                  for ( index = 0; index < nzaxis; index++ )
+                    {
+                      zaxisID0 = vlistZaxis(vlistID, index);
+                      if ( zaxisID != zaxisID0 )
+                        {
+                          zaxisInqName(zaxisID0, axisname0);
+                          if ( strcmp(axisname0, axisname2) == 0 ) break;
+                        }
+                    }
+                  if ( index == nzaxis ) checkname = FALSE;
+                }
+              else
+                {
+                  checkname = FALSE;
+                }
+            }
 
-  iegScanTimestep1(streamptr);
+          if ( checkname ) ilevel++;
 
-  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
+          if ( ilevel > 99 ) break;
+        }
 
-  fileSetPos(fileID, 0, SEEK_SET);
+      if ( ilevel ) sprintf(&axisname[strlen(axisname)], "_%1d", ilevel+1);
 
-  return (status);
-}
+      if ( type == ZAXIS_REFERENCE )
+	cdfDefZaxisUUID(streamptr, zaxisID);
 
-static
-long iegScanTimestep(stream_t *streamptr)
-{
-  int status;
-  int fileID;
-  int tsID;
-  int tabnum;
-  int param = 0;
-  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
-  size_t recsize = 0;
-  off_t recpos = 0;
-  int recID;
-  taxis_t *taxis;
-  int rindex, nrecs = 0;
-  IEGCOMPVAR compVar, compVar0;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+      if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+        {
+          if ( type == ZAXIS_HYBRID )
+            {
+	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  if ( CDI_Debug )
-    {
-      Message("streamID = %d", streamptr->self);
-      Message("cts = %d", streamptr->curTsID);
-      Message("rts = %d", streamptr->rtsteps);
-      Message("nts = %d", streamptr->ntsteps);
-    }
+	      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+	      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID,  &ncvarid);
 
-  if ( streamptr->rtsteps == 0 )
-    Error("Internal problem! Missing contents.");
+	      strcpy(tmpname, "hybrid_sigma_pressure");
+	      cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "hybrid level at layer midpoints");
+	      cdf_put_att_text(fileID, ncvarid, "long_name", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "level");
+	      cdf_put_att_text(fileID, ncvarid, "units", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "down");
+	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "hyam hybm (mlev=hyam+hybm*aps)");
+	      cdf_put_att_text(fileID, ncvarid, "formula", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "ap: hyam b: hybm ps: aps");
+	      cdf_put_att_text(fileID, ncvarid, "formula_terms", strlen(tmpname), tmpname);
+	      /*
+	      strcpy(tmpname, "ilev");
+	      cdf_put_att_text(fileID, ncvarid, "borders", strlen(tmpname), tmpname);
+	      */
+	      cdf_enddef(fileID);
+	      streamptr->ncmode = 2;
 
-  tsID  = streamptr->rtsteps;
-  taxis = &streamptr->tsteps[tsID].taxis;
+	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+            }
 
-  if ( streamptr->tsteps[tsID].recordSize == 0 )
-    {
-      cdi_create_records(streamptr, tsID);
+          if ( type == ZAXIS_HYBRID_HALF )
+            {
+	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      nrecs = streamptr->tsteps[1].nrecs;
+	      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+	      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID,  &ncvarid);
 
-      streamptr->tsteps[tsID].nrecs = nrecs;
-      streamptr->tsteps[tsID].recIDs
-        = (int *)xmalloc((size_t)nrecs * sizeof (int));
-      for ( recID = 0; recID < nrecs; recID++ )
-	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
+	      strcpy(tmpname, "hybrid_sigma_pressure");
+	      cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "hybrid level at layer interfaces");
+	      cdf_put_att_text(fileID, ncvarid, "long_name", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "level");
+	      cdf_put_att_text(fileID, ncvarid, "units", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "down");
+	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "hyai hybi (ilev=hyai+hybi*aps)");
+	      cdf_put_att_text(fileID, ncvarid, "formula", strlen(tmpname), tmpname);
+	      strcpy(tmpname, "ap: hyai b: hybi ps: aps");
+	      cdf_put_att_text(fileID, ncvarid, "formula_terms", strlen(tmpname), tmpname);
 
-      fileID = streamptr->fileID;
+	      cdf_enddef(fileID);
+	      streamptr->ncmode = 2;
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+            }
 
-      for ( rindex = 0; rindex <= nrecs; rindex++ )
-	{
-	  recpos = fileGetPos(fileID);
-	  status = iegRead(fileID, iegp);
-	  if ( status != 0 )
-	    {
-	      streamptr->ntsteps = streamptr->rtsteps + 1;
-	      break;
-	    }
-	  recsize = (size_t)(fileGetPos(fileID) - recpos);
+          cdfDefVCT(streamptr, zaxisID);
 
-	  rcode  = IEG_P_Parameter(iegp->ipdb);
-	  tabnum = IEG_P_CodeTable(iegp->ipdb);
-	  param  = cdiEncodeParam(rcode, tabnum, 255);
+          if ( dimID == UNDEFID )
+            {
+              if ( type == ZAXIS_HYBRID )
+                streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
+              else
+                streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
+            }
+        }
+      else
+        {
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-	  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
-	    rlevel = IEG_P_Level1(iegp->ipdb);
-	  else
-	    rlevel = IEG_P_Level2(iegp->ipdb);
+          cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-	  if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
+          zaxisInqLongname(zaxisID, longname);
+          zaxisInqUnits(zaxisID, units);
+          zaxisInqStdname(zaxisID, stdname);
 
-	  iegDateTime(iegp->ipdb, &vdate, &vtime);
+          cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
 
-	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
-	  if ( rindex == nrecs ) continue;
-	  recID = streamptr->tsteps[tsID].recIDs[rindex];
+          if ( (len = strlen(stdname)) )
+            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+          if ( (len = strlen(longname)) )
+            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+          if ( (len = strlen(units)) )
+            cdf_put_att_text(fileID, ncvarid, "units", len, units);
 
-	  if ( rindex == 0 )
+	  positive = zaxisInqPositive(zaxisID);
+	  if ( positive == POSITIVE_UP )
 	    {
-	      taxis->type  = TAXIS_ABSOLUTE;
-	      taxis->vdate = vdate;
-	      taxis->vtime = vtime;
+	      strcpy(tmpname, "up");
+	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
 	    }
-
-	  compVar.param = param;
-          compVar.level = rlevel;
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
+	  else if ( positive == POSITIVE_DOWN )
 	    {
-	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
-		      tsID, recID,
-		      streamptr->tsteps[tsID].records[recID].param, param,
-		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	      Error("Invalid, unsupported or inconsistent record structure");
+	      strcpy(tmpname, "down");
+	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
 	    }
 
-	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = recsize;
-
-	  if ( CDI_Debug )
-	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, param, rlevel, vdate, vtime);
-	}
-
-      streamptr->rtsteps++;
-
-      if ( streamptr->ntsteps != streamptr->rtsteps )
-	{
-	  tsID = tstepsNewEntry(streamptr);
-	  if ( tsID != streamptr->rtsteps )
-	    Error("Internal error. tsID = %d", tsID);
+          cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
 
-	  streamptr->tsteps[tsID-1].next   = 1;
-	  streamptr->tsteps[tsID].position = recpos;
-	}
+	  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+            {
+              size_t nvertex = 2;
+	      if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+		cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
 
-      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
-      streamptr->tsteps[tsID].position = recpos;
-    }
+	      if ( nvdimID != UNDEFID )
+		{
+		  strcat(axisname, "_bnds");
+		  dimIDs[0] = dimID;
+		  dimIDs[1] = nvdimID;
+		  cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
+		  cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
+		}
+	    }
 
-  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
-    {
-      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
-      streamptr->ntsteps = tsID;
-    }
+          cdf_enddef(fileID);
+          streamptr->ncmode = 2;
 
-  return (streamptr->ntsteps);
-}
+          cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
 
+          if ( ncbvarid != UNDEFID )
+	    {
+	      double *zbounds, *lbounds, *ubounds;
 
-int iegInqTimestep(stream_t *streamptr, int tsID)
-{
-  int nrecs;
+	      lbounds = (double *) malloc(dimlen*sizeof(double));
+	      ubounds = (double *) malloc(dimlen*sizeof(double));
+	      zbounds = (double *) malloc(2*dimlen*sizeof(double));
 
-  if ( tsID == 0 && streamptr->rtsteps == 0 )
-    Error("Call to cdiInqContents missing!");
+	      zaxisInqLbounds(zaxisID, lbounds);
+	      zaxisInqUbounds(zaxisID, ubounds);
 
-  if ( CDI_Debug )
-    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
+	      for (size_t i = 0; i < dimlen; ++i )
+		{
+		  zbounds[2*i  ] = lbounds[i];
+		  zbounds[2*i+1] = ubounds[i];
+		}
 
-  long ntsteps = UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = iegScanTimestep(streamptr);
+	      cdf_put_var_double(fileID, ncbvarid, zbounds);
 
-  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
-    {
-      nrecs = 0;
-    }
-  else
-    {
-      streamptr->curTsID = tsID;
-      nrecs = streamptr->tsteps[tsID].nrecs;
+	      free(zbounds);
+	      free(ubounds);
+	      free(lbounds);
+	    }
+        }
     }
 
-  return (nrecs);
+  if ( dimID != UNDEFID )
+    streamptr->zaxisID[zaxisindex] = dimID;
 }
 
 
-void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+static
+void cdfDefPole(stream_t *streamptr, int gridID)
 {
-  int vlistID, fileID;
-  int levID, nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+  int fileID;
+  int ncvarid = UNDEFID;
+  int ncerr;
+  double xpole, ypole, angle;
+  char varname[] = "rotated_pole";
+  char mapname[] = "rotated_latitude_longitude";
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
+  fileID  = streamptr->fileID;
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+  ypole = gridInqYpole(gridID);
+  xpole = gridInqXpole(gridID);
+  angle = gridInqAngle(gridID);
 
-  currentfilepos = fileGetPos(fileID);
+  cdf_redef(fileID);
 
-  for (levID = 0; levID < nlevs; levID++)
+  ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+  if ( ncerr == NC_NOERR )
     {
-      recID = streamptr->vars[varID].level[levID];
-      recpos = streamptr->tsteps[tsid].records[recID].position;
-      fileSetPos(fileID, recpos, SEEK_SET);
-      iegRead(fileID, iegp);
-      iegInqDataDP(iegp, &data[levID*gridsize]);
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
+      cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
+      cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
+      if ( IS_NOT_EQUAL(angle, 0) )
+        cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1, &angle);
     }
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  *nmiss = 0;
-  for ( i = 0; i < nlevs*gridsize; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
+  cdf_enddef(fileID);
 }
 
 
-void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+static
+void cdfDefMapping(stream_t *streamptr, int gridID)
 {
-  int vlistID, fileID;
-  int nlevs, gridID, gridsize;
-  off_t recpos, currentfilepos;
-  int tsid;
-  int recID;
-  int i;
-  double missval;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  nlevs    = streamptr->vars[varID].nlevs;
-  missval  = vlistInqVarMissval(vlistID, varID);
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  tsid     = streamptr->curTsID;
-
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d",
-	     nlevs, gridID, gridsize);
-
-  currentfilepos = fileGetPos(fileID);
+  int fileID;
+  int ncvarid = UNDEFID;
+  int ncerr;
 
-  recID = streamptr->vars[varID].level[levID];
-  recpos = streamptr->tsteps[tsid].records[recID].position;
-  fileSetPos(fileID, recpos, SEEK_SET);
-  iegRead(fileID, iegp);
-  iegInqDataDP(iegp, data);
+  if ( gridInqType(gridID) == GRID_SINUSOIDAL )
+    {
+      char varname[] = "sinusoidal";
+      char mapname[] = "sinusoidal";
 
-  fileSetPos(fileID, currentfilepos, SEEK_SET);
+      fileID  = streamptr->fileID;
 
-  *nmiss = 0;
-  for ( i = 0; i < gridsize; i++ )
-    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
-      {
-	data[i] = missval;
-	(*nmiss)++;
-      }
-}
+      cdf_redef(fileID);
 
+      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerr == NC_NOERR )
+        {
+          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
+          /*
+          cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
+          cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
+          */
+        }
 
-void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
-{
-  int fileID;
-  int levID, nlevs, gridID, gridsize;
-  int zaxisID;
-  int datatype;
-  int tsID;
-  int vlistID;
-  int i;
-  int date, time;
-  int param, pdis, pcat, pnum;
-  double refval;
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
+      cdf_enddef(fileID);
+    }
+  else if ( gridInqType(gridID) == GRID_LAEA )
+    {
+      char varname[] = "laea";
+      char mapname[] = "lambert_azimuthal_equal_area";
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamptr->self, varID);
+      fileID  = streamptr->fileID;
 
-  iegInitMem(iegp);
-  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+      cdf_redef(fileID);
 
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  tsID     = streamptr->curTsID;
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  gridsize = gridInqSize(gridID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  nlevs    = zaxisInqSize(zaxisID);
+      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerr == NC_NOERR )
+        {
+          double a, lon_0, lat_0;
 
-  if ( CDI_Debug )
-    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+          gridInqLaea(gridID, &a, &lon_0, &lat_0);
 
-  param    = vlistInqVarParam(vlistID, varID);
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  IEG_P_Parameter(iegp->ipdb) = pnum;
-  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
-  date     = streamptr->tsteps[tsID].taxis.vdate;
-  time     = streamptr->tsteps[tsID].taxis.vtime;
+          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
+          cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &a);
+          cdf_put_att_double(fileID, ncvarid, "longitude_of_projection_origin", NC_DOUBLE, 1, &lon_0);
+          cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
+        }
 
-  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
-  iegDefGrid(iegp->igdb, gridID);
+      cdf_enddef(fileID);
+    }
+  else if ( gridInqType(gridID) == GRID_LCC2 )
+    {
+      char varname[] = "Lambert_Conformal";
+      char mapname[] = "lambert_conformal_conic";
 
-  datatype = vlistInqVarDatatype(vlistID, varID);
+      fileID  = streamptr->fileID;
 
-  iegp->dprec = iegDefDatatype(datatype);
+      cdf_redef(fileID);
 
-  for ( levID = 0;  levID < nlevs; levID++ )
-    {
-      iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
+      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerr == NC_NOERR )
+        {
+          double radius, lon_0, lat_0, lat_1, lat_2;
 
-      refval = data[0];
-      for ( i = 1; i < gridsize; i++ )
-	if ( data[levID*gridsize+i] < refval ) refval = data[levID*gridsize+i];
+          gridInqLcc2(gridID, &radius, &lon_0, &lat_0, &lat_1, &lat_2);
 
-      iegp->refval = refval;
+          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
+          if ( radius > 0 )
+            cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &radius);
+          cdf_put_att_double(fileID, ncvarid, "longitude_of_central_meridian", NC_DOUBLE, 1, &lon_0);
+          cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
+          if ( IS_EQUAL(lat_1, lat_2) )
+            cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 1, &lat_1);
+          else
+            {
+              double lat_1_2[2];
+              lat_1_2[0] = lat_1;
+              lat_1_2[1] = lat_2;
+              cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 2, lat_1_2);
+            }
+        }
 
-      iegDefDataDP(iegp, &data[levID*gridsize]);
-      iegWrite(fileID, iegp);
+      cdf_enddef(fileID);
     }
 }
 
 
-void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+static
+void cdfDefGrid(stream_t *streamptr, int gridID)
 {
-  int fileID;
-  int gridID;
-  int zaxisID;
-  /* double level; */
-  int datatype;
-  /* int tsID; */
+  int gridtype, size;
+  int gridindex;
   int vlistID;
-  /* int param, date, time, datasize; */
-  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
-
-  vlistID  = streamptr->vlistID;
-  fileID   = streamptr->fileID;
-  /* tsID     = streamptr->curTsID; */
-  gridID   = vlistInqVarGrid(vlistID, varID);
-  zaxisID  = vlistInqVarZaxis(vlistID, varID);
-  (void)levID;
-  /* level    = zaxisInqLevel(zaxisID, levID); */
-
-  if ( CDI_Debug )
-    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
-
-  /* param = vlistInqVarParam(vlistID, varID); */
-  /* date = streamptr->tsteps[tsID].taxis.vdate; */
-  /* time = streamptr->tsteps[tsID].taxis.vtime; */
-  /* datasize = gridInqSize(gridID); */
-
-  datatype = vlistInqVarDatatype(vlistID, varID);
-
-  iegp->dprec = iegDefDatatype(datatype);
-
-  iegDefDataDP(iegp, data);
-  iegWrite(fileID, iegp);
-}
-
-#endif /* HAVE_LIBIEG */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#ifdef HAVE_LIBNETCDF
-
-//#define TEST_GROUPS 1
-
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-#include <float.h>
-
-#include <netcdf.h>
 
+  vlistID = streamptr->vlistID;
+  gridindex = vlistGridIndex(vlistID, gridID);
+  if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
 
-//#define PROJECTION_TEST
-
-#undef  UNDEFID
-#define UNDEFID  CDI_UNDEFID
-
-
-#if defined HAVE_LIBNETCDF
-static void cdfDefGlobalAtts(stream_t *streamptr);
-static void cdfDefLocalAtts(stream_t *streamptr);
-#endif
-
-#define  X_AXIS  1
-#define  Y_AXIS  2
-#define  Z_AXIS  3
-#define  T_AXIS  4
-
-#define  POSITIVE_UP    1
-#define  POSITIVE_DOWN  2
+  gridtype = gridInqType(gridID);
+  size     = gridInqSize(gridID);
 
-typedef struct {
-  int     ncvarid;
-  int     dimtype;
-  size_t  len;
-  char    name[CDI_MAX_NAME];
-}
-ncdim_t;
+  if ( CDI_Debug )
+    Message("gridtype = %d  size = %d", gridtype, size);
 
-#define  MAX_COORDVARS  4
-#define  MAX_AUXVARS    4
+  if ( gridtype == GRID_GAUSSIAN ||
+       gridtype == GRID_LONLAT   ||
+       gridtype == GRID_GENERIC )
+    {
+      if ( gridtype == GRID_GENERIC )
+        {
+          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+            {
+              /* no grid information */
+            }
+          else
+            {
+              int lx = 0, ly = 0;
+              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefXaxis(streamptr, gridID, 1);
+                  lx = 1;
+                }
 
-typedef struct {
-  int      ncid;
-  int      ignore;
-  int      isvar;
-  int      islon;
-  int      islat;
-  int      islev;
-  int      istime;
-  int      warn;
-  int      tsteptype;
-  int      param;
-  int      code;
-  int      tabnum;
-  int      climatology;
-  int      bounds;
-  int      gridID;
-  int      zaxisID;
-  int      gridtype;
-  int      zaxistype;
-  int      xdim;
-  int      ydim;
-  int      zdim;
-  int      xvarid;
-  int      yvarid;
-  int      zvarid;
-  int      tvarid;
-  int      ncoordvars;
-  int      coordvarids[MAX_COORDVARS];
-  int      nauxvars;
-  int      auxvarids[MAX_AUXVARS];
-  int      cellarea;
-  int      calendar;
-  int      tableID;
-  int      truncation;
-  int      position;
-  int      defmissval;
-  int      deffillval;
-  int      xtype;
-  int      ndims;
-  int      gmapid;
-  int      positive;
-  int      dimids[8];
-  int      dimtype[8];
-  int      chunks[8];
-  int      chunked;
-  int      chunktype;
-  int      natts;
-  int     *atts;
-  int      deflate;
-  int      lunsigned;
-  int      lvalidrange;
-  size_t   vlen;
-  double  *vdata;
-  double   missval;
-  double   fillval;
-  double   addoffset;
-  double   scalefactor;
-  double   validrange[2];
-  char     name[CDI_MAX_NAME];
-  char     longname[CDI_MAX_NAME];
-  char     stdname[CDI_MAX_NAME];
-  char     units[CDI_MAX_NAME];
-  char     extra[CDI_MAX_NAME];
-  ensinfo_t   *ensdata;    /* Ensemble information */
-}
-ncvar_t;
+              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefYaxis(streamptr, gridID, 1);
+                  ly = 1;
+                }
 
-static
-void strtolower(char *str)
-{
-  if ( str )
-    for (size_t i = 0; str[i]; ++i)
-      str[i] = (char)tolower((int)str[i]);
-}
+              if ( lx == 0 && ly == 0 ) cdfDefGdim(streamptr, gridID);
+            }
+        }
+      else
+        {
+          int ndims = 1;
+          if ( gridtype == GRID_LONLAT && size == 1 && gridInqHasDims(gridID) == FALSE )
+            ndims = 0;
 
-static
-int get_timeunit(size_t len, const char *ptu)
-{
-  int timeunit = -1;
+          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, ndims);
+          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, ndims);
+        }
 
-  if ( len > 2 )
+      if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
+    }
+  else if ( gridtype == GRID_CURVILINEAR )
     {
-      if      ( memcmp(ptu, "sec",    3) == 0 )          timeunit = TUNIT_SECOND;
-      else if ( memcmp(ptu, "minute", 6) == 0 )          timeunit = TUNIT_MINUTE;
-      else if ( memcmp(ptu, "hour",   4) == 0 )          timeunit = TUNIT_HOUR;
-      else if ( memcmp(ptu, "day",    3) == 0 )          timeunit = TUNIT_DAY;
-      else if ( memcmp(ptu, "month",  5) == 0 )          timeunit = TUNIT_MONTH;
-      else if ( memcmp(ptu, "calendar_month", 14) == 0 ) timeunit = TUNIT_MONTH;
-      else if ( memcmp(ptu, "year",   4) == 0 )          timeunit = TUNIT_YEAR;
+      cdfDefCurvilinear(streamptr, gridID);
     }
-  else if ( len == 1 )
+  else if ( gridtype == GRID_UNSTRUCTURED )
     {
-      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
+      cdfDefUnstructured(streamptr, gridID);
+    }
+  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+    {
+      cdfDefRgrid(streamptr, gridID);
+    }
+  else if ( gridtype == GRID_SPECTRAL )
+    {
+      cdfDefComplex(streamptr, gridID);
+      cdfDefSP(streamptr, gridID);
+    }
+  else if ( gridtype == GRID_FOURIER )
+    {
+      cdfDefComplex(streamptr, gridID);
+      cdfDefFC(streamptr, gridID);
+    }
+  else if ( gridtype == GRID_TRAJECTORY )
+    {
+      cdfDefTrajLon(streamptr, gridID);
+      cdfDefTrajLat(streamptr, gridID);
     }
+  else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
+    {
+      cdfDefXaxis(streamptr, gridID, 1);
+      cdfDefYaxis(streamptr, gridID, 1);
 
-  return (timeunit);
+      cdfDefMapping(streamptr, gridID);
+    }
+  /*
+  else if ( gridtype == GRID_LCC )
+    {
+      cdfDefLcc(streamptr, gridID);
+    }
+  */
+  else
+    {
+      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+    }
 }
 
+
 static
-int isTimeUnits(const char *timeunits)
+int cdfDefVar(stream_t *streamptr, int varID)
 {
-  int status = 0;
+  int ncvarid = -1;
+  int fileID;
+  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID, tid = UNDEFID;
+  size_t xsize = 0, ysize = 0;
+  int code, param, gridID, zaxisID;
+  int pnum, pcat, pdis;
+  char varname[CDI_MAX_NAME];
+  const char *name = NULL;
+  const char *longname = NULL;
+  const char *stdname = NULL;
+  const char *units = NULL;
+  int dims[4];
+  int lchunk = FALSE;
+  int chunktype;
+  size_t chunks[4] = {0,0,0,0};
+  int tableID;
+  int ndims = 0;
+  int tsteptype;
+  int xtype, dtype;
+  int gridtype, gridsize;
+  int gridindex, zaxisindex;
+  int tablenum;
+  int vlistID;
+  int dimorder[3];
+  size_t iax = 0;
+  char axis[5];
+  int ensID, ensCount, forecast_type;
+  int retval;
 
-  if ( strncmp(timeunits, "sec",    3) == 0 ||
-       strncmp(timeunits, "minute", 6) == 0 ||
-       strncmp(timeunits, "hour",   4) == 0 ||
-       strncmp(timeunits, "day",    3) == 0 ||
-       strncmp(timeunits, "month",  5) == 0 ) status = 1;
+  fileID  = streamptr->fileID;
 
-  return (status);
-}
+  if ( CDI_Debug )
+    Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
 
-static
-int isTimeAxisUnits(const char *timeunits)
-{
-  char *ptu, *tu;
-  int timetype = -1;
-  int timeunit;
-  int status = FALSE;
+  if ( streamptr->vars[varID].ncvarid != UNDEFID )
+    return (streamptr->vars[varID].ncvarid);
 
-  size_t len = strlen(timeunits);
-  tu = xmalloc((len+1)*sizeof(char));
-  memcpy(tu, timeunits, (len+1) * sizeof(char));
-  ptu = tu;
+  vlistID   = streamptr->vlistID;
+  gridID    = vlistInqVarGrid(vlistID, varID);
+  zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  code      = vlistInqVarCode(vlistID, varID);
+  param     = vlistInqVarParam(vlistID, varID);
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
-  for (size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
+  chunktype = vlistInqVarChunkType(vlistID, varID);
 
-  timeunit = get_timeunit(len, ptu);
-  if ( timeunit != -1 )
+  vlistInqVarDimorder(vlistID, varID, &dimorder);
+
+  gridsize  = gridInqSize(gridID);
+  if ( gridsize > 1 ) lchunk = TRUE;
+  gridtype  = gridInqType(gridID);
+  gridindex = vlistGridIndex(vlistID, gridID);
+  if ( gridtype != GRID_TRAJECTORY )
     {
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
+      if ( xid != UNDEFID ) cdf_inq_dimlen(fileID, xid, &xsize);
+      if ( yid != UNDEFID ) cdf_inq_dimlen(fileID, yid, &ysize);
+    }
 
-      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
-      if ( *ptu )
-        {
-          while ( isspace(*ptu) ) ptu++;
+  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+  zid = streamptr->zaxisID[zaxisindex];
 
-          if ( memcmp(ptu, "as", 2) == 0 )
-            timetype = TAXIS_ABSOLUTE;
-          else if ( memcmp(ptu, "since", 5) == 0 )
-            timetype = TAXIS_RELATIVE;
+  if ( dimorder[0] != 3 ) lchunk = FALSE; /* ZYX and ZXY */
 
-          if ( timetype != -1 ) status = TRUE;
-        }
+  if ( ((dimorder[0]>0)+(dimorder[1]>0)+(dimorder[2]>0)) < ((xid!=UNDEFID)+(yid!=UNDEFID)+(zid!=UNDEFID)) )
+    {
+      printf("zid=%d  yid=%d  xid=%d\n", zid, yid, xid);
+      Error("Internal problem, dimension order missing!");
     }
 
-  free(tu);
+  tid = streamptr->basetime.ncdimid;
 
-  return (status);
-}
+  if ( tsteptype != TSTEP_CONSTANT )
+    {
+      if ( tid == UNDEFID ) Error("Internal problem, time undefined!");
+      chunks[ndims] = 1;
+      dims[ndims++] = tid;
+      axis[iax++] = 'T';
+    }
+  /*
+  if ( zid != UNDEFID ) axis[iax++] = 'Z';
+  if ( zid != UNDEFID ) chunks[ndims] = 1;
+  if ( zid != UNDEFID ) dims[ndims++] = zid;
 
-static
-void scanTimeString(const char *ptu, int *rdate, int *rtime)
-{
-  int year, month, day;
-  int hour = 0, minute = 0, second = 0;
-  int v1, v2, v3;
+  if ( yid != UNDEFID ) chunks[ndims] = ysize;
+  if ( yid != UNDEFID ) dims[ndims++] = yid;
 
-  *rdate = 0;
-  *rtime = 0;
+  if ( xid != UNDEFID ) chunks[ndims] = xsize;
+  if ( xid != UNDEFID ) dims[ndims++] = xid;
+  */
+  for ( int id = 0; id < 3; ++id )
+    {
+      if ( dimorder[id] == 3 && zid != UNDEFID )
+        {
+          axis[iax++] = 'Z';
+          chunks[ndims] = 1;
+          dims[ndims] = zid;
+          ndims++;
+        }
+      else if ( dimorder[id] == 2 && yid != UNDEFID )
+        {
+          if ( chunktype == CHUNK_LINES )
+            chunks[ndims] = 1;
+          else
+            chunks[ndims] = ysize;
+          dims[ndims] = yid;
+          ndims++;
+        }
+      else if ( dimorder[id] == 1 && xid != UNDEFID )
+        {
+          chunks[ndims] = xsize;
+          dims[ndims] = xid;
+          ndims++;
+        }
+    }
 
-  v1 = atoi(ptu);
-  if ( v1 < 0 ) ptu++;
-  while ( isdigit((int) *ptu) ) ptu++;
-  v2 = atoi(++ptu);
-  while ( isdigit((int) *ptu) ) ptu++;
-  v3 = atoi(++ptu);
-  while ( isdigit((int) *ptu) ) ptu++;
+  if ( CDI_Debug )
+    fprintf(stderr, "chunktype %d  chunks %d %d %d %d\n", chunktype, (int)chunks[0], (int)chunks[1], (int)chunks[2], (int)chunks[3]);
 
-  if ( v3 > 999 && v1 < 32 )
-    { year = v3; month = v2; day = v1; }
-  else
-    { year = v1; month = v2; day = v3; }
+  tableID  = vlistInqVarTable(vlistID, varID);
 
-  while ( isspace((int) *ptu) ) ptu++;
+  name     = vlistInqVarNamePtr(vlistID, varID);
+  longname = vlistInqVarLongnamePtr(vlistID, varID);
+  stdname  = vlistInqVarStdnamePtr(vlistID, varID);
+  units    = vlistInqVarUnitsPtr(vlistID, varID);
 
-  if ( *ptu )
+  if ( name     == NULL )     name = tableInqParNamePtr(tableID, code);
+  if ( longname == NULL ) longname = tableInqParLongnamePtr(tableID, code);
+  if ( units    == NULL )    units = tableInqParUnitsPtr(tableID, code);
+  if ( name )
     {
-      while ( ! isdigit((int) *ptu) ) ptu++;
+      int checkname;
+      int iz;
+      int status;
 
-      hour = atoi(ptu);
-      while ( isdigit((int) *ptu) ) ptu++;
-      if ( *ptu == ':' )
+      sprintf(varname, "%s", name);
+
+      checkname = TRUE;
+      iz = 0;
+
+      while ( checkname )
         {
-          ptu++;
-          minute = atoi(ptu);
-          while ( isdigit((int) *ptu) ) ptu++;
-          if ( *ptu == ':' )
+          if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
+
+          status = nc_inq_varid(fileID, varname, &ncvarid);
+          if ( status != NC_NOERR )
             {
-              ptu++;
-              second = atoi(ptu);
+              checkname = FALSE;
             }
+
+          if ( checkname ) iz++;
+
+          if ( iz >= CDI_MAX_NAME ) Error("Double entry of variable name '%s'!", name);
+        }
+
+      if ( strcmp(name, varname) != 0 )
+        {
+          if ( iz == 1 )
+            Warning("Changed double entry of variable name '%s' to '%s'!", name, varname);
+          else
+            Warning("Changed multiple entry of variable name '%s' to '%s'!", name, varname);
         }
+
+      name = varname;
     }
+  else
+    {
+      int checkname;
+      int iz;
+      int status;
+      char *varname2;
 
-  *rdate = cdiEncodeDate(year, month, day);
-  *rtime = cdiEncodeTime(hour, minute, second);
-}
+      if ( code < 0 ) code = -code;
+      if ( pnum < 0 ) pnum = -pnum;
 
-static
-int scanTimeUnit(const char *unitstr)
-{
-  int timeunit = -1;
-  size_t len = strlen(unitstr);
-  timeunit = get_timeunit(len, unitstr);
-  if ( timeunit == -1 )
-    Message("Unsupported TIMEUNIT: %s!", unitstr);
+      if ( pdis == 255 )
+	sprintf(varname, "var%d", code);
+      else
+	sprintf(varname, "param%d.%d.%d", pnum, pcat, pdis);
 
-  return (timeunit);
-}
+      varname2 = varname+strlen(varname);
 
-static
-void setForecastTime(const char *timestr, taxis_t *taxis)
-{
-  int len;
+      checkname = TRUE;
+      iz = 0;
 
-  (*taxis).fdate = 0;
-  (*taxis).ftime = 0;
+      while ( checkname )
+        {
+          if ( iz ) sprintf(varname2, "_%d", iz+1);
 
-  len = (int) strlen(timestr);
-  if ( len == 0 ) return;
+          status = nc_inq_varid(fileID, varname, &ncvarid);
+          if ( status != NC_NOERR ) checkname = FALSE;
 
-  int fdate = 0, ftime = 0;
-  scanTimeString(timestr, &fdate, &ftime);
+          if ( checkname ) iz++;
 
-  (*taxis).fdate = fdate;
-  (*taxis).ftime = ftime;
-}
+          if ( iz >= CDI_MAX_NAME ) break;
+        }
 
-static
-int setBaseTime(const char *timeunits, taxis_t *taxis)
-{
-  char *ptu, *tu;
-  int timetype = TAXIS_ABSOLUTE;
-  int rdate = -1, rtime = -1;
-  int timeunit;
+      name = varname;
+      code = 0;
+      pdis = 255;
+    }
 
-  size_t len = strlen(timeunits);
-  tu = xmalloc((len+1) * sizeof (char));
-  memcpy(tu, timeunits, (len+1) * sizeof (char));
-  ptu = tu;
+  /* if ( streamptr->ncmode == 2 ) cdf_redef(fileID); */
 
-  for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int) ptu[i]);
+  dtype = vlistInqVarDatatype(vlistID, varID);
+  xtype = cdfDefDatatype(dtype, streamptr->filetype);
 
-  timeunit = get_timeunit(len, ptu);
-  if ( timeunit == -1 )
-    {
-      Message("Unsupported TIMEUNIT: %s!", timeunits);
-      return (1);
-    }
+  cdf_def_var(fileID, name, (nc_type) xtype, ndims, dims, &ncvarid);
 
-  while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
-  if ( *ptu )
+#if  defined  (HAVE_NETCDF4)
+  if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
     {
-      while ( isspace(*ptu) ) ptu++;
+      if ( chunktype == CHUNK_AUTO )
+        retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
+      else
+        retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks);
 
-      if ( memcmp(ptu, "as", 2) == 0 )
-        timetype = TAXIS_ABSOLUTE;
-      else if ( memcmp(ptu, "since", 5) == 0 )
-        timetype = TAXIS_RELATIVE;
+      if ( retval ) Error("nc_def_var_chunking failed, status = %d", retval);
+    }
+#endif
 
-      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
-      if ( *ptu )
+  if ( streamptr->comptype == COMPRESS_ZIP )
+    {
+      if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
         {
-          while ( isspace(*ptu) ) ptu++;
-
-          if ( timetype == TAXIS_ABSOLUTE )
+          cdfDefVarDeflate(fileID, ncvarid, streamptr->complevel);
+        }
+      else
+        {
+          if ( lchunk )
             {
-              if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
-                {
-                  Message("Unsupported format %s for TIMEUNIT day!", ptu);
-                  timeunit = -1;
-                }
-              else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
+              static int lwarn = TRUE;
+
+              if ( lwarn )
                 {
-                  Message("Unsupported format %s for TIMEUNIT month!", ptu);
-                  timeunit = -1;
+                  lwarn = FALSE;
+                  Warning("Deflate compression is only available for netCDF4!");
                 }
             }
-          else if ( timetype == TAXIS_RELATIVE )
-            {
-              scanTimeString(ptu, &rdate, &rtime);
+        }
+    }
 
-              (*taxis).rdate = rdate;
-              (*taxis).rtime = rtime;
+  if ( streamptr->comptype == COMPRESS_SZIP )
+    {
+      if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
+        {
+#if defined (NC_SZIP_NN_OPTION_MASK)
+          cdfDefVarSzip(fileID, ncvarid);
+#else
+          static int lwarn = TRUE;
 
-              if ( CDI_Debug )
-                Message("rdate = %d  rtime = %d", rdate, rtime);
+          if ( lwarn )
+            {
+              lwarn = FALSE;
+              Warning("netCDF4/SZIP compression not available!");
+            }
+#endif
+        }
+      else
+        {
+          static int lwarn = TRUE;
+
+          if ( lwarn )
+            {
+              lwarn = FALSE;
+              Warning("SZIP compression is only available for netCDF4!");
             }
         }
     }
 
-  (*taxis).type = timetype;
-  (*taxis).unit = timeunit;
+  if ( stdname && *stdname )
+    cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(stdname), stdname);
 
-  free(tu);
+  if ( longname && *longname )
+    cdf_put_att_text(fileID, ncvarid, "long_name", strlen(longname), longname);
 
-  if ( CDI_Debug )
-    Message("timetype = %d  unit = %d", timetype, timeunit);
+  if ( units && *units )
+    cdf_put_att_text(fileID, ncvarid, "units", strlen(units), units);
 
-  return (0);
-}
+  if ( code > 0 && pdis == 255 )
+    cdf_put_att_int(fileID, ncvarid, "code", NC_INT, 1, &code);
 
-static
-void cdfGetAttInt(int fileID, int ncvarid, char *attname, int attlen, int *attint)
-{
-  size_t nc_attlen;
-  int *pintatt;
+  if ( pdis != 255 )
+    {
+      char paramstr[32];
+      cdiParamToString(param, paramstr, sizeof(paramstr));
+      cdf_put_att_text(fileID, ncvarid, "param", strlen(paramstr), paramstr);
+    }
 
-  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+  if ( tableID != UNDEFID )
+    {
+      tablenum = tableInqNum(tableID);
+      if ( tablenum > 0 )
+        cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
+    }
 
-  if ( (int)nc_attlen > attlen )
-    pintatt = (int *) malloc(nc_attlen * sizeof (int));
-  else
-    pintatt = attint;
+  if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT  && gridtype != GRID_CURVILINEAR )
+    {
+      size_t len = strlen(gridNamePtr(gridtype));
+      if ( len > 0 )
+        cdf_put_att_text(fileID, ncvarid, "grid_type", len, gridNamePtr(gridtype));
+    }
+
+  if ( gridIsRotated(gridID) )
+    {
+      char mapping[] = "rotated_pole";
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
+    }
+
+  if ( gridtype == GRID_SINUSOIDAL )
+    {
+      char mapping[] = "sinusoidal";
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
+    }
+  else if ( gridtype == GRID_LAEA )
+    {
+      char mapping[] = "laea";
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
+    }
+  else if ( gridtype == GRID_LCC2 )
+    {
+      char mapping[] = "Lambert_Conformal";
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
+    }
+  else if ( gridtype == GRID_TRAJECTORY )
+    {
+      cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "tlon tlat" );
+    }
+  else if ( gridtype == GRID_LONLAT && xid == UNDEFID && yid == UNDEFID && gridsize == 1 )
+    {
+      char coordinates[CDI_MAX_NAME] = "";
+      int ncxvarID, ncyvarID;
+      int gridindex;
+      size_t len;
+
+      gridindex = vlistGridIndex(vlistID, gridID);
+      ncxvarID = streamptr->ncxvarID[gridindex];
+      ncyvarID = streamptr->ncyvarID[gridindex];
+      if ( ncxvarID != CDI_UNDEFID )
+        cdf_inq_varname(fileID, ncxvarID, coordinates);
+      len = strlen(coordinates);
+      if ( ncyvarID != CDI_UNDEFID )
+        {
+          if ( len ) coordinates[len++] = ' ';
+          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+        }
+      len = strlen(coordinates);
+      if ( len )
+        cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
+    }
+  else if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
+    {
+      char coordinates[CDI_MAX_NAME] = "";
+      char cellarea[CDI_MAX_NAME] = "area: ";
+      int ncxvarID, ncyvarID, ncavarID;
+      int gridindex;
+      size_t len;
+
+      gridindex = vlistGridIndex(vlistID, gridID);
+      ncxvarID = streamptr->ncxvarID[gridindex];
+      ncyvarID = streamptr->ncyvarID[gridindex];
+      ncavarID = streamptr->ncavarID[gridindex];
+      if ( ncxvarID != CDI_UNDEFID )
+        cdf_inq_varname(fileID, ncxvarID, coordinates);
+      len = strlen(coordinates);
+      if ( ncyvarID != CDI_UNDEFID )
+        {
+          if ( len ) coordinates[len++] = ' ';
+          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+        }
+      len = strlen(coordinates);
+      if ( len )
+        cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
 
-  cdf_get_att_int(fileID, ncvarid, attname, pintatt);
+      if ( ncavarID != CDI_UNDEFID )
+        {
+          len = strlen(cellarea);
+          cdf_inq_varname(fileID, ncavarID, cellarea+len);
+          len = strlen(cellarea);
+          cdf_put_att_text(fileID, ncvarid, "cell_measures", len, cellarea);
+        }
 
-  if ( (int)nc_attlen > attlen )
-    {
-      memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
-      free(pintatt);
+      if ( gridtype == GRID_UNSTRUCTURED )
+        {
+          int position = gridInqPosition(gridID);
+          if ( position > 0 )
+            cdf_put_att_int(fileID, ncvarid, "number_of_grid_in_reference", NC_INT, 1, &position);
+        }
     }
-}
-
-static
-void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
-{
-  size_t nc_attlen;
-  double *pdoubleatt;
-
-  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
-
-  if ( (int)nc_attlen > attlen )
-    pdoubleatt = (double *) malloc(nc_attlen * sizeof (double));
-  else
-    pdoubleatt = attdouble;
-
-  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
-
-  if ( (int)nc_attlen > attlen )
+  else if ( gridtype == GRID_SPECTRAL || gridtype == GRID_FOURIER )
     {
-      memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
-      free(pdoubleatt);
+      int gridTruncation = gridInqTrunc(gridID);
+
+      axis[iax++] = '-';
+      axis[iax++] = '-';
+      cdf_put_att_text(fileID, ncvarid, "axis", iax, axis);
+      cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1, &gridTruncation);
     }
-}
 
-static
-void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *atttext)
-{
-  nc_type atttype;
-  size_t nc_attlen;
+  /*  if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) */
+    {
+      int laddoffset, lscalefactor;
+      double addoffset, scalefactor;
+      int astype = NC_DOUBLE;
 
-  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
-  cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
+      addoffset    = vlistInqVarAddoffset(vlistID, varID);
+      scalefactor  = vlistInqVarScalefactor(vlistID, varID);
+      laddoffset   = IS_NOT_EQUAL(addoffset, 0);
+      lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
 
-  if ( atttype == NC_CHAR )
-    {
-      char attbuf[65636];
-      if ( nc_attlen < sizeof(attbuf) )
+      if ( laddoffset || lscalefactor )
         {
-          cdf_get_att_text(fileID, ncvarid, attname, attbuf);
+          if ( IS_EQUAL(addoffset,   (double) ((float) addoffset)) &&
+               IS_EQUAL(scalefactor, (double) ((float) scalefactor)) )
+            {
+              astype = NC_FLOAT;
+            }
 
-          attbuf[nc_attlen++] = 0;
+          if ( xtype == (int) NC_FLOAT ) astype = NC_FLOAT;
 
-          if ( (int) nc_attlen > attlen ) nc_attlen = (size_t)attlen;
-          memcpy(atttext, attbuf, nc_attlen);
-        }
-      else
-        {
-          atttext[0] = 0;
+          cdf_put_att_double(fileID, ncvarid, "add_offset",   (nc_type) astype, 1, &addoffset);
+          cdf_put_att_double(fileID, ncvarid, "scale_factor", (nc_type) astype, 1, &scalefactor);
         }
     }
-#if  defined  (HAVE_NETCDF4)
-  else if ( atttype == NC_STRING )
+
+  if ( dtype == DATATYPE_UINT8 && xtype == NC_BYTE )
     {
-      if ( nc_attlen == 1 )
-        {
-          char *attbuf = NULL;
-          cdf_get_att_string(fileID, ncvarid, attname, &attbuf);
+      int validrange[2] = {0, 255};
+      cdf_put_att_int(fileID, ncvarid, "valid_range", NC_SHORT, 2, validrange);
+      cdf_put_att_text(fileID, ncvarid, "_Unsigned", 4, "true");
+    }
 
-          size_t ssize = strlen(attbuf) + 1;
+  streamptr->vars[varID].ncvarid = ncvarid;
 
-          if ( ssize > (size_t)attlen ) ssize = (size_t)attlen;
-          memcpy(atttext, attbuf, ssize);
-          atttext[ssize - 1] = 0;
-          free(attbuf);
-        }
-      else
+  if ( vlistInqVarMissvalUsed(vlistID, varID) )
+    cdfDefVarMissval(streamptr, varID, vlistInqVarDatatype(vlistID, varID), 0);
+
+  if ( zid == -1 )
+    {
+      if ( zaxisInqType(zaxisID) == ZAXIS_CLOUD_BASE          ||
+           zaxisInqType(zaxisID) == ZAXIS_CLOUD_TOP           ||
+           zaxisInqType(zaxisID) == ZAXIS_ISOTHERM_ZERO       ||
+           zaxisInqType(zaxisID) == ZAXIS_TOA                 ||
+           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM          ||
+           zaxisInqType(zaxisID) == ZAXIS_LAKE_BOTTOM         ||
+           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM     ||
+           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM_TA  ||
+           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM_TW  ||
+           zaxisInqType(zaxisID) == ZAXIS_MIX_LAYER           ||
+           zaxisInqType(zaxisID) == ZAXIS_ATMOSPHERE )
         {
-          atttext[0] = 0;
+          zaxisInqName(zaxisID, varname);
+          cdf_put_att_text(fileID, ncvarid, "level_type", strlen(varname), varname);
         }
     }
-#endif
-}
 
-static
-int xtypeIsText(int xtype)
-{
-  int isText = FALSE;
+  if ( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
+    {
+      /* void cdf_put_att_int(  int ncid, int varid, const char *name, nc_type xtype,
+	                        size_t len, const int *ip )
+       */
+	cdf_put_att_int(fileID, ncvarid, "realization", NC_INT, 1, &ensID);
+	cdf_put_att_int(fileID, ncvarid, "ensemble_members", NC_INT, 1, &ensCount);
+	cdf_put_att_int(fileID, ncvarid, "forecast_init_type", NC_INT, 1, &forecast_type);
 
-  if ( xtype == NC_CHAR )
-    isText = TRUE;
-#if  defined  (HAVE_NETCDF4)
-  else if ( xtype == NC_STRING )
-    isText = TRUE;
+#ifdef DBG
+	if( DBG )
+	  {
+	    fprintf( stderr, "cdfDefVar :\n EnsID  %d\n Enscount %d\n Forecast init type %d\n",  ensID,
+		     ensCount,  forecast_type );
+	  }
 #endif
+    }
 
-  return (isText);
-}
-
-static
-int xtypeIsFloat(int xtype)
-{
-  int isFloat = FALSE;
+  /* Attributes */
+  defineAttributes(vlistID, varID, fileID, ncvarid);
 
-  if ( xtype == NC_FLOAT || xtype == NC_DOUBLE ) isFloat = TRUE;
+  /* if ( streamptr->ncmode == 2 ) cdf_enddef(fileID); */
 
-  return isFloat;
+  return (ncvarid);
 }
 
 static
-int cdfInqDatatype(int xtype, int lunsigned)
+void scale_add(size_t size, double *data, double addoffset, double scalefactor)
 {
-  int datatype = -1;
-
-#if  defined  (HAVE_NETCDF4)
-  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
-#endif
+  int laddoffset;
+  int lscalefactor;
 
-  if      ( xtype == NC_BYTE   )  datatype = DATATYPE_INT8;
-  /* else if ( xtype == NC_CHAR   )  datatype = DATATYPE_UINT8; */
-  else if ( xtype == NC_SHORT  )  datatype = DATATYPE_INT16;
-  else if ( xtype == NC_INT    )  datatype = DATATYPE_INT32;
-  else if ( xtype == NC_FLOAT  )  datatype = DATATYPE_FLT32;
-  else if ( xtype == NC_DOUBLE )  datatype = DATATYPE_FLT64;
-#if  defined  (HAVE_NETCDF4)
-  else if ( xtype == NC_UBYTE  )  datatype = DATATYPE_UINT8;
-  else if ( xtype == NC_LONG   )  datatype = DATATYPE_INT32;
-  else if ( xtype == NC_USHORT )  datatype = DATATYPE_UINT16;
-  else if ( xtype == NC_UINT   )  datatype = DATATYPE_UINT32;
-  else if ( xtype == NC_INT64  )  datatype = DATATYPE_FLT64;
-  else if ( xtype == NC_UINT64 )  datatype = DATATYPE_FLT64;
-#endif
+  laddoffset   = IS_NOT_EQUAL(addoffset, 0);
+  lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
 
-  return (datatype);
+  if ( laddoffset || lscalefactor )
+    {
+      for (size_t i = 0; i < size; ++i )
+        {
+          if ( lscalefactor ) data[i] *= scalefactor;
+          if ( laddoffset )   data[i] += addoffset;
+        }
+    }
 }
 
 static
-int cdfDefDatatype(int datatype, int filetype)
+void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], size_t (*count)[4])
 {
-  int xtype;
+  int vlistID = streamptr->vlistID;
+  int tsID = streamptr->curTsID;
+  int gridID    = vlistInqVarGrid(vlistID, varID);
+  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  int gridindex = vlistGridIndex(vlistID, gridID);
 
-  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
-    Error("CDI/netCDF library does not support complex numbers!");
+  if ( CDI_Debug ) Message("tsID = %d", tsID);
 
-  if ( filetype == FILETYPE_NC4 )
+  int xid = UNDEFID, yid = UNDEFID;
+  if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
-      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
-      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
-#if  defined  (HAVE_NETCDF4)
-      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_UBYTE;
-      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_USHORT;
-      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_UINT;
-#else
-      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
-      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
-      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
-#endif
-      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
-      else                                    xtype = NC_FLOAT;
+      cdfReadGridTraj(streamptr, gridID);
     }
   else
     {
-      if      ( datatype == DATATYPE_INT8   ) xtype = NC_BYTE;
-      else if ( datatype == DATATYPE_INT16  ) xtype = NC_SHORT;
-      else if ( datatype == DATATYPE_INT32  ) xtype = NC_INT;
-      else if ( datatype == DATATYPE_UINT8  ) xtype = NC_SHORT;
-      else if ( datatype == DATATYPE_UINT16 ) xtype = NC_INT;
-      else if ( datatype == DATATYPE_UINT32 ) xtype = NC_INT;
-      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
-      else                                    xtype = NC_FLOAT;
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
+  int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+  int zid = streamptr->zaxisID[zaxisindex];
 
-  return (xtype);
-}
+  int ndims = 0;
+#define addDimension(startCoord, length) do \
+    { \
+      (*start)[ndims] = startCoord; \
+      (*count)[ndims] = length; \
+      ndims++; \
+    } while(0)
+  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
+  if ( zid != UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
+  if ( yid != UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
+  if ( xid != UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
+#undef addDimension
 
-static inline void *
-resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
-{
-  if (reqSize > *bufSize)
-    {
-      *buf = xrealloc(*buf, reqSize);
-      *bufSize = reqSize;
-    }
-  return *buf;
+  assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
+  assert(ndims <= (int)(sizeof(*count)/sizeof(**count)));
+
+  if ( CDI_Debug )
+    for (int idim = 0; idim < ndims; idim++)
+      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 }
 
+//Scans the data array for missVals, optionally applying first a scale factor and then an offset.
+//Returns the number of missing + out-of-range values encountered.
 static
-void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
-{
-  int natts, iatt;
-  int atttype, attlen;
-  size_t len;
-  char attname[CDI_MAX_NAME+1];
-  void *attBuf = NULL;
-  size_t attBufSize = 0;
-
-  vlistInqNatts(vlistID, varID, &natts);
+size_t cdfDoInputDataTransformationDP(size_t valueCount, double *data, bool haveMissVal, double missVal, double scaleFactor, double offset, double validMin, double validMax)
+ {
+  const bool haveOffset   = IS_NOT_EQUAL(offset, 0);
+  const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
+  size_t missValCount = 0;
 
-  for ( iatt = 0; iatt < natts; iatt++ )
-    {
-      vlistInqAtt(vlistID, varID, iatt, attname, &atttype, &attlen);
+  if ( IS_EQUAL(validMin, VALIDMISS) ) validMin = DBL_MIN;
+  if ( IS_EQUAL(validMax, VALIDMISS) ) validMax = DBL_MAX;
 
-      if ( attlen == 0 ) continue;
+  bool haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin,DBL_MIN));
+  assert(!haveRangeCheck || haveMissVal);
 
-      if ( atttype == DATATYPE_TXT )
+  switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
+          | ((int)haveOffset << 2) | ((int)haveRangeCheck << 3))
+    {
+    case 15: /* haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
         {
-          size_t attSize = (size_t)attlen*sizeof(char);
-          char *atttxt = (char *)resizeBuf(&attBuf, &attBufSize, attSize);
-          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
-          len = (size_t)attlen;
-          cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? missVal
+            : isMissVal ? data[i] : data[i] * scaleFactor + offset;
         }
-      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
+      break;
+    case 13: /* haveRangeCheck & haveMissVal & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
         {
-          size_t attSize = (size_t)attlen*sizeof(int);
-          int *attint = (int *)resizeBuf(&attBuf, &attBufSize, attSize);
-          vlistInqAttInt(vlistID, varID, attname, attlen, &attint[0]);
-          len = (size_t)attlen;
-          cdf_put_att_int(fileID, ncvarID, attname, atttype == DATATYPE_INT16 ? NC_SHORT : NC_INT, len, attint);
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? missVal
+            : isMissVal ? data[i] : data[i] + offset;
         }
-      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
+      break;
+    case 11: /* haveRangeCheck & haveMissVal & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
         {
-          size_t attSize = (size_t)attlen * sizeof(double);
-          double *attflt = (double *)resizeBuf(&attBuf, &attBufSize, attSize);
-          vlistInqAttFlt(vlistID, varID, attname, attlen, attflt);
-          len = (size_t)attlen;
-          cdf_put_att_double(fileID, ncvarID, attname, atttype == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE, len, attflt);
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? missVal
+            : isMissVal ? data[i] : data[i] * scaleFactor;
         }
-    }
-  free(attBuf);
-}
-
-void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
-{
-  int memtype  = MEMTYPE_DOUBLE;
-  int vlistID1 = streamptr1->vlistID;
-  int tsID1    = streamptr1->curTsID;
-  int recID1   = streamptr1->tsteps[tsID1].curRecID;
-  int ivarID   = streamptr1->tsteps[tsID1].records[recID1].varID;
-  int gridID   = vlistInqVarGrid(vlistID1, ivarID);
-  int datasize = gridInqSize(gridID);
-
-  double *data = xmalloc((size_t)datasize * sizeof (double));
-
-  int nmiss;
-  cdfReadRecord(streamptr1, data, &nmiss);
-  cdf_write_record(streamptr2, memtype, data, nmiss);
-
-  free(data);
-}
-
-/* not used
-int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
-{
-  int tsID, recID;
-
-  recID = streamptr->tsteps[0].curRecID++;
-  printf("cdfInqRecord recID %d %d\n", recID, streamptr->tsteps[0].curRecID);
-  printf("cdfInqRecord tsID %d\n", streamptr->curTsID);
-
-  if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
-    {
-      streamptr->tsteps[0].curRecID = 0;
+      break;
+    case 9: /* haveRangeCheck & haveMissVal */
+      for ( size_t i = 0; i < valueCount; i++ )
+        {
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? missVal : data[i];
+        }
+      break;
+    case 7: /* haveMissVal & haveScaleFactor & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] = data[i] * scaleFactor + offset;
+      break;
+    case 6: /* haveOffset & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] = data[i] * scaleFactor + offset;
+      break;
+    case 5: /* haveMissVal & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] += offset;
+      break;
+    case 4: /* haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] += offset;
+      break;
+    case 3: /* haveMissVal & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] *= scaleFactor;
+      break;
+    case 2: /* haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] *= scaleFactor;
+      break;
+    case 1: /* haveMissVal */
+      for ( size_t i = 0; i < valueCount; i++ )
+        missValCount += (unsigned)DBL_IS_EQUAL(data[i], missVal);
+      break;
     }
 
-  *varID   = streamptr->tsteps[0].records[recID].varID;
-  *levelID = streamptr->tsteps[0].records[recID].levelID;
-
-  streamptr->record->varID   = *varID;
-  streamptr->record->levelID = *levelID;
-
-  if ( CDI_Debug )
-    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
-
-  return (recID+1);
-}
-*/
-
-
-void cdfDefRecord(stream_t *streamptr)
-{
-  (void)streamptr;
+  return missValCount;
 }
 
-
 static
-void cdfWriteGridTraj(stream_t *streamptr, int gridID)
-{
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+size_t cdfDoInputDataTransformationSP(size_t valueCount, float *data, bool haveMissVal, double missVal, double scaleFactor, double offset, double validMin, double validMax)
+ {
+  const bool haveOffset   = IS_NOT_EQUAL(offset, 0);
+  const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
+  size_t missValCount = 0;
 
-  int gridindex = vlistGridIndex(vlistID, gridID);
-  int lonID = streamptr->xdimID[gridindex],
-    latID = streamptr->ydimID[gridindex];
+  if ( IS_EQUAL(validMin, VALIDMISS) ) validMin = DBL_MIN;
+  if ( IS_EQUAL(validMax, VALIDMISS) ) validMax = DBL_MAX;
 
-  double xlon = gridInqXval(gridID, 0),
-    xlat = gridInqYval(gridID, 0);
-  int tsID = streamptr->curTsID;
-  size_t index = (size_t)tsID;
+  bool haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin,DBL_MIN));
+  assert(!haveRangeCheck || haveMissVal);
+
+  switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
+          | ((int)haveOffset << 2) | ((int)haveRangeCheck << 3))
+    {
+    case 15: /* haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        {
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? (float)missVal
+            : isMissVal ? data[i] : (float)(data[i] * scaleFactor + offset);
+        }
+      break;
+    case 13: /* haveRangeCheck & haveMissVal & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        {
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? (float)missVal
+            : isMissVal ? data[i] : (float)(data[i] + offset);
+        }
+      break;
+    case 11: /* haveRangeCheck & haveMissVal & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        {
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? (float)missVal
+            : isMissVal ? data[i] : (float)(data[i] * scaleFactor);
+        }
+      break;
+    case 9: /* haveRangeCheck & haveMissVal */
+      for ( size_t i = 0; i < valueCount; i++ )
+        {
+          int outOfRange = data[i] < validMin || data[i] > validMax;
+          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
+          missValCount += (size_t)(outOfRange | isMissVal);
+          data[i] = outOfRange ? (float)missVal : data[i];
+        }
+      break;
+    case 7: /* haveMissVal & haveScaleFactor & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] = (float)(data[i] * scaleFactor + offset);
+      break;
+    case 6: /* haveOffset & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] = (float)(data[i] * scaleFactor + offset);
+      break;
+    case 5: /* haveMissVal & haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] = (float)(data[i] + offset);
+      break;
+    case 4: /* haveOffset */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] = (float)(data[i] + offset);
+      break;
+    case 3: /* haveMissVal & haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        if ( DBL_IS_EQUAL(data[i], missVal) )
+          missValCount++;
+        else
+          data[i] = (float)(data[i] * scaleFactor);
+      break;
+    case 2: /* haveScaleFactor */
+      for ( size_t i = 0; i < valueCount; i++ )
+        data[i] = (float)(data[i] * scaleFactor);
+      break;
+    case 1: /* haveMissVal */
+      for ( size_t i = 0; i < valueCount; i++ )
+        missValCount += (unsigned)DBL_IS_EQUAL(data[i], missVal);
+      break;
+    }
 
-  cdf_put_var1_double(fileID, lonID, &index, &xlon);
-  cdf_put_var1_double(fileID, latID, &index, &xlat);
+  return missValCount;
 }
 
-static
-void cdfReadGridTraj(stream_t *streamptr, int gridID)
+static void
+cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, long nvals, size_t xsize, size_t ysize, int swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
 {
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  const double *pdata_dp = (const double *) data;
+  double *mdata_dp = NULL;
+  double *sdata_dp = NULL;
+  const float *pdata_sp = (const float *) data;
+  float *mdata_sp = NULL;
+  float *sdata_sp = NULL;
+  extern int CDF_Debug;
 
-  int gridindex = vlistGridIndex(vlistID, gridID);
-  int lonID = streamptr->xdimID[gridindex];
-  int latID = streamptr->ydimID[gridindex];
+  /*  if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
+    {
+      bool laddoffset, lscalefactor;
+      double addoffset, scalefactor;
+      double missval;
 
-  int tsID = streamptr->curTsID;
-  size_t index = (size_t)tsID;
+      addoffset    = vlistInqVarAddoffset(vlistID, varID);
+      scalefactor  = vlistInqVarScalefactor(vlistID, varID);
+      laddoffset   = IS_NOT_EQUAL(addoffset, 0);
+      lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
 
-  double xlon, xlat;
-  cdf_get_var1_double(fileID, lonID, &index, &xlon);
-  cdf_get_var1_double(fileID, latID, &index, &xlat);
+      missval      = vlistInqVarMissval(vlistID, varID);
 
-  gridDefXvals(gridID, &xlon);
-  gridDefYvals(gridID, &xlat);
-}
+      if ( laddoffset || lscalefactor )
+        {
+          if ( memtype == MEMTYPE_FLOAT )
+            {
+              mdata_sp = (float *) malloc((size_t)nvals*sizeof(float));
+              memcpy(mdata_sp, pdata_sp, (size_t)nvals * sizeof (float));
+              pdata_sp = mdata_sp;
 
+              if ( nmiss > 0 )
+                {
+                  for (long i = 0; i < nvals; i++ )
+                    {
+                      double temp = mdata_sp[i];
+                      if ( !DBL_IS_EQUAL(temp, missval) )
+                        {
+                          if ( laddoffset )   temp -= addoffset;
+                          if ( lscalefactor ) temp /= scalefactor;
+                          mdata_sp[i] = (float)temp;
+                        }
+                    }
+                }
+              else
+                {
+                  for (long i = 0; i < nvals; i++ )
+                    {
+                      double temp = mdata_sp[i];
+                      if ( laddoffset )   temp -= addoffset;
+                      if ( lscalefactor ) temp /= scalefactor;
+                      mdata_sp[i] = (float)temp;
+                    }
+                }
+            }
+          else
+            {
+              mdata_dp = (double *) malloc((size_t)nvals * sizeof(double));
+              memcpy(mdata_dp, pdata_dp, (size_t)nvals * sizeof(double));
+              pdata_dp = mdata_dp;
 
-static
-void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
-{
-#if  defined  (HAVE_NETCDF4)
-  int retval;
-  /* Set chunking, shuffle, and deflate. */
-  int shuffle = 1;
-  int deflate = 1;
+              if ( nmiss > 0 )
+                {
+                  for (long i = 0; i < nvals; i++ )
+                    {
+                      if ( !DBL_IS_EQUAL(mdata_dp[i], missval) )
+                        {
+                          if ( laddoffset )   mdata_dp[i] -= addoffset;
+                          if ( lscalefactor ) mdata_dp[i] /= scalefactor;
+                        }
+                    }
+                }
+              else
+                {
+                  for (long i = 0; i < nvals; i++ )
+                    {
+                      if ( laddoffset )   mdata_dp[i] -= addoffset;
+                      if ( lscalefactor ) mdata_dp[i] /= scalefactor;
+                    }
+                }
+            }
+        }
 
-  if ( deflate_level < 1 || deflate_level > 9 ) deflate_level = 1;
+      if ( dtype == DATATYPE_UINT8 || dtype == DATATYPE_INT8 ||
+           dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 )
+        {
+          if ( memtype == MEMTYPE_FLOAT )
+            {
+              if ( mdata_sp == NULL )
+                {
+                  mdata_sp = (float *) malloc((size_t)nvals * sizeof(float));
+                  memcpy(mdata_sp, pdata_sp, (size_t)nvals * sizeof(float));
+                  pdata_sp = mdata_sp;
+                }
 
-  if ((retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)))
-    {
-      Error("nc_def_var_deflate failed, status = %d", retval);
-    }
-#else
-  static int lwarn = TRUE;
+              for (long i = 0; i < nvals; i++ ) mdata_sp[i] = roundf(mdata_sp[i]);
 
-  if ( lwarn )
-    {
-      lwarn = FALSE;
-      Warning("Deflate compression failed, netCDF4 not available!");
-    }
-#endif
-}
+              if ( dtype == DATATYPE_UINT8 )
+                {
+                  nc_type xtype;
+                  cdf_inq_vartype(fileID, ncvarid, &xtype);
+                  if ( xtype == NC_BYTE )
+                    {
+                      for ( long i = 0; i < nvals; ++i )
+                        if ( mdata_sp[i] > 127 ) mdata_sp[i] -= 256;
+                    }
+                }
+            }
+          else
+            {
+              if ( mdata_dp == NULL )
+                {
+                  mdata_dp = (double *) malloc((size_t)nvals * sizeof (double));
+                  memcpy(mdata_dp, pdata_dp, (size_t)nvals * sizeof (double));
+                  pdata_dp = mdata_dp;
+                }
 
+              for (long i = 0; i < nvals; i++ ) mdata_dp[i] = round(mdata_dp[i]);
 
-#if defined(NC_SZIP_NN_OPTION_MASK)
-static
-void cdfDefVarSzip(int ncid, int ncvarid)
-{
-  int retval;
-  /* Set options_mask and bits_per_pixel. */
-  int options_mask = NC_SZIP_NN_OPTION_MASK;
-  int bits_per_pixel = 16;
+              if ( dtype == DATATYPE_UINT8 )
+                {
+                  nc_type xtype;
+                  cdf_inq_vartype(fileID, ncvarid, &xtype);
+                  if ( xtype == NC_BYTE )
+                    {
+                      for (long i = 0; i < nvals; ++i )
+                        if ( mdata_dp[i] > 127 ) mdata_dp[i] -= 256;
+                    }
+                }
+            }
+        }
 
-  if ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
-    {
-      if ( retval == NC_EINVAL )
+      if ( CDF_Debug && memtype != MEMTYPE_FLOAT )
         {
-          static int lwarn = TRUE;
-
-          if ( lwarn )
+          double fmin, fmax;
+          fmin =  1.0e200;
+          fmax = -1.0e200;
+          for ( long i = 0; i < nvals; ++i )
             {
-              lwarn = FALSE;
-              Warning("netCDF4/Szip compression not compiled in!");
+              if ( !DBL_IS_EQUAL(pdata_dp[i], missval) )
+                {
+                  if ( pdata_dp[i] < fmin ) fmin = pdata_dp[i];
+                  if ( pdata_dp[i] > fmax ) fmax = pdata_dp[i];
+                }
             }
+          Message("nvals = %d, nmiss = %d, missval = %g, minval = %g, maxval = %g",
+                  nvals, nmiss, missval, fmin, fmax);
         }
-      else
-        Error("nc_def_var_szip failed, status = %d", retval);
     }
-}
-#endif
 
-static
-void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
-{
-  if ( streamptr->vars[varID].defmiss == FALSE )
+  if ( swapxy )
     {
-      int fileID;
-      int ncvarid;
-      double missval;
-      int vlistID;
-      int xtype;
-
-      vlistID = streamptr->vlistID;
-      fileID  = streamptr->fileID;
-      ncvarid = streamptr->vars[varID].ncvarid;
-      missval = vlistInqVarMissval(vlistID, varID);
-
-      if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-      xtype = cdfDefDatatype(dtype, streamptr->filetype);
-
-      if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
-
-      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
-      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
+      if ( memtype == MEMTYPE_FLOAT )
+        {
+          /* malloc and the loop imply nvals >= ysize * xsize,
+           * but that is not checked and the types don't match */
+          sdata_sp = (float *)xmalloc((size_t)nvals * sizeof (float));
+          for ( size_t j = 0; j < ysize; ++j )
+            for ( size_t i = 0; i < xsize; ++i )
+              sdata_sp[i*ysize+j] = pdata_sp[j*xsize+i];
+          pdata_sp = sdata_sp;
+        }
+      else
+        {
+          sdata_dp = (double *)xmalloc((size_t)nvals * sizeof (double));
+          for ( size_t j = 0; j < ysize; ++j )
+            for ( size_t i = 0; i < xsize; ++i )
+              sdata_dp[i*ysize+j] = pdata_dp[j*xsize+i];
+          pdata_dp = sdata_dp;
+        }
+    }
 
-      if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
+  if ( memtype == MEMTYPE_FLOAT )
+    cdf_put_vara_float(fileID, ncvarid, start, count, pdata_sp);
+  else
+    cdf_put_vara_double(fileID, ncvarid, start, count, pdata_dp);
 
-      streamptr->vars[varID].defmiss = TRUE;
-    }
+  if ( mdata_dp ) free(mdata_dp);
+  if ( sdata_dp ) free(sdata_dp);
+  if ( mdata_sp ) free(mdata_sp);
+  if ( sdata_sp ) free(sdata_sp);
 }
 
 
-void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
-  int varID;
-  int levelID;
-
-  varID   = streamptr->record->varID;
-  levelID = streamptr->record->levelID;
+  int fileID;
+  int gridID;
+  int zaxisID;
+  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
+  int ncvarid;
+  size_t xsize = 0, ysize = 0;
+  size_t size;
+  size_t start[5];
+  size_t count[5];
+  long nvals;
+  int swapxy = FALSE;
+  int ndims = 0;
+  int idim;
+  int tsteptype;
+  int gridindex, zaxisindex;
+  int dtype;
+  int vlistID;
 
   if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
-}
-
-void cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
-{
-  if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
-
-  int tsID    = streamptr->curTsID;
-  int vrecID  = streamptr->tsteps[tsID].curRecID;
-  int recID   = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID   = streamptr->tsteps[tsID].records[recID].varID;
-  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
-}
+  long ntsteps = streamptr->ntsteps;
+  if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
 
-static
-void cdfDefTimeValue(stream_t *streamptr, int tsID)
-{
-  int fileID = streamptr->fileID;
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+  ncvarid = cdfDefVar(streamptr, varID);
 
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  gridID    = vlistInqVarGrid(vlistID, varID);
+  zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  tsteptype = vlistInqVarTsteptype(vlistID, varID);
 
-  if ( streamptr->ncmode == 1 )
+  gridindex = vlistGridIndex(vlistID, gridID);
+  if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      cdfWriteGridTraj(streamptr, gridID);
     }
-
-  size_t index = (size_t)tsID;
-
-  double timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
-  if ( CDI_Debug ) Message("tsID = %d  timevalue = %f", tsID, timevalue);
-
-  int ncvarid = streamptr->basetime.ncvarid;
-  cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
-
-  if ( taxis->has_bounds )
+  else
     {
-      size_t start[2], count[2];
-
-      ncvarid = streamptr->basetime.ncvarboundsid;
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
+    }
 
-      timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
-      start[0] = (size_t)tsID; count[0] = 1; start[1] = 0; count[1] = 1;
-      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+  zid = streamptr->zaxisID[zaxisindex];
 
-      timevalue = cdiEncodeTimeval(taxis->vdate_ub, taxis->vtime_ub, &streamptr->tsteps[0].taxis);
-      start[0] = (size_t)tsID; count[0] = 1; start[1] = 1; count[1] = 1;
-      cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
+  if ( tsteptype != TSTEP_CONSTANT )
+    {
+      start[ndims] = (size_t)ntsteps - 1;
+      count[ndims] = 1;
+      ndims++;
     }
-
-  ncvarid = streamptr->basetime.leadtimeid;
-  if ( taxis->type == TAXIS_FORECAST && ncvarid != UNDEFID )
+  if ( zid != UNDEFID )
     {
-      timevalue = taxis->fc_period;
-      cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+      start[ndims] = 0;
+      count[ndims] = (size_t)zaxisInqSize(zaxisID);
+      ndims++;
     }
-
-  /*
-printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
-  */
-}
-
-static
-int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, char* taxis_name, taxis_t* taxis)
-{
-  int time_bndsid = -1;
-  int dims[2];
-  char tmpstr[CDI_MAX_NAME];
-
-  dims[0] = nctimedimid;
-
-  /* fprintf(stderr, "time has bounds\n"); */
-
-  if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
-    cdf_def_dim(fileID, "nb2", 2, &dims[1]);
-
-  if ( taxis->climatology )
+  if ( yid != UNDEFID )
     {
-      strcpy(tmpstr, "climatology");
-      strcat(tmpstr, "_bnds");
-      cdf_def_var(fileID, tmpstr, NC_DOUBLE, 2, dims, &time_bndsid);
-
-      cdf_put_att_text(fileID, nctimevarid, "climatology", strlen(tmpstr), tmpstr);
+      start[ndims] = 0;
+      cdf_inq_dimlen(fileID, yid, &size);
+      /*      count[ndims] = gridInqYsize(gridID); */
+      count[ndims] = size;
+      ndims++;
     }
-  else
+  if ( xid != UNDEFID )
     {
-      strcpy(tmpstr, taxis_name);
-      strcat(tmpstr, "_bnds");
-      cdf_def_var(fileID, tmpstr, NC_DOUBLE, 2, dims, &time_bndsid);
-
-      cdf_put_att_text(fileID, nctimevarid, "bounds", strlen(tmpstr), tmpstr);
+      start[ndims] = 0;
+      cdf_inq_dimlen(fileID, xid, &size);
+      /*      count[ndims] = gridInqXsize(gridID); */
+      count[ndims] = size;
+      ndims++;
     }
 
-  return (time_bndsid);
-}
-
-static
-void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
-{
-  unitstr[0] = 0;
+  if ( CDI_Debug )
+    for (idim = 0; idim < ndims; idim++)
+      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
-  if ( taxis0->type == TAXIS_ABSOLUTE )
+  if ( streamptr->ncmode == 1 )
     {
-      if ( taxis0->unit == TUNIT_YEAR )
-        sprintf(unitstr, "year as %s", "%Y.%f");
-      else if ( taxis0->unit == TUNIT_MONTH )
-        sprintf(unitstr, "month as %s", "%Y%m.%f");
-      else
-        sprintf(unitstr, "day as %s", "%Y%m%d.%f");
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
-  else
-    {
-      int year, month, day, hour, minute, second;
-      int rdate, rtime;
-      int timeunit;
-
-      timeunit = taxis->unit;
-      if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
-      rdate    = taxis->rdate;
-      rtime    = taxis->rtime;
-      if ( rdate == -1 )
-        {
-          rdate  = taxis->vdate;
-          rtime  = taxis->vtime;
-        }
-
-      cdiDecodeDate(rdate, &year, &month, &day);
-      cdiDecodeTime(rtime, &hour, &minute, &second);
-
-      if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
-      if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
-      if ( timeunit == TUNIT_3HOURS  ||
-	   timeunit == TUNIT_6HOURS  ||
-	   timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
 
-      sprintf(unitstr, "%s since %d-%02d-%02d %02d:%02d:%02d",
-              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
-    }
-}
+  dtype = vlistInqVarDatatype(vlistID, varID);
 
-static
-void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
-{
-  unitstr[0] = 0;
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
-  if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
+  nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
 
-  if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
-  if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
-  if ( timeunit == TUNIT_3HOURS  ||
-       timeunit == TUNIT_6HOURS  ||
-       timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
+  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
 
-  sprintf(unitstr, "%s", tunitNamePtr(timeunit));
 }
 
-static
-void cdfDefCalendar(int fileID, int ncvarid, int calendar)
-{
-  size_t len;
-  char calstr[80];
-
-  calstr[0] = 0;
-
-  if      ( calendar == CALENDAR_STANDARD )  strcpy(calstr, "standard");
-  else if ( calendar == CALENDAR_PROLEPTIC ) strcpy(calstr, "proleptic_gregorian");
-  else if ( calendar == CALENDAR_NONE )      strcpy(calstr, "none");
-  else if ( calendar == CALENDAR_360DAYS )   strcpy(calstr, "360_day");
-  else if ( calendar == CALENDAR_365DAYS )   strcpy(calstr, "365_day");
-  else if ( calendar == CALENDAR_366DAYS )   strcpy(calstr, "366_day");
-
-  len = strlen(calstr);
-
-  if ( len ) cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
-}
 
-static
-void cdfDefTime(stream_t* streamptr)
+void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
+                         const int rect[][2], const void *data, int nmiss)
 {
   int fileID;
-  int time_varid;
-  int time_dimid;
-  int time_bndsid = -1;
-  char unitstr[CDI_MAX_NAME];
-  char tmpstr[CDI_MAX_NAME];
-  char default_name[] = "time";
-  char* taxis_name = default_name;
-  size_t len;
-  taxis_t* taxis;
-
-  if ( streamptr->basetime.ncvarid != UNDEFID ) return;
-
-  fileID = streamptr->fileID;
-
-  if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
-
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-  taxis = &streamptr->tsteps[0].taxis;
+  int gridID;
+  int zaxisID;
+  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
+  int ncvarid;
+  size_t xsize = 0, ysize = 0;
+  size_t start[5];
+  size_t count[5];
+  long nvals;
+  int swapxy = FALSE;
+  int ndims = 0;
+  int idim;
+  int tsteptype;
+  int gridindex, zaxisindex;
+  int dtype;
+  int vlistID;
+  int streamID = streamptr->self;
 
-  if ( taxis->name && taxis->name[0] ) taxis_name = taxis->name;
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d", streamID, varID);
 
-  cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
-  streamptr->basetime.ncdimid = time_dimid;
+  vlistID = streamInqVlist(streamID);
+  fileID  = streamInqFileID(streamID);
 
-  cdf_def_var(fileID, taxis_name, NC_DOUBLE, 1, &time_dimid, &time_varid);
+  long ntsteps = streamptr->ntsteps;
+  if ( CDI_Debug )
+    Message("ntsteps = %ld", ntsteps);
 
-  streamptr->basetime.ncvarid = time_varid;
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  strcpy(tmpstr, "time");
-  cdf_put_att_text(fileID, time_varid, "standard_name", strlen(tmpstr), tmpstr);
+  ncvarid = cdfDefVar(streamptr, varID);
 
-  if ( taxis->longname && taxis->longname[0] )
-    cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
+  gridID    = vlistInqVarGrid(vlistID, varID);
+  zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  tsteptype = vlistInqVarTsteptype(vlistID, varID);
 
-  if ( taxis->has_bounds )
+  gridindex = vlistGridIndex(vlistID, gridID);
+  if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
-      streamptr->basetime.ncvarboundsid = time_bndsid;
+      cdfWriteGridTraj(streamptr, gridID);
+    }
+  else
+    {
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
 
-  cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
+  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+  zid = streamptr->zaxisID[zaxisindex];
 
-  len = strlen(unitstr);
-  if ( len )
+  if ( tsteptype != TSTEP_CONSTANT )
     {
-      cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
-      /*
-      if ( taxis->has_bounds )
-        cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
-      */
+      start[ndims] = (size_t)ntsteps - 1;
+      count[ndims] = 1;
+      ndims++;
     }
-
-  if ( taxis->calendar != -1 )
+  if ( zid != UNDEFID )
     {
-      cdfDefCalendar(fileID, time_varid, taxis->calendar);
-      /*
-      if ( taxis->has_bounds )
-        cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
-      */
+      int size = zaxisInqSize(zaxisID);
+      xassert(rect[2][0] >= 0 && rect[2][0] <= rect[2][1]
+              && rect[2][1] <= size);
+      start[ndims] = (size_t)rect[2][0];
+      count[ndims] = (size_t)rect[2][1] - (size_t)rect[2][0] + 1;
+      ndims++;
     }
-
-  if ( taxis->type == TAXIS_FORECAST )
+  if ( yid != UNDEFID )
     {
-      int leadtimeid;
-
-      cdf_def_var(fileID, "leadtime", NC_DOUBLE, 1, &time_dimid, &leadtimeid);
+      size_t size;
+      cdf_inq_dimlen(fileID, yid, &size);
+      xassert(rect[1][0] >= 0 && rect[1][0] <= rect[1][1]
+              && (size_t)rect[1][1] <= size);
+      start[ndims] = (size_t)rect[1][0];
+      count[ndims] = (size_t)rect[1][1] - (size_t)rect[1][0] + 1;
+      ndims++;
+    }
+  if ( xid != UNDEFID )
+    {
+      size_t size;
+      cdf_inq_dimlen(fileID, xid, &size);
+      xassert(rect[0][0] >= 0 && rect[0][0] <= rect[0][1]
+              && (size_t)rect[0][1] <= size);
+      start[ndims] = (size_t)rect[0][0];
+      count[ndims] = (size_t)rect[0][1] - (size_t)rect[0][0] + 1;
+      ndims++;
+    }
 
-      streamptr->basetime.leadtimeid = leadtimeid;
+  if ( CDI_Debug )
+    for (idim = 0; idim < ndims; idim++)
+      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
-      strcpy(tmpstr, "forecast_period");
-      cdf_put_att_text(fileID, leadtimeid, "standard_name", strlen(tmpstr), tmpstr);
+  if ( streamptr->ncmode == 1 )
+    {
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-      strcpy(tmpstr, "Time elapsed since the start of the forecast");
-      cdf_put_att_text(fileID, leadtimeid, "long_name", strlen(tmpstr), tmpstr);
+  dtype = vlistInqVarDatatype(vlistID, varID);
 
-      cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
-      len = strlen(unitstr);
-      if ( len ) cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
-    }
+  nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
 
-  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals,
+                     xsize, ysize, swapxy, start, count, memtype, data, nmiss);
 }
 
-
-void cdfDefTimestep(stream_t *streamptr, int tsID)
+static
+size_t min_size(size_t a, size_t b)
 {
-  int vlistID = streamptr->vlistID;
-
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
-  cdfDefTimeValue(streamptr, tsID);
+  return a < b ? a : b;
 }
 
 static
-void cdfDefComplex(stream_t *streamptr, int gridID)
+void transpose2dArrayDP(size_t inWidth, size_t inHeight, double* data)
 {
-  char axisname[] = "nc2";
-  int dimID = UNDEFID;
-  int gridID0, gridtype0;
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-
-  int ngrids = vlistNgrids(vlistID);
-
-  for ( int index = 0; index < ngrids; index++ )
+  const size_t cacheBlockSize = 256;    // Purely an optimization parameter. Current value of 32 means we are handling 8kB blocks,
+                                       // which should be a decent compromise on many architectures.
+  double (*temp)[inWidth] = malloc(inHeight*sizeof(*temp));
+  double (*out)[inHeight] = (double (*)[inHeight])data;
+  memcpy(temp, data, inHeight*sizeof(*temp));
+  /*
+  for ( size_t y = 0; y < inHeight; ++y )
+    for ( size_t x = 0; x < inWidth; ++x )
+      out[x][y] = temp[y][x];
+  */
+  for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
     {
-      if ( streamptr->xdimID[index] != UNDEFID )
+      for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
         {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
+          for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
             {
-              dimID = streamptr->xdimID[index];
-              break;
+              for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
+                {
+                  out[x][y] = temp[y][x];
+                }
             }
         }
     }
 
-  if ( dimID == UNDEFID )
-    {
-      size_t dimlen = 2;
-
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
-
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
-
-  int gridindex = vlistGridIndex(vlistID, gridID);
-  streamptr->xdimID[gridindex] = dimID;
+  free(temp);
 }
 
-
 static
-void cdfDefSP(stream_t *streamptr, int gridID)
+void transpose2dArraySP(size_t inWidth, size_t inHeight, float* data)
 {
+  const size_t cacheBlockSize = 256;    // Purely an optimization parameter. Current value of 32 means we are handling 8kB blocks,
+                                       // which should be a decent compromise on many architectures.
+  float (*temp)[inWidth] = malloc(inHeight*sizeof(*temp));
+  float (*out)[inHeight] = (float (*)[inHeight])data;
+  memcpy(temp, data, inHeight*sizeof(*temp));
   /*
-  char longname[] = "Spherical harmonic coefficient";
+  for ( size_t y = 0; y < inHeight; ++y )
+    for ( size_t x = 0; x < inWidth; ++x )
+      out[x][y] = temp[y][x];
   */
-  char axisname[5] = "nspX";
-  int index, iz = 0;
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int ngrids;
-  int fileID;
-  int vlistID;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-
-  ngrids = vlistNgrids(vlistID);
-
-  size_t dimlen = (size_t)gridInqSize(gridID)/2;
-
-  for ( index = 0; index < ngrids; index++ )
+  for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
     {
-      if ( streamptr->ydimID[index] != UNDEFID )
+      for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
         {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_SPECTRAL )
+          for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
             {
-              size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
-              if ( dimlen == dimlen0 )
+              for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
                 {
-                  dimID = streamptr->ydimID[index];
-                  break;
+                  out[x][y] = temp[y][x];
                 }
-              else
-                iz++;
             }
         }
     }
 
-  if ( dimID == UNDEFID )
-    {
-      if ( iz == 0 ) axisname[3] = '\0';
-      else           sprintf(&axisname[3], "%1d", iz+1);
+  free(temp);
+}
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+static
+void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
+{
+  int gridId = vlistInqVarGrid(streamptr->vlistID, varId);
+  int gridindex = vlistGridIndex(streamptr->vlistID, gridId);
 
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = UNDEFID;
+  switch ( gridInqType(gridId) )
+    {
+      case GRID_TRAJECTORY:
+        cdfReadGridTraj(streamptr, gridId);
+        break;
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      case GRID_UNSTRUCTURED:
+        (*outDimIds)[0] = streamptr->xdimID[gridindex];
+        break;
+
+      default:
+        (*outDimIds)[0] = streamptr->xdimID[gridindex];
+        (*outDimIds)[1] = streamptr->ydimID[gridindex];
+        break;
     }
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  streamptr->ydimID[gridindex] = dimID;
+  int zaxisID = vlistInqVarZaxis(streamptr->vlistID, varId);
+  int zaxisindex = vlistZaxisIndex(streamptr->vlistID, zaxisID);
+  (*outDimIds)[2] = streamptr->zaxisID[zaxisindex];
 }
 
-
 static
-void cdfDefFC(stream_t *streamptr, int gridID)
+int cdfGetSkipDim(int fileId, int ncvarid, int (*dimIds)[3])
 {
-  char axisname[5] = "nfcX";
-  int index, iz = 0;
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int ngrids;
-  int fileID;
-  int vlistID;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-
-  ngrids = vlistNgrids(vlistID);
-
-  size_t dimlen = (size_t)gridInqSize(gridID)/2;
+  if((*dimIds)[0] != UNDEFID) return 0;
+  if((*dimIds)[1] != UNDEFID) return 0;
+  int nvdims;
+  cdf_inq_varndims(fileId, ncvarid, &nvdims);
+  if(nvdims != 3) return 0;
 
-  for ( index = 0; index < ngrids; index++ )
+  int varDimIds[3];
+  cdf_inq_vardimid(fileId, ncvarid, varDimIds);
+  size_t size = 0;
+  if ( (*dimIds)[2] == varDimIds[2] )
     {
-      if ( streamptr->ydimID[index] != UNDEFID )
-        {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_FOURIER )
-            {
-              size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
-              if ( dimlen == dimlen0 )
-                {
-                  dimID = streamptr->ydimID[index];
-                  break;
-                }
-              else
-                iz++;
-            }
-        }
+      cdf_inq_dimlen(fileId, varDimIds[1], &size);
+      if ( size == 1 ) return 1;
     }
-
-  if ( dimID == UNDEFID )
+  else if ( (*dimIds)[2] == varDimIds[1] )
     {
-      if ( iz == 0 ) axisname[3] = '\0';
-      else           sprintf(&axisname[3], "%1d", iz+1);
-
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
-
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      cdf_inq_dimlen(fileId, varDimIds[2], &size);
+      if ( size == 1 ) return 2;
     }
-
-  gridindex = vlistGridIndex(vlistID, gridID);
-  streamptr->ydimID[gridindex] = dimID;
+  return 0;
 }
 
 
 static
-void cdfDefTrajLon(stream_t *streamptr, int gridID)
+void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, bool *outSwapXY, size_t (*start)[4], size_t (*count)[4])
 {
-  char units[CDI_MAX_NAME];
-  char longname[CDI_MAX_NAME];
-  char stdname[CDI_MAX_NAME];
-  char axisname[CDI_MAX_NAME];
-  int gridtype, gridindex;
-  int dimID = UNDEFID;
-  int fileID;
-  int dimlen;
-  size_t len;
-  int ncvarid;
-  int vlistID;
-  int xtype = NC_DOUBLE;
-
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
-
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-
-  gridtype = gridInqType(gridID);
-  dimlen = gridInqXsize(gridID);
-  if ( dimlen != 1 ) Error("Xsize isn't 1 for %s grid!", gridNamePtr(gridtype));
-
-  gridindex = vlistGridIndex(vlistID, gridID);
-  ncvarid = streamptr->xdimID[gridindex];
-
-  gridInqXname(gridID, axisname);
-  gridInqXlongname(gridID, longname);
-  gridInqXstdname(gridID, stdname);
-  gridInqXunits(gridID, units);
+  int tsID = streamptr->curTsID;
+  if ( CDI_Debug ) Message("tsID = %d", tsID);
 
-  if ( ncvarid == UNDEFID )
-    {
-      dimID = streamptr->basetime.ncvarid;
+  int fileId = streamptr->fileID;
+  int vlistId = streamptr->vlistID;
+  int ncvarid = streamptr->vars[varId].ncvarid;
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+  int gridId = vlistInqVarGrid(vlistId, varId);
+  int tsteptype = vlistInqVarTsteptype(vlistId, varId);
+  int gridsize = gridInqSize(gridId);
 
-      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
+  streamptr->numvals += gridsize;
 
-      if ( (len = strlen(stdname)) )
-        cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
-      if ( (len = strlen(longname)) )
-        cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
-      if ( (len = strlen(units)) )
-        cdf_put_att_text(fileID, ncvarid, "units", len, units);
+  int dimIds[3];    //this array joins the old variables xid, yid, and zid
+  cdfInqDimIds(streamptr, varId, &dimIds);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
+  int skipdim = cdfGetSkipDim(fileId, ncvarid, &dimIds);
 
-  streamptr->xdimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
-}
+  int dimorder[3];
+  vlistInqVarDimorder(vlistId, varId, &dimorder);
 
+  *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != UNDEFID && dimIds[1] != UNDEFID ;
 
-static
-void cdfDefTrajLat(stream_t *streamptr, int gridID)
-{
-  char units[] = "degrees_north";
-  char longname[] = "latitude";
-  char stdname[] = "latitude";
-  char axisname[] = "tlat";
-  int gridtype, gridindex;
-  int dimID = UNDEFID;
-  int fileID;
-  int dimlen;
-  size_t len;
-  int ncvarid;
-  int vlistID;
-  int xtype = NC_DOUBLE;
+  int ndims = 0;
 
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+#define addDimension(startIndex, extent) do {   \
+      (*start)[ndims] = startIndex; \
+      (*count)[ndims] = extent; \
+      ndims++; \
+  } while(0)
 
-  vlistID = streamptr->vlistID;
-  fileID = streamptr->fileID;
+  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
+  if ( skipdim == 1 ) addDimension(0, 1);
 
-  gridtype = gridInqType(gridID);
-  dimlen = gridInqYsize(gridID);
-  if ( dimlen != 1 ) Error("Ysize isn't 1 for %s grid!", gridNamePtr(gridtype));
+  for ( int id = 0; id < 3; ++id )
+    {
+      size_t size;
+      int curDimId = dimIds[dimorder[id]-1];
+      if ( curDimId == UNDEFID ) continue;
+      switch ( dimorder[id] )
+        {
+          Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
+          case 1:
+          case 2:
+            cdf_inq_dimlen(fileId, curDimId, &size);
+            addDimension(0, size);
+            break;
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  ncvarid = streamptr->ydimID[gridindex];
+          case 3:
+            addDimension((size_t)levelId, 1);
+            break;
 
-  gridInqYname(gridID, axisname);
-  gridInqYlongname(gridID, longname);
-  gridInqYstdname(gridID, stdname);
-  gridInqYunits(gridID, units);
+          default:
+            Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
+        }
+    }
 
-  if ( ncvarid == UNDEFID )
-    {
-      dimID = streamptr->basetime.ncvarid;
+  if ( skipdim == 2 ) addDimension(0, 1);
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+  assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
+  assert(ndims <= (int)(sizeof(*count)/sizeof(**count)));
 
-      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
+#undef addDimension
 
-      if ( (len = strlen(stdname)) )
-        cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
-      if ( (len = strlen(longname)) )
-        cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
-      if ( (len = strlen(units)) )
-        cdf_put_att_text(fileID, ncvarid, "units", len, units);
+  if ( CDI_Debug )
+    for (int idim = 0; idim < ndims; idim++)
+      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
+  int nvdims;
+  cdf_inq_varndims(fileId, ncvarid, &nvdims);
 
-  streamptr->ydimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
+  if ( nvdims != ndims )
+    Error("Internal error, variable %s has an unsupported array structure!", vlistInqVarNamePtr(vlistId, varId));
 }
 
-
-static
-int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID, int ngrids, int mode)
+void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  int iz, index;
-  int gridID0;
-  int ncdimid;
-  char axisname0[CDI_MAX_NAME];
-  char axisname2[CDI_MAX_NAME];
-  int checkname;
-  int status;
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  /* check that the name is not already defined */
-  checkname = TRUE;
-  iz = 0;
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  do
-    {
-      strcpy(axisname2, axisname);
-      if ( iz ) sprintf(&axisname2[strlen(axisname2)], "_%d", iz+1);
+  int ncvarid = streamptr->vars[varID].ncvarid;
 
-      //status = nc_inq_varid(fileID, axisname2, &ncvarid);
-      if ( type == 'V' ) /* type Var oder Dim */
-        status = nc_inq_varid(fileID, axisname2, &ncdimid);
-      else
-        status = nc_inq_dimid(fileID, axisname2, &ncdimid);
+  int gridID  = vlistInqVarGrid(vlistID, varID);
+  int zaxisID = vlistInqVarZaxis(vlistID, varID);
 
-      if ( status != NC_NOERR )
-        {
-          if ( iz )
-            {
-              /* check that the name does not exist for other grids */
-              for ( index = 0; index < ngrids; index++ )
-                {
-                  gridID0 = vlistGrid(vlistID, index);
-                  if ( gridID != gridID0 )
-                    {
-                      if ( mode == 'X' ) /* mode X or Y */
-                        gridInqXname(gridID0, axisname0);
-                      else
-                        gridInqYname(gridID0, axisname0);
+  size_t start[4];
+  size_t count[4];
+  cdfGetSlapDescription(streamptr, varID, &start, &count);
 
-                      if ( strcmp(axisname0, axisname2) == 0 ) break;
-                    }
-                }
-              if ( index == ngrids ) checkname = FALSE;
-            }
-          else
-            {
-              checkname = FALSE;
-            }
-        }
+  cdf_get_vara_double(fileID, ncvarid, start, count, data);
+
+  size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
+  double missval = vlistInqVarMissval(vlistID, varID);
+  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
+  double validRange[2];
+  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
+    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
+  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
+  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
+  size_t nmiss_ = cdfDoInputDataTransformationDP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
+  assert(nmiss_ <= INT_MAX);
+  *nmiss = (int)nmiss_;
+}
 
-      if ( checkname ) iz++;
-    }
-  while (checkname && iz <= 99);
+void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
+{
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  if ( iz ) sprintf(&axisname[strlen(axisname)], "_%d", iz+1);
+  int ncvarid = streamptr->vars[varID].ncvarid;
 
-  return (iz);
-}
+  int gridID  = vlistInqVarGrid(vlistID, varID);
+  int zaxisID = vlistInqVarZaxis(vlistID, varID);
 
+  size_t start[4];
+  size_t count[4];
+  cdfGetSlapDescription(streamptr, varID, &start, &count);
 
-static
-void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
-{
-  char units[CDI_MAX_NAME];
-  char longname[CDI_MAX_NAME];
-  char stdname[CDI_MAX_NAME];
-  char axisname[CDI_MAX_NAME];
-  int index;
-  /*  int index2; */
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int dimIDs[2];
-  int ngrids = 0;
-  int fileID;
-  size_t len;
-  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
-  int nvdimID = UNDEFID;
-  int vlistID;
-  int xtype = NC_DOUBLE;
+  cdf_get_vara_float(fileID, ncvarid, start, count, data);
 
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+  size_t size = (size_t)gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
+  double missval = vlistInqVarMissval(vlistID, varID);
+  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
+  double validRange[2];
+  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
+    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
+  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
+  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
+  size_t nmiss_ = cdfDoInputDataTransformationSP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
+  assert(nmiss_ <= INT_MAX);
+  *nmiss = (int)nmiss_;
+}
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
+{
+  size_t start[4];
+  size_t count[4];
 
-  if ( ndims ) ngrids = vlistNgrids(vlistID);
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
 
-  size_t dimlen = (size_t)gridInqXsize(gridID);
-  gridindex = vlistGridIndex(vlistID, gridID);
+  int vlistID = streamptr->vlistID;
+  int fileID = streamptr->fileID;
 
-  gridInqXname(gridID, axisname);
-  gridInqXlongname(gridID, longname);
-  gridInqXstdname(gridID, stdname);
-  gridInqXunits(gridID, units);
+  bool swapxy;
+  cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
 
-  if ( axisname[0] == 0 ) Error("axis name undefined!");
+  int ncvarid = streamptr->vars[varID].ncvarid;
+  int gridId = vlistInqVarGrid(vlistID, varID);
+  size_t gridsize = (size_t)gridInqSize(gridId);
+  size_t xsize = (size_t)gridInqXsize(gridId);
+  size_t ysize = (size_t)gridInqYsize(gridId);
 
-  for ( index = 0; index < ngrids; index++ )
+  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
     {
-      if ( streamptr->xdimID[index] != UNDEFID )
+      float *data_fp = (float *)xmalloc(gridsize*sizeof(*data_fp));
+      cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
+      for ( size_t i = 0; i < gridsize; i++ )
+        data[i] = (double) data_fp[i];
+      free(data_fp);
+    }
+  else if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
+    {
+      nc_type xtype;
+      cdf_inq_vartype(fileID, ncvarid, &xtype);
+      if ( xtype == NC_BYTE )
         {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_GAUSSIAN    ||
-               gridtype0 == GRID_LONLAT      ||
-               gridtype0 == GRID_CURVILINEAR ||
-               gridtype0 == GRID_GENERIC )
-            {
-              size_t dimlen0 = (size_t)gridInqXsize(gridID0);
-              if ( dimlen == dimlen0 )
-                if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
-                     IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) )
-                  {
-                    dimID = streamptr->xdimID[index];
-                    break;
-                  }
-              /*
-              for ( index2 = 0; index2 < index; index2++ )
-                if ( streamptr->xdimID[index] == streamptr->xdimID[index2] )
-                  break;
-              if ( index2 == index ) iz++;
-              */
-            }
+          for ( size_t i = 0; i < gridsize; i++ )
+            if ( data[i] < 0 ) data[i] += 256;
         }
     }
-
-  if ( dimID == UNDEFID )
+  else
     {
-      int status;
-      status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'X');
-      if ( status == 0 && ndims )
-        status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
-
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      cdf_get_vara_double(fileID, ncvarid, start, count, data);
+    }
 
-      if ( ndims )
-        {
-          cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  if ( swapxy ) transpose2dArrayDP(ysize, xsize, data);
 
-          if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
-            {
-              size_t nvertex = 2;
-              if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-                cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
-            }
-        }
+  double missval = vlistInqVarMissval(vlistID, varID);
+  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
+  double validRange[2];
+  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
+    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
+  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
+  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
+  size_t nmiss_ = cdfDoInputDataTransformationDP(gridsize, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
+  assert(nmiss_ <= INT_MAX);
+  *nmiss = (int)nmiss_;
+}
 
-      if ( gridInqXvalsPtr(gridID) )
-        {
-          cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
 
-          if ( (len = strlen(stdname)) )
-            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
-          if ( (len = strlen(longname)) )
-            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
-          if ( (len = strlen(units)) )
-            cdf_put_att_text(fileID, ncvarid, "units", len, units);
+void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss)
+{
+  size_t start[4];
+  size_t count[4];
 
-          cdf_put_att_text(fileID, ncvarid, "axis", 1, "X");
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
 
-          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
-            {
-              strcat(axisname, "_bnds");
-              dimIDs[0] = dimID;
-              dimIDs[1] = nvdimID;
-              cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
-              cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
-            }
-          /*
-          if ( gridIsRotated(gridID) )
-            {
-              double north_pole = gridInqXpole(gridID);
-              cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
-            }
-          */
-        }
+  int vlistID = streamptr->vlistID;
+  int fileID = streamptr->fileID;
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+  bool swapxy;
+  cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
 
-      if ( ncvarid  != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqXvalsPtr(gridID));
-      if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqXboundsPtr(gridID));
+  int ncvarid = streamptr->vars[varID].ncvarid;
+  int gridId = vlistInqVarGrid(vlistID, varID);
+  size_t gridsize = (size_t)gridInqSize(gridId);
+  size_t xsize = (size_t)gridInqXsize(gridId);
+  size_t ysize = (size_t)gridInqYsize(gridId);
 
-      if ( ndims == 0 ) streamptr->ncxvarID[gridindex] = ncvarid;
+  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT64 )
+    {
+      double *data_dp = (double *)xmalloc(gridsize*sizeof(*data_dp));
+      cdf_get_vara_double(fileID, ncvarid, start, count, data_dp);
+      for ( size_t i = 0; i < gridsize; i++ )
+        data[i] = (float) data_dp[i];
+      free(data_dp);
+    }
+  else if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
+    {
+      nc_type xtype;
+      cdf_inq_vartype(fileID, ncvarid, &xtype);
+      if ( xtype == NC_BYTE )
+        {
+          for ( size_t i = 0; i < gridsize; i++ )
+            if ( data[i] < 0 ) data[i] += 256;
+        }
+    }
+  else
+    {
+      cdf_get_vara_float(fileID, ncvarid, start, count, data);
     }
 
-  streamptr->xdimID[gridindex] = dimID;
+  if ( swapxy ) transpose2dArraySP(ysize, xsize, data);
+
+  double missval = vlistInqVarMissval(vlistID, varID);
+  bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
+  double validRange[2];
+  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
+    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
+  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
+  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
+  size_t nmiss_ = cdfDoInputDataTransformationSP(gridsize, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
+  assert(nmiss_ <= INT_MAX);
+  *nmiss = (int)nmiss_;
 }
 
 
-static
-void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
+void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
-  char units[CDI_MAX_NAME];
-  char longname[CDI_MAX_NAME];
-  char stdname[CDI_MAX_NAME];
-  char axisname[CDI_MAX_NAME];
-  int index;
-  /*  int index2; */
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int dimIDs[2];
-  int ngrids = 0;
-  int fileID;
-  size_t len;
-  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
-  int nvdimID = UNDEFID;
-  int vlistID;
-  int xtype = NC_DOUBLE;
+  size_t xsize = 0, ysize = 0;
+  size_t start[5];
+  size_t count[5];
+  int dimorder[3];
+  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
 
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  if ( ndims ) ngrids = vlistNgrids(vlistID);
+  long ntsteps = streamptr->ntsteps;
+  if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
 
-  size_t dimlen = (size_t)gridInqYsize(gridID);
-  gridindex = vlistGridIndex(vlistID, gridID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  gridInqYname(gridID, axisname);
-  gridInqYlongname(gridID, longname);
-  gridInqYstdname(gridID, stdname);
-  gridInqYunits(gridID, units);
+  int ncvarid = cdfDefVar(streamptr, varID);
 
-  if ( axisname[0] == 0 ) Error("axis name undefined!");
+  int gridID    = vlistInqVarGrid(vlistID, varID);
+  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  vlistInqVarDimorder(vlistID, varID, &dimorder);
 
-  for ( index = 0; index < ngrids; index++ )
+
+  if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      if ( streamptr->ydimID[index] != UNDEFID )
-        {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_GAUSSIAN    ||
-               gridtype0 == GRID_LONLAT      ||
-               gridtype0 == GRID_CURVILINEAR ||
-               gridtype0 == GRID_GENERIC )
-            {
-              size_t dimlen0 = (size_t)gridInqYsize(gridID0);
-              if ( dimlen == dimlen0 )
-                if ( IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
-                     IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
-                  {
-                    dimID = streamptr->ydimID[index];
-                    break;
-                  }
-              /*
-              for ( index2 = 0; index2 < index; index2++ )
-                if ( streamptr->ydimID[index] == streamptr->ydimID[index2] )
-                  break;
-              if ( index2 == index ) iz++;
-              */
-            }
-        }
+      cdfWriteGridTraj(streamptr, gridID);
     }
-
-  if ( dimID == UNDEFID )
+  else
     {
-      int status;
-      status = checkGridName('V', axisname, fileID, vlistID, gridID, ngrids, 'Y');
-      if ( status == 0 && ndims )
-        status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'Y');
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
+    }
+  {
+    int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+    zid = streamptr->zaxisID[zaxisindex];
+  }
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+  int swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != UNDEFID && yid != UNDEFID;
+  /*
+  printf("swapxy %d\n", swapxy);
+  printf("dimorder: %d %d %d\n", dimorder[0], dimorder[1], dimorder[2]);
+  */
 
-      if ( ndims )
-        {
-          cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  size_t ndims = 0;
+  if ( tsteptype != TSTEP_CONSTANT )
+    {
+      start[ndims] = (size_t)ntsteps - 1;
+      count[ndims] = 1;
+      ndims++;
+    }
 
-          if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
-            {
-              size_t nvertex = 2;
-              if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-                cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
-            }
+  for ( int id = 0; id < 3; ++id )
+    {
+      if ( dimorder[id] == 3 && zid != UNDEFID )
+        {
+          start[ndims] = (size_t)levelID;
+          count[ndims] = 1;
+          ndims++;
         }
-
-      if ( gridInqYvalsPtr(gridID) )
+      else if ( dimorder[id] == 2 && yid != UNDEFID )
         {
-          cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
-
-          if ( (len = strlen(stdname)) )
-            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
-          if ( (len = strlen(longname)) )
-            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
-          if ( (len = strlen(units)) )
-            cdf_put_att_text(fileID, ncvarid, "units", len, units);
-
-          cdf_put_att_text(fileID, ncvarid, "axis", 1, "Y");
-
-          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
-            {
-              strcat(axisname, "_bnds");
-              dimIDs[0] = dimID;
-              dimIDs[1] = nvdimID;
-              cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
-              cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
-            }
-          /*
-          if ( gridIsRotated(gridID) )
-            {
-              double north_pole = gridInqYpole(gridID);
-              cdf_put_att_double(fileID, ncvarid, "north_pole", NC_DOUBLE, 1, &north_pole);
-            }
-          */
+          start[ndims] = 0;
+          cdf_inq_dimlen(fileID, yid, &ysize);
+          count[ndims] = ysize;
+          ndims++;
+        }
+      else if ( dimorder[id] == 1 && xid != UNDEFID )
+        {
+          start[ndims] = 0;
+          cdf_inq_dimlen(fileID, xid, &xsize);
+          count[ndims] = xsize;
+          ndims++;
         }
+    }
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+  if ( CDI_Debug )
+    for (size_t idim = 0; idim < ndims; idim++)
+      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
-      if ( ncvarid  != UNDEFID ) cdf_put_var_double(fileID, ncvarid, gridInqYvalsPtr(gridID));
-      if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, gridInqYboundsPtr(gridID));
+  int dtype = vlistInqVarDatatype(vlistID, varID);
 
-      if ( ndims == 0 ) streamptr->ncyvarID[gridindex] = ncvarid;
-    }
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
-  streamptr->ydimID[gridindex] = dimID;
-}
+  long nvals = gridInqSize(gridID);
 
+  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
 
-static
-void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
-{
-#if  defined  (HAVE_NETCDF4)
-  if ( gridsize > 1 && comptype == COMPRESS_ZIP && (filetype == FILETYPE_NC4 || filetype == FILETYPE_NC4C) )
-    {
-      nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
-      cdfDefVarDeflate(fileID, ncvarid, 1);
-    }
-#endif
 }
 
 
 static
-void cdfDefCurvilinear(stream_t *streamptr, int gridID)
+void cdfCreateRecords(stream_t *streamptr, int tsID)
 {
-  char xunits[CDI_MAX_NAME];
-  char xlongname[CDI_MAX_NAME];
-  char xstdname[CDI_MAX_NAME];
-  char yunits[CDI_MAX_NAME];
-  char ylongname[CDI_MAX_NAME];
-  char ystdname[CDI_MAX_NAME];
-  char xaxisname[CDI_MAX_NAME];
-  char yaxisname[CDI_MAX_NAME];
-  char xdimname[4] = "x";
-  char ydimname[4] = "y";
-  int index;
-  int gridID0, gridtype0, gridindex;
-  int xdimID = UNDEFID;
-  int ydimID = UNDEFID;
-  int dimIDs[3];
-  int ngrids;
-  int fileID;
-  size_t len;
-  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
-  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
-  int nvdimID = UNDEFID;
-  int vlistID;
-  int xtype = NC_DOUBLE;
+  int varID, levelID, recID, vrecID, zaxisID;
+  int nlev, nvrecs;
 
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+  int vlistID  = streamptr->vlistID;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
 
-  ngrids = vlistNgrids(vlistID);
+  if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
 
-  size_t xdimlen = (size_t)gridInqXsize(gridID);
-  size_t ydimlen = (size_t)gridInqYsize(gridID);
-  gridindex = vlistGridIndex(vlistID, gridID);
+  tsteps_t* sourceTstep = streamptr->tsteps;
+  tsteps_t* destTstep = sourceTstep + tsID;
 
-  gridInqXname(gridID, xaxisname);
-  gridInqXlongname(gridID, xlongname);
-  gridInqXstdname(gridID, xstdname);
-  gridInqXunits(gridID, xunits);
-  gridInqYname(gridID, yaxisname);
-  gridInqYlongname(gridID, ylongname);
-  gridInqYstdname(gridID, ystdname);
-  gridInqYunits(gridID, yunits);
+  int nvars = vlistNvars(vlistID);
+  int nrecs = vlistNrecs(vlistID);
 
-  for ( index = 0; index < ngrids; index++ )
+  if ( nrecs <= 0 ) return;
+
+  if ( tsID == 0 )
     {
-      if ( streamptr->xdimID[index] != UNDEFID )
+      nvrecs = nrecs; /* use all records at first timestep */
+
+      streamptr->nrecs += nrecs;
+
+      destTstep->records    = (record_t *)xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
+      destTstep->recIDs     = (int *)xmalloc((size_t)nvrecs*sizeof (int));;
+      for ( recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
+
+      record_t *records = destTstep->records;
+
+      recID = 0;
+      for ( varID = 0; varID < nvars; varID++ )
         {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_GAUSSIAN    ||
-               gridtype0 == GRID_LONLAT      ||
-               gridtype0 == GRID_CURVILINEAR ||
-               gridtype0 == GRID_GENERIC )
+          zaxisID = vlistInqVarZaxis(vlistID, varID);
+          nlev    = zaxisInqSize(zaxisID);
+          for ( levelID = 0; levelID < nlev; levelID++ )
             {
-              size_t dimlen0 = (size_t)gridInqXsize(gridID0);
-              if ( xdimlen == dimlen0 )
-                if ( IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
-                     IS_EQUAL(gridInqXval(gridID0, (int)xdimlen-1), gridInqXval(gridID, (int)xdimlen-1)) )
-                  {
-                    xdimID = streamptr->xdimID[index];
-                    ncxvarid = streamptr->ncxvarID[index];
-                    break;
-                  }
-              dimlen0 = (size_t)gridInqYsize(gridID0);
-              if ( ydimlen == dimlen0 )
-                if ( IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
-                     IS_EQUAL(gridInqYval(gridID0, (int)xdimlen-1), gridInqYval(gridID, (int)xdimlen-1)) )
-                  {
-                    ydimID = streamptr->ydimID[index];
-                    ncyvarid = streamptr->ncyvarID[index];
-                    break;
-                  }
+              recordInitEntry(&records[recID]);
+              records[recID].varID   = (short)varID;
+              records[recID].levelID = (short)levelID;
+              recID++;
+            }
+        }
+    }
+  else if ( tsID == 1 )
+    {
+      nvrecs = 0;
+      for ( varID = 0; varID < nvars; varID++ )
+        {
+          if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+            {
+              zaxisID = vlistInqVarZaxis(vlistID, varID);
+              nvrecs += zaxisInqSize(zaxisID);
             }
         }
-    }
 
-  if ( xdimID == UNDEFID || ydimID == UNDEFID )
-    {
-      checkGridName('V', xaxisname, fileID, vlistID, gridID, ngrids, 'X');
-      checkGridName('V', yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
-      checkGridName('D', xdimname, fileID, vlistID, gridID, ngrids, 'X');
-      checkGridName('D', ydimname, fileID, vlistID, gridID, ngrids, 'Y');
+      streamptr->nrecs += nvrecs;
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      destTstep->records    = (record_t *) xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
 
-      cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
-      cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
 
-      if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
+      if ( nvrecs )
         {
-          size_t nvertex = 4;
-          if ( nc_inq_dimid(fileID, "nv4", &nvdimID) != NC_NOERR )
-            cdf_def_dim(fileID, "nv4", nvertex, &nvdimID);
+          destTstep->recIDs = (int *) xmalloc((size_t)nvrecs * sizeof (int));
+          vrecID = 0;
+          for ( recID = 0; recID < nrecs; recID++ )
+            {
+              varID = destTstep->records[recID].varID;
+              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+                {
+                  destTstep->recIDs[vrecID++] = recID;
+                }
+            }
         }
+    }
+  else
+    {
+      if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
 
-      dimIDs[0] = ydimID;
-      dimIDs[1] = xdimID;
+      nvrecs = streamptr->tsteps[1].nrecs;
 
-      if ( gridInqXvalsPtr(gridID) )
-        {
-          cdf_def_var(fileID, xaxisname, (nc_type) xtype, 2, dimIDs, &ncxvarid);
-          cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+      streamptr->nrecs += nvrecs;
 
-          if ( (len = strlen(xstdname)) )
-            cdf_put_att_text(fileID, ncxvarid, "standard_name", len, xstdname);
-          if ( (len = strlen(xlongname)) )
-            cdf_put_att_text(fileID, ncxvarid, "long_name", len, xlongname);
-          if ( (len = strlen(xunits)) )
-            cdf_put_att_text(fileID, ncxvarid, "units", len, xunits);
+      destTstep->records    = (record_t *) xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
 
-          /* attribute for Panoply */
-          cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
 
-          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
-            {
-              strcat(xaxisname, "_bnds");
-              dimIDs[0] = ydimID;
-              dimIDs[1] = xdimID;
-              dimIDs[2] = nvdimID;
-              cdf_def_var(fileID, xaxisname, (nc_type) xtype, 3, dimIDs, &ncbxvarid);
-              cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+      destTstep->recIDs     = (int *) xmalloc((size_t)nvrecs * sizeof(int));
 
-              cdf_put_att_text(fileID, ncxvarid, "bounds", strlen(xaxisname), xaxisname);
-            }
-        }
+      memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
+    }
+}
 
-      if ( gridInqYvalsPtr(gridID) )
-        {
-          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncyvarid);
-          cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-          if ( (len = strlen(ystdname)) )
-            cdf_put_att_text(fileID, ncyvarid, "standard_name", len, ystdname);
-          if ( (len = strlen(ylongname)) )
-            cdf_put_att_text(fileID, ncyvarid, "long_name", len, ylongname);
-          if ( (len = strlen(yunits)) )
-            cdf_put_att_text(fileID, ncyvarid, "units", len, yunits);
+static
+int cdfTimeDimID(int fileID, int ndims, int nvars)
+{
+  int dimid = UNDEFID;
+  int timedimid = UNDEFID;
+  char dimname[80];
+  char timeunits[CDI_MAX_NAME];
+  char attname[CDI_MAX_NAME];
+  char name[CDI_MAX_NAME];
+  nc_type xtype;
+  int nvdims, nvatts;
+  int dimids[9];
+  int varid, iatt;
 
-          /* attribute for Panoply */
-          cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
+  for ( dimid = 0; dimid < ndims; dimid++ )
+    {
+      cdf_inq_dimname(fileID, dimid, dimname);
+      if ( memcmp(dimname, "time", 4) == 0 )
+        {
+          timedimid = dimid;
+          break;
+        }
+    }
 
-          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+  if ( timedimid == UNDEFID )
+    {
+      for ( varid = 0; varid < nvars; varid++ )
+        {
+          cdf_inq_var(fileID, varid, name, &xtype, &nvdims, dimids, &nvatts);
+          if ( nvdims == 1 )
             {
-              strcat(yaxisname, "_bnds");
-              dimIDs[0] = ydimID;
-              dimIDs[1] = xdimID;
-              dimIDs[2] = nvdimID;
-              cdf_def_var(fileID, yaxisname, (nc_type) xtype, 3, dimIDs, &ncbyvarid);
-              cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+              for ( iatt = 0; iatt < nvatts; iatt++ )
+                {
+                  cdf_inq_attname(fileID, varid, iatt, attname);
+                  if ( strncmp(attname, "units", 5) == 0 )
+                    {
+                      cdfGetAttText(fileID, varid, "units", sizeof(timeunits), timeunits);
+                      strtolower(timeunits);
 
-              cdf_put_att_text(fileID, ncyvarid, "bounds", strlen(yaxisname), yaxisname);
+                      if ( isTimeUnits(timeunits) )
+                        {
+                          timedimid = dimids[0];
+                          break;
+                        }
+                    }
+                }
             }
         }
+    }
 
-      if ( gridInqAreaPtr(gridID) )
-        {
-          char yaxisname[] = "cell_area";
-          char units[] = "m2";
-          char longname[] = "area of grid cell";
-          char stdname[] = "cell_area";
-
-          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncavarid);
-
-          cdf_put_att_text(fileID, ncavarid, "standard_name", strlen(stdname), stdname);
-          cdf_put_att_text(fileID, ncavarid, "long_name", strlen(longname), longname);
-          cdf_put_att_text(fileID, ncavarid, "units", strlen(units), units);
-        }
+  return (timedimid);
+}
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+static
+void init_ncdims(long ndims, ncdim_t *ncdims)
+{
+  long ncdimid;
 
-      if ( ncxvarid  != UNDEFID ) cdf_put_var_double(fileID, ncxvarid,  gridInqXvalsPtr(gridID));
-      if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
-      if ( ncyvarid  != UNDEFID ) cdf_put_var_double(fileID, ncyvarid,  gridInqYvalsPtr(gridID));
-      if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
-      if ( ncavarid  != UNDEFID ) cdf_put_var_double(fileID, ncavarid,  gridInqAreaPtr(gridID));
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+    {
+      ncdims[ncdimid].ncvarid      = UNDEFID;
+      ncdims[ncdimid].dimtype      = UNDEFID;
+      ncdims[ncdimid].len          = 0;
+      ncdims[ncdimid].name[0]      = 0;
     }
-
-  streamptr->xdimID[gridindex] = xdimID;
-  streamptr->ydimID[gridindex] = ydimID;
-  streamptr->ncxvarID[gridindex] = ncxvarid;
-  streamptr->ncyvarID[gridindex] = ncyvarid;
-  streamptr->ncavarID[gridindex] = ncavarid;
 }
 
-
 static
-void cdfDefRgrid(stream_t *streamptr, int gridID)
+void init_ncvars(long nvars, ncvar_t *ncvars)
 {
-  char axisname[7] = "rgridX";
-  int index, iz = 0;
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int ngrids;
-  int fileID;
-  int vlistID;
-  int lwarn = TRUE;
+  long ncvarid;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
+    {
+      ncvars[ncvarid].ncid            = UNDEFID;
+      ncvars[ncvarid].ignore          = FALSE;
+      ncvars[ncvarid].isvar           = UNDEFID;
+      ncvars[ncvarid].islon           = FALSE;
+      ncvars[ncvarid].islat           = FALSE;
+      ncvars[ncvarid].islev           = FALSE;
+      ncvars[ncvarid].istime          = FALSE;
+      ncvars[ncvarid].warn            = FALSE;
+      ncvars[ncvarid].tsteptype       = TSTEP_CONSTANT;
+      ncvars[ncvarid].param           = UNDEFID;
+      ncvars[ncvarid].code            = UNDEFID;
+      ncvars[ncvarid].tabnum          = 0;
+      ncvars[ncvarid].calendar        = FALSE;
+      ncvars[ncvarid].climatology     = FALSE;
+      ncvars[ncvarid].bounds          = UNDEFID;
+      ncvars[ncvarid].gridID          = UNDEFID;
+      ncvars[ncvarid].zaxisID         = UNDEFID;
+      ncvars[ncvarid].gridtype        = UNDEFID;
+      ncvars[ncvarid].zaxistype       = UNDEFID;
+      ncvars[ncvarid].xdim            = UNDEFID;
+      ncvars[ncvarid].ydim            = UNDEFID;
+      ncvars[ncvarid].zdim            = UNDEFID;
+      ncvars[ncvarid].xvarid          = UNDEFID;
+      ncvars[ncvarid].yvarid          = UNDEFID;
+      ncvars[ncvarid].zvarid          = UNDEFID;
+      ncvars[ncvarid].tvarid          = UNDEFID;
+      ncvars[ncvarid].ncoordvars      = 0;
+      for ( int i = 0; i < MAX_COORDVARS; ++i )
+        ncvars[ncvarid].coordvarids[i]  = UNDEFID;
+      ncvars[ncvarid].nauxvars      = 0;
+      for ( int i = 0; i < MAX_AUXVARS; ++i )
+        ncvars[ncvarid].auxvarids[i]  = UNDEFID;
+      ncvars[ncvarid].cellarea        = UNDEFID;
+      ncvars[ncvarid].tableID         = UNDEFID;
+      ncvars[ncvarid].xtype           = 0;
+      ncvars[ncvarid].ndims           = 0;
+      ncvars[ncvarid].gmapid          = UNDEFID;
+      ncvars[ncvarid].vlen            = 0;
+      ncvars[ncvarid].vdata           = NULL;
+      ncvars[ncvarid].truncation      = 0;
+      ncvars[ncvarid].position        = 0;
+      ncvars[ncvarid].positive        = 0;
+      ncvars[ncvarid].chunked         = 0;
+      ncvars[ncvarid].chunktype       = UNDEFID;
+      ncvars[ncvarid].defmissval      = 0;
+      ncvars[ncvarid].deffillval      = 0;
+      ncvars[ncvarid].missval         = 0;
+      ncvars[ncvarid].fillval         = 0;
+      ncvars[ncvarid].addoffset       = 0;
+      ncvars[ncvarid].scalefactor     = 1;
+      ncvars[ncvarid].name[0]         = 0;
+      ncvars[ncvarid].longname[0]     = 0;
+      ncvars[ncvarid].stdname[0]      = 0;
+      ncvars[ncvarid].units[0]        = 0;
+      ncvars[ncvarid].extra[0]        = 0;
+      ncvars[ncvarid].natts           = 0;
+      ncvars[ncvarid].atts            = NULL;
+      ncvars[ncvarid].deflate         = 0;
+      ncvars[ncvarid].lunsigned       = 0;
+      ncvars[ncvarid].lvalidrange     = 0;
+      ncvars[ncvarid].validrange[0]   = VALIDMISS;
+      ncvars[ncvarid].validrange[1]   = VALIDMISS;
+      ncvars[ncvarid].ensdata         = NULL;
+    }
+}
 
-  ngrids = vlistNgrids(vlistID);
+static
+int isLonAxis(const char *units, const char *stdname)
+{
+  int status = FALSE;
+  char lc_units[16];
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
+  memcpy(lc_units, units, 15);
+  lc_units[15] = 0;
+  strtolower(lc_units);
 
-  for ( index = 0; index < ngrids; index++ )
+  if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
+        (memcmp(stdname, "grid_longitude", 14) == 0 || memcmp(stdname, "longitude", 9) == 0)) )
     {
-      if ( streamptr->xdimID[index] != UNDEFID )
-        {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_GAUSSIAN_REDUCED )
-            {
-              size_t dimlen0 = (size_t)gridInqSize(gridID0);
-
-              if ( dimlen == dimlen0 )
-                {
-                  dimID = streamptr->xdimID[index];
-                  break;
-                }
-              else
-                iz++;
-            }
-        }
+      status = TRUE;
     }
 
-  if ( dimID == UNDEFID )
+  if ( status == FALSE &&
+       memcmp(stdname, "grid_latitude", 13) && memcmp(stdname, "latitude", 8) &&
+       memcmp(lc_units, "degree", 6) == 0 )
     {
-      if ( lwarn )
-        {
-          Warning("Creating a netCDF file with data on a gaussian reduced grid.");
-          Warning("The further processing of the resulting file is unsupported!");
-          lwarn = FALSE;
-        }
+      int ioff = 6;
+      if ( lc_units[ioff] == 's' ) ioff++;
+      if ( lc_units[ioff] == '_' ) ioff++;
+      if ( lc_units[ioff] == 'e' ) status = TRUE;
+    }
 
-      if ( iz == 0 ) axisname[5] = '\0';
-      else           sprintf(&axisname[5], "%1d", iz+1);
+  return (status);
+}
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+static
+int isLatAxis(const char *units, const char *stdname)
+{
+  int status = FALSE;
+  char lc_units[16];
 
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  memcpy(lc_units, units, 15);
+  lc_units[15] = 0;
+  strtolower(lc_units);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+  if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
+        (memcmp(stdname, "grid_latitude", 13) == 0 || memcmp(stdname, "latitude", 8) == 0)) )
+    {
+      status = TRUE;
     }
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  streamptr->xdimID[gridindex] = dimID;
-}
+  if ( status == FALSE &&
+       memcmp(stdname, "grid_longitude", 14) && memcmp(stdname, "longitude", 9) &&
+       memcmp(lc_units, "degree", 6) == 0 )
+    {
+      int ioff = 6;
+      if ( lc_units[ioff] == 's' ) ioff++;
+      if ( lc_units[ioff] == '_' ) ioff++;
+      if ( lc_units[ioff] == 'n' ) status = TRUE;
+    }
 
+  return (status);
+}
 
 static
-void cdfDefGdim(stream_t *streamptr, int gridID)
+int isDBLAxis(/*const char *units,*/ const char *longname)
 {
-  int index, iz = 0;
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int ngrids;
-  int fileID;
-  int vlistID;
+  int status = FALSE;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  if ( strcmp(longname, "depth below land")         == 0 ||
+       strcmp(longname, "depth_below_land")         == 0 ||
+       strcmp(longname, "levels below the surface") == 0 )
+    {
+      /*
+      if ( strcmp(ncvars[ncvarid].units, "cm") == 0 ||
+           strcmp(ncvars[ncvarid].units, "dm") == 0 ||
+           strcmp(ncvars[ncvarid].units, "m")  == 0 )
+      */
+        status = TRUE;
+    }
 
-  ngrids = vlistNgrids(vlistID);
+  return (status);
+}
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
+static
+int unitsIsMeter(const char *units)
+{
+  return (*units == 'm' && (strcmp(units, "m") == 0 || strncmp(units, "meter", 5) == 0));
+}
 
-  if ( gridInqYsize(gridID) == 0 )
-    for ( index = 0; index < ngrids; index++ )
-      {
-        if ( streamptr->xdimID[index] != UNDEFID )
-          {
-            gridID0 = vlistGrid(vlistID, index);
-            gridtype0 = gridInqType(gridID0);
-            if ( gridtype0 == GRID_GENERIC )
-              {
-                size_t dimlen0 = (size_t)gridInqSize(gridID0);
-                if ( dimlen == dimlen0 )
-                  {
-                    dimID = streamptr->xdimID[index];
-                    break;
-                  }
-                else
-                  iz++;
-              }
-          }
-      }
+static
+int isDepthAxis(const char *stdname, const char *longname)
+{
+  int status = FALSE;
 
-  if ( gridInqXsize(gridID) == 0 )
-    for ( index = 0; index < ngrids; index++ )
+  if ( strcmp(stdname, "depth") == 0 ) status = TRUE;
+
+  if ( status == FALSE )
+    if ( strcmp(longname, "depth_below_sea") == 0 ||
+         strcmp(longname, "depth below sea") == 0 )
       {
-        if ( streamptr->ydimID[index] != UNDEFID )
-          {
-            gridID0 = vlistGrid(vlistID, index);
-            gridtype0 = gridInqType(gridID0);
-            if ( gridtype0 == GRID_GENERIC )
-              {
-                size_t dimlen0 = (size_t)gridInqSize(gridID0);
-                if ( dimlen == dimlen0 )
-                  {
-                    dimID = streamptr->ydimID[index];
-                    break;
-                  }
-                else
-                  iz++;
-              }
-          }
+        status = TRUE;
       }
 
-  if ( dimID == UNDEFID )
-    {
-      char axisname[CDI_MAX_NAME];
-      strcpy(axisname, "gsize");
+  return (status);
+}
 
-      checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
-      /*
-      if ( iz == 0 ) axisname[5] = '\0';
-      else           sprintf(&axisname[5], "%1d", iz+1);
-      */
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+static
+int isHeightAxis(const char *stdname, const char *longname)
+{
+  int status = FALSE;
 
-      //printf("axisname, dimlen %s %d\n", axisname, dimlen);
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  if ( strcmp(stdname, "height") == 0 ) status = TRUE;
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
+  if ( status == FALSE )
+    if ( strcmp(longname, "height") == 0 ||
+         strcmp(longname, "height above the surface") == 0 )
+      {
+        status = TRUE;
+      }
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  streamptr->xdimID[gridindex] = dimID;
+  return (status);
 }
 
-
 static
-void cdfDefGridReference(stream_t *streamptr, int gridID)
+int unitsIsPressure(const char *units)
 {
-  int fileID  = streamptr->fileID;
-  int number = gridInqNumber(gridID);
+  int status = FALSE;
 
-  if ( number > 0 )
+  if ( memcmp(units, "millibar", 8) == 0 ||
+       memcmp(units, "mb", 2)       == 0 ||
+       memcmp(units, "hectopas", 8) == 0 ||
+       memcmp(units, "hPa", 3)      == 0 ||
+       memcmp(units, "Pa", 2)       == 0 )
     {
-      cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
+      status = TRUE;
     }
 
-  if ( gridInqReference(gridID, NULL) )
+  return (status);
+}
+
+static
+int isGaussGrid(size_t ysize, double yinc, double *yvals)
+{
+  int lgauss = FALSE;
+  double *yv, *yw;
+
+  if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
     {
-      char gridfile[8912];
-      gridInqReference(gridID, gridfile);
+      size_t i;
+      yv = (double *) malloc(ysize*sizeof(double));
+      yw = (double *) malloc(ysize*sizeof(double));
+      gaussaw(yv, yw, ysize);
+      free(yw);
+      for ( i = 0; i < ysize; i++ )
+        yv[i] = asin(yv[i])/M_PI*180.0;
 
-      if ( gridfile[0] != 0 )
-        cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
+      for ( i = 0; i < ysize; i++ )
+        if ( fabs(yv[i] - yvals[i]) >
+             ((yv[0] - yv[1])/500) ) break;
+
+      if ( i == ysize ) lgauss = TRUE;
+
+      /* check S->N */
+      if ( lgauss == FALSE )
+        {
+          for ( i = 0; i < ysize; i++ )
+            if ( fabs(yv[i] - yvals[ysize-i-1]) >
+                 ((yv[0] - yv[1])/500) ) break;
+
+          if ( i == ysize ) lgauss = TRUE;
+        }
+
+      free(yv);
     }
+
+  return (lgauss);
 }
 
 static
-void cdfDefGridUUID(stream_t *streamptr, int gridID)
+void cdfSetVar(ncvar_t *ncvars, int ncvarid, int isvar)
 {
-  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+  if ( isvar != TRUE && isvar != FALSE )
+    Error("Internal problem! var %s undefined", ncvars[ncvarid].name);
 
-  gridInqUUID(gridID, uuidOfHGrid);
-  if ( !cdiUUIDIsNull(uuidOfHGrid) )
+  if ( ncvars[ncvarid].isvar != UNDEFID &&
+       ncvars[ncvarid].isvar != isvar   &&
+       ncvars[ncvarid].warn  == FALSE )
     {
-      char uuidOfHGridStr[37];
-      uuid2str(uuidOfHGrid, uuidOfHGridStr);
-      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
-        {
-          int fileID  = streamptr->fileID;
-          //if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
-          //if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
-        }
+      if ( ! ncvars[ncvarid].ignore )
+        Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
+
+      ncvars[ncvarid].warn = TRUE;
+      isvar = FALSE;
+    }
+
+  ncvars[ncvarid].isvar = isvar;
+}
+
+static
+void cdfSetDim(ncvar_t *ncvars, int ncvarid, int dimid, int dimtype)
+{
+  if ( ncvars[ncvarid].dimtype[dimid] != UNDEFID &&
+       ncvars[ncvarid].dimtype[dimid] != dimtype )
+    {
+      Warning("Inconsistent dimension definition for %s! dimid = %d;  type = %d;  newtype = %d",
+              ncvars[ncvarid].name, dimid, ncvars[ncvarid].dimtype[dimid], dimtype);
     }
+
+  ncvars[ncvarid].dimtype[dimid] = dimtype;
 }
 
 static
-void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
+void printNCvars(ncvar_t *ncvars, int nvars, const char *oname)
 {
-  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
-  zaxisInqUUID(zaxisID, uuidOfVGrid);
+  char axis[7];
+  int ncvarid, i;
+  int ndim;
+  static const char iaxis[] = {'t', 'z', 'y', 'x'};
 
-  if ( uuidOfVGrid[0] != 0 )
+  fprintf(stderr, "%s:\n", oname);
+
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      char uuidOfVGridStr[37];
-      uuid2str(uuidOfVGrid, uuidOfVGridStr);
-      if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
+      ndim = 0;
+      if ( ncvars[ncvarid].isvar )
         {
-          int fileID  = streamptr->fileID;
-          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
-          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+          axis[ndim++] = 'v';
+          axis[ndim++] = ':';
+          for ( i = 0; i < ncvars[ncvarid].ndims; i++ )
+            {/*
+              if      ( ncvars[ncvarid].tvarid != -1 ) axis[ndim++] = iaxis[0];
+              else if ( ncvars[ncvarid].zvarid != -1 ) axis[ndim++] = iaxis[1];
+              else if ( ncvars[ncvarid].yvarid != -1 ) axis[ndim++] = iaxis[2];
+              else if ( ncvars[ncvarid].xvarid != -1 ) axis[ndim++] = iaxis[3];
+              else
+             */
+              if      ( ncvars[ncvarid].dimtype[i] == T_AXIS ) axis[ndim++] = iaxis[0];
+              else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) axis[ndim++] = iaxis[1];
+              else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) axis[ndim++] = iaxis[2];
+              else if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) axis[ndim++] = iaxis[3];
+              else                                             axis[ndim++] = '?';
+            }
+        }
+      else
+        {
+          axis[ndim++] = 'c';
+          axis[ndim++] = ':';
+          if      ( ncvars[ncvarid].istime ) axis[ndim++] = iaxis[0];
+          else if ( ncvars[ncvarid].islev  ) axis[ndim++] = iaxis[1];
+          else if ( ncvars[ncvarid].islat  ) axis[ndim++] = iaxis[2];
+          else if ( ncvars[ncvarid].islon  ) axis[ndim++] = iaxis[3];
+          else                               axis[ndim++] = '?';
         }
+
+      axis[ndim++] = 0;
+
+      fprintf(stderr, "%3d %3d  %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
     }
 }
 
 static
-void cdfDefUnstructured(stream_t *streamptr, int gridID)
+void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
+                          int timedimid, int modelID, int format)
 {
-  char xunits[CDI_MAX_NAME];
-  char xlongname[CDI_MAX_NAME];
-  char xstdname[CDI_MAX_NAME];
-  char yunits[CDI_MAX_NAME];
-  char ylongname[CDI_MAX_NAME];
-  char ystdname[CDI_MAX_NAME];
-  char xaxisname[CDI_MAX_NAME];
-  char yaxisname[CDI_MAX_NAME];
-  int index;
-  int gridID0, gridtype0, gridindex;
-  int dimID = UNDEFID;
-  int ngrids;
-  int fileID;
-  size_t len;
-  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
-  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
-  int nvdimID = UNDEFID;
-  int vlistID;
-  int xtype = NC_DOUBLE;
+  int ncid;
+  int ncdimid;
+  int nvdims, nvatts;
+  int *dimidsp;
+  int iatt;
+  int i;
+  int tablenum;
+  nc_type xtype, atttype;
+  size_t attlen;
+  char name[CDI_MAX_NAME];
+  char attname[CDI_MAX_NAME];
+  const int attstringlen = 8192; char attstring[8192];
 
-  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+  int nchecked_vars = 0;
+  char *checked_vars[9];
+  for ( i = 0; i < 9; ++i ) checked_vars[i] = NULL;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    {
+      ncid    = ncvars[ncvarid].ncid;
+      dimidsp = ncvars[ncvarid].dimids;
 
-  ngrids = vlistNgrids(vlistID);
+      cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
+      strcpy(ncvars[ncvarid].name, name);
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
-  gridindex = vlistGridIndex(vlistID, gridID);
+      for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
+        ncvars[ncvarid].dimtype[ncdimid] = -1;
 
-  gridInqXname(gridID, xaxisname);
-  gridInqXlongname(gridID, xlongname);
-  gridInqXstdname(gridID, xstdname);
-  gridInqXunits(gridID, xunits);
-  gridInqYname(gridID, yaxisname);
-  gridInqYlongname(gridID, ylongname);
-  gridInqYstdname(gridID, ystdname);
-  gridInqYunits(gridID, yunits);
+      ncvars[ncvarid].xtype = xtype;
+      ncvars[ncvarid].ndims = nvdims;
 
-  for ( index = 0; index < ngrids; index++ )
-    {
-      if ( streamptr->xdimID[index] != UNDEFID )
+#if  defined  (HAVE_NETCDF4)
+      if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
         {
-          gridID0 = vlistGrid(vlistID, index);
-          gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_UNSTRUCTURED )
+          char buf[CDI_MAX_NAME];
+          int shuffle, deflate, deflate_level;
+          size_t chunks[nvdims];
+          int storage_in;
+          nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflate_level);
+          if ( deflate > 0 ) ncvars[ncvarid].deflate = 1;
+
+          if ( nc_inq_var_chunking(ncid, ncvarid, &storage_in, chunks) == NC_NOERR )
             {
-              size_t dimlen0 = (size_t)gridInqSize(gridID0);
-              if ( dimlen == dimlen0 )
-		if ( gridInqNvertex(gridID0) == gridInqNvertex(gridID) &&
-		     IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0)) &&
-                     IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1), gridInqXval(gridID, (int)dimlen-1)) )
-		  {
-		    dimID = streamptr->xdimID[index];
-                    ncxvarid = streamptr->ncxvarID[index];
-                    ncyvarid = streamptr->ncyvarID[index];
-                    ncavarid = streamptr->ncavarID[index];
-		    break;
-		  }
+              if ( storage_in == NC_CHUNKED )
+                {
+                  ncvars[ncvarid].chunked = 1;
+                  for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = (int)chunks[i];
+                  if ( CDI_Debug )
+                    {
+                      fprintf(stderr, "%s: chunking %d %d %d  chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED);
+                      for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
+                      fprintf(stderr, "\n");
+                    }
+                  strcat(ncvars[ncvarid].extra, "chunks=");
+                  for ( int i = nvdims-1; i >= 0; --i )
+                    {
+                      sprintf(buf, "%ld", (long) chunks[i]);
+                      strcat(ncvars[ncvarid].extra, buf);
+                      if ( i > 0 ) strcat(ncvars[ncvarid].extra, "x");
+                    }
+                  strcat(ncvars[ncvarid].extra, " ");
+                }
             }
         }
-    }
+#endif
 
-  if ( dimID == UNDEFID )
-    {
-      char axisname[CDI_MAX_NAME];
-      char vertname[CDI_MAX_NAME];
-      strcpy(axisname, "ncells");
-      strcpy(vertname, "nv");
+      if ( nvdims > 0 )
+        {
+          if ( timedimid == dimidsp[0] )
+            {
+              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
+              cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
+            }
+          else
+            {
+              for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
+                {
+                  if ( timedimid == dimidsp[ncdimid] )
+                    {
+                      Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = FALSE;
+                    }
+                }
+            }
+        }
 
-      checkGridName('V', xaxisname, fileID, vlistID, gridID, ngrids, 'X');
-      checkGridName('V', yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
-      checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
-      checkGridName('D', vertname, fileID, vlistID, gridID, ngrids, 'X');
+      for ( iatt = 0; iatt < nvatts; iatt++ )
+        {
+          cdf_inq_attname(ncid, ncvarid, iatt, attname);
+          cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
+          cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          if ( strcmp(attname, "long_name") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].longname);
+            }
+          else if ( strcmp(attname, "standard_name") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].stdname);
+            }
+          else if ( strcmp(attname, "units") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].units);
+            }
+          else if ( strcmp(attname, "calendar") == 0 )
+            {
+              ncvars[ncvarid].calendar = TRUE;
+            }
+          else if ( strcmp(attname, "param") == 0 && xtypeIsText(atttype) )
+            {
+	      char paramstr[32];
+	      int pnum = 0, pcat = 255, pdis = 255;
+              cdfGetAttText(ncid, ncvarid, attname, sizeof(paramstr), paramstr);
+	      sscanf(paramstr, "%d.%d.%d", &pnum, &pcat, &pdis);
+	      ncvars[ncvarid].param = cdiEncodeParam(pnum, pcat, pdis);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "code") == 0 && !xtypeIsText(atttype) )
+            {
+              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].code);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "table") == 0 && !xtypeIsText(atttype) )
+            {
+              cdfGetAttInt(ncid, ncvarid, attname, 1, &tablenum);
+              if ( tablenum > 0 )
+                {
+                  ncvars[ncvarid].tabnum = tablenum;
+                  ncvars[ncvarid].tableID = tableInq(modelID, tablenum, NULL);
+                  if ( ncvars[ncvarid].tableID == CDI_UNDEFID )
+                    ncvars[ncvarid].tableID = tableDef(modelID, tablenum, NULL);
+                }
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "trunc_type") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              if ( memcmp(attstring, "Triangular", attlen) == 0 )
+                ncvars[ncvarid].gridtype = GRID_SPECTRAL;
+            }
+          else if ( strcmp(attname, "grid_type") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
 
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+              if      ( strcmp(attstring, "gaussian reduced") == 0 )
+                ncvars[ncvarid].gridtype = GRID_GAUSSIAN_REDUCED;
+              else if ( strcmp(attstring, "gaussian") == 0 )
+                ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
+              else if ( strncmp(attstring, "spectral", 8) == 0 )
+                ncvars[ncvarid].gridtype = GRID_SPECTRAL;
+              else if ( strncmp(attstring, "fourier", 7) == 0 )
+                ncvars[ncvarid].gridtype = GRID_FOURIER;
+              else if ( strcmp(attstring, "trajectory") == 0 )
+                ncvars[ncvarid].gridtype = GRID_TRAJECTORY;
+              else if ( strcmp(attstring, "generic") == 0 )
+                ncvars[ncvarid].gridtype = GRID_GENERIC;
+              else if ( strcmp(attstring, "cell") == 0 )
+                ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
+              else if ( strcmp(attstring, "unstructured") == 0 )
+                ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
+              else if ( strcmp(attstring, "curvilinear") == 0 )
+                ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
+              else if ( strcmp(attstring, "sinusoidal") == 0 )
+                ;
+              else if ( strcmp(attstring, "laea") == 0 )
+                ;
+              else if ( strcmp(attstring, "lcc2") == 0 )
+                ;
+              else if ( strcmp(attstring, "linear") == 0 ) // ignore grid type linear
+                ;
+              else
+                {
+                  static int warn = TRUE;
+                  if ( warn )
+                    {
+                      warn = FALSE;
+                      Warning("netCDF attribute grid_type='%s' unsupported!", attstring);
+                    }
+                }
 
-      size_t nvertex = (size_t)gridInqNvertex(gridID);
-      if ( nvertex > 0 ) cdf_def_dim(fileID, vertname, nvertex, &nvdimID);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "level_type") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
 
-      cdfDefGridReference(streamptr, gridID);
+              if      ( strcmp(attstring, "toa") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_TOA;
+              else if ( strcmp(attstring, "cloudbase") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_BASE;
+              else if ( strcmp(attstring, "cloudtop") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_TOP;
+              else if ( strcmp(attstring, "isotherm0") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_ISOTHERM_ZERO;
+              else if ( strcmp(attstring, "seabottom") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_SEA_BOTTOM;
+              else if ( strcmp(attstring, "lakebottom") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_LAKE_BOTTOM;
+              else if ( strcmp(attstring, "sedimentbottom") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM;
+              else if ( strcmp(attstring, "sedimentbottomta") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;
+              else if ( strcmp(attstring, "sedimentbottomtw") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;
+              else if ( strcmp(attstring, "mixlayer") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_MIX_LAYER;
+              else if ( strcmp(attstring, "atmosphere") == 0 )
+                ncvars[ncvarid].zaxistype = ZAXIS_ATMOSPHERE;
+              else
+                {
+                  static int warn = TRUE;
+                  if ( warn )
+                    {
+                      warn = FALSE;
+                      Warning("netCDF attribute level_type='%s' unsupported!", attstring);
+                    }
+                }
 
-      cdfDefGridUUID(streamptr, gridID);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "trunc_count") == 0 && !xtypeIsText(atttype) )
+            {
+              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
+            }
+          else if ( strcmp(attname, "truncation") == 0 && !xtypeIsText(atttype) )
+            {
+              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
+            }
+          else if ( strcmp(attname, "number_of_grid_in_reference") == 0 && !xtypeIsText(atttype) )
+            {
+              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].position);
+            }
+          else if ( strcmp(attname, "add_offset") == 0 && !xtypeIsText(atttype) )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].addoffset);
+	      /*
+		if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
+		if ( ncvars[ncvarid].addoffset != 0 )
+		Warning("attribute add_offset not supported for atttype %d", atttype);
+	      */
+	      /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "scale_factor") == 0 && !xtypeIsText(atttype) )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].scalefactor);
+	      /*
+		if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
+		if ( ncvars[ncvarid].scalefactor != 1 )
+		Warning("attribute scale_factor not supported for atttype %d", atttype);
+	      */
+	      /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "climatology") == 0 && xtypeIsText(atttype) )
+            {
+              int status, ncboundsid;
 
-      if ( gridInqXvalsPtr(gridID) )
-        {
-          cdf_def_var(fileID, xaxisname, (nc_type) xtype, 1, &dimID, &ncxvarid);
-          cdfGridCompress(fileID, ncxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 
-          if ( (len = strlen(xstdname)) )
-            cdf_put_att_text(fileID, ncxvarid, "standard_name", len, xstdname);
-          if ( (len = strlen(xlongname)) )
-            cdf_put_att_text(fileID, ncxvarid, "long_name", len, xlongname);
-          if ( (len = strlen(xunits)) )
-            cdf_put_att_text(fileID, ncxvarid, "units", len, xunits);
+              status = nc_inq_varid(ncid, attstring, &ncboundsid);
 
-          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+              if ( status == NC_NOERR )
+                {
+                  ncvars[ncvarid].climatology = TRUE;
+                  ncvars[ncvarid].bounds = ncboundsid;
+                  cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
+                  cdfSetVar(ncvars, ncvarid, FALSE);
+                }
+              else
+                Warning("%s - %s", nc_strerror(status), attstring);
+            }
+          else if ( strcmp(attname, "bounds") == 0 && xtypeIsText(atttype) )
             {
-              int dimIDs[2];
-              dimIDs[0] = dimID;
-              dimIDs[1] = nvdimID;
-              strcat(xaxisname, "_vertices");
-              cdf_def_var(fileID, xaxisname, (nc_type) xtype, 2, dimIDs, &ncbxvarid);
-              cdfGridCompress(fileID, ncbxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+              int status, ncboundsid;
 
-              cdf_put_att_text(fileID, ncxvarid, "bounds", strlen(xaxisname), xaxisname);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+
+              status = nc_inq_varid(ncid, attstring, &ncboundsid);
+
+              if ( status == NC_NOERR )
+                {
+                  ncvars[ncvarid].bounds = ncboundsid;
+                  cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
+                  cdfSetVar(ncvars, ncvarid, FALSE);
+                }
+              else
+                Warning("%s - %s", nc_strerror(status), attstring);
             }
-        }
+          else if ( strcmp(attname, "cell_measures") == 0 && xtypeIsText(atttype) )
+            {
+              char *pstring, *cell_measures = NULL, *cell_var = NULL;
 
-      if ( gridInqYvalsPtr(gridID) )
-        {
-          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 1, &dimID, &ncyvarid);
-          cdfGridCompress(fileID, ncyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              pstring = attstring;
 
-          if ( (len = strlen(ystdname)) )
-            cdf_put_att_text(fileID, ncyvarid, "standard_name", len, ystdname);
-          if ( (len = strlen(ylongname)) )
-            cdf_put_att_text(fileID, ncyvarid, "long_name", len, ylongname);
-          if ( (len = strlen(yunits)) )
-            cdf_put_att_text(fileID, ncyvarid, "units", len, yunits);
+              while ( isspace((int) *pstring) ) pstring++;
+              cell_measures = pstring;
+              while ( isalnum((int) *pstring) ) pstring++;
+              *pstring++ = 0;
+              while ( isspace((int) *pstring) ) pstring++;
+              cell_var = pstring;
+              while ( ! isspace((int) *pstring) && *pstring != 0 ) pstring++;
+              *pstring++ = 0;
+              /*
+              printf("cell_measures >%s<\n", cell_measures);
+              printf("cell_var >%s<\n", cell_var);
+              */
+              if ( memcmp(cell_measures, "area", 4) == 0 )
+                {
+                  int status;
+                  int nc_cell_id;
 
-          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+                  status = nc_inq_varid(ncid, cell_var, &nc_cell_id);
+                  if ( status == NC_NOERR )
+                    {
+                      ncvars[ncvarid].cellarea = nc_cell_id;
+                      /* ncvars[nc_cell_id].isvar = UNDEFID; */
+                      cdfSetVar(ncvars, nc_cell_id, FALSE);
+                    }
+                  else
+                    Warning("%s - %s", nc_strerror(status), cell_var);
+                }
+              else
+                {
+                  Warning("%s has an unexpected contents: %s", attname, cell_measures);
+                }
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          /*
+          else if ( strcmp(attname, "coordinates") == 0 )
             {
-              int dimIDs[2];
-              dimIDs[0] = dimID;
-              dimIDs[1] = nvdimID;
-              strcat(yaxisname, "_vertices");
-              cdf_def_var(fileID, yaxisname, (nc_type) xtype, 2, dimIDs, &ncbyvarid);
-              cdfGridCompress(fileID, ncbyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
+              char *pstring, *xvarname = NULL, *yvarname = NULL;
 
-              cdf_put_att_text(fileID, ncyvarid, "bounds", strlen(yaxisname), yaxisname);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              pstring = attstring;
+
+              while ( isspace((int) *pstring) ) pstring++;
+              xvarname = pstring;
+              while ( isgraph((int) *pstring) ) pstring++;
+              *pstring++ = 0;
+              while ( isspace((int) *pstring) ) pstring++;
+              yvarname = pstring;
+              while ( isgraph((int) *pstring) ) pstring++;
+              *pstring++ = 0;
+
+              cdf_inq_varid(ncid, xvarname, &ncvars[ncvarid].xvarid);
+              cdf_inq_varid(ncid, yvarname, &ncvars[ncvarid].yvarid);
+
+              cdfSetVar(ncvars, ncvars[ncvarid].xvarid, FALSE);
+              cdfSetVar(ncvars, ncvars[ncvarid].yvarid, FALSE);
+              cdfSetVar(ncvars, ncvarid, TRUE);
             }
-        }
+          */
+          else if ( (strcmp(attname, "associate")  == 0 || strcmp(attname, "coordinates") == 0) && xtypeIsText(atttype) )
+            {
+              int status;
+              char *pstring, *varname = NULL;
+              int lstop = FALSE;
+              int dimvarid;
+              extern int cdiIgnoreAttCoordinates;
 
-      if ( gridInqAreaPtr(gridID) )
-        {
-          char yaxisname[] = "cell_area";
-          char units[] = "m2";
-          char longname[] = "area of grid cell";
-          char stdname[] = "cell_area";
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              pstring = attstring;
 
-          cdf_def_var(fileID, yaxisname, (nc_type) xtype, 1, &dimID, &ncavarid);
+              for ( i = 0; i < MAX_COORDVARS; i++ )
+                {
+                  while ( isspace((int) *pstring) ) pstring++;
+                  if ( *pstring == 0 ) break;
+                  varname = pstring;
+                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+                  if ( *pstring == 0 ) lstop = TRUE;
+                  *pstring++ = 0;
+
+                  status = nc_inq_varid(ncid, varname, &dimvarid);
+                  if ( status == NC_NOERR )
+                    {
+                      cdfSetVar(ncvars, dimvarid, FALSE);
+                      if ( cdiIgnoreAttCoordinates == FALSE )
+                        {
+                          ncvars[ncvarid].coordvarids[i] = dimvarid;
+                          ncvars[ncvarid].ncoordvars++;
+                        }
+                    }
+                  else
+                    {
+                      int k;
+                      for ( k = 0; k < nchecked_vars; ++k )
+                        if ( strcmp(checked_vars[k], varname) == 0 ) break;
 
-          cdf_put_att_text(fileID, ncavarid, "standard_name", strlen(stdname), stdname);
-          cdf_put_att_text(fileID, ncavarid, "long_name", strlen(longname), longname);
-          cdf_put_att_text(fileID, ncavarid, "units", strlen(units), units);
-        }
+                      if ( k == nchecked_vars )
+                        {
+                          if ( nchecked_vars < 9 ) checked_vars[nchecked_vars++] = strdup(varname);
+                          Warning("%s - %s", nc_strerror(status), varname);
+                        }
+                    }
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+                  if ( lstop ) break;
+                }
 
-      if ( ncxvarid  != UNDEFID ) cdf_put_var_double(fileID, ncxvarid,  gridInqXvalsPtr(gridID));
-      if ( ncbxvarid != UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, gridInqXboundsPtr(gridID));
-      if ( ncyvarid  != UNDEFID ) cdf_put_var_double(fileID, ncyvarid,  gridInqYvalsPtr(gridID));
-      if ( ncbyvarid != UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, gridInqYboundsPtr(gridID));
-      if ( ncavarid  != UNDEFID ) cdf_put_var_double(fileID, ncavarid,  gridInqAreaPtr(gridID));
-    }
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( (strcmp(attname, "auxiliary_variable") == 0) && xtypeIsText(atttype) )
+            {
+              int status;
+              char *pstring, *varname = NULL;
+              int lstop = FALSE;
+              int dimvarid;
+              extern int cdiIgnoreAttCoordinates;
 
-  streamptr->xdimID[gridindex] = dimID;
-  streamptr->ncxvarID[gridindex] = ncxvarid;
-  streamptr->ncyvarID[gridindex] = ncyvarid;
-  streamptr->ncavarID[gridindex] = ncavarid;
-}
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              pstring = attstring;
 
+              for ( i = 0; i < MAX_AUXVARS; i++ )
+                {
+                  while ( isspace((int) *pstring) ) pstring++;
+                  if ( *pstring == 0 ) break;
+                  varname = pstring;
+                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+                  if ( *pstring == 0 ) lstop = TRUE;
+                  *pstring++ = 0;
 
-static
-void cdfDefVCT(stream_t *streamptr, int zaxisID)
-{
-  int type;
+                  status = nc_inq_varid(ncid, varname, &dimvarid);
+                  if ( status == NC_NOERR )
+                    {
+                      cdfSetVar(ncvars, dimvarid, FALSE);
+                      //  if ( cdiIgnoreAttCoordinates == FALSE )
+                        {
+                          ncvars[ncvarid].auxvarids[i] = dimvarid;
+                          ncvars[ncvarid].nauxvars++;
+                        }
+                    }
+                  else
+                    Warning("%s - %s", nc_strerror(status), varname);
 
-  type = zaxisInqType(zaxisID);
-  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
-    {
-      int i;
-      int fileID;
-      int ilev = zaxisInqVctSize(zaxisID)/2;
-      int mlev = ilev - 1;
-      size_t start;
-      size_t count = 1;
-      int ncdimid, ncdimid2;
-      int hyaiid, hybiid, hyamid, hybmid;
-      double mval;
-      char tmpname[CDI_MAX_NAME];
+                  if ( lstop ) break;
+                }
 
-      if ( streamptr->vct.ilev > 0 )
-        {
-          if ( streamptr->vct.ilev != ilev )
-            Error("more than one VCT for each file unsupported!");
-          return;
-        }
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "grid_mapping") == 0 && xtypeIsText(atttype) )
+            {
+              int status;
+              int nc_gmap_id;
 
-      if ( ilev == 0 )
-        {
-          Warning("VCT missing");
-          return;
-        }
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 
-      fileID = streamptr->fileID;
+              status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
+              if ( status == NC_NOERR )
+                {
+                  ncvars[ncvarid].gmapid = nc_gmap_id;
+                  cdfSetVar(ncvars, ncvars[ncvarid].gmapid, FALSE);
+                }
+              else
+                Warning("%s - %s", nc_strerror(status), attstring);
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "positive") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
 
-      cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
-      cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
+              if    ( memcmp(attstring, "down", 4) == 0 ) ncvars[ncvarid].positive = POSITIVE_DOWN;
+              else if ( memcmp(attstring, "up", 2) == 0 ) ncvars[ncvarid].positive = POSITIVE_UP;
 
-      streamptr->vct.mlev   = mlev;
-      streamptr->vct.ilev   = ilev;
-      streamptr->vct.mlevID = ncdimid;
-      streamptr->vct.ilevID = ncdimid2;
+              if ( ncvars[ncvarid].ndims == 1 )
+                {
+                  cdfSetVar(ncvars, ncvarid, FALSE);
+                  cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
+                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
+                }
+            }
+          else if ( strcmp(attname, "_FillValue") == 0 && !xtypeIsText(atttype) )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
+	      ncvars[ncvarid].deffillval = TRUE;
+	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "missing_value") == 0 && !xtypeIsText(atttype) )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
+	      ncvars[ncvarid].defmissval = TRUE;
+	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
+            {
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                      if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
+                        ncvars[ncvarid].lunsigned = TRUE;
+                      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
+                    }
+                }
+            }
+          else if ( strcmp(attname, "valid_min") == 0 && attlen == 1 )
+            {
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
+                    }
+                }
+            }
+          else if ( strcmp(attname, "valid_max") == 0 && attlen == 1 )
+            {
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
+                    }
+                }
+            }
+          else if ( strcmp(attname, "_Unsigned") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
 
-      cdf_def_var(fileID, "hyai", NC_DOUBLE, 1, &ncdimid2, &hyaiid);
-      cdf_def_var(fileID, "hybi", NC_DOUBLE, 1, &ncdimid2, &hybiid);
-      cdf_def_var(fileID, "hyam", NC_DOUBLE, 1, &ncdimid,  &hyamid);
-      cdf_def_var(fileID, "hybm", NC_DOUBLE, 1, &ncdimid,  &hybmid);
+              if ( memcmp(attstring, "true", 4) == 0 )
+                {
+                  ncvars[ncvarid].lunsigned = TRUE;
+                  /*
+                  ncvars[ncvarid].lvalidrange = TRUE;
+                  ncvars[ncvarid].validrange[0] = 0;
+                  ncvars[ncvarid].validrange[1] = 255;
+                  */
+                }
+	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "cdi") == 0 && xtypeIsText(atttype) )
+            {
+	      cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+	      strtolower(attstring);
 
-      strcpy(tmpname, "hybrid A coefficient at layer interfaces");
-      cdf_put_att_text(fileID, hyaiid, "long_name", strlen(tmpname), tmpname);
-      strcpy(tmpname, "Pa");
-      cdf_put_att_text(fileID, hyaiid, "units", strlen(tmpname), tmpname);
-      strcpy(tmpname, "hybrid B coefficient at layer interfaces");
-      cdf_put_att_text(fileID, hybiid, "long_name", strlen(tmpname), tmpname);
-      strcpy(tmpname, "1");
-      cdf_put_att_text(fileID, hybiid, "units", strlen(tmpname), tmpname);
-      strcpy(tmpname, "hybrid A coefficient at layer midpoints");
-      cdf_put_att_text(fileID, hyamid, "long_name", strlen(tmpname), tmpname);
-      strcpy(tmpname, "Pa");
-      cdf_put_att_text(fileID, hyamid, "units", strlen(tmpname), tmpname);
-      strcpy(tmpname, "hybrid B coefficient at layer midpoints");
-      cdf_put_att_text(fileID, hybmid, "long_name", strlen(tmpname), tmpname);
-      strcpy(tmpname, "1");
-      cdf_put_att_text(fileID, hybmid, "units", strlen(tmpname), tmpname);
+	      if ( memcmp(attstring, "ignore", 6) == 0 )
+		{
+		  ncvars[ncvarid].ignore = TRUE;
+		  cdfSetVar(ncvars, ncvarid, FALSE);
+		}
+            }
+          else if ( strcmp(attname, "axis") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+	      attlen = strlen(attstring);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+	      if ( (int) attlen > nvdims )
+		{
+		  if ( nvdims > 0 )
+		    Warning("Unexpected axis attribute length for %s, ignored!", name);
+		}
+	      else
+		{
+		  strtolower(attstring);
+		  for ( i = 0; i < (int)attlen; ++i )
+		    {
+		      if ( attstring[i] != '-' && attstring[i] != 't' && attstring[i] != 'z' &&
+			   attstring[i] != 'y' && attstring[i] != 'x' )
+			{
+			  Warning("Unexpected character in axis attribute for %s, ignored!", name);
+			  break;
+			}
+		    }
 
-      const double *vctptr = zaxisInqVctPtr(zaxisID);
+		  if ( i == (int) attlen && (int) attlen == nvdims)
+		    {
+		      while ( attlen-- )
+			{
+			  if ( (int) attstring[attlen] == 't' )
+			    {
+			      if ( attlen != 0 ) Warning("axis attribute 't' not on first position");
+			      cdfSetDim(ncvars, ncvarid, (int)attlen, T_AXIS);
+			    }
+			  else if ( (int) attstring[attlen] == 'z' )
+			    {
+			      ncvars[ncvarid].zdim = dimidsp[attlen];
+			      cdfSetDim(ncvars, ncvarid, (int)attlen, Z_AXIS);
 
-      cdf_put_var_double(fileID, hyaiid, vctptr);
-      cdf_put_var_double(fileID, hybiid, vctptr+ilev);
+			      if ( ncvars[ncvarid].ndims == 1 )
+				{
+				  cdfSetVar(ncvars, ncvarid, FALSE);
+				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
+				}
+			    }
+			  else if ( (int) attstring[attlen] == 'y' )
+			    {
+			      ncvars[ncvarid].ydim = dimidsp[attlen];
+			      cdfSetDim(ncvars, ncvarid, (int)attlen, Y_AXIS);
 
-      for ( i = 0; i < mlev; i++ )
-        {
-          start = (size_t)i;
-          mval = (vctptr[i] + vctptr[i+1]) * 0.5;
-          cdf_put_vara_double(fileID, hyamid, &start, &count, &mval);
-          mval = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
-          cdf_put_vara_double(fileID, hybmid, &start, &count, &mval);
-        }
-    }
-}
+			      if ( ncvars[ncvarid].ndims == 1 )
+				{
+				  cdfSetVar(ncvars, ncvarid, FALSE);
+				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Y_AXIS;
+				}
+			    }
+			  else if ( (int) attstring[attlen] == 'x' )
+			    {
+			      ncvars[ncvarid].xdim = dimidsp[attlen];
+			      cdfSetDim(ncvars, ncvarid, (int)attlen, X_AXIS);
 
+			      if ( ncvars[ncvarid].ndims == 1 )
+				{
+				  cdfSetVar(ncvars, ncvarid, FALSE);
+				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = X_AXIS;
+				}
+			    }
+			}
+		    }
+		}
+	    }
+	  else if ( ( strcmp(attname, "realization") == 0 )         ||
+	            ( strcmp(attname, "ensemble_members") == 0 )    ||
+	            ( strcmp(attname, "forecast_init_type") == 0 )    )
+	    {
+	      int temp;
 
-static
-void cdfDefZaxis(stream_t *streamptr, int zaxisID)
-{
-  /*  char zaxisname0[CDI_MAX_NAME]; */
-  char axisname[CDI_MAX_NAME];
-  char stdname[CDI_MAX_NAME];
-  char longname[CDI_MAX_NAME];
-  char units[CDI_MAX_NAME];
-  char tmpname[CDI_MAX_NAME];
-  int index;
-  int zaxisID0;
-  int dimID = UNDEFID;
-  int dimIDs[2];
-  int fileID;
-  size_t len;
-  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
-  int nvdimID = UNDEFID;
-  int type;
-  int nzaxis;
-  int ilevel = 0;
-  int vlistID;
-  int zaxisindex;
-  int xtype = NC_DOUBLE;
-  int positive;
+	      if( ncvars[ncvarid].ensdata == NULL )
+		ncvars[ncvarid].ensdata = (ensinfo_t *) malloc( sizeof( ensinfo_t ) );
 
-  if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+	      cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+	      if( strcmp(attname, "realization") == 0 )
+		ncvars[ncvarid].ensdata->ens_index = temp;
+	      else if( strcmp(attname, "ensemble_members") == 0 )
+		ncvars[ncvarid].ensdata->ens_count = temp;
+	      else if( strcmp(attname, "forecast_init_type") == 0 )
+		ncvars[ncvarid].ensdata->forecast_init_type = temp;
 
-  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+	      cdfSetVar(ncvars, ncvarid, TRUE);
+	    }
+	  else
+	    {
+	      if ( ncvars[ncvarid].natts == 0 )
+		ncvars[ncvarid].atts
+                  = (int *)xmalloc((size_t)nvatts * sizeof (int));
 
-  nzaxis = vlistNzaxis(vlistID);
+	      ncvars[ncvarid].atts[ncvars[ncvarid].natts++] = iatt;
+	      /*
+	      int attrint;
+	      double attrflt;
+	      nc_type attrtype;
+	      cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+	      cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
+	      if ( attlen == 1 && (attrtype == NC_INT || attrtype == NC_SHORT) )
+		{
+		  cdfGetAttInt(ncid, ncvarid, attname, 1, &attrint);
+		  printf("int: %s.%s = %d\n", ncvars[ncvarid].name, attname, attrint);
+		}
+	      else if ( attlen == 1 && (attrtype == NC_FLOAT || attrtype == NC_DOUBLE) )
+		{
+		  cdfGetAttDouble(ncid, ncvarid, attname, 1, &attrflt);
+		  printf("flt: %s.%s = %g\n", ncvars[ncvarid].name, attname, attrflt);
+		}
+	      else if ( attrtype == NC_CHAR )
+		{
+		  cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+		  attstring[attlen] = 0;
+		  printf("txt: %s.%s = %s\n", ncvars[ncvarid].name, attname, attstring);
+		}
+	      else
+		printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
+	      */
+	    }
+	}
+    }
 
-  size_t dimlen = (size_t)zaxisInqSize(zaxisID);
-  type   = zaxisInqType(zaxisID);
+  for ( i = 0; i < 9; ++i ) if ( checked_vars[i] ) free(checked_vars[i]);
+}
 
-  if (dimlen == 1)
-    switch (type)
-      {
-      case ZAXIS_SURFACE:
-      case ZAXIS_CLOUD_BASE:
-      case ZAXIS_CLOUD_TOP:
-      case ZAXIS_ISOTHERM_ZERO:
-      case ZAXIS_TOA:
-      case ZAXIS_SEA_BOTTOM:
-      case ZAXIS_ATMOSPHERE:
-      case ZAXIS_MEANSEA:
-      case ZAXIS_LAKE_BOTTOM:
-      case ZAXIS_SEDIMENT_BOTTOM:
-      case ZAXIS_SEDIMENT_BOTTOM_TA:
-      case ZAXIS_SEDIMENT_BOTTOM_TW:
-      case ZAXIS_MIX_LAYER:
-        return;
-      }
+static
+void setDimType(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
+{
+  int ndims;
+  int ncvarid, ncdimid;
+  int i;
 
-  zaxisInqName(zaxisID, axisname);
-  /*
-  for ( index = 0; index < nzaxis; index++ )
-    {
-      if ( streamptr->zaxisID[index] != UNDEFID )
-        {
-          zaxisID0 = vlistZaxis(vlistID, index);
-          zaxisInqName(zaxisID0, zaxisname0);
-          if ( strcmp(zaxisname0, axisname) == 0 ) ilevel++;
-        }
-    }
-  */
-  if ( dimID == UNDEFID )
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      char axisname0[CDI_MAX_NAME];
-      char axisname2[CDI_MAX_NAME];
-      int checkname = FALSE;
-      int status;
+      if ( ncvars[ncvarid].isvar == TRUE )
+	{
+	  int lxdim = 0, lydim = 0, lzdim = 0/* , ltdim = 0 */;
+	  ndims = ncvars[ncvarid].ndims;
+	  for ( i = 0; i < ndims; i++ )
+	    {
+	      ncdimid = ncvars[ncvarid].dimids[i];
+	      if      ( ncdims[ncdimid].dimtype == X_AXIS ) cdfSetDim(ncvars, ncvarid, i, X_AXIS);
+	      else if ( ncdims[ncdimid].dimtype == Y_AXIS ) cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
+	      else if ( ncdims[ncdimid].dimtype == Z_AXIS ) cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
+	      else if ( ncdims[ncdimid].dimtype == T_AXIS ) cdfSetDim(ncvars, ncvarid, i, T_AXIS);
+	    }
 
-      /* check that the name is not already defined */
-      checkname = TRUE;
-      ilevel = 0;
+	  if ( CDI_Debug )
+	    {
+	      Message("var %d %s", ncvarid, ncvars[ncvarid].name);
+	      for ( i = 0; i < ndims; i++ )
+		printf("  dim%d type=%d  ", i, ncvars[ncvarid].dimtype[i]);
+	      printf("\n");
+	    }
 
-      while ( checkname )
-        {
-          strcpy(axisname2, axisname);
-          if ( ilevel ) sprintf(&axisname2[strlen(axisname2)], "_%d", ilevel+1);
+	  for ( i = 0; i < ndims; i++ )
+	    {
+	      if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) lxdim = TRUE;
+	      else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) lydim = TRUE;
+	      else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) lzdim = TRUE;
+	      /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = TRUE; */
+	    }
 
-          status = nc_inq_varid(fileID, axisname2, &ncvarid);
-          if ( status != NC_NOERR )
+          if ( lxdim == FALSE && ncvars[ncvarid].xvarid != UNDEFID )
             {
-              if ( ilevel )
-                {
-                  /* check that the name does not exist for other grids */
-                  for ( index = 0; index < nzaxis; index++ )
-                    {
-                      zaxisID0 = vlistZaxis(vlistID, index);
-                      if ( zaxisID != zaxisID0 )
-                        {
-                          zaxisInqName(zaxisID0, axisname0);
-                          if ( strcmp(axisname0, axisname2) == 0 ) break;
-                        }
-                    }
-                  if ( index == nzaxis ) checkname = FALSE;
-                }
-              else
-                {
-                  checkname = FALSE;
-                }
+              if (  ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = TRUE;
             }
 
-          if ( checkname ) ilevel++;
+          if ( lydim == FALSE && ncvars[ncvarid].yvarid != UNDEFID )
+            {
+              if (  ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = TRUE;
+            }
+
+          //   if ( ndims > 1 )
+            for ( i = ndims-1; i >= 0; i-- )
+              {
+                if ( ncvars[ncvarid].dimtype[i] == -1 )
+                  {
+                    if ( lxdim == FALSE )
+                      {
+                        cdfSetDim(ncvars, ncvarid, i, X_AXIS);
+                        lxdim = TRUE;
+                      }
+                    else if ( lydim == FALSE && ncvars[ncvarid].gridtype != GRID_UNSTRUCTURED )
+                      {
+                        cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
+                        lydim = TRUE;
+                      }
+                    else if ( lzdim == FALSE )
+                      {
+                        cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
+                        lzdim = TRUE;
+                      }
+                  }
+              }
+	}
+    }
+}
 
-          if ( ilevel > 99 ) break;
-        }
+/* verify coordinate vars - first scan (dimname == varname) */
+static
+void verify_coordinate_vars_1(int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid)
+{
+  int ncdimid, ncvarid;
 
-      if ( ilevel ) sprintf(&axisname[strlen(axisname)], "_%1d", ilevel+1);
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+    {
+      ncvarid = ncdims[ncdimid].ncvarid;
+      if ( ncvarid != -1 )
+	{
+	  if ( ncvars[ncvarid].dimids[0] == timedimid )
+	    {
+              ncvars[ncvarid].istime = TRUE;
+	      ncdims[ncdimid].dimtype = T_AXIS;
+	      continue;
+	    }
 
-      if ( type == ZAXIS_REFERENCE )
-	cdfDefZaxisUUID(streamptr, zaxisID);
+	  if ( ncvars[ncvarid].units[0] != 0 )
+	    {
+	      if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+		{
+		  ncvars[ncvarid].islon = TRUE;
+		  cdfSetVar(ncvars, ncvarid, FALSE);
+		  cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
+		  ncdims[ncdimid].dimtype = X_AXIS;
+		}
+	      else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+		{
+		  ncvars[ncvarid].islat = TRUE;
+		  cdfSetVar(ncvars, ncvarid, FALSE);
+		  cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
+		  ncdims[ncdimid].dimtype = Y_AXIS;
+		}
+	      else if ( unitsIsPressure(ncvars[ncvarid].units) )
+		{
+		  ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
+		}
+	      else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
+		{
+		  if      ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+		  else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+		  else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
+		}
+	      else if ( isDBLAxis(ncvars[ncvarid].longname) )
+                {
+                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+		}
+	      else if ( unitsIsMeter(ncvars[ncvarid].units) )
+		{
+		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
+		  else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
+		}
+	    }
 
-      if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
-        {
-          if ( type == ZAXIS_HYBRID )
-            {
-	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+	  if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
+               ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
+	    {
+	      if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
+		{
+		  ncvars[ncvarid].islon = TRUE;
+		  cdfSetVar(ncvars, ncvarid, FALSE);
+		  cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
+		  ncdims[ncdimid].dimtype = X_AXIS;
+		  continue;
+		}
+	      else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
+		{
+		  ncvars[ncvarid].islat = TRUE;
+		  cdfSetVar(ncvars, ncvarid, FALSE);
+		  cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
+		  ncdims[ncdimid].dimtype = Y_AXIS;
+		  continue;
+		}
+	    }
 
-	      cdf_def_dim(fileID, axisname, dimlen, &dimID);
-	      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID,  &ncvarid);
+	  if ( ncvars[ncvarid].zaxistype != UNDEFID )
+	    {
+              ncvars[ncvarid].islev = TRUE;
+	      cdfSetVar(ncvars, ncvarid, FALSE);
+	      cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
+	      ncdims[ncdimid].dimtype = Z_AXIS;
+	    }
+	}
+    }
+}
 
-	      strcpy(tmpname, "hybrid_sigma_pressure");
-	      cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "hybrid level at layer midpoints");
-	      cdf_put_att_text(fileID, ncvarid, "long_name", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "level");
-	      cdf_put_att_text(fileID, ncvarid, "units", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "down");
-	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "hyam hybm (mlev=hyam+hybm*aps)");
-	      cdf_put_att_text(fileID, ncvarid, "formula", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "ap: hyam b: hybm ps: aps");
-	      cdf_put_att_text(fileID, ncvarid, "formula_terms", strlen(tmpname), tmpname);
-	      /*
-	      strcpy(tmpname, "ilev");
-	      cdf_put_att_text(fileID, ncvarid, "borders", strlen(tmpname), tmpname);
-	      */
-	      cdf_enddef(fileID);
-	      streamptr->ncmode = 2;
+/* verify coordinate vars - second scan (all other variables) */
+static
+void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
+{
+  int ncvarid;
 
-	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    {
+      if ( ncvars[ncvarid].isvar == 0 )
+	{
+	  if ( ncvars[ncvarid].units[0] != 0 )
+	    {
+	      if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+		{
+		  ncvars[ncvarid].islon = TRUE;
+		  continue;
+		}
+	      else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
+		{
+		  ncvars[ncvarid].islat = TRUE;
+		  continue;
+		}
+	      else if ( unitsIsPressure(ncvars[ncvarid].units) )
+		{
+		  ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
+		  continue;
+		}
+	      else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
+		{
+		  if      ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
+		  else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
+		  else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
+		    ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
+		  continue;
+		}
+	      else if ( isDBLAxis(ncvars[ncvarid].longname) )
+		{
+                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+		  continue;
+		}
+	      else if ( unitsIsMeter(ncvars[ncvarid].units) )
+		{
+		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
+		  else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
+		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
+		  continue;
+		}
             }
 
-          if ( type == ZAXIS_HYBRID_HALF )
-            {
-	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+	  /* not needed anymore for rotated grids */
+	  if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
+               ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
+	    {
+	      if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
+		{
+		  ncvars[ncvarid].islon = TRUE;
+		  continue;
+		}
+	      else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
+		{
+		  ncvars[ncvarid].islat = TRUE;
+		  continue;
+		}
+	    }
+	}
+    }
+}
 
-	      cdf_def_dim(fileID, axisname, dimlen, &dimID);
-	      cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID,  &ncvarid);
+#if defined (PROJECTION_TEST)
+static
+void copy_numeric_projatts(int gridID, int ncvarID, int ncfileID)
+{
+  int iatt, nvatts;
+  size_t attlen;
+  char attname[CDI_MAX_NAME];
+  nc_type xtype;
 
-	      strcpy(tmpname, "hybrid_sigma_pressure");
-	      cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "hybrid level at layer interfaces");
-	      cdf_put_att_text(fileID, ncvarid, "long_name", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "level");
-	      cdf_put_att_text(fileID, ncvarid, "units", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "down");
-	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "hyai hybi (ilev=hyai+hybi*aps)");
-	      cdf_put_att_text(fileID, ncvarid, "formula", strlen(tmpname), tmpname);
-	      strcpy(tmpname, "ap: hyai b: hybi ps: aps");
-	      cdf_put_att_text(fileID, ncvarid, "formula_terms", strlen(tmpname), tmpname);
+  cdf_inq_varnatts(ncfileID, ncvarID, &nvatts);
 
-	      cdf_enddef(fileID);
-	      streamptr->ncmode = 2;
+  for ( iatt = 0; iatt < nvatts; iatt++ )
+    {
+      cdf_inq_attname(ncfileID, ncvarID, iatt, attname);
+      cdf_inq_atttype(ncfileID, ncvarID, attname, &xtype);
+      cdf_inq_attlen(ncfileID, ncvarID, attname, &attlen);
 
-	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
-            }
+      //  printf("%s %d\n", attname, (int)attlen);
+    }
 
-          cdfDefVCT(streamptr, zaxisID);
+}
+#endif
 
-          if ( dimID == UNDEFID )
-            {
-              if ( type == ZAXIS_HYBRID )
-                streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
-              else
-                streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
-            }
+static
+void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
+{
+  if ( ncvar->chunked )
+    {
+      int ndims = ncvar->ndims;
+
+      if ( grid->type == GRID_UNSTRUCTURED )
+        {
+          if ( ncvar->chunks[ndims-1] == grid->size )
+            ncvar->chunktype = CHUNK_GRID;
+          else
+            ncvar->chunktype = CHUNK_AUTO;
         }
       else
         {
-          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          if ( grid->xsize > 1 && grid->ysize > 1 && ndims > 1 &&
+               grid->xsize == ncvar->chunks[ndims-1] &&
+               grid->ysize == ncvar->chunks[ndims-2] )
+            ncvar->chunktype = CHUNK_GRID;
+          else if ( grid->xsize > 1 && grid->xsize == ncvar->chunks[ndims-1] )
+            ncvar->chunktype = CHUNK_LINES;
+          else
+            ncvar->chunktype = CHUNK_AUTO;
+        }
+    }
+}
 
-          cdf_def_dim(fileID, axisname, dimlen, &dimID);
+/* define all input grids */
+static
+void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
+{
+  int ncvarid, ncvarid2;
+  int ndims;
+  int nbdims;
+  int i;
+  int nvatts;
+  int skipvar;
+  size_t nvertex;
+  grid_t grid;
+  grid_t proj;
+  int gridindex;
+  size_t size = 0, xsize, ysize, np;
+  char name[CDI_MAX_NAME];
+  int iatt;
+  int ltwarn = TRUE;
+  size_t attlen;
+  char attname[CDI_MAX_NAME];
+  double datt;
 
-          zaxisInqLongname(zaxisID, longname);
-          zaxisInqUnits(zaxisID, units);
-          zaxisInqStdname(zaxisID, stdname);
+  for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
+    {
+      if ( ncvars[ncvarid].isvar && ncvars[ncvarid].gridID == UNDEFID )
+	{
+	  int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
+	  int xdimid = -1, ydimid = -1;
+	  int xvarid = -1, yvarid = -1;
+	  int islon = 0, islat = 0;
+	  int nxdims = 0, nydims = 0;
+	  double xinc = 0, yinc = 0;
 
-          cdf_def_var(fileID, axisname, (nc_type) xtype, 1, &dimID, &ncvarid);
+	  xsize = 0;
+	  ysize = 0;
+          np    = 0;
 
-          if ( (len = strlen(stdname)) )
-            cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
-          if ( (len = strlen(longname)) )
-            cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
-          if ( (len = strlen(units)) )
-            cdf_put_att_text(fileID, ncvarid, "units", len, units);
+	  ndims = ncvars[ncvarid].ndims;
+	  for ( i = 0; i < ndims; i++ )
+	    {
+	      if ( ncvars[ncvarid].dimtype[i] == X_AXIS && nxdims < 2 )
+		{
+		  xdimids[nxdims] = ncvars[ncvarid].dimids[i];
+		  nxdims++;
+		}
+	      else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS && nydims < 2 )
+		{
+		  ydimids[nydims] = ncvars[ncvarid].dimids[i];
+		  nydims++;
+		}
+	    }
 
-	  positive = zaxisInqPositive(zaxisID);
-	  if ( positive == POSITIVE_UP )
+	  if ( nxdims == 2 )
 	    {
-	      strcpy(tmpname, "up");
-	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
+	      xdimid = xdimids[1];
+	      ydimid = xdimids[0];
 	    }
-	  else if ( positive == POSITIVE_DOWN )
+	  else if ( nydims == 2 )
 	    {
-	      strcpy(tmpname, "down");
-	      cdf_put_att_text(fileID, ncvarid, "positive", strlen(tmpname), tmpname);
+	      xdimid = ydimids[1];
+	      ydimid = ydimids[0];
 	    }
-
-          cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
-
-	  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-            {
-              size_t nvertex = 2;
-	      if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-		cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
-
-	      if ( nvdimID != UNDEFID )
-		{
-		  strcat(axisname, "_bnds");
-		  dimIDs[0] = dimID;
-		  dimIDs[1] = nvdimID;
-		  cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
-		  cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
-		}
+	  else
+	    {
+	      xdimid = xdimids[0];
+	      ydimid = ydimids[0];
 	    }
 
-          cdf_enddef(fileID);
-          streamptr->ncmode = 2;
+	  if ( ncvars[ncvarid].xvarid != UNDEFID )
+	    xvarid = ncvars[ncvarid].xvarid;
+	  else if ( xdimid != UNDEFID )
+	    xvarid = ncdims[xdimid].ncvarid;
 
-          cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+	  if ( ncvars[ncvarid].yvarid != UNDEFID )
+	    yvarid = ncvars[ncvarid].yvarid;
+	  else if ( ydimid != UNDEFID )
+	    yvarid = ncdims[ydimid].ncvarid;
 
-          if ( ncbvarid != UNDEFID )
-	    {
-	      double *zbounds, *lbounds, *ubounds;
+	  /*
+	  if ( xdimid != UNDEFID )
+	    xvarid = ncdims[xdimid].ncvarid;
+	  if ( xvarid == UNDEFID && ncvars[ncvarid].xvarid != UNDEFID )
+	    xvarid = ncvars[ncvarid].xvarid;
 
-	      lbounds = (double *) malloc(dimlen*sizeof(double));
-	      ubounds = (double *) malloc(dimlen*sizeof(double));
-	      zbounds = (double *) malloc(2*dimlen*sizeof(double));
+	  if ( ydimid != UNDEFID )
+	    yvarid = ncdims[ydimid].ncvarid;
+	  if ( yvarid == UNDEFID && ncvars[ncvarid].yvarid != UNDEFID )
+	    yvarid = ncvars[ncvarid].yvarid;
+	  */
 
-	      zaxisInqLbounds(zaxisID, lbounds);
-	      zaxisInqUbounds(zaxisID, ubounds);
+	  if ( xdimid != UNDEFID ) xsize = ncdims[xdimid].len;
+	  if ( ydimid != UNDEFID ) ysize = ncdims[ydimid].len;
 
-	      for (size_t i = 0; i < dimlen; ++i )
+	  if ( ydimid == UNDEFID && yvarid != UNDEFID )
+	    {
+	      if ( ncvars[yvarid].ndims == 1 )
 		{
-		  zbounds[2*i  ] = lbounds[i];
-		  zbounds[2*i+1] = ubounds[i];
+		  ydimid = ncvars[yvarid].dimids[0];
+		  ysize  = ncdims[ydimid].len;
 		}
+	    }
 
-	      cdf_put_var_double(fileID, ncbvarid, zbounds);
+	  if ( ncvars[ncvarid].gridtype == UNDEFID || ncvars[ncvarid].gridtype == GRID_GENERIC )
+	    if ( xdimid != UNDEFID && xdimid == ydimid ) ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
 
-	      free(zbounds);
-	      free(ubounds);
-	      free(lbounds);
+	  grid_init(&grid);
+	  grid_init(&proj);
+
+	  grid.prec  = DATATYPE_FLT64;
+	  grid.trunc = ncvars[ncvarid].truncation;
+
+	  if ( ncvars[ncvarid].gridtype == GRID_TRAJECTORY )
+	    {
+	      if ( ncvars[ncvarid].xvarid == UNDEFID )
+		Error("Longitude coordinate undefined for %s!", name);
+	      if ( ncvars[ncvarid].yvarid == UNDEFID )
+		Error("Latitude coordinate undefined for %s!", name);
 	    }
-        }
-    }
+	  else
+	    {
+	      size_t start[3], count[3];
+	      int ltgrid = FALSE;
 
-  if ( dimID != UNDEFID )
-    streamptr->zaxisID[zaxisindex] = dimID;
-}
+	      if ( xvarid != UNDEFID && yvarid != UNDEFID )
+		{
+		  if ( ncvars[xvarid].ndims != ncvars[yvarid].ndims )
+		    {
+		      Warning("Inconsistent grid structure for variable %s!", ncvars[ncvarid].name);
+		      ncvars[ncvarid].xvarid = UNDEFID;
+		      ncvars[ncvarid].yvarid = UNDEFID;
+		      xvarid = UNDEFID;
+		      yvarid = UNDEFID;
+		    }
+
+		  if ( ncvars[xvarid].ndims > 2 || ncvars[yvarid].ndims > 2 )
+		    {
+		      if ( ncvars[xvarid].ndims == 3 && ncvars[xvarid].dimids[0] == timedimid &&
+			   ncvars[yvarid].ndims == 3 && ncvars[yvarid].dimids[0] == timedimid )
+			{
+			  if ( ltwarn )
+			    Warning("Time varying grids unsupported, using grid at time step 1!");
+			  ltgrid = TRUE;
+			  ltwarn = FALSE;
+			  start[0] = start[1] = start[2] = 0;
+			  count[0] = 1; count[1] = ysize; count[2] = xsize;
+			}
+		      else
+			{
+			  Warning("Unsupported grid structure for variable %s (grid dims > 2)!", ncvars[ncvarid].name);
+			  ncvars[ncvarid].xvarid = UNDEFID;
+			  ncvars[ncvarid].yvarid = UNDEFID;
+			  xvarid = UNDEFID;
+			  yvarid = UNDEFID;
+			}
+		    }
+		}
 
+              if ( xvarid != UNDEFID )
+                {
+                  if ( ncvars[xvarid].ndims > 3 || (ncvars[xvarid].ndims == 3 && ltgrid == FALSE) )
+                    {
+                      Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[xvarid].name, ncvars[xvarid].ndims);
+                      //ncvars[ncvarid].xvarid = UNDEFID;
+                      xvarid = UNDEFID;
+                    }
+                }
 
-static
-void cdfDefPole(stream_t *streamptr, int gridID)
-{
-  int fileID;
-  int ncvarid = UNDEFID;
-  int ncerr;
-  double xpole, ypole, angle;
-  char varname[] = "rotated_pole";
-  char mapname[] = "rotated_latitude_longitude";
+              if ( yvarid != UNDEFID )
+                {
+                  if ( ncvars[yvarid].ndims > 3 || (ncvars[yvarid].ndims == 3 && ltgrid == FALSE) )
+                    {
+                      Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
+                      //ncvars[ncvarid].yvarid = UNDEFID;
+                      yvarid = UNDEFID;
+                    }
+                }
 
-  fileID  = streamptr->fileID;
+              if ( xvarid != UNDEFID )
+		{
+                  skipvar = TRUE;
+		  islon = ncvars[xvarid].islon;
+		  ndims = ncvars[xvarid].ndims;
+		  if ( ndims == 2 || ndims == 3 )
+		    {
+		      ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
+		      size = xsize*ysize;
+		      /* Check size of 2 dimensional coordinate variables */
+		      {
+			int dimid;
+			size_t dimsize1, dimsize2;
+			dimid = ncvars[xvarid].dimids[ndims-2];
+			dimsize1 = ncdims[dimid].len;
+			dimid = ncvars[xvarid].dimids[ndims-1];
+			dimsize2 = ncdims[dimid].len;
+			if ( dimsize1*dimsize2 == size ) skipvar = FALSE;
+		      }
+		    }
+		  else if ( ndims == 1 )
+		    {
+		      size = xsize;
+		      /* Check size of 1 dimensional coordinate variables */
+		      {
+			int dimid;
+			size_t dimsize;
+			dimid = ncvars[xvarid].dimids[0];
+			dimsize = ncdims[dimid].len;
+			if ( dimsize == size ) skipvar = FALSE;
+		      }
+		    }
+		  else if ( ndims == 0 && xsize == 0 )
+		    {
+                      xsize = 1;
+		      size = xsize;
+                      skipvar = FALSE;
+		    }
 
-  ypole = gridInqYpole(gridID);
-  xpole = gridInqXpole(gridID);
-  angle = gridInqAngle(gridID);
+                  if ( skipvar )
+                    {
+                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = -1;
+                      continue;
+                    }
 
-  cdf_redef(fileID);
+		  if ( ncvars[xvarid].xtype == NC_FLOAT ) grid.prec = DATATYPE_FLT32;
+		  grid.xvals = (double *) malloc(size*sizeof(double));
 
-  ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
-  if ( ncerr == NC_NOERR )
-    {
-      cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
-      cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
-      cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
-      if ( angle > 0 )
-        cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1, &angle);
-    }
+		  if ( ltgrid )
+		    cdf_get_vara_double(ncvars[xvarid].ncid, xvarid, start, count, grid.xvals);
+		  else
+		    cdf_get_var_double(ncvars[xvarid].ncid, xvarid, grid.xvals);
 
-  cdf_enddef(fileID);
-}
+                  scale_add(size, grid.xvals, ncvars[xvarid].addoffset, ncvars[xvarid].scalefactor);
 
+		  strcpy(grid.xname, ncvars[xvarid].name);
+		  strcpy(grid.xlongname, ncvars[xvarid].longname);
+		  strcpy(grid.xunits, ncvars[xvarid].units);
+		  /* don't change the name !!! */
+		  /*
+		  if ( (len = strlen(grid.xname)) > 2 )
+		    if ( grid.xname[len-2] == '_' && isdigit((int) grid.xname[len-1]) )
+		      grid.xname[len-2] = 0;
+		  */
+		  if ( islon && xsize > 1 )
+		    {
+		      xinc = fabs(grid.xvals[0] - grid.xvals[1]);
+		      for ( i = 2; i < (int) xsize; i++ )
+			if ( (fabs(grid.xvals[i-1] - grid.xvals[i]) - xinc) > (xinc/1000) ) break;
 
-static
-void cdfDefMapping(stream_t *streamptr, int gridID)
-{
-  int fileID;
-  int ncvarid = UNDEFID;
-  int ncerr;
+		      if ( i < (int) xsize ) xinc = 0;
+		    }
+		}
 
-  if ( gridInqType(gridID) == GRID_SINUSOIDAL )
-    {
-      char varname[] = "sinusoidal";
-      char mapname[] = "sinusoidal";
+	      if ( yvarid != UNDEFID )
+		{
+                  skipvar = TRUE;
+		  islat = ncvars[yvarid].islat;
+		  ndims = ncvars[yvarid].ndims;
+		  if ( ndims == 2 || ndims == 3 )
+		    {
+		      ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
+		      size = xsize*ysize;
+		      /* Check size of 2 dimensional coordinate variables */
+		      {
+			int dimid;
+			size_t dimsize1, dimsize2;
+			dimid = ncvars[yvarid].dimids[ndims-2];
+			dimsize1 = ncdims[dimid].len;
+			dimid = ncvars[yvarid].dimids[ndims-1];
+			dimsize2 = ncdims[dimid].len;
+			if ( dimsize1*dimsize2 == size ) skipvar = FALSE;
+		      }
+		    }
+		  else if ( ndims == 1 )
+		    {
+		      if ( (int) ysize == 0 ) size = xsize;
+		      else                    size = ysize;
 
-      fileID  = streamptr->fileID;
+		      /* Check size of 1 dimensional coordinate variables */
+		      {
+			int dimid;
+			size_t dimsize;
+			dimid = ncvars[yvarid].dimids[0];
+			dimsize = ncdims[dimid].len;
+			if ( dimsize == size ) skipvar = FALSE;
+		      }
+		    }
+		  else if ( ndims == 0 && ysize == 0 )
+		    {
+                      ysize = 1;
+		      size = ysize;
+                      skipvar = FALSE;
+		    }
 
-      cdf_redef(fileID);
+                  if ( skipvar )
+                    {
+                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = -1;
+                      continue;
+                    }
 
-      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
-      if ( ncerr == NC_NOERR )
-        {
-          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
-          /*
-          cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
-          cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
-          */
-        }
+		  if ( ncvars[yvarid].xtype == NC_FLOAT ) grid.prec = DATATYPE_FLT32;
+		  grid.yvals = (double *) malloc(size*sizeof(double));
 
-      cdf_enddef(fileID);
-    }
-  else if ( gridInqType(gridID) == GRID_LAEA )
-    {
-      char varname[] = "laea";
-      char mapname[] = "lambert_azimuthal_equal_area";
+		  if ( ltgrid )
+		    cdf_get_vara_double(ncvars[yvarid].ncid, yvarid, start, count, grid.yvals);
+		  else
+		    cdf_get_var_double(ncvars[yvarid].ncid, yvarid, grid.yvals);
 
-      fileID  = streamptr->fileID;
+                  scale_add(size, grid.yvals, ncvars[yvarid].addoffset, ncvars[yvarid].scalefactor);
 
-      cdf_redef(fileID);
+		  strcpy(grid.yname, ncvars[yvarid].name);
+		  strcpy(grid.ylongname, ncvars[yvarid].longname);
+		  strcpy(grid.yunits, ncvars[yvarid].units);
+		  /* don't change the name !!! */
+		  /*
+		  if ( (len = strlen(grid.yname)) > 2 )
+		    if ( grid.yname[len-2] == '_' && isdigit((int) grid.yname[len-1]) )
+		      grid.yname[len-2] = 0;
+		  */
+		  if ( islon && (int) ysize > 1 )
+		    {
+		      yinc = fabs(grid.yvals[0] - grid.yvals[1]);
+		      for ( i = 2; i < (int) ysize; i++ )
+			if ( (fabs(grid.yvals[i-1] - grid.yvals[i]) - yinc) > (yinc/1000) ) break;
 
-      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
-      if ( ncerr == NC_NOERR )
-        {
-          double a, lon_0, lat_0;
+		      if ( i < (int) ysize ) yinc = 0;
+		    }
+		}
 
-          gridInqLaea(gridID, &a, &lon_0, &lat_0);
+	      if      ( (int) ysize == 0 ) size = xsize;
+	      else if ( (int) xsize == 0 ) size = ysize;
+	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize;
+	      else                         size = xsize*ysize;
+	    }
 
-          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
-          cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &a);
-          cdf_put_att_double(fileID, ncvarid, "longitude_of_projection_origin", NC_DOUBLE, 1, &lon_0);
-          cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
-        }
+	  if ( ncvars[ncvarid].gridtype == UNDEFID ||
+	       ncvars[ncvarid].gridtype == GRID_GENERIC )
+	    {
+	      if ( islat && islon )
+		{
+		  if ( isGaussGrid(ysize, yinc, grid.yvals) )
+                    {
+                      ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
+                      np = ysize/2;
+                    }
+                  else
+		    ncvars[ncvarid].gridtype = GRID_LONLAT;
+		}
+	      else if ( islat && !islon && xsize == 0 )
+		{
+		  if ( isGaussGrid(ysize, yinc, grid.yvals) )
+                    {
+                      ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
+                      np = ysize/2;
+                    }
+                  else
+		    ncvars[ncvarid].gridtype = GRID_LONLAT;
+		}
+	      else if ( islon && !islat && ysize == 0 )
+		{
+		  ncvars[ncvarid].gridtype = GRID_LONLAT;
+		}
+	      else
+		ncvars[ncvarid].gridtype = GRID_GENERIC;
+	    }
 
-      cdf_enddef(fileID);
-    }
-  else if ( gridInqType(gridID) == GRID_LCC2 )
-    {
-      char varname[] = "Lambert_Conformal";
-      char mapname[] = "lambert_conformal_conic";
+	  switch (ncvars[ncvarid].gridtype)
+	    {
+	    case GRID_GENERIC:
+	    case GRID_LONLAT:
+	    case GRID_GAUSSIAN:
+	    case GRID_UNSTRUCTURED:
+	    case GRID_CURVILINEAR:
+	      {
+		grid.size  = (int)size;
+		grid.xsize = (int)xsize;
+		grid.ysize = (int)ysize;
+                grid.np    = (int)np;
+		if ( xvarid != UNDEFID )
+		  {
+		    grid.xdef  = 1;
+		    if ( ncvars[xvarid].bounds != UNDEFID )
+		      {
+			nbdims = ncvars[ncvars[xvarid].bounds].ndims;
+			if ( nbdims == 2 || nbdims == 3 )
+			  {
+			    nvertex = ncdims[ncvars[ncvars[xvarid].bounds].dimids[nbdims-1]].len;
+			    grid.nvertex = (int) nvertex;
+			    grid.xbounds = (double *) malloc(nvertex*size*sizeof(double));
+			    cdf_get_var_double(ncvars[xvarid].ncid, ncvars[xvarid].bounds, grid.xbounds);
+			  }
+		      }
+		  }
+		if ( yvarid != UNDEFID )
+		  {
+		    grid.ydef  = 1;
+		    if ( ncvars[yvarid].bounds != UNDEFID )
+		      {
+			nbdims = ncvars[ncvars[yvarid].bounds].ndims;
+			if ( nbdims == 2 || nbdims == 3 )
+			  {
+			    nvertex = ncdims[ncvars[ncvars[yvarid].bounds].dimids[nbdims-1]].len;
+			    /*
+			    if ( nvertex != grid.nvertex )
+			      Warning("nvertex problem! nvertex x %d, nvertex y %d",
+				      grid.nvertex, (int) nvertex);
+			    */
+			    grid.ybounds = (double *) malloc(nvertex*size*sizeof(double));
+			    cdf_get_var_double(ncvars[yvarid].ncid, ncvars[yvarid].bounds, grid.ybounds);
+			  }
+		      }
+		  }
 
-      fileID  = streamptr->fileID;
+		if ( ncvars[ncvarid].cellarea != UNDEFID )
+		  {
+		    grid.area = (double *) malloc(size*sizeof(double));
+		    cdf_get_var_double(ncvars[ncvarid].ncid, ncvars[ncvarid].cellarea, grid.area);
+		  }
 
-      cdf_redef(fileID);
+		break;
+	      }
+	    case GRID_SPECTRAL:
+	      {
+		grid.size = (int)size;
+		grid.lcomplex = 1;
+		break;
+	      }
+	    case GRID_FOURIER:
+	      {
+		grid.size = (int)size;
+		break;
+	      }
+	    case GRID_TRAJECTORY:
+	      {
+		grid.size = 1;
+		break;
+	      }
+	    }
 
-      ncerr = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
-      if ( ncerr == NC_NOERR )
-        {
-          double radius, lon_0, lat_0, lat_1, lat_2;
+	  grid.type = ncvars[ncvarid].gridtype;
 
-          gridInqLcc2(gridID, &radius, &lon_0, &lat_0, &lat_1, &lat_2);
+	  if ( grid.size == 0 )
+	    {
+	      if ( (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == T_AXIS) ||
+		   (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == Z_AXIS) ||
+		   (ncvars[ncvarid].ndims == 2 && ncvars[ncvarid].dimtype[0] == T_AXIS && ncvars[ncvarid].dimtype[1] == Z_AXIS) )
+		{
+		  grid.type  = GRID_GENERIC;
+		  grid.size  = 1;
+		  grid.xsize = 0;
+		  grid.ysize = 0;
+		}
+	      else
+		{
+		  Warning("Variable %s has an unsupported grid, skipped!", ncvars[ncvarid].name);
+		  ncvars[ncvarid].isvar = -1;
+		  continue;
+		}
+	    }
 
-          cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
-          if ( radius > 0 )
-            cdf_put_att_double(fileID, ncvarid, "earth_radius", NC_DOUBLE, 1, &radius);
-          cdf_put_att_double(fileID, ncvarid, "longitude_of_central_meridian", NC_DOUBLE, 1, &lon_0);
-          cdf_put_att_double(fileID, ncvarid, "latitude_of_projection_origin", NC_DOUBLE, 1, &lat_0);
-          if ( IS_EQUAL(lat_1, lat_2) )
-            cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 1, &lat_1);
-          else
-            {
-              double lat_1_2[2];
-              lat_1_2[0] = lat_1;
-              lat_1_2[1] = lat_2;
-              cdf_put_att_double(fileID, ncvarid, "standard_parallel", NC_DOUBLE, 2, lat_1_2);
-            }
-        }
+	  if ( number_of_grid_used != UNDEFID && (grid.type == UNDEFID || grid.type == GRID_GENERIC) )
+            grid.type   = GRID_UNSTRUCTURED;
 
-      cdf_enddef(fileID);
-    }
-}
+	  if ( number_of_grid_used != UNDEFID && grid.type == GRID_UNSTRUCTURED )
+            grid.number = number_of_grid_used;
 
+	  if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
+	    {
+	      cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
 
-static
-void cdfDefGrid(stream_t *streamptr, int gridID)
-{
-  int gridtype, size;
-  int gridindex;
-  int vlistID;
+	      for ( iatt = 0; iatt < nvatts; iatt++ )
+		{
+		  cdf_inq_attname(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, iatt, attname);
+		  cdf_inq_attlen(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, &attlen);
 
-  vlistID = streamptr->vlistID;
-  gridindex = vlistGridIndex(vlistID, gridID);
-  if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
+		  if ( strcmp(attname, "grid_mapping_name") == 0 )
+		    {
+                      enum {
+                        attstringlen = 8192,
+                      };
+                      char attstring[attstringlen];
 
-  gridtype = gridInqType(gridID);
-  size     = gridInqSize(gridID);
+		      cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen, attstring);
+		      strtolower(attstring);
 
-  if ( CDI_Debug )
-    Message("gridtype = %d  size = %d", gridtype, size);
+		      if ( strcmp(attstring, "rotated_latitude_longitude") == 0 )
+			grid.isRotated = TRUE;
+		      else if ( strcmp(attstring, "sinusoidal") == 0 )
+			grid.type = GRID_SINUSOIDAL;
+		      else if ( strcmp(attstring, "lambert_azimuthal_equal_area") == 0 )
+			grid.type = GRID_LAEA;
+		      else if ( strcmp(attstring, "lambert_conformal_conic") == 0 )
+			grid.type = GRID_LCC2;
+		      else if ( strcmp(attstring, "lambert_cylindrical_equal_area") == 0 )
+			{
+			  proj.type = GRID_PROJECTION;
+			  proj.name = strdup(attstring);
+			}
+		    }
+		  else if ( strcmp(attname, "earth_radius") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
+		      grid.laea_a = datt;
+		      grid.lcc2_a = datt;
+		    }
+		  else if ( strcmp(attname, "longitude_of_projection_origin") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.laea_lon_0);
+		    }
+		  else if ( strcmp(attname, "longitude_of_central_meridian") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.lcc2_lon_0);
+		    }
+		  else if ( strcmp(attname, "latitude_of_projection_origin") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
+		      grid.laea_lat_0 = datt;
+		      grid.lcc2_lat_0 = datt;
+		    }
+		  else if ( strcmp(attname, "standard_parallel") == 0 )
+		    {
+		      if ( attlen == 1 )
+			{
+			  cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
+			  grid.lcc2_lat_1 = datt;
+			  grid.lcc2_lat_2 = datt;
+			}
+		      else
+			{
+			  double datt2[2];
+			  cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 2, datt2);
+			  grid.lcc2_lat_1 = datt2[0];
+			  grid.lcc2_lat_2 = datt2[1];
+			}
+		    }
+		  else if ( strcmp(attname, "grid_north_pole_latitude") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.ypole);
+		    }
+		  else if ( strcmp(attname, "grid_north_pole_longitude") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.xpole);
+		    }
+		  else if ( strcmp(attname, "north_pole_grid_longitude") == 0 )
+		    {
+		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.angle);
+		    }
+		}
+	    }
 
-  if ( gridtype == GRID_GAUSSIAN ||
-       gridtype == GRID_LONLAT   ||
-       gridtype == GRID_GENERIC )
-    {
-      if ( gridtype == GRID_GENERIC )
-        {
-          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
-            {
-              /* no grid information */
-            }
-          else
+          if ( grid.type == GRID_UNSTRUCTURED )
             {
-              int lx = 0, ly = 0;
-              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+              int zdimid = UNDEFID;
+              int xdimidx = -1, ydimidx = -1;
+
+              for ( i = 0; i < ndims; i++ )
                 {
-                  cdfDefXaxis(streamptr, gridID, 1);
-                  lx = 1;
+                  if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) xdimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) ydimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) zdimid = ncvars[ncvarid].dimids[i];
                 }
 
-              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+              if ( xdimid != UNDEFID && ydimid != UNDEFID && zdimid == UNDEFID )
                 {
-                  cdfDefYaxis(streamptr, gridID, 1);
-                  ly = 1;
+                  if ( grid.xsize > grid.ysize && grid.ysize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[ydimidx] = Z_AXIS;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.xsize;
+                      grid.ysize = 0;
+                    }
+                  else if ( grid.ysize > grid.xsize && grid.xsize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[xdimidx] = Z_AXIS;
+                      xdimid = ydimid;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.ysize;
+                      grid.xsize = grid.ysize;
+                      grid.ysize = 0;
+                    }
                 }
 
-              if ( lx == 0 && ly == 0 ) cdfDefGdim(streamptr, gridID);
-            }
-        }
-      else
-        {
-          int ndims = 1;
-          if ( gridtype == GRID_LONLAT && size == 1 && gridInqHasDims(gridID) == FALSE )
-            ndims = 0;
-
-          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, ndims);
-          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, ndims);
-        }
-
-      if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_CURVILINEAR )
-    {
-      cdfDefCurvilinear(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_UNSTRUCTURED )
-    {
-      cdfDefUnstructured(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      cdfDefRgrid(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_SPECTRAL )
-    {
-      cdfDefComplex(streamptr, gridID);
-      cdfDefSP(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_FOURIER )
-    {
-      cdfDefComplex(streamptr, gridID);
-      cdfDefFC(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_TRAJECTORY )
-    {
-      cdfDefTrajLon(streamptr, gridID);
-      cdfDefTrajLat(streamptr, gridID);
-    }
-  else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
-    {
-      cdfDefXaxis(streamptr, gridID, 1);
-      cdfDefYaxis(streamptr, gridID, 1);
+              if ( grid.size != grid.xsize )
+                {
+                  Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                  ncvars[ncvarid].isvar = -1;
+                  continue;
+                }
 
-      cdfDefMapping(streamptr, gridID);
-    }
-  /*
-  else if ( gridtype == GRID_LCC )
-    {
-      cdfDefLcc(streamptr, gridID);
-    }
-  */
-  else
-    {
-      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-    }
-}
+              if ( ncvars[ncvarid].position > 0 ) grid.position = ncvars[ncvarid].position;
+              if ( uuidOfHGrid[0] != 0 ) memcpy(grid.uuid, uuidOfHGrid, 16);
+            }
 
+#if defined (PROJECTION_TEST)
+	  if ( proj.type == GRID_PROJECTION )
+	    {
+	      if ( grid.type == GRID_GENERIC )
+		{
+		  grid.type = GRID_CURVILINEAR;
+		}
 
-static
-int cdfDefVar(stream_t *streamptr, int varID)
-{
-  int ncvarid = -1;
-  int fileID;
-  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID, tid = UNDEFID;
-  size_t xsize = 0, ysize = 0;
-  int code, param, gridID, zaxisID;
-  int pnum, pcat, pdis;
-  char varname[CDI_MAX_NAME];
-  const char *name = NULL;
-  const char *longname = NULL;
-  const char *stdname = NULL;
-  const char *units = NULL;
-  int dims[4];
-  int lchunk = FALSE;
-  int chunktype;
-  size_t chunks[4] = {0,0,0,0};
-  int tableID;
-  int ndims = 0;
-  int tsteptype;
-  int xtype, dtype;
-  int gridtype, gridsize;
-  int gridindex, zaxisindex;
-  int tablenum;
-  int vlistID;
-  int dimorder[3];
-  size_t iax = 0;
-  char axis[5];
-  int ensID, ensCount, forecast_type;
-  int retval;
+	      if ( grid.type == GRID_CURVILINEAR )
+		{
+		  proj.size  = grid.size;
+		  proj.xsize = grid.xsize;
+                  proj.ysize = grid.ysize;
+		}
 
-  fileID  = streamptr->fileID;
+	      //  grid.proj = gridGenerate(proj);
+	    }
+#endif
 
-  if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
+	  if ( CDI_Debug )
+	    {
+	      Message("grid: type = %d, size = %d, nx = %d, ny %d",
+		      grid.type, grid.size, grid.xsize, grid.ysize);
+	      Message("proj: type = %d, size = %d, nx = %d, ny %d",
+		      proj.type, proj.size, proj.xsize, proj.ysize);
+	    }
 
-  if ( streamptr->vars[varID].ncvarid != UNDEFID )
-    return (streamptr->vars[varID].ncvarid);
+#if defined (PROJECTION_TEST)
+	  if ( proj.type == GRID_PROJECTION )
+	    {
+	      ncvars[ncvarid].gridID = varDefGrid(vlistID, &proj, 1);
+	      copy_numeric_projatts(ncvars[ncvarid].gridID, ncvars[ncvarid].gmapid, ncvars[ncvarid].ncid);
+	    }
+	  else
+#endif
+	    ncvars[ncvarid].gridID = varDefGrid(vlistID, &grid, 1);
 
-  vlistID   = streamptr->vlistID;
-  gridID    = vlistInqVarGrid(vlistID, varID);
-  zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  tsteptype = vlistInqVarTsteptype(vlistID, varID);
-  code      = vlistInqVarCode(vlistID, varID);
-  param     = vlistInqVarParam(vlistID, varID);
-  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+          if ( grid.type == GRID_UNSTRUCTURED )
+            {
+              if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
+            }
 
-  chunktype = vlistInqVarChunkType(vlistID, varID);
+          if ( ncvars[ncvarid].chunked ) grid_set_chunktype(&grid, &ncvars[ncvarid]);
 
-  vlistInqVarDimorder(vlistID, varID, &dimorder);
+	  gridindex = vlistGridIndex(vlistID, ncvars[ncvarid].gridID);
+	  streamptr->xdimID[gridindex] = xdimid;
+	  streamptr->ydimID[gridindex] = ydimid;
+          if ( xdimid == -1 && ydimid == -1 && grid.size == 1 )
+            gridDefHasDims(ncvars[ncvarid].gridID, FALSE);
 
-  gridsize  = gridInqSize(gridID);
-  if ( gridsize > 1 ) lchunk = TRUE;
-  gridtype  = gridInqType(gridID);
-  gridindex = vlistGridIndex(vlistID, gridID);
-  if ( gridtype != GRID_TRAJECTORY )
-    {
-      xid = streamptr->xdimID[gridindex];
-      yid = streamptr->ydimID[gridindex];
-      if ( xid != UNDEFID ) cdf_inq_dimlen(fileID, xid, &xsize);
-      if ( yid != UNDEFID ) cdf_inq_dimlen(fileID, yid, &ysize);
-    }
+	  if ( CDI_Debug )
+	    Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
 
-  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-  zid = streamptr->zaxisID[zaxisindex];
+	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
+	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].gridID == UNDEFID )
+	      {
+		int xdimid2 = UNDEFID, ydimid2 = UNDEFID, zdimid2 = UNDEFID;
+                int xdimidx = -1, ydimidx = -1;
+		int ndims2 = ncvars[ncvarid2].ndims;
 
-  if ( dimorder[0] != 3 ) lchunk = FALSE; /* ZYX and ZXY */
+		for ( i = 0; i < ndims2; i++ )
+		  {
+		    if ( ncvars[ncvarid2].dimtype[i] == X_AXIS )
+		      { xdimid2 = ncvars[ncvarid2].dimids[i]; xdimidx = i; }
+		    else if ( ncvars[ncvarid2].dimtype[i] == Y_AXIS )
+		      { ydimid2 = ncvars[ncvarid2].dimids[i]; ydimidx = i; }
+		    else if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+		      { zdimid2 = ncvars[ncvarid2].dimids[i]; }
+		  }
 
-  if ( ((dimorder[0]>0)+(dimorder[1]>0)+(dimorder[2]>0)) < ((xid!=UNDEFID)+(yid!=UNDEFID)+(zid!=UNDEFID)) )
-    {
-      printf("zid=%d  yid=%d  xid=%d\n", zid, yid, xid);
-      Error("Internal problem, dimension order missing!");
-    }
+                if ( ncvars[ncvarid2].gridtype == UNDEFID && grid.type == GRID_UNSTRUCTURED )
+                  {
+                    if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
+                        ydimid2 = UNDEFID;
+                      }
 
-  tid = streamptr->basetime.ncdimid;
+                    if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
+                        xdimid2 = ydimid2;
+                        ydimid2 = UNDEFID;
+                      }
+                  }
 
-  if ( tsteptype != TSTEP_CONSTANT )
-    {
-      if ( tid == UNDEFID ) Error("Internal problem, time undefined!");
-      chunks[ndims] = 1;
-      dims[ndims++] = tid;
-      axis[iax++] = 'T';
-    }
-  /*
-  if ( zid != UNDEFID ) axis[iax++] = 'Z';
-  if ( zid != UNDEFID ) chunks[ndims] = 1;
-  if ( zid != UNDEFID ) dims[ndims++] = zid;
+                if ( xdimid == xdimid2 &&
+		    (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
+		  {
+		    int same_grid = TRUE;
+                    /*
+		    if ( xvarid != -1 && ncvars[ncvarid2].xvarid != UNDEFID &&
+			 xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
 
-  if ( yid != UNDEFID ) chunks[ndims] = ysize;
-  if ( yid != UNDEFID ) dims[ndims++] = yid;
+		    if ( yvarid != -1 && ncvars[ncvarid2].yvarid != UNDEFID &&
+			 yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
+                    */
+		    if ( ncvars[ncvarid].xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
+		    if ( ncvars[ncvarid].yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
 
-  if ( xid != UNDEFID ) chunks[ndims] = xsize;
-  if ( xid != UNDEFID ) dims[ndims++] = xid;
-  */
-  for ( int id = 0; id < 3; ++id )
-    {
-      if ( dimorder[id] == 3 && zid != UNDEFID )
-        {
-          axis[iax++] = 'Z';
-          chunks[ndims] = 1;
-          dims[ndims] = zid;
-          ndims++;
-        }
-      else if ( dimorder[id] == 2 && yid != UNDEFID )
-        {
-          if ( chunktype == CHUNK_LINES )
-            chunks[ndims] = 1;
-          else
-            chunks[ndims] = ysize;
-          dims[ndims] = yid;
-          ndims++;
-        }
-      else if ( dimorder[id] == 1 && xid != UNDEFID )
-        {
-          chunks[ndims] = xsize;
-          dims[ndims] = xid;
-          ndims++;
-        }
-    }
+		    if ( ncvars[ncvarid].position != ncvars[ncvarid2].position ) same_grid = FALSE;
 
-  if ( CDI_Debug )
-    fprintf(stderr, "chunktype %d  chunks %d %d %d %d\n", chunktype, (int)chunks[0], (int)chunks[1], (int)chunks[2], (int)chunks[3]);
+		    if ( same_grid )
+		      {
+			if ( CDI_Debug )
+			  Message("Same gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
+			ncvars[ncvarid2].gridID = ncvars[ncvarid].gridID;
+			ncvars[ncvarid2].chunktype = ncvars[ncvarid].chunktype;
+		      }
+		  }
+	      }
 
-  tableID  = vlistInqVarTable(vlistID, varID);
+	  grid_free(&grid);
+	  grid_free(&proj);
+	}
+    }
+}
 
-  name     = vlistInqVarNamePtr(vlistID, varID);
-  longname = vlistInqVarLongnamePtr(vlistID, varID);
-  stdname  = vlistInqVarStdnamePtr(vlistID, varID);
-  units    = vlistInqVarUnitsPtr(vlistID, varID);
+/* define all input zaxes */
+static
+void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
+		      size_t vctsize, double *vct, unsigned char *uuidOfVGrid)
+{
+  int ncvarid, ncvarid2;
+  int i, ilev, ndims;
+  int zaxisindex;
+  int zprec;
+  int nbdims, nvertex, nlevel;
+  int positive = 0;
+  char *pname, *plongname, *punits;
 
-  if ( name     == NULL )     name = tableInqParNamePtr(tableID, code);
-  if ( longname == NULL ) longname = tableInqParLongnamePtr(tableID, code);
-  if ( units    == NULL )    units = tableInqParUnitsPtr(tableID, code);
-  if ( name )
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      int checkname;
-      int iz;
-      int status;
+      if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].zaxisID == UNDEFID )
+	{
+	  int with_bounds = FALSE;
+	  int zdimid = UNDEFID;
+	  int zvarid = UNDEFID;
+	  int zsize = 1;
+	  double *lbounds = NULL;
+	  double *ubounds = NULL;
+	  int zaxisType;
 
-      sprintf(varname, "%s", name);
+          positive = 0;
 
-      checkname = TRUE;
-      iz = 0;
+	  ndims = ncvars[ncvarid].ndims;
+	  for ( i = 0; i < ndims; i++ )
+	    {
+	      if ( ncvars[ncvarid].dimtype[i] == Z_AXIS )
+		zdimid = ncvars[ncvarid].dimids[i];
+	    }
 
-      while ( checkname )
-        {
-          if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
+	  if ( zdimid != UNDEFID )
+	    {
+	      zvarid = ncdims[zdimid].ncvarid;
+	      zsize  = (int)ncdims[zdimid].len;
+	    }
 
-          status = nc_inq_varid(fileID, varname, &ncvarid);
-          if ( status != NC_NOERR )
-            {
-              checkname = FALSE;
-            }
+	  if ( CDI_Debug ) Message("nlevs = %d", zsize);
 
-          if ( checkname ) iz++;
+	  double *zvar = (double *)xmalloc((size_t)zsize * sizeof (double));
 
-          if ( iz >= CDI_MAX_NAME ) Error("Double entry of variable name '%s'!", name);
-        }
+	  zaxisType = UNDEFID;
 
-      if ( strcmp(name, varname) != 0 )
-        {
-          if ( iz == 1 )
-            Warning("Changed double entry of variable name '%s' to '%s'!", name, varname);
-          else
-            Warning("Changed multiple entry of variable name '%s' to '%s'!", name, varname);
-        }
+	  if ( zvarid != UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
 
-      name = varname;
-    }
-  else
-    {
-      int checkname;
-      int iz;
-      int status;
-      char *varname2;
+	  if ( zaxisType == UNDEFID )  zaxisType = ZAXIS_GENERIC;
 
-      if ( code < 0 ) code = -code;
-      if ( pnum < 0 ) pnum = -pnum;
+	  zprec = DATATYPE_FLT64;
 
-      if ( pdis == 255 )
-	sprintf(varname, "var%d", code);
-      else
-	sprintf(varname, "param%d.%d.%d", pnum, pcat, pdis);
+	  if ( zvarid != UNDEFID )
+	    {
+	      positive  = ncvars[zvarid].positive;
+	      pname     = ncvars[zvarid].name;
+	      plongname = ncvars[zvarid].longname;
+	      punits    = ncvars[zvarid].units;
+	      if ( ncvars[zvarid].xtype == NC_FLOAT ) zprec = DATATYPE_FLT32;
+	      /* don't change the name !!! */
+	      /*
+	      if ( (len = strlen(pname)) > 2 )
+		if ( pname[len-2] == '_' && isdigit((int) pname[len-1]) )
+		  pname[len-2] = 0;
+	      */
+	      cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
 
-      varname2 = varname+strlen(varname);
+	      if ( ncvars[zvarid].bounds != UNDEFID )
+		{
+		  nbdims = ncvars[ncvars[zvarid].bounds].ndims;
+		  if ( nbdims == 2 )
+		    {
+		      nlevel  = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
+		      nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1]].len;
+		      if ( nlevel == zsize && nvertex == 2 )
+			{
+			  double *zbounds;
+			  with_bounds = TRUE;
+			  zbounds = (double *) malloc(2*(size_t)nlevel*sizeof(double));
+			  lbounds = (double *) malloc((size_t)nlevel*sizeof(double));
+			  ubounds = (double *) malloc((size_t)nlevel*sizeof(double));
+			  cdf_get_var_double(ncvars[zvarid].ncid, ncvars[zvarid].bounds, zbounds);
+			  for ( i = 0; i < nlevel; ++i )
+			    {
+			      lbounds[i] = zbounds[i*2];
+			      ubounds[i] = zbounds[i*2+1];
+			    }
+			  free(zbounds);
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      pname     = NULL;
+	      plongname = NULL;
+	      punits    = NULL;
 
-      checkname = TRUE;
-      iz = 0;
+	      if ( zsize == 1 )
+		{
+                  if ( ncvars[ncvarid].zaxistype != UNDEFID )
+                    zaxisType = ncvars[ncvarid].zaxistype;
+                  else
+                    zaxisType = ZAXIS_SURFACE;
 
-      while ( checkname )
-        {
-          if ( iz ) sprintf(varname2, "_%d", iz+1);
+		  zvar[0] = 0;
+		  /*
+		  if ( zdimid == UNDEFID )
+		    zvar[0] = 9999;
+		  else
+		    zvar[0] = 0;
+		  */
+		}
+	      else
+		{
+		  for ( ilev = 0; ilev < zsize; ilev++ ) zvar[ilev] = ilev + 1;
+		}
+	    }
 
-          status = nc_inq_varid(fileID, varname, &ncvarid);
-          if ( status != NC_NOERR ) checkname = FALSE;
+      	  ncvars[ncvarid].zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, with_bounds, lbounds, ubounds,
+						(int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
 
-          if ( checkname ) iz++;
+	  if ( uuidOfVGrid[0] != 0 )
+            {
+              // printf("uuidOfVGrid: defined\n");
+              zaxisDefUUID(ncvars[ncvarid].zaxisID, uuidOfVGrid);
+            }
 
-          if ( iz >= CDI_MAX_NAME ) break;
-        }
+          if ( positive > 0 ) zaxisDefPositive(ncvars[ncvarid].zaxisID, positive);
 
-      name = varname;
-      code = 0;
-      pdis = 255;
-    }
+	  free(zvar);
+	  free(lbounds);
+	  free(ubounds);
 
-  /* if ( streamptr->ncmode == 2 ) cdf_redef(fileID); */
+	  zaxisindex = vlistZaxisIndex(vlistID, ncvars[ncvarid].zaxisID);
+	  streamptr->zaxisID[zaxisindex]  = zdimid;
 
-  dtype = vlistInqVarDatatype(vlistID, varID);
-  xtype = cdfDefDatatype(dtype, streamptr->filetype);
+	  if ( CDI_Debug )
+	    Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
 
-  cdf_def_var(fileID, name, (nc_type) xtype, ndims, dims, &ncvarid);
+	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
+	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID )
+	      {
+		int zdimid2 = -1;
+		ndims = ncvars[ncvarid2].ndims;
+		for ( i = 0; i < ndims; i++ )
+		  {
+		    if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+		      zdimid2 = ncvars[ncvarid2].dimids[i];
+		  }
+		if ( zdimid == zdimid2 )
+		  {
+		    if ( CDI_Debug )
+		      Message("zaxisID %d %d %s",
+			      ncvars[ncvarid].zaxisID, ncvarid2, ncvars[ncvarid2].name);
+		    ncvars[ncvarid2].zaxisID = ncvars[ncvarid].zaxisID;
+		  }
+	      }
+	}
+    }
+}
 
-#if  defined  (HAVE_NETCDF4)
-  if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
-    {
-      if ( chunktype == CHUNK_AUTO )
-        retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
-      else
-        retval = nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks);
+struct varinfo
+{
+  int      ncvarid;
+  const char *name;
+};
 
-      if ( retval ) Error("nc_def_var_chunking failed, status = %d", retval);
-    }
-#endif
+static
+int cmpvarname(const void *s1, const void *s2)
+{
+  const struct varinfo *x = (const struct varinfo *)s1,
+    *y = (const struct varinfo *)s2;
+  return (strcmp(x->name, y->name));
+}
 
-  if ( streamptr->comptype == COMPRESS_ZIP )
+/* define all input data variables */
+static
+void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, int num_ncvars, ncvar_t *ncvars)
+{
+  if ( streamptr->sortname )
     {
-      if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
-        {
-          cdfDefVarDeflate(fileID, ncvarid, streamptr->complevel);
-        }
-      else
-        {
-          if ( lchunk )
-            {
-              static int lwarn = TRUE;
+      struct varinfo *varInfo
+        = (struct varinfo *)xmalloc((size_t)nvars * sizeof (struct varinfo));
 
-              if ( lwarn )
-                {
-                  lwarn = FALSE;
-                  Warning("Deflate compression is only available for netCDF4!");
-                }
-            }
-        }
+      for ( int varID = 0; varID < nvars; varID++ )
+	{
+	  int ncvarid = varids[varID];
+	  varInfo[varID].ncvarid = ncvarid;
+	  varInfo[varID].name = ncvars[ncvarid].name;
+	}
+      qsort(varInfo, (size_t)nvars, sizeof(varInfo[0]), cmpvarname);
+      for ( int varID = 0; varID < nvars; varID++ )
+	{
+	  varids[varID] = varInfo[varID].ncvarid;
+	}
+      free(varInfo);
     }
 
-  if ( streamptr->comptype == COMPRESS_SZIP )
+  for ( int varID1 = 0; varID1 < nvars; varID1++ )
     {
-      if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
-        {
-#if defined (NC_SZIP_NN_OPTION_MASK)
-          cdfDefVarSzip(fileID, ncvarid);
-#else
-          static int lwarn = TRUE;
+      int gridID, zaxisID;
 
-          if ( lwarn )
-            {
-              lwarn = FALSE;
-              Warning("netCDF4/SZIP compression not available!");
-            }
+      int ncvarid = varids[varID1];
+      gridID  = ncvars[ncvarid].gridID;
+      zaxisID = ncvars[ncvarid].zaxisID;
+
+      stream_new_var(streamptr, gridID, zaxisID);
+      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
+
+#if  defined  (HAVE_NETCDF4)
+      if ( ncvars[ncvarid].deflate )
+	vlistDefVarCompType(vlistID, varID, COMPRESS_ZIP);
+
+      if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != UNDEFID )
+        vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
 #endif
-        }
-      else
-        {
-          static int lwarn = TRUE;
 
-          if ( lwarn )
-            {
-              lwarn = FALSE;
-              Warning("SZIP compression is only available for netCDF4!");
-            }
-        }
-    }
+      streamptr->vars[varID1].defmiss = 0;
+      streamptr->vars[varID1].ncvarid = ncvarid;
 
-  if ( stdname && *stdname )
-    cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(stdname), stdname);
+      vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
+      if ( ncvars[ncvarid].param != UNDEFID ) vlistDefVarParam(vlistID, varID, ncvars[ncvarid].param);
+      if ( ncvars[ncvarid].code != UNDEFID )  vlistDefVarCode(vlistID, varID, ncvars[ncvarid].code);
+      if ( ncvars[ncvarid].code != UNDEFID )
+	{
+	  int param;
+	  param = cdiEncodeParam(ncvars[ncvarid].code, ncvars[ncvarid].tabnum, 255);
+	  vlistDefVarParam(vlistID, varID, param);
+	}
+      if ( ncvars[ncvarid].longname[0] )  vlistDefVarLongname(vlistID, varID, ncvars[ncvarid].longname);
+      if ( ncvars[ncvarid].stdname[0] )   vlistDefVarStdname(vlistID, varID, ncvars[ncvarid].stdname);
+      if ( ncvars[ncvarid].units[0] )     vlistDefVarUnits(vlistID, varID, ncvars[ncvarid].units);
 
-  if ( longname && *longname )
-    cdf_put_att_text(fileID, ncvarid, "long_name", strlen(longname), longname);
+      if ( ncvars[ncvarid].lvalidrange )
+        vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
 
-  if ( units && *units )
-    cdf_put_att_text(fileID, ncvarid, "units", strlen(units), units);
+      if ( IS_NOT_EQUAL(ncvars[ncvarid].addoffset, 0) )
+	vlistDefVarAddoffset(vlistID, varID, ncvars[ncvarid].addoffset);
+      if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
+	vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
 
-  if ( code > 0 && pdis == 255 )
-    cdf_put_att_int(fileID, ncvarid, "code", NC_INT, 1, &code);
+      vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
 
-  if ( pdis != 255 )
-    {
-      char paramstr[32];
-      cdiParamToString(param, paramstr, sizeof(paramstr));
-      cdf_put_att_text(fileID, ncvarid, "param", strlen(paramstr), paramstr);
-    }
+      vlistDefVarInstitut(vlistID, varID, instID);
+      vlistDefVarModel(vlistID, varID, modelID);
+      if ( ncvars[ncvarid].tableID != UNDEFID )
+	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
 
-  if ( tableID != UNDEFID )
-    {
-      tablenum = tableInqNum(tableID);
-      if ( tablenum > 0 )
-        cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
-    }
+      if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
+        {
+          ncvars[ncvarid].deffillval = TRUE;
+          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
+        }
 
-  if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT  && gridtype != GRID_CURVILINEAR )
-    {
-      size_t len = strlen(gridNamePtr(gridtype));
-      if ( len > 0 )
-        cdf_put_att_text(fileID, ncvarid, "grid_type", len, gridNamePtr(gridtype));
-    }
+      if ( ncvars[ncvarid].deffillval == TRUE )
+        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
 
-  if ( gridIsRotated(gridID) )
-    {
-      char mapping[] = "rotated_pole";
-      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
-    }
+      if ( CDI_Debug )
+	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
+		vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
 
-  if ( gridtype == GRID_SINUSOIDAL )
-    {
-      char mapping[] = "sinusoidal";
-      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
-    }
-  else if ( gridtype == GRID_LAEA )
-    {
-      char mapping[] = "laea";
-      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
-    }
-  else if ( gridtype == GRID_LCC2 )
-    {
-      char mapping[] = "Lambert_Conformal";
-      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
-    }
-  else if ( gridtype == GRID_TRAJECTORY )
-    {
-      cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "tlon tlat" );
-    }
-  else if ( gridtype == GRID_LONLAT && xid == UNDEFID && yid == UNDEFID && gridsize == 1 )
-    {
-      char coordinates[CDI_MAX_NAME] = "";
-      int ncxvarID, ncyvarID;
-      int gridindex;
-      size_t len;
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      int xdimid = streamptr->xdimID[gridindex];
+      int ydimid = streamptr->ydimID[gridindex];
 
-      gridindex = vlistGridIndex(vlistID, gridID);
-      ncxvarID = streamptr->ncxvarID[gridindex];
-      ncyvarID = streamptr->ncyvarID[gridindex];
-      if ( ncxvarID != CDI_UNDEFID )
-        cdf_inq_varname(fileID, ncxvarID, coordinates);
-      len = strlen(coordinates);
-      if ( ncyvarID != CDI_UNDEFID )
+      int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+      int zdimid = streamptr->zaxisID[zaxisindex];
+
+      int ndims = ncvars[ncvarid].ndims;
+      int iodim = 0;
+      int ixyz = 0;
+      int ipow10[4] = {1, 10, 100, 1000};
+
+      if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
+
+      if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
         {
-          if ( len ) coordinates[len++] = ' ';
-          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+          if ( xdimid == ncvars[ncvarid].dimids[ndims-1] )
+            {
+              ixyz = 321;
+            }
+          else
+            {
+              ixyz = 213;
+            }
         }
-      len = strlen(coordinates);
-      if ( len )
-        cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
-    }
-  else if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
-    {
-      char coordinates[CDI_MAX_NAME] = "";
-      char cellarea[CDI_MAX_NAME] = "area: ";
-      int ncxvarID, ncyvarID, ncavarID;
-      int gridindex;
-      size_t len;
-
-      gridindex = vlistGridIndex(vlistID, gridID);
-      ncxvarID = streamptr->ncxvarID[gridindex];
-      ncyvarID = streamptr->ncyvarID[gridindex];
-      ncavarID = streamptr->ncavarID[gridindex];
-      if ( ncxvarID != CDI_UNDEFID )
-        cdf_inq_varname(fileID, ncxvarID, coordinates);
-      len = strlen(coordinates);
-      if ( ncyvarID != CDI_UNDEFID )
+      else
         {
-          if ( len ) coordinates[len++] = ' ';
-          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
+          for ( int idim = iodim; idim < ndims; idim++ )
+            {
+              if      ( xdimid == ncvars[ncvarid].dimids[idim] )
+                ixyz += 1*ipow10[ndims-idim-1];
+              else if ( ydimid == ncvars[ncvarid].dimids[idim] )
+                ixyz += 2*ipow10[ndims-idim-1];
+              else if ( zdimid == ncvars[ncvarid].dimids[idim] )
+                ixyz += 3*ipow10[ndims-idim-1];
+            }
         }
-      len = strlen(coordinates);
-      if ( len )
-        cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
 
-      if ( ncavarID != CDI_UNDEFID )
+      vlistDefVarXYZ(vlistID, varID, ixyz);
+      /*
+      printf("ixyz %d\n", ixyz);
+      printf("ndims %d\n", ncvars[ncvarid].ndims);
+      for ( int i = 0; i < ncvars[ncvarid].ndims; ++i )
+        printf("dimids: %d %d\n", i, ncvars[ncvarid].dimids[i]);
+      printf("xdimid, ydimid %d %d\n", xdimid, ydimid);
+      */
+      if ( ncvars[ncvarid].ensdata != NULL )
         {
-          len = strlen(cellarea);
-          cdf_inq_varname(fileID, ncavarID, cellarea+len);
-          len = strlen(cellarea);
-          cdf_put_att_text(fileID, ncvarid, "cell_measures", len, cellarea);
+          vlistDefVarEnsemble( vlistID, varID, ncvars[ncvarid].ensdata->ens_index,
+                               ncvars[ncvarid].ensdata->ens_count,
+                               ncvars[ncvarid].ensdata->forecast_init_type );
+          free(ncvars[ncvarid].ensdata);
+          ncvars[ncvarid].ensdata = NULL;
         }
 
-      if ( gridtype == GRID_UNSTRUCTURED )
+      if ( ncvars[ncvarid].extra[0] != 0 )
         {
-          int position = gridInqPosition(gridID);
-          if ( position > 0 )
-            cdf_put_att_int(fileID, ncvarid, "number_of_grid_in_reference", NC_INT, 1, &position);
+          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
         }
     }
-  else if ( gridtype == GRID_SPECTRAL || gridtype == GRID_FOURIER )
-    {
-      int gridTruncation = gridInqTrunc(gridID);
-
-      axis[iax++] = '-';
-      axis[iax++] = '-';
-      cdf_put_att_text(fileID, ncvarid, "axis", iax, axis);
-      cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1, &gridTruncation);
-    }
 
-  /*  if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) */
+  for ( int varID = 0; varID < nvars; varID++ )
     {
-      int laddoffset, lscalefactor;
-      double addoffset, scalefactor;
-      int astype = NC_DOUBLE;
+      int ncvarid = varids[varID];
+      int ncid = ncvars[ncvarid].ncid;
 
-      addoffset    = vlistInqVarAddoffset(vlistID, varID);
-      scalefactor  = vlistInqVarScalefactor(vlistID, varID);
-      laddoffset   = IS_NOT_EQUAL(addoffset, 0);
-      lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+      if ( ncvars[ncvarid].natts )
+	{
+	  int attnum;
+	  int iatt;
+	  nc_type attrtype;
+	  size_t attlen;
+	  char attname[CDI_MAX_NAME];
+	  const int attstringlen = 8192; char attstring[8192];
+	  int nvatts = ncvars[ncvarid].natts;
 
-      if ( laddoffset || lscalefactor )
-        {
-          if ( IS_EQUAL(addoffset,   (double) ((float) addoffset)) &&
-               IS_EQUAL(scalefactor, (double) ((float) scalefactor)) )
-            {
-              astype = NC_FLOAT;
-            }
+	  for ( iatt = 0; iatt < nvatts; iatt++ )
+	    {
+	      attnum = ncvars[ncvarid].atts[iatt];
+	      cdf_inq_attname(ncid, ncvarid, attnum, attname);
+	      cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+	      cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
 
-          if ( xtype == (int) NC_FLOAT ) astype = NC_FLOAT;
+	      if ( attrtype == NC_SHORT || attrtype == NC_INT )
+		{
+		  int *attint = (int *) malloc(attlen*sizeof(int));
+		  cdfGetAttInt(ncid, ncvarid, attname, (int)attlen, attint);
+		  if ( attrtype == NC_SHORT )
+		    vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT16, (int)attlen, attint);
+		  else
+		    vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT32, (int)attlen, attint);
+		  free(attint);
+		}
+	      else if ( attrtype == NC_FLOAT || attrtype == NC_DOUBLE )
+		{
+		  double *attflt = (double *) malloc(attlen*sizeof(double));
+		  cdfGetAttDouble(ncid, ncvarid, attname, (int)attlen, attflt);
+		  if ( attrtype == NC_FLOAT )
+		    vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT32, (int)attlen, attflt);
+		  else
+		    vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT64, (int)attlen, attflt);
+		  free(attflt);
+		}
+	      else if ( xtypeIsText(attrtype) )
+		{
+		  cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+		  vlistDefAttTxt(vlistID, varID, attname, (int)attlen, attstring);
+		}
+	      else
+		{
+		  if ( CDI_Debug ) printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
+		}
+	    }
 
-          cdf_put_att_double(fileID, ncvarid, "add_offset",   (nc_type) astype, 1, &addoffset);
-          cdf_put_att_double(fileID, ncvarid, "scale_factor", (nc_type) astype, 1, &scalefactor);
-        }
+	  free(ncvars[ncvarid].atts);
+          ncvars[ncvarid].atts = NULL;
+	}
     }
 
-  if ( dtype == DATATYPE_UINT8 && xtype == NC_BYTE )
+  /* release mem of not freed attributes */
+  for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
+    if ( ncvars[ncvarid].atts ) free(ncvars[ncvarid].atts);
+
+  if ( varids ) free(varids);
+
+  for ( int varID = 0; varID < nvars; varID++ )
     {
-      int validrange[2] = {0, 255};
-      cdf_put_att_int(fileID, ncvarid, "valid_range", NC_SHORT, 2, validrange);
-      cdf_put_att_text(fileID, ncvarid, "_Unsigned", 4, "true");
+      if ( vlistInqVarCode(vlistID, varID) == -varID-1 )
+	{
+	  const char *pname = vlistInqVarNamePtr(vlistID, varID);
+	  size_t len = strlen(pname);
+	  if ( len > 3 && isdigit((int) pname[3]) )
+	    {
+	      if ( memcmp("var", pname, 3) == 0 )
+		{
+		  vlistDefVarCode(vlistID, varID, atoi(pname+3));
+		  vlistDestroyVarName(vlistID, varID);
+		}
+	    }
+	  else if ( len > 4 && isdigit((int) pname[4]) )
+	    {
+	      if ( memcmp("code", pname, 4) == 0 )
+		{
+		  vlistDefVarCode(vlistID, varID, atoi(pname+4));
+		  vlistDestroyVarName(vlistID, varID);
+		}
+	    }
+	  else if ( len > 5 && isdigit((int) pname[5]) )
+	    {
+	      if ( memcmp("param", pname, 5) == 0 )
+		{
+		  int pnum = -1, pcat = 255, pdis = 255;
+		  sscanf(pname+5, "%d.%d.%d", &pnum, &pcat, &pdis);
+		  vlistDefVarParam(vlistID, varID, cdiEncodeParam(pnum, pcat, pdis));
+		  vlistDestroyVarName(vlistID, varID);
+		}
+	    }
+	}
     }
 
-  streamptr->vars[varID].ncvarid = ncvarid;
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      int instID  = vlistInqVarInstitut(vlistID, varID);
+      int modelID = vlistInqVarModel(vlistID, varID);
+      int tableID = vlistInqVarTable(vlistID, varID);
+      int code = vlistInqVarCode(vlistID, varID);
+      if ( cdiDefaultTableID != UNDEFID )
+	{
+	  if ( tableInqParNamePtr(cdiDefaultTableID, code) )
+	    {
+	      vlistDestroyVarName(vlistID, varID);
+	      vlistDestroyVarLongname(vlistID, varID);
+	      vlistDestroyVarUnits(vlistID, varID);
 
-  if ( vlistInqVarMissvalUsed(vlistID, varID) )
-    cdfDefVarMissval(streamptr, varID, vlistInqVarDatatype(vlistID, varID), 0);
+	      if ( tableID != UNDEFID )
+		{
+		  vlistDefVarName(vlistID, varID, tableInqParNamePtr(cdiDefaultTableID, code));
+		  if ( tableInqParLongnamePtr(cdiDefaultTableID, code) )
+		    vlistDefVarLongname(vlistID, varID, tableInqParLongnamePtr(cdiDefaultTableID, code));
+		  if ( tableInqParUnitsPtr(cdiDefaultTableID, code) )
+		    vlistDefVarUnits(vlistID, varID, tableInqParUnitsPtr(cdiDefaultTableID, code));
+		}
+	      else
+		{
+		  tableID = cdiDefaultTableID;
+		}
+	    }
 
-  if ( zid == -1 )
-    {
-      if ( zaxisInqType(zaxisID) == ZAXIS_CLOUD_BASE          ||
-           zaxisInqType(zaxisID) == ZAXIS_CLOUD_TOP           ||
-           zaxisInqType(zaxisID) == ZAXIS_ISOTHERM_ZERO       ||
-           zaxisInqType(zaxisID) == ZAXIS_TOA                 ||
-           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM          ||
-           zaxisInqType(zaxisID) == ZAXIS_LAKE_BOTTOM         ||
-           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM     ||
-           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM_TA  ||
-           zaxisInqType(zaxisID) == ZAXIS_SEDIMENT_BOTTOM_TW  ||
-           zaxisInqType(zaxisID) == ZAXIS_MIX_LAYER           ||
-           zaxisInqType(zaxisID) == ZAXIS_ATMOSPHERE )
-        {
-          zaxisInqName(zaxisID, varname);
-          cdf_put_att_text(fileID, ncvarid, "level_type", strlen(varname), varname);
-        }
+	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID ) instID  = cdiDefaultInstID;
+	}
+      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
+      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
+      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
     }
+}
 
-  if ( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
+static
+void scan_global_attributes(int fileID, int vlistID, stream_t *streamptr, int ngatts, int *instID, int *modelID, int *ucla_les, unsigned char *uuidOfHGrid, unsigned char *uuidOfVGrid, char *gridfile, int *number_of_grid_used)
+{
+  nc_type xtype;
+  size_t attlen;
+  char attname[CDI_MAX_NAME];
+  enum { attstringlen = 65636 };
+  char attstring[attstringlen];
+  int iatt;
+
+  for ( iatt = 0; iatt < ngatts; iatt++ )
     {
-      /* void cdf_put_att_int(  int ncid, int varid, const char *name, nc_type xtype,
-	                        size_t len, const int *ip )
-       */
-	cdf_put_att_int(fileID, ncvarid, "realization", NC_INT, 1, &ensID);
-	cdf_put_att_int(fileID, ncvarid, "ensemble_members", NC_INT, 1, &ensCount);
-	cdf_put_att_int(fileID, ncvarid, "forecast_init_type", NC_INT, 1, &forecast_type);
+      cdf_inq_attname(fileID, NC_GLOBAL, iatt, attname);
+      cdf_inq_atttype(fileID, NC_GLOBAL, attname, &xtype);
+      cdf_inq_attlen(fileID, NC_GLOBAL, attname, &attlen);
 
-#ifdef DBG
-	if( DBG )
-	  {
-	    fprintf( stderr, "cdfDefVar :\n EnsID  %d\n Enscount %d\n Forecast init type %d\n",  ensID,
-		     ensCount,  forecast_type );
-	  }
-#endif
-    }
+      if ( xtypeIsText(xtype) )
+	{
+	  cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen, attstring);
 
-  /* Attributes */
-  defineAttributes(vlistID, varID, fileID, ncvarid);
+          size_t attstrlen = strlen(attstring);
 
-  /* if ( streamptr->ncmode == 2 ) cdf_enddef(fileID); */
+	  if ( attlen > 0 && attstring[0] != 0 )
+	    {
+	      if ( strcmp(attname, "history") == 0 )
+		{
+		  streamptr->historyID = iatt;
+		}
+	      else if ( strcmp(attname, "institution") == 0 )
+		{
+		  *instID = institutInq(0, 0, NULL, attstring);
+		  if ( *instID == UNDEFID )
+		    *instID = institutDef(0, 0, NULL, attstring);
+		}
+	      else if ( strcmp(attname, "source") == 0 )
+		{
+		  *modelID = modelInq(-1, 0, attstring);
+		  if ( *modelID == UNDEFID )
+		    *modelID = modelDef(-1, 0, attstring);
+		}
+	      else if ( strcmp(attname, "Source") == 0 )
+		{
+		  if ( strncmp(attstring, "UCLA-LES", 8) == 0 )
+		    *ucla_les = TRUE;
+		}
+	      /*
+	      else if ( strcmp(attname, "Conventions") == 0 )
+		{
+		}
+	      */
+	      else if ( strcmp(attname, "CDI") == 0 )
+		{
+		}
+	      else if ( strcmp(attname, "CDO") == 0 )
+		{
+		}
+              /*
+	      else if ( strcmp(attname, "forecast_reference_time") == 0 )
+		{
+                  memcpy(fcreftime, attstring, attstrlen+1);
+		}
+              */
+	      else if ( strcmp(attname, "grid_file_uri") == 0 )
+		{
+                  memcpy(gridfile, attstring, attstrlen+1);
+		}
+	      else if ( strcmp(attname, "uuidOfHGrid") == 0 && attstrlen == 36 )
+		{
+                  attstring[36] = 0;
+                  str2uuid(attstring, uuidOfHGrid);
+                  //   printf("uuid: %d %s\n", attlen, attstring);
+		}
+	      else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
+		{
+                  attstring[36] = 0;
+                  str2uuid(attstring, uuidOfVGrid);
+		}
+	      else
+		{
+                  if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
+                    {
+                      memcpy(gridfile, attstring, attstrlen+1);
+                    }
 
-  return (ncvarid);
+		  vlistDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attstrlen, attstring);
+		}
+	    }
+	}
+      else if ( xtype == NC_SHORT || xtype == NC_INT )
+	{
+	  if ( strcmp(attname, "number_of_grid_used") == 0 )
+	    {
+	      (*number_of_grid_used) = UNDEFID;
+	      cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
+	    }
+ 	  else
+            {
+              int *attint;
+              attint = (int *) malloc(attlen*sizeof(int));
+              cdfGetAttInt(fileID, NC_GLOBAL, attname, (int)attlen, attint);
+              if ( xtype == NC_SHORT )
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
+              else
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
+              free(attint);
+            }
+        }
+      else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
+	{
+	  double *attflt;
+	  attflt = (double *) malloc(attlen*sizeof(double));
+	  cdfGetAttDouble(fileID, NC_GLOBAL, attname, (int)attlen, attflt);
+	  if ( xtype == NC_FLOAT )
+	    vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT32, (int)attlen, attflt);
+	  else
+	    vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT64, (int)attlen, attflt);
+	  free(attflt);
+	}
+    }
 }
 
 static
-void scale_add(size_t size, double *data, double addoffset, double scalefactor)
+int find_leadtime(int nvars, ncvar_t *ncvars)
 {
-  int laddoffset;
-  int lscalefactor;
-
-  laddoffset   = IS_NOT_EQUAL(addoffset, 0);
-  lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+  int leadtime_id = UNDEFID;
 
-  if ( laddoffset || lscalefactor )
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      for (size_t i = 0; i < size; ++i )
+      if ( ncvars[ncvarid].stdname[0] )
         {
-          if ( lscalefactor ) data[i] *= scalefactor;
-          if ( laddoffset )   data[i] += addoffset;
+          if ( strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
+            {
+              leadtime_id = ncvarid;
+              break;
+            }
         }
     }
+
+  return (leadtime_id);
 }
 
 static
-void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], size_t (*count)[4])
+void find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, stream_t *streamptr,
+                    int *time_has_units, int *time_has_bounds, int *time_climatology)
 {
-  int vlistID = streamptr->vlistID;
-  int tsID = streamptr->curTsID;
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-  int gridindex = vlistGridIndex(vlistID, gridID);
-
-  if ( CDI_Debug ) Message("tsID = %d", tsID);
+  int ncvarid;
 
-  int xid = UNDEFID, yid = UNDEFID;
-  if ( gridInqType(gridID) == GRID_TRAJECTORY )
+  if ( timedimid == UNDEFID )
     {
-      cdfReadGridTraj(streamptr, gridID);
+      char timeunits[CDI_MAX_NAME];
+
+      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+        {
+          if ( ncvars[ncvarid].ndims == 0 && strcmp(ncvars[ncvarid].name, "time") == 0 )
+            {
+              if ( ncvars[ncvarid].units[0] )
+                {
+                  strcpy(timeunits, ncvars[ncvarid].units);
+                  strtolower(timeunits);
+
+                  if ( isTimeUnits(timeunits) )
+                    {
+                      streamptr->basetime.ncvarid = ncvarid;
+                      break;
+                    }
+                }
+            }
+        }
     }
   else
     {
-      xid = streamptr->xdimID[gridindex];
-      yid = streamptr->ydimID[gridindex];
-    }
-  int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-  int zid = streamptr->zaxisID[zaxisindex];
-
-  int ndims = 0;
-#define addDimension(startCoord, length) do \
-    { \
-      (*start)[ndims] = startCoord; \
-      (*count)[ndims] = length; \
-      ndims++; \
-    } while(0)
-  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
-  if ( zid != UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
-  if ( yid != UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
-  if ( xid != UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
-#undef addDimension
-
-  assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
-  assert(ndims <= (int)(sizeof(*count)/sizeof(**count)));
+      int ltimevar = FALSE;
 
-  if ( CDI_Debug )
-    for (int idim = 0; idim < ndims; idim++)
-      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
-}
+      if ( ncdims[timedimid].ncvarid != UNDEFID )
+        {
+          streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
+          ltimevar = TRUE;
+        }
 
-//Scans the data array for missVals, optionally applying first a scale factor and then an offset.
-//Returns the number of missing + out-of-range values encountered.
-static
-size_t cdfDoInputDataTransformationDP(size_t valueCount, double *data, bool haveMissVal, double missVal, double scaleFactor, double offset, double validMin, double validMax)
- {
-  const bool haveOffset   = IS_NOT_EQUAL(offset, 0);
-  const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
-  size_t missValCount = 0;
-  if (validMin == VALIDMISS)
-    validMin = DBL_MIN;
-  if (validMax == VALIDMISS)
-    validMax = DBL_MAX;
+      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+        if ( ncvarid != streamptr->basetime.ncvarid &&
+             ncvars[ncvarid].ndims == 1 &&
+             timedimid == ncvars[ncvarid].dimids[0] &&
+             !xtypeIsText(ncvars[ncvarid].xtype) &&
+             isTimeAxisUnits(ncvars[ncvarid].units) )
+          {
+            ncvars[ncvarid].isvar = FALSE;
 
-  bool haveRangeCheck = (validMax != DBL_MAX) | (validMin != DBL_MIN);
-  assert(!haveRangeCheck || haveMissVal);
+            if ( !ltimevar )
+              {
+                streamptr->basetime.ncvarid = ncvarid;
+                ltimevar = TRUE;
+                if ( CDI_Debug )
+                  fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
+              }
+            else
+              {
+                Warning("Found more than one time variable, skipped variable %s!", ncvars[ncvarid].name);
+              }
+          }
 
-  switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
-          | ((int)haveOffset << 2) | ((int)haveRangeCheck << 3))
-    {
-    case 15: /* haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? missVal
-            : isMissVal ? data[i] : data[i] * scaleFactor + offset;
-        }
-      break;
-    case 13: /* haveRangeCheck & haveMissVal & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? missVal
-            : isMissVal ? data[i] : data[i] + offset;
-        }
-      break;
-    case 11: /* haveRangeCheck & haveMissVal & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
+      if ( ltimevar == FALSE ) /* search for WRF time description */
         {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? missVal
-            : isMissVal ? data[i] : data[i] * scaleFactor;
+          for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+            if ( ncvarid != streamptr->basetime.ncvarid &&
+                 ncvars[ncvarid].ndims == 2 &&
+                 timedimid == ncvars[ncvarid].dimids[0] &&
+                 !xtypeIsText(ncvars[ncvarid].xtype) &&
+                 ncdims[ncvars[ncvarid].dimids[1]].len == 19 )
+              {
+                streamptr->basetime.ncvarid = ncvarid;
+                streamptr->basetime.lwrf    = TRUE;
+                break;
+              }
         }
-      break;
-    case 9: /* haveRangeCheck & haveMissVal */
-      for ( size_t i = 0; i < valueCount; i++ )
+
+      /* time varID */
+      ncvarid = streamptr->basetime.ncvarid;
+
+      if ( ncvarid == UNDEFID )
         {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? missVal : data[i];
+          Warning("Time variable >%s< not found!", ncdims[timedimid].name);
         }
-      break;
-    case 7: /* haveMissVal & haveScaleFactor & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] = data[i] * scaleFactor + offset;
-      break;
-    case 6: /* haveOffset & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] = data[i] * scaleFactor + offset;
-      break;
-    case 5: /* haveMissVal & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] += offset;
-      break;
-    case 4: /* haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] += offset;
-      break;
-    case 3: /* haveMissVal & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] *= scaleFactor;
-      break;
-    case 2: /* haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] *= scaleFactor;
-      break;
-    case 1: /* haveMissVal */
-      for ( size_t i = 0; i < valueCount; i++ )
-        missValCount += (unsigned)DBL_IS_EQUAL(data[i], missVal);
-      break;
     }
 
-  return missValCount;
-}
-
-static
-size_t cdfDoInputDataTransformationSP(size_t valueCount, float *data, bool haveMissVal, double missVal, double scaleFactor, double offset, double validMin, double validMax)
- {
-  const bool haveOffset   = IS_NOT_EQUAL(offset, 0);
-  const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
-  size_t missValCount = 0;
-
-  if (validMin == VALIDMISS)
-    validMin = DBL_MIN;
-  if (validMax == VALIDMISS)
-    validMax = DBL_MAX;
-
-  bool haveRangeCheck = (validMax != DBL_MAX) | (validMin != DBL_MIN);
-  assert(!haveRangeCheck || haveMissVal);
+  /* time varID */
+  ncvarid = streamptr->basetime.ncvarid;
 
-  switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
-          | ((int)haveOffset << 2) | ((int)haveRangeCheck << 3))
+  if ( ncvarid != UNDEFID && streamptr->basetime.lwrf == FALSE )
     {
-    case 15: /* haveRangeCheck & haveMissVal & haveScaleFactor & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? (float)missVal
-            : isMissVal ? data[i] : (float)(data[i] * scaleFactor + offset);
-        }
-      break;
-    case 13: /* haveRangeCheck & haveMissVal & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? (float)missVal
-            : isMissVal ? data[i] : (float)(data[i] + offset);
-        }
-      break;
-    case 11: /* haveRangeCheck & haveMissVal & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? (float)missVal
-            : isMissVal ? data[i] : (float)(data[i] * scaleFactor);
-        }
-      break;
-    case 9: /* haveRangeCheck & haveMissVal */
-      for ( size_t i = 0; i < valueCount; i++ )
+      if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = TRUE;
+
+      if ( ncvars[ncvarid].bounds != UNDEFID )
         {
-          int outOfRange = data[i] < validMin || data[i] > validMax;
-          int isMissVal = DBL_IS_EQUAL(data[i], missVal);
-          missValCount += (size_t)(outOfRange | isMissVal);
-          data[i] = outOfRange ? (float)missVal : data[i];
+          int nbdims = ncvars[ncvars[ncvarid].bounds].ndims;
+          if ( nbdims == 2 )
+            {
+              int len = (int) ncdims[ncvars[ncvars[ncvarid].bounds].dimids[nbdims-1]].len;
+              if ( len == 2 && timedimid == ncvars[ncvars[ncvarid].bounds].dimids[0] )
+                {
+                  *time_has_bounds = TRUE;
+                  streamptr->basetime.ncvarboundsid = ncvars[ncvarid].bounds;
+                  if ( ncvars[ncvarid].climatology ) *time_climatology = TRUE;
+                }
+            }
         }
-      break;
-    case 7: /* haveMissVal & haveScaleFactor & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] = (float)(data[i] * scaleFactor + offset);
-      break;
-    case 6: /* haveOffset & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] = (float)(data[i] * scaleFactor + offset);
-      break;
-    case 5: /* haveMissVal & haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] = (float)(data[i] + offset);
-      break;
-    case 4: /* haveOffset */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] = (float)(data[i] + offset);
-      break;
-    case 3: /* haveMissVal & haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        if ( DBL_IS_EQUAL(data[i], missVal) )
-          missValCount++;
-        else
-          data[i] = (float)(data[i] * scaleFactor);
-      break;
-    case 2: /* haveScaleFactor */
-      for ( size_t i = 0; i < valueCount; i++ )
-        data[i] = (float)(data[i] * scaleFactor);
-      break;
-    case 1: /* haveMissVal */
-      for ( size_t i = 0; i < valueCount; i++ )
-        missValCount += (unsigned)DBL_IS_EQUAL(data[i], missVal);
-      break;
     }
-
-  return missValCount;
 }
 
-static void
-cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, long nvals, size_t xsize, size_t ysize, int swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
+int cdfInqContents(stream_t *streamptr)
 {
-  const double *pdata_dp = (const double *) data;
-  double *mdata_dp = NULL;
-  double *sdata_dp = NULL;
-  const float *pdata_sp = (const float *) data;
-  float *mdata_sp = NULL;
-  float *sdata_sp = NULL;
-  extern int CDF_Debug;
-
-  /*  if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
-    {
-      bool laddoffset, lscalefactor;
-      double addoffset, scalefactor;
-      double missval;
+  int ndims, nvars, ngatts, unlimdimid;
+  int ncvarid;
+  int ncdimid;
+  size_t ntsteps;
+  int timedimid = -1;
+  int *varids;
+  int nvarids;
+  int time_has_units = FALSE;
+  int time_has_bounds = FALSE;
+  int time_climatology = FALSE;
+  int leadtime_id = UNDEFID;
+  int nvars_data;
+  int nvcth_id = UNDEFID, vcta_id = UNDEFID, vctb_id = UNDEFID;
+  size_t vctsize = 0;
+  double *vct = NULL;
+  int instID  = UNDEFID;
+  int modelID = UNDEFID;
+  int taxisID;
+  int i;
+  int calendar = UNDEFID;
+  ncdim_t *ncdims;
+  ncvar_t *ncvars = NULL;
+  int format = 0;
+  int ucla_les = FALSE;
+  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
+  char gridfile[8912];
+  char fcreftime[CDI_MAX_NAME];
+  int number_of_grid_used = UNDEFID;
 
-      addoffset    = vlistInqVarAddoffset(vlistID, varID);
-      scalefactor  = vlistInqVarScalefactor(vlistID, varID);
-      laddoffset   = IS_NOT_EQUAL(addoffset, 0);
-      lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+  memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
+  memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
+  gridfile[0] = 0;
+  fcreftime[0] = 0;
 
-      missval      = vlistInqVarMissval(vlistID, varID);
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-      if ( laddoffset || lscalefactor )
-        {
-          if ( memtype == MEMTYPE_FLOAT )
-            {
-              mdata_sp = (float *) malloc((size_t)nvals*sizeof(float));
-              memcpy(mdata_sp, pdata_sp, (size_t)nvals * sizeof (float));
-              pdata_sp = mdata_sp;
+  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
-              if ( nmiss > 0 )
-                {
-                  for (long i = 0; i < nvals; i++ )
-                    {
-                      double temp = mdata_sp[i];
-                      if ( !DBL_IS_EQUAL(temp, missval) )
-                        {
-                          if ( laddoffset )   temp -= addoffset;
-                          if ( lscalefactor ) temp /= scalefactor;
-                          mdata_sp[i] = (float)temp;
-                        }
-                    }
-                }
-              else
-                {
-                  for (long i = 0; i < nvals; i++ )
-                    {
-                      double temp = mdata_sp[i];
-                      if ( laddoffset )   temp -= addoffset;
-                      if ( lscalefactor ) temp /= scalefactor;
-                      mdata_sp[i] = (float)temp;
-                    }
-                }
-            }
-          else
-            {
-              mdata_dp = (double *) malloc((size_t)nvals * sizeof(double));
-              memcpy(mdata_dp, pdata_dp, (size_t)nvals * sizeof(double));
-              pdata_dp = mdata_dp;
+#if  defined  (HAVE_NETCDF4)
+  nc_inq_format(fileID, &format);
+#endif
 
-              if ( nmiss > 0 )
-                {
-                  for (long i = 0; i < nvals; i++ )
-                    {
-                      if ( !DBL_IS_EQUAL(mdata_dp[i], missval) )
-                        {
-                          if ( laddoffset )   mdata_dp[i] -= addoffset;
-                          if ( lscalefactor ) mdata_dp[i] /= scalefactor;
-                        }
-                    }
-                }
-              else
-                {
-                  for (long i = 0; i < nvals; i++ )
-                    {
-                      if ( laddoffset )   mdata_dp[i] -= addoffset;
-                      if ( lscalefactor ) mdata_dp[i] /= scalefactor;
-                    }
-                }
-            }
-        }
+  cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
 
-      if ( dtype == DATATYPE_UINT8 || dtype == DATATYPE_INT8 ||
-           dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 )
-        {
-          if ( memtype == MEMTYPE_FLOAT )
-            {
-              if ( mdata_sp == NULL )
-                {
-                  mdata_sp = (float *) malloc((size_t)nvals * sizeof(float));
-                  memcpy(mdata_sp, pdata_sp, (size_t)nvals * sizeof(float));
-                  pdata_sp = mdata_sp;
-                }
+  if ( CDI_Debug )
+    Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
 
-              for (long i = 0; i < nvals; i++ ) mdata_sp[i] = roundf(mdata_sp[i]);
+  if ( ndims == 0 )
+    {
+      Warning("ndims = %d", ndims);
+      return (CDI_EUFSTRUCT);
+    }
 
-              if ( dtype == DATATYPE_UINT8 )
-                {
-                  nc_type xtype;
-                  cdf_inq_vartype(fileID, ncvarid, &xtype);
-                  if ( xtype == NC_BYTE )
-                    {
-                      for ( long i = 0; i < nvals; ++i )
-                        if ( mdata_sp[i] > 127 ) mdata_sp[i] -= 256;
-                    }
-                }
-            }
-          else
-            {
-              if ( mdata_dp == NULL )
-                {
-                  mdata_dp = (double *) malloc((size_t)nvals * sizeof (double));
-                  memcpy(mdata_dp, pdata_dp, (size_t)nvals * sizeof (double));
-                  pdata_dp = mdata_dp;
-                }
+  /* alloc ncdims */
+  ncdims = (ncdim_t *)xmalloc((size_t)ndims * sizeof (ncdim_t));
+  init_ncdims(ndims, ncdims);
 
-              for (long i = 0; i < nvals; i++ ) mdata_dp[i] = round(mdata_dp[i]);
+  if ( nvars > 0 )
+    {
+      /* alloc ncvars */
+      ncvars = (ncvar_t *)xmalloc((size_t)nvars * sizeof (ncvar_t));
+      init_ncvars(nvars, ncvars);
 
-              if ( dtype == DATATYPE_UINT8 )
-                {
-                  nc_type xtype;
-                  cdf_inq_vartype(fileID, ncvarid, &xtype);
-                  if ( xtype == NC_BYTE )
-                    {
-                      for (long i = 0; i < nvals; ++i )
-                        if ( mdata_dp[i] > 127 ) mdata_dp[i] -= 256;
-                    }
-                }
-            }
-        }
+      for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
+        ncvars[ncvarid].ncid = fileID;
+    }
 
-      if ( CDF_Debug && memtype != MEMTYPE_FLOAT )
+#if  defined  (TEST_GROUPS)
+#if  defined  (HAVE_NETCDF4)
+  if ( format == NC_FORMAT_NETCDF4 )
+    {
+      int ncid;
+      int numgrps;
+      int ncids[NC_MAX_VARS];
+      char name1[CDI_MAX_NAME];
+      int gndims, gnvars, gngatts, gunlimdimid;
+      nc_inq_grps(fileID, &numgrps, ncids);
+      for ( int i = 0; i < numgrps; ++i )
         {
-          double fmin, fmax;
-          fmin =  1.0e200;
-          fmax = -1.0e200;
-          for ( long i = 0; i < nvals; ++i )
-            {
-              if ( !DBL_IS_EQUAL(pdata_dp[i], missval) )
-                {
-                  if ( pdata_dp[i] < fmin ) fmin = pdata_dp[i];
-                  if ( pdata_dp[i] > fmax ) fmax = pdata_dp[i];
-                }
+          ncid = ncids[i];
+          nc_inq_grpname (ncid, name1);
+          cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
+
+          if ( CDI_Debug )
+            Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
+
+          if ( gndims == 0 )
+            {
             }
-          Message("nvals = %d, nmiss = %d, missval = %g, minval = %g, maxval = %g",
-                  nvals, nmiss, missval, fmin, fmax);
         }
     }
+#endif
+#endif
 
-  if ( swapxy )
+  if ( nvars == 0 )
     {
-      if ( memtype == MEMTYPE_FLOAT )
-        {
-          /* malloc and the loop imply nvals >= ysize * xsize,
-           * but that is not checked and the types don't match */
-          sdata_sp = (float *)xmalloc((size_t)nvals * sizeof (float));
-          for ( size_t j = 0; j < ysize; ++j )
-            for ( size_t i = 0; i < xsize; ++i )
-              sdata_sp[i*ysize+j] = pdata_sp[j*xsize+i];
-          pdata_sp = sdata_sp;
-        }
-      else
-        {
-          sdata_dp = (double *)xmalloc((size_t)nvals * sizeof (double));
-          for ( size_t j = 0; j < ysize; ++j )
-            for ( size_t i = 0; i < xsize; ++i )
-              sdata_dp[i*ysize+j] = pdata_dp[j*xsize+i];
-          pdata_dp = sdata_dp;
-        }
+      Warning("nvars = %d", nvars);
+      return (CDI_EUFSTRUCT);
     }
 
-  if ( memtype == MEMTYPE_FLOAT )
-    cdf_put_vara_float(fileID, ncvarid, start, count, pdata_sp);
-  else
-    cdf_put_vara_double(fileID, ncvarid, start, count, pdata_dp);
+  /* scan global attributes */
+  scan_global_attributes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, 
+                         uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
 
-  if ( mdata_dp ) free(mdata_dp);
-  if ( sdata_dp ) free(sdata_dp);
-  if ( mdata_sp ) free(mdata_sp);
-  if ( sdata_sp ) free(sdata_sp);
-}
+  /* find time dim */
+  if ( unlimdimid >= 0 )
+    timedimid = unlimdimid;
+  else
+    timedimid = cdfTimeDimID(fileID, ndims, nvars);
 
+  streamptr->basetime.ncdimid = timedimid;
 
-void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
-{
-  int fileID;
-  int gridID;
-  int zaxisID;
-  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
-  int ncvarid;
-  size_t xsize = 0, ysize = 0;
-  size_t size;
-  size_t start[5];
-  size_t count[5];
-  long nvals;
-  int swapxy = FALSE;
-  int ndims = 0;
-  int idim;
-  int tsteptype;
-  int gridindex, zaxisindex;
-  int dtype;
-  int vlistID;
+  if ( timedimid != UNDEFID )
+    cdf_inq_dimlen(fileID, timedimid, &ntsteps);
+  else
+    ntsteps = 0;
 
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  if ( CDI_Debug ) Message("Number of timesteps = %d", ntsteps);
+  if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
+  /* read ncdims */
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+    {
+      cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
+      cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name);
+      if ( timedimid == ncdimid )
+	ncdims[ncdimid].dimtype = T_AXIS;
+    }
 
-  long ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "cdfScanVarAttributes");
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+  /* scan attributes of all variables */
+  cdfScanVarAttributes(nvars, ncvars, ncdims, timedimid, modelID, format);
 
-  ncvarid = cdfDefVar(streamptr, varID);
 
-  gridID    = vlistInqVarGrid(vlistID, varID);
-  zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "find coordinate vars");
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  if ( gridInqType(gridID) == GRID_TRAJECTORY )
+  /* find coordinate vars */
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
-      cdfWriteGridTraj(streamptr, gridID);
+      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+	{
+	  if ( ncvars[ncvarid].ndims == 1 )
+	    {
+	      if ( timedimid != UNDEFID && timedimid == ncvars[ncvarid].dimids[0] )
+		{
+		  if ( ncvars[ncvarid].isvar != FALSE ) cdfSetVar(ncvars, ncvarid, TRUE);
+		}
+	      else
+		{
+                  //  if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
+		}
+	      // if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
+
+	      if ( ncdimid == ncvars[ncvarid].dimids[0] && ncdims[ncdimid].ncvarid == UNDEFID )
+		if ( strcmp(ncvars[ncvarid].name, ncdims[ncdimid].name) == 0 )
+		  {
+		    ncdims[ncdimid].ncvarid = ncvarid;
+		    ncvars[ncvarid].isvar = FALSE;
+		  }
+	    }
+	}
     }
-  else
+
+  /* find time vars */
+  find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
+
+  leadtime_id = find_leadtime(nvars, ncvars);
+  if ( leadtime_id != UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
+
+  /* check ncvars */
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      xid = streamptr->xdimID[gridindex];
-      yid = streamptr->ydimID[gridindex];
+      if ( timedimid != UNDEFID )
+	if ( ncvars[ncvarid].isvar == -1 &&
+	     ncvars[ncvarid].ndims > 1   &&
+	     timedimid == ncvars[ncvarid].dimids[0] )
+	  cdfSetVar(ncvars, ncvarid, TRUE);
+
+      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
+	cdfSetVar(ncvars, ncvarid, FALSE);
+
+      //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
+      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
+	cdfSetVar(ncvars, ncvarid, TRUE);
+
+      if ( ncvars[ncvarid].isvar == -1 )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( ncvars[ncvarid].ndims > 4 )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("%d dimensional variables are not supported, skipped variable %s!",
+		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( ncvars[ncvarid].ndims == 4 && timedimid == UNDEFID )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
+		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( xtypeIsText(ncvars[ncvarid].xtype) )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  continue;
+	}
+
+      if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("Variable %s has an unsupported data type, skipped!", ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( timedimid != UNDEFID && ntsteps == 0 && ncvars[ncvarid].ndims > 0 )
+	{
+	  if ( timedimid == ncvars[ncvarid].dimids[0] )
+	    {
+	      ncvars[ncvarid].isvar = 0;
+	      Warning("Number of time steps undefined, skipped variable %s!", ncvars[ncvarid].name);
+	      continue;
+	    }
+	}
     }
 
-  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-  zid = streamptr->zaxisID[zaxisindex];
+  /* verify coordinate vars - first scan (dimname == varname) */
+  verify_coordinate_vars_1(ndims, ncdims, ncvars, timedimid);
 
-  if ( tsteptype != TSTEP_CONSTANT )
+  /* verify coordinate vars - second scan (all other variables) */
+  verify_coordinate_vars_2(nvars, ncvars);
+
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "verify_coordinate_vars");
+
+  if ( ucla_les == TRUE )
     {
-      start[ndims] = (size_t)ntsteps - 1;
-      count[ndims] = 1;
-      ndims++;
+      for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+	{
+	  ncvarid = ncdims[ncdimid].ncvarid;
+	  if ( ncvarid != -1 )
+	    {
+	      if ( ncdims[ncdimid].dimtype == UNDEFID && ncvars[ncvarid].units[0] == 'm' )
+		{
+		  if      ( ncvars[ncvarid].name[0] == 'x' ) ncdims[ncdimid].dimtype = X_AXIS;
+		  else if ( ncvars[ncvarid].name[0] == 'y' ) ncdims[ncdimid].dimtype = Y_AXIS;
+		  else if ( ncvars[ncvarid].name[0] == 'z' ) ncdims[ncdimid].dimtype = Z_AXIS;
+		}
+	    }
+	}
     }
-  if ( zid != UNDEFID )
+  /*
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
-      start[ndims] = 0;
-      count[ndims] = (size_t)zaxisInqSize(zaxisID);
-      ndims++;
+      ncvarid = ncdims[ncdimid].ncvarid;
+      if ( ncvarid != -1 )
+	{
+	  printf("coord var %d %s %s\n", ncvarid, ncvars[ncvarid].name, ncvars[ncvarid].units);
+	  if ( ncdims[ncdimid].dimtype == X_AXIS )
+	    printf("coord var %d %s is x dim\n", ncvarid, ncvars[ncvarid].name);
+	  if ( ncdims[ncdimid].dimtype == Y_AXIS )
+	    printf("coord var %d %s is y dim\n", ncvarid, ncvars[ncvarid].name);
+	  if ( ncdims[ncdimid].dimtype == Z_AXIS )
+	    printf("coord var %d %s is z dim\n", ncvarid, ncvars[ncvarid].name);
+	  if ( ncdims[ncdimid].dimtype == T_AXIS )
+	    printf("coord var %d %s is t dim\n", ncvarid, ncvars[ncvarid].name);
+
+	  if ( ncvars[ncvarid].islon )
+	    printf("coord var %d %s is lon\n", ncvarid, ncvars[ncvarid].name);
+	  if ( ncvars[ncvarid].islat )
+	    printf("coord var %d %s is lat\n", ncvarid, ncvars[ncvarid].name);
+	  if ( ncvars[ncvarid].islev )
+	    printf("coord var %d %s is lev\n", ncvarid, ncvars[ncvarid].name);
+	}
     }
-  if ( yid != UNDEFID )
+  */
+
+  /* Set coordinate varids (att: associate)  */
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      start[ndims] = 0;
-      cdf_inq_dimlen(fileID, yid, &size);
-      /*      count[ndims] = gridInqYsize(gridID); */
-      count[ndims] = size;
-      ndims++;
+      if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].ncoordvars )
+	{
+	  /* ndims = ncvars[ncvarid].ndims; */
+	  ndims = ncvars[ncvarid].ncoordvars;
+	  for ( i = 0; i < ndims; i++ )
+	    {
+	      if ( ncvars[ncvars[ncvarid].coordvarids[i]].islon )
+		ncvars[ncvarid].xvarid = ncvars[ncvarid].coordvarids[i];
+	      else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islat )
+		ncvars[ncvarid].yvarid = ncvars[ncvarid].coordvarids[i];
+	      else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islev )
+		ncvars[ncvarid].zvarid = ncvars[ncvarid].coordvarids[i];
+	    }
+	}
     }
-  if ( xid != UNDEFID )
+
+  /* set dim type */
+  setDimType(nvars, ncvars, ncdims);
+
+  /* find VCT */
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      start[ndims] = 0;
-      cdf_inq_dimlen(fileID, xid, &size);
-      /*      count[ndims] = gridInqXsize(gridID); */
-      count[ndims] = size;
-      ndims++;
+      if ( ncvars[ncvarid].ndims == 1 )
+	{
+	  if ( memcmp(ncvars[ncvarid].name, "hyai", 4) == 0 )
+	    {
+	      vcta_id = ncvarid;
+	      nvcth_id = ncvars[ncvarid].dimids[0];
+              ncvars[ncvarid].isvar = FALSE;
+	      continue;
+	    }
+	  if ( memcmp(ncvars[ncvarid].name, "hybi", 4) == 0 )
+	    {
+	      vctb_id = ncvarid;
+	      nvcth_id = ncvars[ncvarid].dimids[0];
+              ncvars[ncvarid].isvar = FALSE;
+	      continue;
+	    }
+
+	  if      ( memcmp(ncvars[ncvarid].name, "hyam", 4) == 0 ) ncvars[ncvarid].isvar = FALSE;
+	  else if ( memcmp(ncvars[ncvarid].name, "hybm", 4) == 0 ) ncvars[ncvarid].isvar = FALSE;
+	}
     }
 
-  if ( CDI_Debug )
-    for (idim = 0; idim < ndims; idim++)
-      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "define_all_grids");
 
-  if ( streamptr->ncmode == 1 )
+
+  /* define all grids */
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
+
+
+  /* read VCT */
+  if ( nvcth_id != UNDEFID && vcta_id != UNDEFID && vctb_id != UNDEFID )
     {
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      vctsize = ncdims[nvcth_id].len;
+      vctsize *= 2;
+      vct = (double *) malloc(vctsize*sizeof(double));
+      cdf_get_var_double(fileID, vcta_id, vct);
+      cdf_get_var_double(fileID, vctb_id, vct+vctsize/2);
     }
 
-  dtype = vlistInqVarDatatype(vlistID, varID);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
+  /* define all zaxes */
+  define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
 
-  nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
 
-  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
+  if ( vct ) free(vct);
 
-}
+  /* select vars */
+  varids = (int *)xmalloc((size_t)nvars * sizeof (int));
+  nvarids = 0;
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
 
+  nvars_data = nvarids;
 
-void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
-                         const int rect[][2], const void *data, int nmiss)
-{
-  int fileID;
-  int gridID;
-  int zaxisID;
-  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
-  int ncvarid;
-  size_t xsize = 0, ysize = 0;
-  size_t start[5];
-  size_t count[5];
-  long nvals;
-  int swapxy = FALSE;
-  int ndims = 0;
-  int idim;
-  int tsteptype;
-  int gridindex, zaxisindex;
-  int dtype;
-  int vlistID;
-  int streamID = streamptr->self;
+  if ( CDI_Debug ) Message("time varid = %d", streamptr->basetime.ncvarid);
+  if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
+  if ( CDI_Debug ) Message("nvars_data = %d", nvars_data);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  if ( nvars_data == 0 )
+    {
+      streamptr->ntsteps = 0;
+      return (CDI_EUFSTRUCT);
+    }
 
-  long ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug )
-    Message("ntsteps = %ld", ntsteps);
+  if ( ntsteps == 0 && streamptr->basetime.ncdimid == UNDEFID && streamptr->basetime.ncvarid != UNDEFID )
+    ntsteps = 1;
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+  streamptr->ntsteps = (long)ntsteps;
 
-  ncvarid = cdfDefVar(streamptr, varID);
+  /* define all data variables */
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
 
-  gridID    = vlistInqVarGrid(vlistID, varID);
-  zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  tsteptype = vlistInqVarTsteptype(vlistID, varID);
 
-  gridindex = vlistGridIndex(vlistID, gridID);
-  if ( gridInqType(gridID) == GRID_TRAJECTORY )
+  cdiCreateTimesteps(streamptr);
+
+  /* time varID */
+  ncvarid = streamptr->basetime.ncvarid;
+
+  if ( time_has_units )
     {
-      cdfWriteGridTraj(streamptr, gridID);
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+
+      if ( setBaseTime(ncvars[ncvarid].units, taxis) == 1 )
+        {
+          ncvarid = UNDEFID;
+          streamptr->basetime.ncvarid = UNDEFID;
+        }
+
+      if ( leadtime_id != UNDEFID && taxis->type == TAXIS_RELATIVE )
+        {
+          streamptr->basetime.leadtimeid = leadtime_id;
+          taxis->type = TAXIS_FORECAST;
+
+          int timeunit = -1;
+          if ( ncvars[leadtime_id].units[0] != 0 ) timeunit = scanTimeUnit(ncvars[leadtime_id].units);
+          if ( timeunit == -1 ) timeunit = taxis->unit;
+          taxis->fc_unit = timeunit;
+
+          setForecastTime(fcreftime, taxis);
+        }
     }
-  else
+
+  if ( time_has_bounds )
     {
-      xid = streamptr->xdimID[gridindex];
-      yid = streamptr->ydimID[gridindex];
+      streamptr->tsteps[0].taxis.has_bounds = TRUE;
+      if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = TRUE;
     }
 
-  zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-  zid = streamptr->zaxisID[zaxisindex];
-
-  if ( tsteptype != TSTEP_CONSTANT )
+  if ( ncvarid != UNDEFID )
     {
-      start[ndims] = (size_t)ntsteps - 1;
-      count[ndims] = 1;
-      ndims++;
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+      ptaxisDefName(taxis, ncvars[ncvarid].name);
+      if ( ncvars[ncvarid].longname[0] )
+        ptaxisDefLongname(taxis, ncvars[ncvarid].longname);
     }
-  if ( zid != UNDEFID )
+
+  if ( ncvarid != UNDEFID )
+    if ( ncvars[ncvarid].calendar == TRUE )
+      {
+        enum {
+          attstringlen = 8192,
+        };
+        char attstring[attstringlen];
+
+	cdfGetAttText(fileID, ncvarid, "calendar", attstringlen, attstring);
+	strtolower(attstring);
+
+	if ( memcmp(attstring, "standard", 8)  == 0 ||
+	     memcmp(attstring, "gregorian", 9) == 0 )
+	  calendar = CALENDAR_STANDARD;
+	else if ( memcmp(attstring, "none", 4) == 0 )
+	  calendar = CALENDAR_NONE;
+	else if ( memcmp(attstring, "proleptic", 9) == 0 )
+	  calendar = CALENDAR_PROLEPTIC;
+	else if ( memcmp(attstring, "360", 3) == 0 )
+	  calendar = CALENDAR_360DAYS;
+	else if ( memcmp(attstring, "365", 3) == 0 ||
+		  memcmp(attstring, "noleap", 6)  == 0 )
+	  calendar = CALENDAR_365DAYS;
+	else if ( memcmp(attstring, "366", 3)  == 0 ||
+		  memcmp(attstring, "all_leap", 8) == 0 )
+	  calendar = CALENDAR_366DAYS;
+	else
+	  Warning("calendar >%s< unsupported!", attstring);
+      }
+
+  if ( streamptr->tsteps[0].taxis.type == TAXIS_FORECAST )
     {
-      int size = zaxisInqSize(zaxisID);
-      xassert(rect[2][0] >= 0 && rect[2][0] <= rect[2][1]
-              && rect[2][1] <= size);
-      start[ndims] = (size_t)rect[2][0];
-      count[ndims] = (size_t)rect[2][1] - (size_t)rect[2][0] + 1;
-      ndims++;
+      taxisID = taxisCreate(TAXIS_FORECAST);
     }
-  if ( yid != UNDEFID )
+  else if ( streamptr->tsteps[0].taxis.type == TAXIS_RELATIVE )
     {
-      size_t size;
-      cdf_inq_dimlen(fileID, yid, &size);
-      xassert(rect[1][0] >= 0 && rect[1][0] <= rect[1][1]
-              && (size_t)rect[1][1] <= size);
-      start[ndims] = (size_t)rect[1][0];
-      count[ndims] = (size_t)rect[1][1] - (size_t)rect[1][0] + 1;
-      ndims++;
+      taxisID = taxisCreate(TAXIS_RELATIVE);
     }
-  if ( xid != UNDEFID )
+  else
     {
-      size_t size;
-      cdf_inq_dimlen(fileID, xid, &size);
-      xassert(rect[0][0] >= 0 && rect[0][0] <= rect[0][1]
-              && (size_t)rect[0][1] <= size);
-      start[ndims] = (size_t)rect[0][0];
-      count[ndims] = (size_t)rect[0][1] - (size_t)rect[0][0] + 1;
-      ndims++;
+      taxisID = taxisCreate(TAXIS_ABSOLUTE);
+      if ( !time_has_units )
+	{
+	  taxisDefTunit(taxisID, TUNIT_DAY);
+	  streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
+	}
     }
 
-  if ( CDI_Debug )
-    for (idim = 0; idim < ndims; idim++)
-      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
-  if ( streamptr->ncmode == 1 )
+  if ( calendar == UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
     {
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      calendar = CALENDAR_STANDARD;
+    }
+
+  if ( calendar != UNDEFID )
+    {
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+      taxis->calendar = calendar;
+      taxisDefCalendar(taxisID, calendar);
     }
 
-  dtype = vlistInqVarDatatype(vlistID, varID);
+  vlistDefTaxis(vlistID, taxisID);
+
+  streamptr->curTsID = 0;
+  streamptr->rtsteps = 1;
+
+  (void) cdfInqTimestep(streamptr, 0);
+
+  cdfCreateRecords(streamptr, 0);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
+  /* free ncdims */
+  free(ncdims);
 
-  nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
+  /* free ncvars */
+  free(ncvars);
 
-  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals,
-                     xsize, ysize, swapxy, start, count, memtype, data, nmiss);
+  return (0);
 }
 
 static
-size_t min_size(size_t a, size_t b)
+void wrf_read_timestep(int fileID, int nctimevarid, int tsID, taxis_t *taxis)
 {
-  return a < b ? a : b;
+  size_t start[2], count[2];
+  char stvalue[32];
+  start[0] = (size_t) tsID; start[1] = 0;
+  count[0] = 1; count[1] = 19;
+  stvalue[0] = 0;
+  cdf_get_vara_text(fileID, nctimevarid, start, count, stvalue);
+  stvalue[19] = 0;
+  {
+    int year = 1, month = 1, day = 1 , hour = 0, minute = 0, second = 0;
+    if ( strlen(stvalue) == 19 )
+      sscanf(stvalue, "%d-%d-%d_%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
+    taxis->vdate = cdiEncodeDate(year, month, day);
+    taxis->vtime = cdiEncodeTime(hour, minute, second);
+    taxis->type = TAXIS_ABSOLUTE;
+  }
 }
 
 static
-void transpose2dArrayDP(size_t inWidth, size_t inHeight, double* data)
+double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
 {
-  const size_t cacheBlockSize = 256;    // Purely an optimization parameter. Current value of 32 means we are handling 8kB blocks,
-                                       // which should be a decent compromise on many architectures.
-  double (*temp)[inWidth] = malloc(inHeight*sizeof(*temp));
-  double (*out)[inHeight] = (double (*)[inHeight])data;
-  memcpy(temp, data, inHeight*sizeof(*temp));
-  /*
-  for ( size_t y = 0; y < inHeight; ++y )
-    for ( size_t x = 0; x < inWidth; ++x )
-      out[x][y] = temp[y][x];
-  */
-  for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
+  double timevalue = 0;
+  size_t index = (size_t) tsID;
+
+  if ( tcache )
     {
-      for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
+      if ( tcache->size == 0 || (tsID < tcache->startid || tsID > (tcache->startid+tcache->size-1)) )
         {
-          for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
+          int maxvals = MAX_TIMECACHE_SIZE;
+          tcache->startid = (tsID/MAX_TIMECACHE_SIZE)*MAX_TIMECACHE_SIZE;
+          if ( (tcache->startid + maxvals) > tcache->maxvals ) maxvals = (tcache->maxvals)%MAX_TIMECACHE_SIZE;
+          tcache->size = maxvals;
+          index = (size_t) tcache->startid;
+          // fprintf(stderr, "fill time cache: %d %d %d %d %d\n", tcache->maxvals, tsID, tcache->startid, tcache->startid+maxvals-1, maxvals);
+          for ( int ival = 0; ival < maxvals; ++ival )
             {
-              for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
-                {
-                  out[x][y] = temp[y][x];
-                }
+              cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+              tcache->cache[ival] = timevalue;
+              index++;
             }
         }
-    }
-
-  free(temp);
-}
 
-static
-void transpose2dArraySP(size_t inWidth, size_t inHeight, float* data)
-{
-  const size_t cacheBlockSize = 256;    // Purely an optimization parameter. Current value of 32 means we are handling 8kB blocks,
-                                       // which should be a decent compromise on many architectures.
-  float (*temp)[inWidth] = malloc(inHeight*sizeof(*temp));
-  float (*out)[inHeight] = (float (*)[inHeight])data;
-  memcpy(temp, data, inHeight*sizeof(*temp));
-  /*
-  for ( size_t y = 0; y < inHeight; ++y )
-    for ( size_t x = 0; x < inWidth; ++x )
-      out[x][y] = temp[y][x];
-  */
-  for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
+      timevalue = tcache->cache[tsID%MAX_TIMECACHE_SIZE];
+    }
+  else
     {
-      for ( size_t xBlock = 0; xBlock < inWidth; xBlock += cacheBlockSize )
-        {
-          for ( size_t y = yBlock, yEnd = min_size(yBlock + cacheBlockSize, inHeight); y < yEnd; y++ )
-            {
-              for ( size_t x = xBlock, xEnd = min_size(xBlock + cacheBlockSize, inWidth); x < xEnd; x++ )
-                {
-                  out[x][y] = temp[y][x];
-                }
-            }
-        }
+      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
+      if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
     }
 
-  free(temp);
+  return timevalue;
 }
 
-static
-void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
+int cdfInqTimestep(stream_t * streamptr, int tsID)
 {
-  int gridId = vlistInqVarGrid(streamptr->vlistID, varId);
-  int gridindex = vlistGridIndex(streamptr->vlistID, gridId);
-
-  (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = UNDEFID;
-  switch ( gridInqType(gridId) )
-    {
-      case GRID_TRAJECTORY:
-        cdfReadGridTraj(streamptr, gridId);
-        break;
-
-      case GRID_UNSTRUCTURED:
-        (*outDimIds)[0] = streamptr->xdimID[gridindex];
-        break;
-
-      default:
-        (*outDimIds)[0] = streamptr->xdimID[gridindex];
-        (*outDimIds)[1] = streamptr->ydimID[gridindex];
-        break;
-    }
+  long nrecs = 0;
+  double timevalue;
+  int fileID;
+  taxis_t *taxis;
 
-  int zaxisID = vlistInqVarZaxis(streamptr->vlistID, varId);
-  int zaxisindex = vlistZaxisIndex(streamptr->vlistID, zaxisID);
-  (*outDimIds)[2] = streamptr->zaxisID[zaxisindex];
-}
+  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
-static
-int cdfGetSkipDim(int fileId, int ncvarid, int (*dimIds)[3])
-{
-  if((*dimIds)[0] != UNDEFID) return 0;
-  if((*dimIds)[1] != UNDEFID) return 0;
-  int nvdims;
-  cdf_inq_varndims(fileId, ncvarid, &nvdims);
-  if(nvdims != 3) return 0;
+  if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
 
-  int varDimIds[3];
-  cdf_inq_vardimid(fileId, ncvarid, varDimIds);
-  size_t size = 0;
-  if ( (*dimIds)[2] == varDimIds[2] )
-    {
-      cdf_inq_dimlen(fileId, varDimIds[1], &size);
-      if ( size == 1 ) return 1;
-    }
-  else if ( (*dimIds)[2] == varDimIds[1] )
+  if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
     {
-      cdf_inq_dimlen(fileId, varDimIds[2], &size);
-      if ( size == 1 ) return 2;
-    }
-  return 0;
-}
+      cdfCreateRecords(streamptr, tsID);
 
+      taxis = &streamptr->tsteps[tsID].taxis;
+      if ( tsID > 0 )
+	ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
 
-static
-void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, bool *outSwapXY, size_t (*start)[4], size_t (*count)[4])
-{
-  int tsID = streamptr->curTsID;
-  if ( CDI_Debug ) Message("tsID = %d", tsID);
+      timevalue = tsID;
 
-  int fileId = streamptr->fileID;
-  int vlistId = streamptr->vlistID;
-  int ncvarid = streamptr->vars[varId].ncvarid;
+      int nctimevarid = streamptr->basetime.ncvarid;
+      if ( nctimevarid != UNDEFID )
+	{
+	  fileID = streamptr->fileID;
+	  size_t index  = (size_t)tsID;
 
-  int gridId = vlistInqVarGrid(vlistId, varId);
-  int tsteptype = vlistInqVarTsteptype(vlistId, varId);
-  int gridsize = gridInqSize(gridId);
+	  if ( streamptr->basetime.lwrf )
+	    {
+              wrf_read_timestep(fileID, nctimevarid, tsID, taxis);
+	    }
+	  else
+	    {
+#if defined (USE_TIMECACHE)
+              if ( streamptr->basetime.timevar_cache == NULL )
+                {
+                  streamptr->basetime.timevar_cache = (timecache_t *) malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t));
+                  streamptr->basetime.timevar_cache->size = 0;
+                  streamptr->basetime.timevar_cache->maxvals = streamptr->ntsteps;
+                }
+#endif
+              timevalue = get_timevalue(fileID, nctimevarid, tsID, streamptr->basetime.timevar_cache);
+	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
+	    }
 
-  streamptr->numvals += gridsize;
+	  int nctimeboundsid = streamptr->basetime.ncvarboundsid;
+	  if ( nctimeboundsid != UNDEFID )
+	    {
+	      size_t start[2], count[2];
+              start[0] = index; count[0] = 1; start[1] = 0; count[1] = 1;
+	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
-  int dimIds[3];    //this array joins the old variables xid, yid, and zid
-  cdfInqDimIds(streamptr, varId, &dimIds);
+	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
 
-  int skipdim = cdfGetSkipDim(fileId, ncvarid, &dimIds);
+              start[0] = index; count[0] = 1; start[1] = 1; count[1] = 1;
+	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
-  int dimorder[3];
-  vlistInqVarDimorder(vlistId, varId, &dimorder);
+	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
+	    }
 
-  *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != UNDEFID && dimIds[1] != UNDEFID ;
+          int leadtimeid = streamptr->basetime.leadtimeid;
+          if ( leadtimeid != UNDEFID )
+            {
+              timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
+              cdiSetForecastPeriod(timevalue, taxis);
+            }
+	}
+    }
 
-  int ndims = 0;
+  streamptr->curTsID = tsID;
+  nrecs = streamptr->tsteps[tsID].nrecs;
 
-#define addDimension(startIndex, extent) do {   \
-      (*start)[ndims] = startIndex; \
-      (*count)[ndims] = extent; \
-      ndims++; \
-  } while(0)
+  return ((int) nrecs);
+}
 
-  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
-  if ( skipdim == 1 ) addDimension(0, 1);
 
-  for ( int id = 0; id < 3; ++id )
-    {
-      size_t size;
-      int curDimId = dimIds[dimorder[id]-1];
-      if ( curDimId == UNDEFID ) continue;
-      switch ( dimorder[id] )
-        {
-          Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
-          case 1:
-          case 2:
-            cdf_inq_dimlen(fileId, curDimId, &size);
-            addDimension(0, size);
-            break;
+void cdfEndDef(stream_t *streamptr)
+{
+  int varID;
+  int nvars;
+  int fileID;
 
-          case 3:
-            addDimension((size_t)levelId, 1);
-            break;
+  fileID  = streamptr->fileID;
 
-          default:
-            Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
-        }
-    }
+  cdfDefGlobalAtts(streamptr);
+  cdfDefLocalAtts(streamptr);
 
-  if ( skipdim == 2 ) addDimension(0, 1);
+  if ( streamptr->accessmode == 0 )
+    {
+      nvars =  streamptr->nvars;
 
-  assert(ndims <= (int)(sizeof(*start)/sizeof(**start)));
-  assert(ndims <= (int)(sizeof(*count)/sizeof(**count)));
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-#undef addDimension
+      for ( varID = 0; varID < nvars; varID++ )
+	cdfDefVar(streamptr, varID);
 
-  if ( CDI_Debug )
-    for (int idim = 0; idim < ndims; idim++)
-      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
+      if ( streamptr->ncmode == 2 )
+        {
+          extern size_t CDI_netcdf_hdr_pad;
 
-  int nvdims;
-  cdf_inq_varndims(fileId, ncvarid, &nvdims);
+          if ( CDI_netcdf_hdr_pad == 0UL )
+            cdf_enddef(fileID);
+          else
+            cdf__enddef(fileID, CDI_netcdf_hdr_pad);
+        }
 
-  if ( nvdims != ndims )
-    Error("Internal error, variable %s has an unsupported array structure!", vlistInqVarNamePtr(vlistId, varId));
+      streamptr->accessmode = 1;
+    }
 }
 
-void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
-{
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
-
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-
-  int ncvarid = streamptr->vars[varID].ncvarid;
-
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int zaxisID = vlistInqVarZaxis(vlistID, varID);
 
-  size_t start[4];
-  size_t count[4];
-  cdfGetSlapDescription(streamptr, varID, &start, &count);
+static void cdfDefInstitut(stream_t *streamptr)
+{
+  int fileID, instID;
+  size_t len;
+  int vlistID;
 
-  cdf_get_vara_double(fileID, ncvarid, start, count, data);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+  instID  = vlistInqInstitut(vlistID);
 
-  size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
-  double missval = vlistInqVarMissval(vlistID, varID);
-  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
-  double validRange[2];
-  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
-    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
-  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
-  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
-  size_t nmiss_ = cdfDoInputDataTransformationDP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
-  assert(nmiss_ <= INT_MAX);
-  *nmiss = (int)nmiss_;
+  if ( instID != UNDEFID )
+    {
+      const char *longname = institutInqLongnamePtr(instID);
+      if ( longname )
+	{
+	  len = strlen(longname);
+	  if ( len > 0 )
+	    {
+	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+	      cdf_put_att_text(fileID, NC_GLOBAL, "institution", len, longname);
+	      if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+	    }
+	}
+    }
 }
 
-void cdfReadVarSP(stream_t *streamptr, int varID, float *data, int *nmiss)
-{
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
+static void cdfDefSource(stream_t *streamptr)
+{
   int vlistID = streamptr->vlistID;
   int fileID  = streamptr->fileID;
+  int modelID = vlistInqModel(vlistID);
 
-  int ncvarid = streamptr->vars[varID].ncvarid;
-
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int zaxisID = vlistInqVarZaxis(vlistID, varID);
-
-  size_t start[4];
-  size_t count[4];
-  cdfGetSlapDescription(streamptr, varID, &start, &count);
-
-  cdf_get_vara_float(fileID, ncvarid, start, count, data);
-
-  size_t size = (size_t)gridInqSize(gridID) * (size_t)zaxisInqSize(zaxisID);
-  double missval = vlistInqVarMissval(vlistID, varID);
-  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
-  double validRange[2];
-  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
-    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
-  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
-  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
-  size_t nmiss_ = cdfDoInputDataTransformationSP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
-  assert(nmiss_ <= INT_MAX);
-  *nmiss = (int)nmiss_;
+  if ( modelID != UNDEFID )
+    {
+      const char *longname = modelInqNamePtr(modelID);
+      if ( longname )
+	{
+          size_t len = strlen(longname);
+	  if ( len > 0 )
+	    {
+	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+	      cdf_put_att_text(fileID, NC_GLOBAL, "source", len, longname);
+	      if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+	    }
+	}
+    }
 }
 
-void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
+
+static void cdfDefGlobalAtts(stream_t *streamptr)
 {
-  size_t start[4];
-  size_t count[4];
+  int natts;
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
+  if ( streamptr->globalatts ) return;
 
   int vlistID = streamptr->vlistID;
-  int fileID = streamptr->fileID;
+  int fileID  = streamptr->fileID;
 
-  bool swapxy;
-  cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
+  cdfDefSource(streamptr);
+  cdfDefInstitut(streamptr);
 
-  int ncvarid = streamptr->vars[varID].ncvarid;
-  int gridId = vlistInqVarGrid(vlistID, varID);
-  size_t gridsize = (size_t)gridInqSize(gridId);
-  size_t xsize = (size_t)gridInqXsize(gridId);
-  size_t ysize = (size_t)gridInqYsize(gridId);
+  vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
 
-  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
-    {
-      float *data_fp = (float *)xmalloc(gridsize*sizeof(*data_fp));
-      cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
-      for ( size_t i = 0; i < gridsize; i++ )
-        data[i] = (double) data_fp[i];
-      free(data_fp);
-    }
-  else if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
-    {
-      nc_type xtype;
-      cdf_inq_vartype(fileID, ncvarid, &xtype);
-      if ( xtype == NC_BYTE )
-        {
-          for ( size_t i = 0; i < gridsize; i++ )
-            if ( data[i] < 0 ) data[i] += 256;
-        }
-    }
-  else
-    {
-      cdf_get_vara_double(fileID, ncvarid, start, count, data);
-    }
+  if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  if ( swapxy ) transpose2dArrayDP(ysize, xsize, data);
+  defineAttributes(vlistID, CDI_GLOBAL, fileID, NC_GLOBAL);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
-  const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
-  double validRange[2];
-  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
-    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
-  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
-  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
-  size_t nmiss_ = cdfDoInputDataTransformationDP(gridsize, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
-  assert(nmiss_ <= INT_MAX);
-  *nmiss = (int)nmiss_;
+  if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
+
+  streamptr->globalatts = 1;
 }
 
 
-void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, int *nmiss)
+static void cdfDefLocalAtts(stream_t *streamptr)
 {
-  size_t start[4];
-  size_t count[4];
-
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
-
   int vlistID = streamptr->vlistID;
-  int fileID = streamptr->fileID;
+  int fileID  = streamptr->fileID;
 
-  bool swapxy;
-  cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
+  if ( streamptr->localatts ) return;
+  if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
 
-  int ncvarid = streamptr->vars[varID].ncvarid;
-  int gridId = vlistInqVarGrid(vlistID, varID);
-  size_t gridsize = (size_t)gridInqSize(gridId);
-  size_t xsize = (size_t)gridInqXsize(gridId);
-  size_t ysize = (size_t)gridInqYsize(gridId);
+  streamptr->localatts = 1;
 
-  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT64 )
-    {
-      double *data_dp = (double *)xmalloc(gridsize*sizeof(*data_dp));
-      cdf_get_vara_double(fileID, ncvarid, start, count, data_dp);
-      for ( size_t i = 0; i < gridsize; i++ )
-        data[i] = (float) data_dp[i];
-      free(data_dp);
-    }
-  else if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
-    {
-      nc_type xtype;
-      cdf_inq_vartype(fileID, ncvarid, &xtype);
-      if ( xtype == NC_BYTE )
-        {
-          for ( size_t i = 0; i < gridsize; i++ )
-            if ( data[i] < 0 ) data[i] += 256;
-        }
-    }
-  else
-    {
-      cdf_get_vara_float(fileID, ncvarid, start, count, data);
-    }
+  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  if ( swapxy ) transpose2dArraySP(ysize, xsize, data);
+  for ( int varID = 0; varID < streamptr->nvars; varID++ )
+    {
+      int instID = vlistInqVarInstitut(vlistID, varID);
+      if ( instID != UNDEFID )
+	{
+          int ncvarid = streamptr->vars[varID].ncvarid;
+  	  const char *name = institutInqNamePtr(instID);
+	  if ( name )
+	    {
+              size_t len = strlen(name);
+	      cdf_put_att_text(fileID, ncvarid, "institution", len, name);
+	    }
+	}
+      }
 
-  double missval = vlistInqVarMissval(vlistID, varID);
-  bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
-  double validRange[2];
-  if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
-    validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
-  double addoffset   = vlistInqVarAddoffset(vlistID, varID);
-  double scalefactor = vlistInqVarScalefactor(vlistID, varID);
-  size_t nmiss_ = cdfDoInputDataTransformationSP(gridsize, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
-  assert(nmiss_ <= INT_MAX);
-  *nmiss = (int)nmiss_;
+  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
 }
 
 
-void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
-{
-  size_t xsize = 0, ysize = 0;
-  size_t start[5];
-  size_t count[5];
-  int dimorder[3];
-  int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
+void cdfDefHistory(stream_t *streamptr, int size, const char *history)
+{
+  int ncid = streamptr->fileID;
+  cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
+}
 
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+int cdfInqHistorySize(stream_t *streamptr)
+{
+  size_t size = 0;
+  int ncid = streamptr->fileID;
+  if ( streamptr->historyID != UNDEFID )
+    cdf_inq_attlen(ncid, NC_GLOBAL, "history", &size);
 
-  long ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
+  return ((int) size);
+}
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  int ncvarid = cdfDefVar(streamptr, varID);
+void cdfInqHistoryString(stream_t *streamptr, char *history)
+{
+  int ncid = streamptr->fileID;
+  if ( streamptr->historyID != UNDEFID )
+    cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
+}
 
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-  vlistInqVarDimorder(vlistID, varID, &dimorder);
 
+void cdfDefVars(stream_t *streamptr)
+{
+  /* int  nvars, ncvarid; */
 
-  if ( gridInqType(gridID) == GRID_TRAJECTORY )
-    {
-      cdfWriteGridTraj(streamptr, gridID);
-    }
-  else
-    {
-      int gridindex = vlistGridIndex(vlistID, gridID);
-      xid = streamptr->xdimID[gridindex];
-      yid = streamptr->ydimID[gridindex];
-    }
-  {
-    int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-    zid = streamptr->zaxisID[zaxisindex];
-  }
+  int vlistID = streamptr->vlistID;
+  if ( vlistID == UNDEFID )
+    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
-  int swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != UNDEFID && yid != UNDEFID;
+  /* nvars  = vlistNvars(vlistID); */
+  int ngrids = vlistNgrids(vlistID);
+  int nzaxis = vlistNzaxis(vlistID);
   /*
-  printf("swapxy %d\n", swapxy);
-  printf("dimorder: %d %d %d\n", dimorder[0], dimorder[1], dimorder[2]);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
   */
+  if (ngrids > 0)
+    for (size_t index = 0; index < (size_t)ngrids; index++ )
+      {
+        int gridID = vlistGrid(vlistID, (int)index);
+        cdfDefGrid(streamptr, gridID);
+      }
 
-  size_t ndims = 0;
-  if ( tsteptype != TSTEP_CONSTANT )
-    {
-      start[ndims] = (size_t)ntsteps - 1;
-      count[ndims] = 1;
-      ndims++;
-    }
-
-  for ( int id = 0; id < 3; ++id )
+  if (nzaxis > 0)
+    for (size_t index = 0; index < (size_t)nzaxis; index++ )
+      {
+        int zaxisID = vlistZaxis(vlistID, (int)index);
+        if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
+      }
+  /*
+    define time first!!!
+  for (varID = 0; varID < nvars; varID++ )
     {
-      if ( dimorder[id] == 3 && zid != UNDEFID )
-        {
-          start[ndims] = (size_t)levelID;
-          count[ndims] = 1;
-          ndims++;
-        }
-      else if ( dimorder[id] == 2 && yid != UNDEFID )
-        {
-          start[ndims] = 0;
-          cdf_inq_dimlen(fileID, yid, &ysize);
-          count[ndims] = ysize;
-          ndims++;
-        }
-      else if ( dimorder[id] == 1 && xid != UNDEFID )
-        {
-          start[ndims] = 0;
-          cdf_inq_dimlen(fileID, xid, &xsize);
-          count[ndims] = xsize;
-          ndims++;
-        }
+      ncvarid = cdfDefVar(streamptr, varID);
     }
+  */
+}
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+typedef struct
+{
+  long date;
+  long time;
+}
+DateTime;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  if ( CDI_Debug )
-    for (size_t idim = 0; idim < ndims; idim++)
-      Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
-
-  int dtype = vlistInqVarDatatype(vlistID, varID);
+#include <stdio.h>
+// #include <float.h>  /* FLT_EPSILON */
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
-  long nvals = gridInqSize(gridID);
+#if  defined  (HAVE_LIBCGRIBEX)
+#endif
 
-  cdf_write_var_data(fileID, vlistID, varID, ncvarid, dtype, nvals, xsize, ysize, swapxy, start, count, memtype, data, nmiss);
+extern int cdiInventoryMode;
 
-}
+typedef struct {
+  int param;
+  int level1;
+  int level2;
+  int ltype;
+  int tsteptype;
+} compvar_t;
 
 
+#if  defined  (HAVE_LIBCGRIBEX)
 static
-void cdfCreateRecords(stream_t *streamptr, int tsID)
+int cgribexGetGridType(int *isec2)
 {
-  int varID, levelID, recID, vrecID, zaxisID;
-  int nvars, nlev, nrecs, nvrecs;
-  record_t *records = NULL;
-  int *recIDs = NULL;
-  int vlistID;
+  int gridtype = GRID_GENERIC;
 
-  vlistID  = streamptr->vlistID;
+  switch (ISEC2_GridType)
+    {
+    case  GRIB1_GTYPE_LATLON:     { if ( ISEC2_Reduced )      break; }
+    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT;   break; }
+    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;      break; }
+    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
+	                              gridtype = GRID_GAUSSIAN_REDUCED;
+                         	    else
+				      gridtype = GRID_GAUSSIAN;
+          	                    break;
+                                  }
+    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL; break; }
+    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;      break; }
+    }
 
-  if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
+  return (gridtype);
+}
 
-  if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
+static
+int cgribexGetIsRotated(int *isec2)
+{
+  int isRotated = 0;
 
-  if ( tsID == 0 )
+  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
-
-      streamptr->nrecs += nrecs;
+      isRotated = 1;
+    }
 
-      if ( nrecs > 0 )
-        records = (record_t *)xmalloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+  return (isRotated);
+}
 
-      nvrecs = nrecs; /* use all records at first timestep */
-      if ( nvrecs > 0 ) recIDs = (int *)xmalloc((size_t)nvrecs * sizeof (int));
-      streamptr->tsteps[tsID].recIDs     = recIDs;
-      for ( recID = 0; recID < nvrecs; recID++ )
-        recIDs[recID] = recID;
+static
+int cgribexGetZaxisHasBounds(int grb_ltype)
+{
+  int lbounds = 0;
 
-      recID = 0;
-      for ( varID = 0; varID < nvars; varID++ )
-        {
-          zaxisID = vlistInqVarZaxis(vlistID, varID);
-          nlev    = zaxisInqSize(zaxisID);
-          for ( levelID = 0; levelID < nlev; levelID++ )
-            {
-              recordInitEntry(&records[recID]);
-              records[recID].varID   = (short)varID;
-              records[recID].levelID = (short)levelID;
-              recID++;
-            }
-        }
-    }
-  else if ( tsID == 1 )
+  switch (grb_ltype)
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
-
-      nvrecs = 0;
-      for ( varID = 0; varID < nvars; varID++ )
-        {
-          if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-            {
-              zaxisID = vlistInqVarZaxis(vlistID, varID);
-              nvrecs += zaxisInqSize(zaxisID);
-            }
-        }
-
-      streamptr->nrecs += nvrecs;
+    case GRIB1_LTYPE_SIGMA_LAYER:
+    case GRIB1_LTYPE_HYBRID_LAYER:
+    case GRIB1_LTYPE_LANDDEPTH_LAYER:
+      {
+	lbounds = 1;
+	break;
+      }
+    }
 
-      records = (record_t *) malloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nvrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+  return (lbounds);
+}
 
-      memcpy(streamptr->tsteps[tsID].records,
-             streamptr->tsteps[0].records,
-             (size_t)nrecs * sizeof (record_t));
+static
+int cgribexGetTimeUnit(int *isec1)
+{
+  int timeunit = TUNIT_HOUR;
+  static int lprint = TRUE;
 
-      if ( nvrecs )
-        {
-          recIDs = (int *) malloc((size_t)nvrecs * sizeof (int));
-          streamptr->tsteps[tsID].recIDs     = recIDs;
-          vrecID = 0;
-          for ( recID = 0; recID < nrecs; recID++ )
-            {
-              varID = records[recID].varID;
-              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-                {
-                  recIDs[vrecID++] = recID;
-                }
-            }
-        }
-    }
-  else
+  switch ( ISEC1_TimeUnit )
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
+    case ISEC1_TABLE4_MINUTE:    timeunit = TUNIT_MINUTE;    break;
+    case ISEC1_TABLE4_QUARTER:   timeunit = TUNIT_QUARTER;   break;
+    case ISEC1_TABLE4_30MINUTES: timeunit = TUNIT_30MINUTES; break;
+    case ISEC1_TABLE4_HOUR:      timeunit = TUNIT_HOUR;      break;
+    case ISEC1_TABLE4_3HOURS:    timeunit = TUNIT_3HOURS;    break;
+    case ISEC1_TABLE4_6HOURS:    timeunit = TUNIT_6HOURS;    break;
+    case ISEC1_TABLE4_12HOURS:   timeunit = TUNIT_12HOURS;   break;
+    case ISEC1_TABLE4_DAY:       timeunit = TUNIT_DAY;       break;
+    default:
+      if ( lprint )
+	{
+	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
+	  lprint = FALSE;
+	}
+      break;
+    }
 
-      nvrecs = streamptr->tsteps[1].nrecs;
+  return (timeunit);
+}
 
-      streamptr->nrecs += nvrecs;
+static
+int cgribexTimeIsFC(int *isec1)
+{
+  int isFC = TRUE;
 
-      records = (record_t *)xmalloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nvrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+  if ( ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0 )
+    isFC = FALSE;
 
-      memcpy(streamptr->tsteps[tsID].records,
-             streamptr->tsteps[0].records,
-             (size_t)nrecs * sizeof (record_t));
+  return (isFC);
+}
 
-      recIDs = (int *) malloc((size_t)nvrecs * sizeof(int));
-      streamptr->tsteps[tsID].recIDs     = recIDs;
+static
+int cgribexGetTsteptype(int timerange)
+{
+  int tsteptype = TSTEP_INSTANT;
+  static int lprint = TRUE;
 
-      memcpy(streamptr->tsteps[tsID].recIDs,
-             streamptr->tsteps[1].recIDs,
-             (size_t)nvrecs * sizeof (int));
+  switch ( timerange )
+    {
+    case  0:  tsteptype = TSTEP_INSTANT;  break;
+    case  1:  tsteptype = TSTEP_INSTANT2; break;
+    case  2:  tsteptype = TSTEP_RANGE;    break;
+    case  3:  tsteptype = TSTEP_AVG;      break;
+    case  4:  tsteptype = TSTEP_ACCUM;    break;
+    case  5:  tsteptype = TSTEP_DIFF;     break;
+    case 10:  tsteptype = TSTEP_INSTANT3; break;
+    default:
+      if ( lprint )
+	{
+	  Message("Time range indicator %d unsupported, set to 0!", timerange);
+	  lprint = FALSE;
+	}
+      break;
     }
-}
 
+  return (tsteptype);
+}
 
 static
-int cdfTimeDimID(int fileID, int ndims, int nvars)
+void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
 {
-  int dimid = UNDEFID;
-  int timedimid = UNDEFID;
-  char dimname[80];
-  char timeunits[CDI_MAX_NAME];
-  char attname[CDI_MAX_NAME];
-  char name[CDI_MAX_NAME];
-  nc_type xtype;
-  int nvdims, nvatts;
-  int dimids[9];
-  int varid, iatt;
+  int compyinc = TRUE;
+  int gridtype = cgribexGetGridType(isec2);
 
-  for ( dimid = 0; dimid < ndims; dimid++ )
+  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
     {
-      cdf_inq_dimname(fileID, dimid, dimname);
-      if ( memcmp(dimname, "time", 4) == 0 )
-        {
-          timedimid = dimid;
-          break;
-        }
+      int ilat, nlon = 0;
+      for ( ilat = 0; ilat < ISEC2_NumLat; ++ilat )
+        if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+      gridtype = GRID_GAUSSIAN;
+      ISEC2_NumLon = nlon;
+      ISEC4_NumValues = nlon*ISEC2_NumLat;
+      compyinc = FALSE;
     }
 
-  if ( timedimid == UNDEFID )
+  memset(grid, 0, sizeof(grid_t));
+  switch (gridtype)
     {
-      for ( varid = 0; varid < nvars; varid++ )
-        {
-          cdf_inq_var(fileID, varid, name, &xtype, &nvdims, dimids, &nvatts);
-          if ( nvdims == 1 )
-            {
-              for ( iatt = 0; iatt < nvatts; iatt++ )
-                {
-                  cdf_inq_attname(fileID, varid, iatt, attname);
-                  if ( strncmp(attname, "units", 5) == 0 )
-                    {
-                      cdfGetAttText(fileID, varid, "units", sizeof(timeunits), timeunits);
-                      strtolower(timeunits);
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+      {
+	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
+	  Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
+	grid->size  = ISEC4_NumValues;
+	grid->xsize = ISEC2_NumLon;
+	grid->ysize = ISEC2_NumLat;
+        if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
+	grid->xinc  = 0;
+	grid->yinc  = 0;
+	grid->xdef  = 0;
+	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
+	  {
+	    if ( grid->xsize > 1 )
+	      {
+                int recompinc = TRUE;
+
+                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+
+		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
+                  {
+                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
+                      {
+                        recompinc = FALSE;
+                        grid->xinc = ISEC2_LonIncr * 0.001;
+                      }
+                  }
+
+		/* recompute xinc if necessary */
+                if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize-1);
+
+		/* correct xinc if necessary */
+		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
+		  {
+		    double xinc = 360. / grid->xsize;
+
+		    if ( fabs(grid->xinc-xinc) > 0.0 )
+		      {
+			grid->xinc = xinc;
+			if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+		      }
+		  }
+	      }
+	    grid->xfirst = ISEC2_FirstLon * 0.001;
+	    grid->xlast  = ISEC2_LastLon  * 0.001;
+	    grid->xdef   = 2;
+	  }
+	grid->ydef  = 0;
+	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
+	  {
+	    if ( grid->ysize > 1 && compyinc )
+	      {
+                int recompinc = TRUE;
+		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
+                  {
+                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
+                      {
+                        recompinc = FALSE;
+                        grid->yinc = ISEC2_LatIncr * 0.001;
+                      }
+                  }
+
+		/* recompute yinc if necessary */
+                if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
+	      }
+	    grid->yfirst = ISEC2_FirstLat * 0.001;
+	    grid->ylast  = ISEC2_LastLat  * 0.001;
+	    grid->ydef   = 2;
+	  }
+	break;
+      }
+    case GRID_GAUSSIAN_REDUCED:
+      {
+        grid->np     = ISEC2_NumPar;
+	grid->size   = ISEC4_NumValues;
+        grid->rowlon = ISEC2_RowLonPtr;
+	grid->ysize  = ISEC2_NumLat;
+	grid->xinc   = 0;
+	grid->yinc   = 0;
+	grid->xdef   = 0;
+	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
+	  {
+	    if ( grid->xsize > 1 )
+	      {
+                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+
+		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
+		  grid->xinc = ISEC2_LonIncr * 0.001;
+		else
+		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->xsize - 1);
+	      }
+	    grid->xfirst = ISEC2_FirstLon * 0.001;
+	    grid->xlast  = ISEC2_LastLon  * 0.001;
+	    grid->xdef   = 2;
+	  }
+	grid->ydef  = 0;
+	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
+	  {
+	    if ( grid->ysize > 1 )
+	      {
+		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
+		  grid->yinc = ISEC2_LatIncr * 0.001;
+		else
+		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->ysize - 1);
+	      }
+	    grid->yfirst = ISEC2_FirstLat * 0.001;
+	    grid->ylast  = ISEC2_LastLat  * 0.001;
+	    grid->ydef   = 2;
+	  }
+	break;
+      }
+    case GRID_LCC:
+      {
+	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
+	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
+		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
+
+	grid->size  = ISEC4_NumValues;
+	grid->xsize = ISEC2_NumLon;
+	grid->ysize = ISEC2_NumLat;
+
+	grid->lcc_xinc      = ISEC2_Lambert_dx;
+	grid->lcc_yinc      = ISEC2_Lambert_dy;
+	grid->lcc_originLon = ISEC2_FirstLon * 0.001;
+	grid->lcc_originLat = ISEC2_FirstLat * 0.001;
+	grid->lcc_lonParY   = ISEC2_Lambert_Lov * 0.001;
+	grid->lcc_lat1      = ISEC2_Lambert_LatS1 * 0.001;
+	grid->lcc_lat2      = ISEC2_Lambert_LatS2 * 0.001;
+	grid->lcc_projflag  = ISEC2_Lambert_ProjFlag;
+	grid->lcc_scanflag  = ISEC2_ScanFlag;
+
+	grid->xdef   = 0;
+	grid->ydef   = 0;
+
+	break;
+      }
+    case GRID_SPECTRAL:
+      {
+	grid->size  = ISEC4_NumValues;
+	grid->trunc = ISEC2_PentaJ;
+	if ( ISEC2_RepMode == 2 )
+	  grid->lcomplex = 1;
+	else
+	  grid->lcomplex = 0;
+
+	break;
+      }
+    case GRID_GME:
+      {
+	grid->size  = ISEC4_NumValues;
+	grid->nd    = ISEC2_GME_ND;
+	grid->ni    = ISEC2_GME_NI;
+	grid->ni2   = ISEC2_GME_NI2;
+	grid->ni3   = ISEC2_GME_NI3;
+	break;
+      }
+    case GRID_GENERIC:
+      {
+	grid->size  = ISEC4_NumValues;
+	grid->xsize = 0;
+	grid->ysize = 0;
+	break;
+      }
+    default:
+      {
+	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
+      }
+    }
 
-                      if ( isTimeUnits(timeunits) )
-                        {
-                          timedimid = dimids[0];
-                          break;
-                        }
-                    }
-                }
-            }
-        }
+  grid->isRotated = FALSE;
+  if ( cgribexGetIsRotated(isec2) )
+    {
+      grid->isRotated = TRUE;
+      grid->ypole     = - ISEC2_LatSP*0.001;
+      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
+      grid->angle     = FSEC2_RotAngle;
     }
 
-  return (timedimid);
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  grid->type  = gridtype;
 }
 
 static
-void init_ncdims(long ndims, ncdim_t *ncdims)
+void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
+		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
 {
-  long ncdimid;
+  int varID;
+  int levelID = 0;
+  grid_t grid;
 
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      ncdims[ncdimid].ncvarid      = UNDEFID;
-      ncdims[ncdimid].dimtype      = UNDEFID;
-      ncdims[ncdimid].len          = 0;
-      ncdims[ncdimid].name[0]      = 0;
-    }
-}
+  int vlistID = streamptr->vlistID;
+  int tsID    = streamptr->curTsID;
+  int recID   = recordNewEntry(streamptr, tsID);
+  record_t *record  = &streamptr->tsteps[tsID].records[recID];
 
-static
-void init_ncvars(long nvars, ncvar_t *ncvars)
-{
-  long ncvarid;
+  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
+  int numavg    = ISEC1_AvgNum;
 
-  for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
-    {
-      ncvars[ncvarid].ncid            = UNDEFID;
-      ncvars[ncvarid].ignore          = FALSE;
-      ncvars[ncvarid].isvar           = UNDEFID;
-      ncvars[ncvarid].islon           = FALSE;
-      ncvars[ncvarid].islat           = FALSE;
-      ncvars[ncvarid].islev           = FALSE;
-      ncvars[ncvarid].istime          = FALSE;
-      ncvars[ncvarid].warn            = FALSE;
-      ncvars[ncvarid].tsteptype       = TSTEP_CONSTANT;
-      ncvars[ncvarid].param           = UNDEFID;
-      ncvars[ncvarid].code            = UNDEFID;
-      ncvars[ncvarid].tabnum          = 0;
-      ncvars[ncvarid].calendar        = FALSE;
-      ncvars[ncvarid].climatology     = FALSE;
-      ncvars[ncvarid].bounds          = UNDEFID;
-      ncvars[ncvarid].gridID          = UNDEFID;
-      ncvars[ncvarid].zaxisID         = UNDEFID;
-      ncvars[ncvarid].gridtype        = UNDEFID;
-      ncvars[ncvarid].zaxistype       = UNDEFID;
-      ncvars[ncvarid].xdim            = UNDEFID;
-      ncvars[ncvarid].ydim            = UNDEFID;
-      ncvars[ncvarid].zdim            = UNDEFID;
-      ncvars[ncvarid].xvarid          = UNDEFID;
-      ncvars[ncvarid].yvarid          = UNDEFID;
-      ncvars[ncvarid].zvarid          = UNDEFID;
-      ncvars[ncvarid].tvarid          = UNDEFID;
-      ncvars[ncvarid].ncoordvars      = 0;
-      for ( int i = 0; i < MAX_COORDVARS; ++i )
-        ncvars[ncvarid].coordvarids[i]  = UNDEFID;
-      ncvars[ncvarid].nauxvars      = 0;
-      for ( int i = 0; i < MAX_AUXVARS; ++i )
-        ncvars[ncvarid].auxvarids[i]  = UNDEFID;
-      ncvars[ncvarid].cellarea        = UNDEFID;
-      ncvars[ncvarid].tableID         = UNDEFID;
-      ncvars[ncvarid].xtype           = 0;
-      ncvars[ncvarid].ndims           = 0;
-      ncvars[ncvarid].gmapid          = UNDEFID;
-      ncvars[ncvarid].vlen            = 0;
-      ncvars[ncvarid].vdata           = NULL;
-      ncvars[ncvarid].truncation      = 0;
-      ncvars[ncvarid].position        = 0;
-      ncvars[ncvarid].positive        = 0;
-      ncvars[ncvarid].chunked         = 0;
-      ncvars[ncvarid].chunktype       = UNDEFID;
-      ncvars[ncvarid].defmissval      = 0;
-      ncvars[ncvarid].deffillval      = 0;
-      ncvars[ncvarid].missval         = 0;
-      ncvars[ncvarid].fillval         = 0;
-      ncvars[ncvarid].addoffset       = 0;
-      ncvars[ncvarid].scalefactor     = 1;
-      ncvars[ncvarid].name[0]         = 0;
-      ncvars[ncvarid].longname[0]     = 0;
-      ncvars[ncvarid].stdname[0]      = 0;
-      ncvars[ncvarid].units[0]        = 0;
-      ncvars[ncvarid].extra[0]        = 0;
-      ncvars[ncvarid].natts           = 0;
-      ncvars[ncvarid].atts            = NULL;
-      ncvars[ncvarid].deflate         = 0;
-      ncvars[ncvarid].lunsigned       = 0;
-      ncvars[ncvarid].lvalidrange     = 0;
-      ncvars[ncvarid].validrange[0]   = VALIDMISS;
-      ncvars[ncvarid].validrange[1]   = VALIDMISS;
-      ncvars[ncvarid].ensdata         = NULL;
-    }
-}
+  int level1  = ISEC1_Level1;
+  int level2  = ISEC1_Level2;
 
-static
-int isLonAxis(const char *units, const char *stdname)
-{
-  int status = FALSE;
-  char lc_units[16];
+  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
 
-  memcpy(lc_units, units, 15);
-  lc_units[15] = 0;
-  strtolower(lc_units);
+  record->size      = (size_t)recsize;
+  record->position  = position;
+  record->param     = param;
+  record->ilevel    = level1;
+  record->ilevel2   = level2;
+  record->ltype     = ISEC1_LevelType;
+  record->tsteptype = tsteptype;
 
-  if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
-        (memcmp(stdname, "grid_longitude", 14) == 0 || memcmp(stdname, "longitude", 9) == 0)) )
-    {
-      status = TRUE;
-    }
+  cgribexGetGrid(streamptr, isec2, fsec2, isec4, &grid, iret);
 
-  if ( status == FALSE &&
-       memcmp(stdname, "grid_latitude", 13) && memcmp(stdname, "latitude", 8) &&
-       memcmp(lc_units, "degree", 6) == 0 )
+  int gridID = varDefGrid(vlistID, &grid, 0);
+
+  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
+
+  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
     {
-      int ioff = 6;
-      if ( lc_units[ioff] == 's' ) ioff++;
-      if ( lc_units[ioff] == '_' ) ioff++;
-      if ( lc_units[ioff] == 'e' ) status = TRUE;
+      size_t vctsize = (size_t)ISEC2_NumVCP;
+      double *vctptr = &fsec2[10];
+
+      varDefVCT(vctsize, vctptr);
     }
 
-  return (status);
-}
+  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
 
-static
-int isLatAxis(const char *units, const char *stdname)
-{
-  int status = FALSE;
-  char lc_units[16];
+  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
+  if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  memcpy(lc_units, units, 15);
-  lc_units[15] = 0;
-  strtolower(lc_units);
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
+	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1, NULL, NULL, NULL, NULL);
 
-  if ( ((memcmp(lc_units, "degree", 6) == 0 || memcmp(lc_units, "radian", 6) == 0) &&
-        (memcmp(stdname, "grid_latitude", 13) == 0 || memcmp(stdname, "latitude", 8) == 0)) )
+  (*record).varID   = (short)varID;
+  (*record).levelID = (short)levelID;
+
+  varDefCompType(varID, comptype);
+
+  if ( ISEC1_LocalFLag )
     {
-      status = TRUE;
+      if      ( ISEC1_CenterID == 78  && isec1[36] == 253 ) // DWD local extension
+        varDefEnsembleInfo(varID, isec1[54], isec1[53], isec1[52]);
+      else if ( ISEC1_CenterID == 252 && isec1[36] ==   1 ) // MPIM local extension
+        varDefEnsembleInfo(varID, isec1[38], isec1[39], isec1[37]);
     }
 
-  if ( status == FALSE &&
-       memcmp(stdname, "grid_longitude", 14) && memcmp(stdname, "longitude", 9) &&
-       memcmp(lc_units, "degree", 6) == 0 )
+  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);
+
+  if ( varInqInst(varID) == CDI_UNDEFID )
     {
-      int ioff = 6;
-      if ( lc_units[ioff] == 's' ) ioff++;
-      if ( lc_units[ioff] == '_' ) ioff++;
-      if ( lc_units[ioff] == 'n' ) status = TRUE;
+      int center, subcenter, instID;
+      center    = ISEC1_CenterID;
+      subcenter = ISEC1_SubCenterID;
+      instID    = institutInq(center, subcenter, NULL, NULL);
+      if ( instID == CDI_UNDEFID )
+	instID = institutDef(center, subcenter, NULL, NULL);
+      varDefInst(varID, instID);
     }
 
-  return (status);
-}
-
-static
-int isDBLAxis(/*const char *units,*/ const char *longname)
-{
-  int status = FALSE;
+  if ( varInqModel(varID) == CDI_UNDEFID )
+    {
+      int modelID;
+      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
+      if ( modelID == CDI_UNDEFID )
+	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
+      varDefModel(varID, modelID);
+    }
 
-  if ( strcmp(longname, "depth below land")         == 0 ||
-       strcmp(longname, "depth_below_land")         == 0 ||
-       strcmp(longname, "levels below the surface") == 0 )
+  if ( varInqTable(varID) == CDI_UNDEFID )
     {
-      /*
-      if ( strcmp(ncvars[ncvarid].units, "cm") == 0 ||
-           strcmp(ncvars[ncvarid].units, "dm") == 0 ||
-           strcmp(ncvars[ncvarid].units, "m")  == 0 )
-      */
-        status = TRUE;
+      int tableID;
+
+      tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
+
+      if ( tableID == CDI_UNDEFID )
+	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
+      varDefTable(varID, tableID);
     }
 
-  return (status);
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
 }
 
 static
-int isDepthAxis(const char *stdname, const char *longname)
+void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
 {
-  int status = FALSE;
-
-  if ( strcmp(stdname, "depth") == 0 ) status = TRUE;
-
-  if ( status == FALSE )
-    if ( strcmp(longname, "depth_below_sea") == 0 ||
-         strcmp(longname, "depth below sea") == 0 )
-      {
-        status = TRUE;
+  /* 2010-01-13: Oliver Fuhrer */
+  if ( ISEC1_CenterID == 215 ) {
+    if (isec1[34] != 0 && isec1[34] != 255) {
+      if (isec1[34] & 2) {
+        if (isec1[34] & 1) {
+          *undef_pds = -0.99*pow(10.0,-isec1[35]);
+        } else {
+          *undef_pds = +0.99*pow(10.0,-isec1[35]);
+        }
+        *undef_eps = pow(10.0,-isec1[35]-1);
+      } else {
+        if (isec1[34] & 1) {
+          *undef_pds = -0.99*pow(10.0,+isec1[35]);
+        } else {
+          *undef_pds = +0.99*pow(10.0,+isec1[35]);
+        }
+        *undef_eps = pow(10.0,isec1[35]-1);
       }
-
-  return (status);
+    }
+  }
 }
 
 static
-int isHeightAxis(const char *stdname, const char *longname)
+void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
+			 int *isec3, double *fsec3, int *isec4, double *fsec4,
+			 int *gribbuffer, int recsize, int *lmv, int *iret)
 {
-  int status = FALSE;
-
-  if ( strcmp(stdname, "height") == 0 ) status = TRUE;
+  int ipunp = 0, iword = 0;
 
-  if ( status == FALSE )
-    if ( strcmp(longname, "height") == 0 ||
-         strcmp(longname, "height above the surface") == 0 )
-      {
-        status = TRUE;
-      }
+  memset(isec1, 0, 256*sizeof(int));
 
-  return (status);
-}
+  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
+	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
 
-static
-int unitsIsPressure(const char *units)
-{
-  int status = FALSE;
+  *lmv = 0;
 
-  if ( memcmp(units, "millibar", 8) == 0 ||
-       memcmp(units, "mb", 2)       == 0 ||
-       memcmp(units, "hectopas", 8) == 0 ||
-       memcmp(units, "hPa", 3)      == 0 ||
-       memcmp(units, "Pa", 2)       == 0 )
+  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
     {
-      status = TRUE;
-    }
+      double undef_pds, undef_eps;
 
-  return (status);
+      MCH_get_undef(isec1, &undef_pds, &undef_eps);
+      FSEC3_MissVal = undef_pds;
+      *lmv = 1;
+    }
 }
 
 static
-int isGaussGrid(size_t ysize, double yinc, double *yvals)
+compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
 {
-  int lgauss = FALSE;
-  double *yv, *yw;
-
-  if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
-    {
-      size_t i;
-      yv = (double *) malloc(ysize*sizeof(double));
-      yw = (double *) malloc(ysize*sizeof(double));
-      gaussaw(yv, yw, ysize);
-      free(yw);
-      for ( i = 0; i < ysize; i++ )
-        yv[i] = asin(yv[i])/M_PI*180.0;
-
-      for ( i = 0; i < ysize; i++ )
-        if ( fabs(yv[i] - yvals[i]) >
-             ((yv[0] - yv[1])/500) ) break;
+  compvar_t compVar;
+  int tsteptype = cgribexGetTsteptype(trange);
 
-      if ( i == ysize ) lgauss = TRUE;
+  compVar.param     = param;
+  compVar.level1    = level1;
+  compVar.level2    = level2;
+  compVar.ltype     = leveltype;
+  compVar.tsteptype = tsteptype;
 
-      /* check S->N */
-      if ( lgauss == FALSE )
-        {
-          for ( i = 0; i < ysize; i++ )
-            if ( fabs(yv[i] - yvals[ysize-i-1]) >
-                 ((yv[0] - yv[1])/500) ) break;
+  return (compVar);
+}
 
-          if ( i == ysize ) lgauss = TRUE;
-        }
+static inline int
+cgribexVarCompare(compvar_t compVar, record_t record, int flag)
+{
+  int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
+                                     & (record.tsteptype == TSTEP_INSTANT3))
+                                    |((compVar.tsteptype == TSTEP_INSTANT3)
+                                      & (record.tsteptype == TSTEP_INSTANT)))))
+    & (compVar.tsteptype != record.tsteptype);
+  int rstatus = (compVar.param != record.param)
+    |           (compVar.level1 != record.ilevel)
+    |           (compVar.level2 != record.ilevel2)
+    |           (compVar.ltype != record.ltype)
+    |           tstepDiff;
+  return (rstatus);
+}
+#endif
 
-      free(yv);
-    }
+#define gribWarning(text, nrecs, timestep, paramstr, level1, level2) \
+            Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text)
 
-  return (lgauss);
-}
+#if  defined  (HAVE_LIBCGRIBEX)
 
-static
-void cdfSetVar(ncvar_t *ncvars, int ncvarid, int isvar)
+static inline void
+cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
 {
-  if ( isvar != TRUE && isvar != FALSE )
-    Error("Internal problem! var %s undefined", ncvars[ncvarid].name);
-
-  if ( ncvars[ncvarid].isvar != UNDEFID &&
-       ncvars[ncvarid].isvar != isvar   &&
-       ncvars[ncvarid].warn  == FALSE )
+  if ( streamptr->ntsteps == -1 )
     {
-      if ( ! ncvars[ncvarid].ignore )
-        Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
+      int tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-      ncvars[ncvarid].warn = TRUE;
-      isvar = FALSE;
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
     }
-
-  ncvars[ncvarid].isvar = isvar;
 }
 
-static
-void cdfSetDim(ncvar_t *ncvars, int ncvarid, int dimid, int dimtype)
+static inline void
+cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
 {
-  if ( ncvars[ncvarid].dimtype[dimid] != UNDEFID &&
-       ncvars[ncvarid].dimtype[dimid] != dimtype )
+  int vlistID = streamptr->vlistID;
+  if ( streamptr->ntsteps == 1 )
     {
-      Warning("Inconsistent dimension definition for %s! dimid = %d;  type = %d;  newtype = %d",
-              ncvars[ncvarid].name, dimid, ncvars[ncvarid].dimtype[dimid], dimtype);
+      if ( taxis->vdate == 0 && taxis->vtime == 0 )
+	{
+	  streamptr->ntsteps = 0;
+	  for (int varID = 0; varID < streamptr->nvars; varID++ )
+	    {
+	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	    }
+	}
     }
-
-  ncvars[ncvarid].dimtype[dimid] = dimtype;
 }
 
-static
-void printNCvars(ncvar_t *ncvars, int nvars, const char *oname)
+
+int cgribexScanTimestep1(stream_t * streamptr)
 {
-  char axis[7];
-  int ncvarid, i;
-  int ndim;
-  static const char iaxis[] = {'t', 'z', 'y', 'x'};
+  int *isec0, *isec1, *isec2, *isec3, *isec4;
+  double fsec2[512], fsec3[2], *fsec4 = NULL;
+  int lmv = 0, iret = 0;
+  off_t recpos = 0;
+  unsigned char *gribbuffer = NULL;
+  size_t buffersize = 0;
+  int rstatus;
+  int fileID;
+  int param = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int tsID;
+  size_t readsize;
+  unsigned nrecords, recID;
+  int nrecs_scanned = 0;
+  int datatype;
+  long recsize = 0;
+  int warn_time = TRUE;
+  int warn_numavg = TRUE;
+  int taxisID = -1;
+  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
+  taxis_t *taxis;
+  int vlistID;
+  int comptype;
+  long unzipsize;
+  char paramstr[32];
+  extern int cdiSkipRecords;
+  int nskip = cdiSkipRecords;
 
-  fprintf(stderr, "%s:\n", oname);
+  streamptr->curTsID = 0;
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  isec0 = streamptr->record->sec0;
+  isec1 = streamptr->record->sec1;
+  isec2 = streamptr->record->sec2;
+  isec3 = streamptr->record->sec3;
+  isec4 = streamptr->record->sec4;
+
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
+
+  if ( tsID != 0 )
+    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+
+  fileID = streamptr->fileID;
+
+  while ( nskip-- > 0 )
     {
-      ndim = 0;
-      if ( ncvars[ncvarid].isvar )
-        {
-          axis[ndim++] = 'v';
-          axis[ndim++] = ':';
-          for ( i = 0; i < ncvars[ncvarid].ndims; i++ )
-            {/*
-              if      ( ncvars[ncvarid].tvarid != -1 ) axis[ndim++] = iaxis[0];
-              else if ( ncvars[ncvarid].zvarid != -1 ) axis[ndim++] = iaxis[1];
-              else if ( ncvars[ncvarid].yvarid != -1 ) axis[ndim++] = iaxis[2];
-              else if ( ncvars[ncvarid].xvarid != -1 ) axis[ndim++] = iaxis[3];
-              else
-             */
-              if      ( ncvars[ncvarid].dimtype[i] == T_AXIS ) axis[ndim++] = iaxis[0];
-              else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) axis[ndim++] = iaxis[1];
-              else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) axis[ndim++] = iaxis[2];
-              else if ( ncvars[ncvarid].dimtype[i] == X_AXIS ) axis[ndim++] = iaxis[3];
-              else                                             axis[ndim++] = '?';
-            }
-        }
-      else
-        {
-          axis[ndim++] = 'c';
-          axis[ndim++] = ':';
-          if      ( ncvars[ncvarid].istime ) axis[ndim++] = iaxis[0];
-          else if ( ncvars[ncvarid].islev  ) axis[ndim++] = iaxis[1];
-          else if ( ncvars[ncvarid].islat  ) axis[ndim++] = iaxis[2];
-          else if ( ncvars[ncvarid].islon  ) axis[ndim++] = iaxis[3];
-          else                               axis[ndim++] = '?';
-        }
+      recsize = gribGetSize(fileID);
+      if ( recsize == 0 )
+	Error("Skipping of %d records failed!", cdiSkipRecords);
+
+      recpos  = fileGetPos(fileID);
+      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
+    }
+
+  unsigned nrecs = 0;
+  while ( TRUE )
+    {
+      recsize = gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
+
+      if ( recsize == 0 )
+	{
+	  if ( nrecs == 0 )
+	    Error("No GRIB records found!");
+
+	  streamptr->ntsteps = 1;
+	  break;
+	}
+      if ( (size_t)recsize > buffersize )
+	{
+	  buffersize = (size_t)recsize;
+	  gribbuffer = (unsigned char *)xrealloc(gribbuffer, buffersize);
+	}
 
-      axis[ndim++] = 0;
+      readsize = (size_t)recsize;
+      rstatus = gribRead(fileID, gribbuffer, &readsize);
+      if ( rstatus ) break;
 
-      fprintf(stderr, "%3d %3d  %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
-    }
-}
+      comptype = COMPRESS_NONE;
+      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
+	{
+	  comptype = COMPRESS_SZIP;
+	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
+	  if ( buffersize < (size_t)unzipsize )
+	    {
+	      buffersize = (size_t)unzipsize;
+	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
+	    }
+	}
 
-static
-void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
-                          int timedimid, int modelID, int format)
-{
-  int ncid;
-  int ncvarid;
-  int ncdimid;
-  int nvdims, nvatts;
-  int *dimidsp;
-  nc_type xtype, atttype;
-  size_t attlen;
-  char name[CDI_MAX_NAME];
-  char attname[CDI_MAX_NAME];
-  const int attstringlen = 8192; char attstring[8192];
-  int iatt;
-  int i;
-  int tablenum;
+      nrecs_scanned++;
+      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
+			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      ncid    = ncvars[ncvarid].ncid;
-      dimidsp = ncvars[ncvarid].dimids;
+      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-      cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
-      strcpy(ncvars[ncvarid].name, name);
+      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+      level1   = ISEC1_Level1;
+      level2   = ISEC1_Level2;
 
-      for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
-        ncvars[ncvarid].dimtype[ncdimid] = -1;
+      gribDateTime(isec1, &vdate, &vtime);
 
-      ncvars[ncvarid].xtype = xtype;
-      ncvars[ncvarid].ndims = nvdims;
+      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
+	datatype = ISEC4_NumBits;
+      else
+        datatype = DATATYPE_PACK;
 
-#if  defined  (HAVE_NETCDF4)
-      if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
-        {
-          char buf[CDI_MAX_NAME];
-          int shuffle, deflate, deflate_level;
-          size_t chunks[nvdims];
-          int storage_in;
-          nc_inq_var_deflate(ncid, ncvarid, &shuffle, &deflate, &deflate_level);
-          if ( deflate > 0 ) ncvars[ncvarid].deflate = 1;
+      if ( nrecs == 0 )
+	{
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
+	  rdate = gribRefDate(isec1);
+	  rtime = gribRefTime(isec1);
+	  tunit = cgribexGetTimeUnit(isec1);
+	  fcast = cgribexTimeIsFC(isec1);
+	}
+      else
+	{
+	  datetime.date  = vdate;
+	  datetime.time  = vtime;
 
-          if ( nc_inq_var_chunking(ncid, ncvarid, &storage_in, chunks) == NC_NOERR )
-            {
-              if ( storage_in == NC_CHUNKED )
-                {
-                  ncvars[ncvarid].chunked = 1;
-                  for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = (int)chunks[i];
-                  if ( CDI_Debug )
-                    {
-                      fprintf(stderr, "\nchunking %d %d %d\nchunks ", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
-                      for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
-                      fprintf(stderr, "\n");
-                    }
-                  strcat(ncvars[ncvarid].extra, "chunks=");
-                  for ( int i = nvdims-1; i >= 0; --i )
-                    {
-                      sprintf(buf, "%ld", (long) chunks[i]);
-                      strcat(ncvars[ncvarid].extra, buf);
-                      if ( i > 0 ) strcat(ncvars[ncvarid].extra, "x");
-                    }
-                  strcat(ncvars[ncvarid].extra, " ");
-                }
-            }
-        }
-#endif
+	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
 
-      if ( nvdims > 0 )
-        {
-          if ( timedimid == dimidsp[0] )
-            {
-              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
-              cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
-            }
-          else
-            {
-              for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
-                {
-                  if ( timedimid == dimidsp[ncdimid] )
-                    {
-                      Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
-                      ncvars[ncvarid].isvar = FALSE;
-                    }
-                }
-            }
-        }
+	  for ( recID = 0; recID < nrecs; recID++ )
+	    {
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
+	    }
 
-      for ( iatt = 0; iatt < nvatts; iatt++ )
-        {
-          cdf_inq_attname(ncid, ncvarid, iatt, attname);
-          cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
-          cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+	  if ( cdiInventoryMode == 1 )
+	    {
+	      if ( recID < nrecs ) break;
+	      if ( warn_time )
+		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
+		  {
+                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+		    warn_time = FALSE;
+		  }
+	    }
+	  else
+	    {
+	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
-          if ( strcmp(attname, "long_name") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].longname);
-            }
-          else if ( strcmp(attname, "standard_name") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].stdname);
-            }
-          else if ( strcmp(attname, "units") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, CDI_MAX_NAME, ncvars[ncvarid].units);
-            }
-          else if ( strcmp(attname, "calendar") == 0 )
-            {
-              ncvars[ncvarid].calendar = TRUE;
-            }
-          else if ( strcmp(attname, "param") == 0 && xtypeIsText(atttype) )
-            {
-	      char paramstr[32];
-	      int pnum = 0, pcat = 255, pdis = 255;
-              cdfGetAttText(ncid, ncvarid, attname, sizeof(paramstr), paramstr);
-	      sscanf(paramstr, "%d.%d.%d", &pnum, &pcat, &pdis);
-	      ncvars[ncvarid].param = cdiEncodeParam(pnum, pcat, pdis);
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "code") == 0 && !xtypeIsText(atttype) )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].code);
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "table") == 0 && !xtypeIsText(atttype) )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &tablenum);
-              if ( tablenum > 0 )
-                {
-                  ncvars[ncvarid].tabnum = tablenum;
-                  ncvars[ncvarid].tableID = tableInq(modelID, tablenum, NULL);
-                  if ( ncvars[ncvarid].tableID == CDI_UNDEFID )
-                    ncvars[ncvarid].tableID = tableDef(modelID, tablenum, NULL);
-                }
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "trunc_type") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              if ( memcmp(attstring, "Triangular", attlen) == 0 )
-                ncvars[ncvarid].gridtype = GRID_SPECTRAL;
-            }
-          else if ( strcmp(attname, "grid_type") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              strtolower(attstring);
+	      if ( recID < nrecs )
+		{
+		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+		  continue;
+		}
+	    }
+	}
 
-              if      ( strcmp(attstring, "gaussian reduced") == 0 )
-                ncvars[ncvarid].gridtype = GRID_GAUSSIAN_REDUCED;
-              else if ( strcmp(attstring, "gaussian") == 0 )
-                ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
-              else if ( strncmp(attstring, "spectral", 8) == 0 )
-                ncvars[ncvarid].gridtype = GRID_SPECTRAL;
-              else if ( strncmp(attstring, "fourier", 7) == 0 )
-                ncvars[ncvarid].gridtype = GRID_FOURIER;
-              else if ( strcmp(attstring, "trajectory") == 0 )
-                ncvars[ncvarid].gridtype = GRID_TRAJECTORY;
-              else if ( strcmp(attstring, "generic") == 0 )
-                ncvars[ncvarid].gridtype = GRID_GENERIC;
-              else if ( strcmp(attstring, "cell") == 0 )
-                ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
-              else if ( strcmp(attstring, "unstructured") == 0 )
-                ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
-              else if ( strcmp(attstring, "curvilinear") == 0 )
-                ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
-              else if ( strcmp(attstring, "sinusoidal") == 0 )
-                ;
-              else if ( strcmp(attstring, "laea") == 0 )
-                ;
-              else if ( strcmp(attstring, "lcc2") == 0 )
-                ;
-              else if ( strcmp(attstring, "linear") == 0 ) // ignore grid type linear
-                ;
-              else
-                {
-                  static int warn = TRUE;
-                  if ( warn )
-                    {
-                      warn = FALSE;
-                      Warning("netCDF attribute grid_type='%s' unsupported!", attstring);
-                    }
-                }
+      if ( ISEC1_AvgNum )
+	{
+	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
+	    {
+	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
+	      warn_numavg = FALSE;
+	    }
+	  else
+	    {
+	      taxis->numavg = ISEC1_AvgNum;
+	    }
+	}
 
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "level_type") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              strtolower(attstring);
+      nrecs++;
 
-              if      ( strcmp(attstring, "toa") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_TOA;
-              else if ( strcmp(attstring, "cloudbase") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_BASE;
-              else if ( strcmp(attstring, "cloudtop") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_CLOUD_TOP;
-              else if ( strcmp(attstring, "isotherm0") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_ISOTHERM_ZERO;
-              else if ( strcmp(attstring, "seabottom") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_SEA_BOTTOM;
-              else if ( strcmp(attstring, "lakebottom") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_LAKE_BOTTOM;
-              else if ( strcmp(attstring, "sedimentbottom") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM;
-              else if ( strcmp(attstring, "sedimentbottomta") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;
-              else if ( strcmp(attstring, "sedimentbottomtw") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;
-              else if ( strcmp(attstring, "mixlayer") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_MIX_LAYER;
-              else if ( strcmp(attstring, "atmosphere") == 0 )
-                ncvars[ncvarid].zaxistype = ZAXIS_ATMOSPHERE;
-              else
-                {
-                  static int warn = TRUE;
-                  if ( warn )
-                    {
-                      warn = FALSE;
-                      Warning("netCDF attribute level_type='%s' unsupported!", attstring);
-                    }
-                }
+      if ( CDI_Debug )
+	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
 
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "trunc_count") == 0 && !xtypeIsText(atttype) )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
-            }
-          else if ( strcmp(attname, "truncation") == 0 && !xtypeIsText(atttype) )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
-            }
-          else if ( strcmp(attname, "number_of_grid_in_reference") == 0 && !xtypeIsText(atttype) )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].position);
-            }
-          else if ( strcmp(attname, "add_offset") == 0 && !xtypeIsText(atttype) )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].addoffset);
-	      /*
-		if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
-		if ( ncvars[ncvarid].addoffset != 0 )
-		Warning("attribute add_offset not supported for atttype %d", atttype);
-	      */
-	      /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
-            }
-          else if ( strcmp(attname, "scale_factor") == 0 && !xtypeIsText(atttype) )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].scalefactor);
-	      /*
-		if ( atttype != NC_BYTE && atttype != NC_SHORT && atttype != NC_INT )
-		if ( ncvars[ncvarid].scalefactor != 1 )
-		Warning("attribute scale_factor not supported for atttype %d", atttype);
-	      */
-	      /* (also used for lon/lat) cdfSetVar(ncvars, ncvarid, TRUE); */
-            }
-          else if ( strcmp(attname, "climatology") == 0 && xtypeIsText(atttype) )
-            {
-              int status, ncboundsid;
+      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
+		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
+    }
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+  streamptr->rtsteps = 1;
 
-              status = nc_inq_varid(ncid, attstring, &ncboundsid);
+  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
 
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].climatology = TRUE;
-                  ncvars[ncvarid].bounds = ncboundsid;
-                  cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
-                  cdfSetVar(ncvars, ncvarid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
-            }
-          else if ( strcmp(attname, "bounds") == 0 && xtypeIsText(atttype) )
-            {
-              int status, ncboundsid;
+  cdi_generate_vars(streamptr);
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+  if ( fcast )
+    {
+      taxisID = taxisCreate(TAXIS_RELATIVE);
+      taxis->type  = TAXIS_RELATIVE;
+      taxis->rdate = rdate;
+      taxis->rtime = rtime;
+      taxis->unit  = tunit;
+    }
+  else
+    {
+      taxisID = taxisCreate(TAXIS_ABSOLUTE);
+      taxis->type  = TAXIS_ABSOLUTE;
+      taxis->unit  = tunit;
+    }
 
-              status = nc_inq_varid(ncid, attstring, &ncboundsid);
+  taxis->vdate = (int)datetime0.date;
+  taxis->vtime = (int)datetime0.time;
 
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].bounds = ncboundsid;
-                  cdfSetVar(ncvars, ncvars[ncvarid].bounds, FALSE);
-                  cdfSetVar(ncvars, ncvarid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
-            }
-          else if ( strcmp(attname, "cell_measures") == 0 && xtypeIsText(atttype) )
-            {
-              char *pstring, *cell_measures = NULL, *cell_var = NULL;
+  vlistID = streamptr->vlistID;
+  vlistDefTaxis(vlistID, taxisID);
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              pstring = attstring;
+  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
+  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
+    {
+      streamptr->tsteps[0].recordSize = (int)nrecords;
+      streamptr->tsteps[0].records =
+      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
+    }
 
-              while ( isspace((int) *pstring) ) pstring++;
-              cell_measures = pstring;
-              while ( isalnum((int) *pstring) ) pstring++;
-              *pstring++ = 0;
-              while ( isspace((int) *pstring) ) pstring++;
-              cell_var = pstring;
-              while ( ! isspace((int) *pstring) && *pstring != 0 ) pstring++;
-              *pstring++ = 0;
-              /*
-              printf("cell_measures >%s<\n", cell_measures);
-              printf("cell_var >%s<\n", cell_var);
-              */
-              if ( memcmp(cell_measures, "area", 4) == 0 )
-                {
-                  int status;
-                  int nc_cell_id;
+  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
+  streamptr->tsteps[0].nrecs = (int)nrecords;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[0].recIDs[recID] = (int)recID;
 
-                  status = nc_inq_varid(ncid, cell_var, &nc_cell_id);
-                  if ( status == NC_NOERR )
-                    {
-                      ncvars[ncvarid].cellarea = nc_cell_id;
-                      /* ncvars[nc_cell_id].isvar = UNDEFID; */
-                      cdfSetVar(ncvars, nc_cell_id, FALSE);
-                    }
-                  else
-                    Warning("%s - %s", nc_strerror(status), cell_var);
-                }
-              else
-                {
-                  Warning("%s has an unexpected contents: %s", attname, cell_measures);
-                }
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          /*
-          else if ( strcmp(attname, "coordinates") == 0 )
-            {
-              char *pstring, *xvarname = NULL, *yvarname = NULL;
+  streamptr->record->buffer     = gribbuffer;
+  streamptr->record->buffersize = (size_t)buffersize;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              pstring = attstring;
+  cgribexScanTsFixNtsteps(streamptr, recpos);
+  cgribexScanTsConstAdjust(streamptr, taxis);
 
-              while ( isspace((int) *pstring) ) pstring++;
-              xvarname = pstring;
-              while ( isgraph((int) *pstring) ) pstring++;
-              *pstring++ = 0;
-              while ( isspace((int) *pstring) ) pstring++;
-              yvarname = pstring;
-              while ( isgraph((int) *pstring) ) pstring++;
-              *pstring++ = 0;
+  return (0);
+}
 
-              cdf_inq_varid(ncid, xvarname, &ncvars[ncvarid].xvarid);
-              cdf_inq_varid(ncid, yvarname, &ncvars[ncvarid].yvarid);
 
-              cdfSetVar(ncvars, ncvars[ncvarid].xvarid, FALSE);
-              cdfSetVar(ncvars, ncvars[ncvarid].yvarid, FALSE);
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          */
-          else if ( (strcmp(attname, "associate")  == 0 || strcmp(attname, "coordinates") == 0) && xtypeIsText(atttype) )
-            {
-              int status;
-              char *pstring, *varname = NULL;
-              int lstop = FALSE;
-              int dimvarid;
-              extern int cdiIgnoreAttCoordinates;
+int cgribexScanTimestep2(stream_t * streamptr)
+{
+  int rstatus = 0;
+  int *isec0, *isec1, *isec2, *isec3, *isec4;
+  double fsec2[512], fsec3[2], *fsec4 = NULL;
+  int lmv = 0, iret = 0;
+  off_t recpos = 0;
+  unsigned char *gribbuffer = NULL;
+  size_t buffersize = 0;
+  int fileID;
+  int param = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int tsID;
+  int varID, gridID;
+  size_t readsize;
+  int nrecords, nrecs, recID, rindex;
+  int nrecs_scanned = 0;
+  long recsize = 0;
+  int warn_numavg = TRUE;
+  int tsteptype;
+  int taxisID = -1;
+  taxis_t *taxis;
+  int vlistID;
+  long unzipsize;
+  char paramstr[32];
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              pstring = attstring;
+  streamptr->curTsID = 1;
 
-              for ( i = 0; i < MAX_COORDVARS; i++ )
-                {
-                  while ( isspace((int) *pstring) ) pstring++;
-                  if ( *pstring == 0 ) break;
-                  varname = pstring;
-                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-                  if ( *pstring == 0 ) lstop = TRUE;
-                  *pstring++ = 0;
+  isec0 = streamptr->record->sec0;
+  isec1 = streamptr->record->sec1;
+  isec2 = streamptr->record->sec2;
+  isec3 = streamptr->record->sec3;
+  isec4 = streamptr->record->sec4;
 
-                  status = nc_inq_varid(ncid, varname, &dimvarid);
-                  if ( status == NC_NOERR )
-                    {
-                      cdfSetVar(ncvars, dimvarid, FALSE);
-                      if ( cdiIgnoreAttCoordinates == FALSE )
-                        {
-                          ncvars[ncvarid].coordvarids[i] = dimvarid;
-                          ncvars[ncvarid].ncoordvars++;
-                        }
-                    }
-                  else
-                    Warning("%s - %s", nc_strerror(status), varname);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
+  taxisID = vlistInqTaxis(vlistID);
 
-                  if ( lstop ) break;
-                }
+  gribbuffer = (unsigned char *) streamptr->record->buffer;
+  buffersize = streamptr->record->buffersize;
 
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( (strcmp(attname, "auxiliary_variable") == 0) && xtypeIsText(atttype) )
-            {
-              int status;
-              char *pstring, *varname = NULL;
-              int lstop = FALSE;
-              int dimvarid;
-              extern int cdiIgnoreAttCoordinates;
+  tsID = streamptr->rtsteps;
+  if ( tsID != 1 )
+    Error("Internal problem! unexpected timestep %d", tsID+1);
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              pstring = attstring;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-              for ( i = 0; i < MAX_AUXVARS; i++ )
-                {
-                  while ( isspace((int) *pstring) ) pstring++;
-                  if ( *pstring == 0 ) break;
-                  varname = pstring;
-                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-                  if ( *pstring == 0 ) lstop = TRUE;
-                  *pstring++ = 0;
+  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-                  status = nc_inq_varid(ncid, varname, &dimvarid);
-                  if ( status == NC_NOERR )
-                    {
-                      cdfSetVar(ncvars, dimvarid, FALSE);
-                      //  if ( cdiIgnoreAttCoordinates == FALSE )
-                        {
-                          ncvars[ncvarid].auxvarids[i] = dimvarid;
-                          ncvars[ncvarid].nauxvars++;
-                        }
-                    }
-                  else
-                    Warning("%s - %s", nc_strerror(status), varname);
+  cdi_create_records(streamptr, tsID);
 
-                  if ( lstop ) break;
-                }
+  nrecords = streamptr->tsteps[tsID].nallrecs;
+  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof(int));
+  streamptr->tsteps[1].nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[1].recIDs[recID] = -1;
 
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "grid_mapping") == 0 && xtypeIsText(atttype) )
-            {
-              int status;
-              int nc_gmap_id;
+  for ( recID = 0; recID < nrecords; recID++ )
+    {
+      varID = streamptr->tsteps[0].records[recID].varID;
+      streamptr->tsteps[tsID].records[recID].position =	streamptr->tsteps[0].records[recID].position;
+      streamptr->tsteps[tsID].records[recID].size     =	streamptr->tsteps[0].records[recID].size;
+    }
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+  nrecs_scanned = nrecords;
+  rindex = 0;
+  while ( TRUE )
+    {
+      if ( rindex > nrecords ) break;
 
-              status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].gmapid = nc_gmap_id;
-                  cdfSetVar(ncvars, ncvars[ncvarid].gmapid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
+      recsize = gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
+      if ( recsize == 0 )
+	{
+	  streamptr->ntsteps = 2;
+	  break;
+	}
+      if ( (size_t)recsize > buffersize )
+	{
+	  buffersize = (size_t)recsize;
+	  gribbuffer = (unsigned char *)xrealloc(gribbuffer, buffersize);
+	}
 
-              cdfSetVar(ncvars, ncvarid, TRUE);
-            }
-          else if ( strcmp(attname, "positive") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              strtolower(attstring);
+      readsize = (size_t)recsize;
+      rstatus = gribRead(fileID, gribbuffer, &readsize);
+      if ( rstatus ) break;
 
-              if    ( memcmp(attstring, "down", 4) == 0 ) ncvars[ncvarid].positive = POSITIVE_DOWN;
-              else if ( memcmp(attstring, "up", 2) == 0 ) ncvars[ncvarid].positive = POSITIVE_UP;
+      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
+	{
+	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
+	  if ( buffersize < (size_t)unzipsize )
+	    {
+	      buffersize = (size_t)unzipsize;
+	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
+	    }
+	}
 
-              if ( ncvars[ncvarid].ndims == 1 )
-                {
-                  cdfSetVar(ncvars, ncvarid, FALSE);
-                  cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
-                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
-                }
-            }
-          else if ( strcmp(attname, "_FillValue") == 0 && !xtypeIsText(atttype) )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
-	      ncvars[ncvarid].deffillval = TRUE;
-	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
-            }
-          else if ( strcmp(attname, "missing_value") == 0 && !xtypeIsText(atttype) )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
-	      ncvars[ncvarid].defmissval = TRUE;
-	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
-            }
-          else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
-            {
-              if ( ncvars[ncvarid].lvalidrange == FALSE )
-                {
-                  extern int cdiIgnoreValidRange;
-                  int lignore = FALSE;
-                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
-                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
-                    {
-                      cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
-                      ncvars[ncvarid].lvalidrange = TRUE;
-                      if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
-                        ncvars[ncvarid].lunsigned = TRUE;
-                      /* cdfSetVar(ncvars, ncvarid, TRUE); */
-                    }
-                  else if ( lignore )
-                    {
-                      Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
-                    }
-                }
-            }
-          else if ( strcmp(attname, "valid_min") == 0 && attlen == 1 )
-            {
-              if ( ncvars[ncvarid].lvalidrange == FALSE )
-                {
-                  extern int cdiIgnoreValidRange;
-                  int lignore = FALSE;
-                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
-                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
-                    {
-                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
-                      ncvars[ncvarid].lvalidrange = TRUE;
-                    }
-                  else if ( lignore )
-                    {
-                      Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
-                    }
-                }
-            }
-          else if ( strcmp(attname, "valid_max") == 0 && attlen == 1 )
-            {
-              if ( ncvars[ncvarid].lvalidrange == FALSE )
-                {
-                  extern int cdiIgnoreValidRange;
-                  int lignore = FALSE;
-                  if ( xtypeIsFloat(atttype) != xtypeIsFloat(xtype) ) lignore = TRUE;
-                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
-                    {
-                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
-                      ncvars[ncvarid].lvalidrange = TRUE;
-                    }
-                  else if ( lignore )
-                    {
-                      Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
-                    }
-                }
-            }
-          else if ( strcmp(attname, "_Unsigned") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-              strtolower(attstring);
+      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
+			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
 
-              if ( memcmp(attstring, "true", 4) == 0 )
-                {
-                  ncvars[ncvarid].lunsigned = TRUE;
-                  /*
-                  ncvars[ncvarid].lvalidrange = TRUE;
-                  ncvars[ncvarid].validrange[0] = 0;
-                  ncvars[ncvarid].validrange[1] = 255;
-                  */
-                }
-	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
-            }
-          else if ( strcmp(attname, "cdi") == 0 && xtypeIsText(atttype) )
-            {
-	      cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-	      strtolower(attstring);
+      nrecs_scanned++;
 
-	      if ( memcmp(attstring, "ignore", 6) == 0 )
-		{
-		  ncvars[ncvarid].ignore = TRUE;
-		  cdfSetVar(ncvars, ncvarid, FALSE);
-		}
-            }
-          else if ( strcmp(attname, "axis") == 0 && xtypeIsText(atttype) )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-	      attlen = strlen(attstring);
+      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	      if ( (int) attlen > nvdims )
-		{
-		  if ( nvdims > 0 )
-		    Warning("Unexpected axis attribute length for %s, ignored!", name);
-		}
-	      else
-		{
-		  strtolower(attstring);
-		  for ( i = 0; i < (int)attlen; ++i )
-		    {
-		      if ( attstring[i] != '-' && attstring[i] != 't' && attstring[i] != 'z' &&
-			   attstring[i] != 'y' && attstring[i] != 'x' )
-			{
-			  Warning("Unexpected character in axis attribute for %s, ignored!", name);
-			  break;
-			}
-		    }
+      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+      level1    = ISEC1_Level1;
+      level2    = ISEC1_Level2;
 
-		  if ( i == (int) attlen && (int) attlen == nvdims)
-		    {
-		      while ( attlen-- )
-			{
-			  if ( (int) attstring[attlen] == 't' )
-			    {
-			      if ( attlen != 0 ) Warning("axis attribute 't' not on first position");
-			      cdfSetDim(ncvars, ncvarid, (int)attlen, T_AXIS);
-			    }
-			  else if ( (int) attstring[attlen] == 'z' )
-			    {
-			      ncvars[ncvarid].zdim = dimidsp[attlen];
-			      cdfSetDim(ncvars, ncvarid, (int)attlen, Z_AXIS);
+      gribDateTime(isec1, &vdate, &vtime);
 
-			      if ( ncvars[ncvarid].ndims == 1 )
-				{
-				  cdfSetVar(ncvars, ncvarid, FALSE);
-				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
-				}
-			    }
-			  else if ( (int) attstring[attlen] == 'y' )
-			    {
-			      ncvars[ncvarid].ydim = dimidsp[attlen];
-			      cdfSetDim(ncvars, ncvarid, (int)attlen, Y_AXIS);
+      if ( rindex == 0 )
+	{
+	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
+	    {
+	      taxis->type  = TAXIS_RELATIVE;
+	      taxis->rdate = gribRefDate(isec1);
+	      taxis->rtime = gribRefTime(isec1);
+	    }
+	  else
+	    {
+	      taxis->type  = TAXIS_ABSOLUTE;
+	    }
+	  taxis->unit  = cgribexGetTimeUnit(isec1);
+	  taxis->vdate = vdate;
+	  taxis->vtime = vtime;
 
-			      if ( ncvars[ncvarid].ndims == 1 )
-				{
-				  cdfSetVar(ncvars, ncvarid, FALSE);
-				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Y_AXIS;
-				}
-			    }
-			  else if ( (int) attstring[attlen] == 'x' )
-			    {
-			      ncvars[ncvarid].xdim = dimidsp[attlen];
-			      cdfSetDim(ncvars, ncvarid, (int)attlen, X_AXIS);
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
+	}
 
-			      if ( ncvars[ncvarid].ndims == 1 )
-				{
-				  cdfSetVar(ncvars, ncvarid, FALSE);
-				  ncdims[ncvars[ncvarid].dimids[0]].dimtype = X_AXIS;
-				}
-			    }
-			}
-		    }
-		}
+      tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
+
+      if ( ISEC1_AvgNum )
+	{
+	  if (  taxis->numavg && warn_numavg &&
+        	(taxis->numavg != ISEC1_AvgNum) )
+	    {
+	  /*
+	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
+	  */
+	      warn_numavg = FALSE;
 	    }
-	  else if ( ( strcmp(attname, "realization") == 0 )         ||
-	            ( strcmp(attname, "ensemble_members") == 0 )    ||
-	            ( strcmp(attname, "forecast_init_type") == 0 )    )
+	  else
 	    {
-	      int temp;
+	      taxis->numavg = ISEC1_AvgNum;
+	    }
+	}
 
-	      if( ncvars[ncvarid].ensdata == NULL )
-		ncvars[ncvarid].ensdata = (ensinfo_t *) malloc( sizeof( ensinfo_t ) );
+      datetime.date  = vdate;
+      datetime.time  = vtime;
 
-	      cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
+      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
 
-	      if( strcmp(attname, "realization") == 0 )
-		ncvars[ncvarid].ensdata->ens_index = temp;
-	      else if( strcmp(attname, "ensemble_members") == 0 )
-		ncvars[ncvarid].ensdata->ens_count = temp;
-	      else if( strcmp(attname, "forecast_init_type") == 0 )
-		ncvars[ncvarid].ensdata->forecast_init_type = temp;
+      for ( recID = 0; recID < nrecords; recID++ )
+	{
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
+	}
 
-	      cdfSetVar(ncvars, ncvarid, TRUE);
+      if ( recID == nrecords )
+	{
+	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+	  return (CDI_EUFSTRUCT);
+	}
+
+      if ( cdiInventoryMode == 1 )
+	{
+	  if ( streamptr->tsteps[tsID].records[recID].used )
+	    {
+	      break;
 	    }
 	  else
 	    {
-	      if ( ncvars[ncvarid].natts == 0 )
-		ncvars[ncvarid].atts
-                  = (int *)xmalloc((size_t)nvatts * sizeof (int));
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
+	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
+	    }
+	}
+      else
+	{
+	  if ( streamptr->tsteps[tsID].records[recID].used )
+	    {
+	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
-	      ncvars[ncvarid].atts[ncvars[ncvarid].natts++] = iatt;
-	      /*
-	      int attrint;
-	      double attrflt;
-	      nc_type attrtype;
-	      cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
-	      cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
-	      if ( attlen == 1 && (attrtype == NC_INT || attrtype == NC_SHORT) )
-		{
-		  cdfGetAttInt(ncid, ncvarid, attname, 1, &attrint);
-		  printf("int: %s.%s = %d\n", ncvars[ncvarid].name, attname, attrint);
-		}
-	      else if ( attlen == 1 && (attrtype == NC_FLOAT || attrtype == NC_DOUBLE) )
-		{
-		  cdfGetAttDouble(ncid, ncvarid, attname, 1, &attrflt);
-		  printf("flt: %s.%s = %g\n", ncvars[ncvarid].name, attname, attrflt);
-		}
-	      else if ( attrtype == NC_CHAR )
-		{
-		  cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-		  attstring[attlen] = 0;
-		  printf("txt: %s.%s = %s\n", ncvars[ncvarid].name, attname, attstring);
-		}
-	      else
-		printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
-	      */
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+	      continue;
+	    }
+	  else
+	    {
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
+	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 	    }
 	}
+
+      if ( CDI_Debug )
+	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
+
+      streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+
+      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
+	{
+	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		  tsID, recID,
+		  streamptr->tsteps[tsID].records[recID].param, param,
+		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
+	  return (CDI_EUFSTRUCT);
+	}
+
+      streamptr->tsteps[1].records[recID].position = recpos;
+      varID = streamptr->tsteps[tsID].records[recID].varID;
+      gridID = vlistInqVarGrid(vlistID, varID);
+      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
+	{
+	  if ( IS_NOT_EQUAL(gridInqXval(gridID, 0),ISEC2_FirstLon*0.001) ||
+	       IS_NOT_EQUAL(gridInqYval(gridID, 0),ISEC2_FirstLat*0.001) )
+	    gridChangeType(gridID, GRID_TRAJECTORY);
+	}
+
+      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
+	vlistDefVarTsteptype(vlistID, varID, tsteptype);
+
+      rindex++;
+    }
+
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    {
+      if ( ! streamptr->tsteps[tsID].records[recID].used )
+	{
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
+          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	}
+      else
+	{
+	  nrecs++;
+	}
     }
+  streamptr->tsteps[tsID].nrecs = nrecs;
+
+  streamptr->rtsteps = 2;
+
+  cgribexScanTsFixNtsteps(streamptr, recpos);
+
+  streamptr->record->buffer     = gribbuffer;
+  streamptr->record->buffersize = buffersize;
+
+  return (rstatus);
 }
+#endif
 
-static
-void setDimType(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
+
+#if  defined  (HAVE_LIBCGRIBEX)
+int cgribexScanTimestep(stream_t * streamptr)
 {
-  int ndims;
-  int ncvarid, ncdimid;
-  int i;
+  int rstatus = 0;
+  double fsec2[512], fsec3[2], *fsec4 = NULL;
+  int lmv = 0, iret = 0;
+  long recsize = 0;
+  off_t recpos = 0;
+  unsigned char *gribbuffer;
+  size_t buffersize = 0;
+  int fileID;
+  int param = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int vrecID, recID;
+  int warn_numavg = TRUE;
+  size_t readsize;
+  int taxisID = -1;
+  int rindex, nrecs = 0;
+  int nrecs_scanned;
+  long unzipsize;
+  char paramstr[32];
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  /*
+  if ( CDI_Debug )
     {
-      if ( ncvars[ncvarid].isvar == TRUE )
+      Message("streamID = %d", streamptr->self);
+      Message("cts = %d", streamptr->curTsID);
+      Message("rts = %d", streamptr->rtsteps);
+      Message("nts = %d", streamptr->ntsteps);
+    }
+  */
+  int *isec0 = streamptr->record->sec0;
+  int *isec1 = streamptr->record->sec1;
+  int *isec2 = streamptr->record->sec2;
+  int *isec3 = streamptr->record->sec3;
+  int *isec4 = streamptr->record->sec4;
+
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+
+  if ( streamptr->tsteps[tsID].recordSize == 0 )
+    {
+      gribbuffer = (unsigned char *) streamptr->record->buffer;
+      buffersize = streamptr->record->buffersize;
+
+      cdi_create_records(streamptr, tsID);
+
+      nrecs = streamptr->tsteps[1].nrecs;
+
+      streamptr->tsteps[tsID].nrecs = nrecs;
+      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
+      for ( recID = 0; recID < nrecs; recID++ )
+	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
+
+      fileID = streamptr->fileID;
+
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+
+      nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
+      rindex = 0;
+      while ( TRUE )
 	{
-	  int lxdim = 0, lydim = 0, lzdim = 0/* , ltdim = 0 */;
-	  ndims = ncvars[ncvarid].ndims;
-	  for ( i = 0; i < ndims; i++ )
+	  if ( rindex > nrecs ) break;
+
+	  recsize = gribGetSize(fileID);
+	  recpos  = fileGetPos(fileID);
+	  if ( recsize == 0 )
 	    {
-	      ncdimid = ncvars[ncvarid].dimids[i];
-	      if      ( ncdims[ncdimid].dimtype == X_AXIS ) cdfSetDim(ncvars, ncvarid, i, X_AXIS);
-	      else if ( ncdims[ncdimid].dimtype == Y_AXIS ) cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
-	      else if ( ncdims[ncdimid].dimtype == Z_AXIS ) cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
-	      else if ( ncdims[ncdimid].dimtype == T_AXIS ) cdfSetDim(ncvars, ncvarid, i, T_AXIS);
+	      streamptr->ntsteps = streamptr->rtsteps + 1;
+	      break;
+	    }
+	  if ( recsize > 0 && (size_t)recsize > buffersize )
+	    {
+	      buffersize = (size_t)recsize;
+	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
 	    }
 
-	  if ( CDI_Debug )
+	  if ( rindex >= nrecs ) break;
+
+	  readsize = (size_t)recsize;
+	  rstatus = gribRead(fileID, gribbuffer, &readsize);
+	  if ( rstatus )
 	    {
-	      Message("var %d %s", ncvarid, ncvars[ncvarid].name);
-	      for ( i = 0; i < ndims; i++ )
-		printf("  dim%d type=%d  ", i, ncvars[ncvarid].dimtype[i]);
-	      printf("\n");
+	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
+                      streamptr->tsteps[tsID].recordSize);
+	      break;
 	    }
 
-	  for ( i = 0; i < ndims; i++ )
+	  if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
 	    {
-	      if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) lxdim = TRUE;
-	      else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) lydim = TRUE;
-	      else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) lzdim = TRUE;
-	      /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = TRUE; */
+	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
+	      if ( buffersize < (size_t)unzipsize )
+		{
+		  buffersize = (size_t)unzipsize;
+		  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
+		}
 	    }
 
-          if ( lxdim == FALSE && ncvars[ncvarid].xvarid != UNDEFID )
-            {
-              if (  ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = TRUE;
-            }
+	  cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
+			      (int *) gribbuffer, (int)recsize, &lmv, &iret);
 
-          if ( lydim == FALSE && ncvars[ncvarid].yvarid != UNDEFID )
-            {
-              if (  ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = TRUE;
-            }
+          nrecs_scanned++;
 
-          //   if ( ndims > 1 )
-            for ( i = ndims-1; i >= 0; i-- )
-              {
-                if ( ncvars[ncvarid].dimtype[i] == -1 )
-                  {
-                    if ( lxdim == FALSE )
-                      {
-                        cdfSetDim(ncvars, ncvarid, i, X_AXIS);
-                        lxdim = TRUE;
-                      }
-                    else if ( lydim == FALSE && ncvars[ncvarid].gridtype != GRID_UNSTRUCTURED )
-                      {
-                        cdfSetDim(ncvars, ncvarid, i, Y_AXIS);
-                        lydim = TRUE;
-                      }
-                    else if ( lzdim == FALSE )
-                      {
-                        cdfSetDim(ncvars, ncvarid, i, Z_AXIS);
-                        lzdim = TRUE;
-                      }
-                  }
-              }
-	}
-    }
-}
+	  param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
+          cdiParamToString(param, paramstr, sizeof(paramstr));
 
-/* verify coordinate vars - first scan (dimname == varname) */
-static
-void verify_coordinate_vars_1(int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid)
-{
-  int ncdimid, ncvarid;
+	  if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+	  if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+	  level1   = ISEC1_Level1;
+	  level2   = ISEC1_Level2;
 
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      ncvarid = ncdims[ncdimid].ncvarid;
-      if ( ncvarid != -1 )
-	{
-	  if ( ncvars[ncvarid].dimids[0] == timedimid )
-	    {
-              ncvars[ncvarid].istime = TRUE;
-	      ncdims[ncdimid].dimtype = T_AXIS;
-	      continue;
-	    }
+	  gribDateTime(isec1, &vdate, &vtime);
 
-	  if ( ncvars[ncvarid].units[0] != 0 )
+	  if ( rindex == nrecs ) break;
+
+	  if ( rindex == 0 )
 	    {
-	      if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islon = TRUE;
-		  cdfSetVar(ncvars, ncvarid, FALSE);
-		  cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
-		  ncdims[ncdimid].dimtype = X_AXIS;
-		}
-	      else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islat = TRUE;
-		  cdfSetVar(ncvars, ncvarid, FALSE);
-		  cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
-		  ncdims[ncdimid].dimtype = Y_AXIS;
-		}
-	      else if ( unitsIsPressure(ncvars[ncvarid].units) )
-		{
-		  ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
-		}
-	      else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
+              int vlistID = streamptr->vlistID;
+	      taxisID = vlistInqTaxis(vlistID);
+	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
-		  if      ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
-		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
-		  else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
-		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
-		  else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
-		}
-	      else if ( isDBLAxis(ncvars[ncvarid].longname) )
-                {
-                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+		  taxis->type  = TAXIS_RELATIVE;
+		  taxis->rdate = gribRefDate(isec1);
+		  taxis->rtime = gribRefTime(isec1);
 		}
-	      else if ( strcmp(ncvars[ncvarid].units, "m")   == 0 )
+	      else
 		{
-		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
-		  else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
+		  taxis->type  = TAXIS_ABSOLUTE;
 		}
+	      taxis->unit  = cgribexGetTimeUnit(isec1);
+	      taxis->vdate = vdate;
+	      taxis->vtime = vtime;
+
+	      datetime0.date = vdate;
+	      datetime0.time = vtime;
 	    }
 
-	  if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
-               ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
+	  if ( ISEC1_AvgNum )
 	    {
-	      if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
+	      if (  taxis->numavg && warn_numavg &&
+		   (taxis->numavg != ISEC1_AvgNum) )
 		{
-		  ncvars[ncvarid].islon = TRUE;
-		  cdfSetVar(ncvars, ncvarid, FALSE);
-		  cdfSetDim(ncvars, ncvarid, 0, X_AXIS);
-		  ncdims[ncdimid].dimtype = X_AXIS;
-		  continue;
+	      /*
+	          Warning("Changing numavg from %d to %d not supported!", streamptr->tsteps[tsID].taxis.numavg, ISEC1_AvgNum);
+	      */
+		  warn_numavg = FALSE;
 		}
-	      else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
+	      else
 		{
-		  ncvars[ncvarid].islat = TRUE;
-		  cdfSetVar(ncvars, ncvarid, FALSE);
-		  cdfSetDim(ncvars, ncvarid, 0, Y_AXIS);
-		  ncdims[ncdimid].dimtype = Y_AXIS;
-		  continue;
+		  taxis->numavg = ISEC1_AvgNum;
 		}
 	    }
 
-	  if ( ncvars[ncvarid].zaxistype != UNDEFID )
+	  datetime.date  = vdate;
+	  datetime.time  = vtime;
+
+	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
+
+	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
-              ncvars[ncvarid].islev = TRUE;
-	      cdfSetVar(ncvars, ncvarid, FALSE);
-	      cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
-	      ncdims[ncdimid].dimtype = Z_AXIS;
+	      recID   = streamptr->tsteps[1].recIDs[vrecID];
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
 	    }
-	}
-    }
-}
 
-/* verify coordinate vars - second scan (all other variables) */
-static
-void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
-{
-  int ncvarid;
+	  if ( vrecID == nrecs )
+	    {
+	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, paramstr, level1, level2);
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( ncvars[ncvarid].isvar == 0 )
-	{
-	  if ( ncvars[ncvarid].units[0] != 0 )
+	      if ( cdiInventoryMode == 1 )
+		return (CDI_EUFSTRUCT);
+	      else
+		continue;
+	    }
+
+	  if ( cdiInventoryMode == 1 )
 	    {
-	      if ( isLonAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islon = TRUE;
-		  continue;
-		}
-	      else if ( isLatAxis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islat = TRUE;
-		  continue;
-		}
-	      else if ( unitsIsPressure(ncvars[ncvarid].units) )
-		{
-		  ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
-		  continue;
-		}
-	      else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
-		{
-		  if      ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer midpoints") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
-		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at midpoints", 25) == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID;
-		  else if ( strcmp(ncvars[ncvarid].longname, "hybrid level at layer interfaces") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
-		  else if ( strncmp(ncvars[ncvarid].longname, "hybrid level at interfaces", 26) == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HYBRID_HALF;
-		  else if ( strcmp(ncvars[ncvarid].units, "level") == 0 )
-		    ncvars[ncvarid].zaxistype = ZAXIS_GENERIC;
-		  continue;
-		}
-	      else if ( isDBLAxis(ncvars[ncvarid].longname) )
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
+	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
+	    }
+	  else
+	    {
+	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+		  char paramstr[32];
+		  cdiParamToString(param, paramstr, sizeof(paramstr));
+
+		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+
+		  if ( CDI_Debug )
+                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
+
 		  continue;
 		}
-	      else if ( strcmp(ncvars[ncvarid].units, "m")   == 0 )
+	      else
 		{
-		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
-		  else if ( isHeightAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
-		  continue;
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
+		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
 		}
-            }
+	    }
 
-	  /* not needed anymore for rotated grids */
-	  if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
-               ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
+	  if ( CDI_Debug )
+            Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
+
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
 	    {
-	      if ( memcmp(ncvars[ncvarid].longname+1, "ongitude", 8) == 0 )
-		{
-		  ncvars[ncvarid].islon = TRUE;
-		  continue;
-		}
-	      else if ( memcmp(ncvars[ncvarid].longname+1, "atitude", 7) == 0 )
-		{
-		  ncvars[ncvarid].islat = TRUE;
-		  continue;
-		}
+	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		      tsID, recID,
+		      streamptr->tsteps[tsID].records[recID].param, param,
+		      streamptr->tsteps[tsID].records[recID].ilevel, level1);
+	      Error("Invalid, unsupported or inconsistent record structure");
 	    }
+
+	  streamptr->tsteps[tsID].records[recID].position = recpos;
+	  streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
+
+	  rindex++;
 	}
-    }
-}
 
-#if defined (PROJECTION_TEST)
-static
-void copy_numeric_projatts(int gridID, int ncvarID, int ncfileID)
-{
-  int iatt, nvatts;
-  size_t attlen;
-  char attname[CDI_MAX_NAME];
-  nc_type xtype;
+      for ( vrecID = 0; vrecID < nrecs; vrecID++ )
+	{
+	  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+	  if ( ! streamptr->tsteps[tsID].records[recID].used ) break;
+	}
 
-  cdf_inq_varnatts(ncfileID, ncvarID, &nvatts);
+      if ( vrecID < nrecs )
+	{
+	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
+	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, paramstr,
+                      streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
+	  return (CDI_EUFSTRUCT);
+	}
 
-  for ( iatt = 0; iatt < nvatts; iatt++ )
-    {
-      cdf_inq_attname(ncfileID, ncvarID, iatt, attname);
-      cdf_inq_atttype(ncfileID, ncvarID, attname, &xtype);
-      cdf_inq_attlen(ncfileID, ncvarID, attname, &attlen);
+      streamptr->rtsteps++;
 
-      //  printf("%s %d\n", attname, (int)attlen);
+      if ( streamptr->ntsteps != streamptr->rtsteps )
+	{
+	  tsID = tstepsNewEntry(streamptr);
+	  if ( tsID != streamptr->rtsteps )
+	    Error("Internal error. tsID = %d", tsID);
+
+	  streamptr->tsteps[tsID-1].next   = 1;
+	  streamptr->tsteps[tsID].position = recpos;
+	}
+
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      streamptr->tsteps[tsID].position = recpos;
+
+      streamptr->record->buffer     = gribbuffer;
+      streamptr->record->buffersize = buffersize;
+    }
+
+  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+    {
+      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
+      streamptr->ntsteps = tsID;
     }
 
+  rstatus = (int)streamptr->ntsteps;
+
+  return (rstatus);
 }
 #endif
 
-static
-void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
+#ifdef gribWarning
+#undef gribWarning
+#endif
+
+#if  defined  (HAVE_LIBCGRIBEX)
+int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
+		  int unreduced, int *nmiss, double missval)
 {
-  if ( ncvar->chunked )
+  int status = 0;
+  int iret = 0, iword = 0;
+  int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
+  double fsec2[512], fsec3[2];
+  char hoper[2];
+
+  if ( unreduced ) strcpy(hoper, "R");
+  else             strcpy(hoper, "D");
+
+  FSEC3_MissVal = missval;
+
+  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, data,
+	   gridsize, (int *) gribbuffer, gribsize, &iword, hoper, &iret);
+
+  if ( ISEC1_Sec2Or3Flag & 64 )
+    *nmiss = ISEC4_NumValues - ISEC4_NumNonMissValues;
+  else
+    *nmiss = 0;
+
+  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
     {
-      int ndims = ncvar->ndims;
+      double undef_pds, undef_eps;
+      int i;
 
-      if ( grid->type == GRID_UNSTRUCTURED )
-        {
-          if ( ncvar->chunks[ndims-1] == grid->size )
-            ncvar->chunktype = CHUNK_GRID;
-          else
-            ncvar->chunktype = CHUNK_AUTO;
-        }
-      else
-        {
-          if ( grid->xsize > 1 && grid->ysize > 1 && ndims > 1 &&
-               grid->xsize == ncvar->chunks[ndims-1] &&
-               grid->ysize == ncvar->chunks[ndims-2] )
-            ncvar->chunktype = CHUNK_GRID;
-          else if ( grid->xsize > 1 && grid->xsize == ncvar->chunks[ndims-1] )
-            ncvar->chunktype = CHUNK_LINES;
-          else
-            ncvar->chunktype = CHUNK_AUTO;
+      MCH_get_undef(isec1, &undef_pds, &undef_eps);
+
+      *nmiss = 0;
+      for ( i = 0; i < gridsize; i++ )
+        if ( (fabs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
+          data[i] = missval;
+          (*nmiss)++;
         }
     }
+
+  return (status);
 }
+#endif
 
-/* define all input grids */
+
+#if  defined  (HAVE_LIBCGRIBEX)
 static
-void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
+void cgribexDefInstitut(int *isec1, int vlistID, int varID)
 {
-  int ncvarid, ncvarid2;
-  int ndims;
-  int nbdims;
-  int i;
-  int nvatts;
-  int skipvar;
-  size_t nvertex;
-  grid_t grid;
-  grid_t proj;
-  int gridindex;
-  size_t size = 0, xsize, ysize, np;
-  char name[CDI_MAX_NAME];
-  int iatt;
-  int ltwarn = TRUE;
-  size_t attlen;
-  char attname[CDI_MAX_NAME];
-  double datt;
+  int instID;
 
-  for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
+  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
+    instID = vlistInqInstitut(vlistID);
+  else
+    instID = vlistInqVarInstitut(vlistID, varID);
+
+  if ( instID != CDI_UNDEFID )
     {
-      if ( ncvars[ncvarid].isvar && ncvars[ncvarid].gridID == UNDEFID )
-	{
-	  int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
-	  int xdimid = -1, ydimid = -1;
-	  int xvarid = -1, yvarid = -1;
-	  int islon = 0, islat = 0;
-	  int nxdims = 0, nydims = 0;
-	  double xinc = 0, yinc = 0;
+      int center, subcenter;
+      center    = institutInqCenter(instID);
+      subcenter = institutInqSubcenter(instID);
+      ISEC1_CenterID    = center;
+      ISEC1_SubCenterID = subcenter;
+    }
+}
 
-	  xsize = 0;
-	  ysize = 0;
-          np    = 0;
+static
+void cgribexDefModel(int *isec1, int vlistID, int varID)
+{
+  int modelID;
 
-	  ndims = ncvars[ncvarid].ndims;
-	  for ( i = 0; i < ndims; i++ )
-	    {
-	      if ( ncvars[ncvarid].dimtype[i] == X_AXIS && nxdims < 2 )
-		{
-		  xdimids[nxdims] = ncvars[ncvarid].dimids[i];
-		  nxdims++;
-		}
-	      else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS && nydims < 2 )
-		{
-		  ydimids[nydims] = ncvars[ncvarid].dimids[i];
-		  nydims++;
-		}
-	    }
+  if ( vlistInqModel(vlistID) != CDI_UNDEFID )
+    modelID = vlistInqModel(vlistID);
+  else
+    modelID = vlistInqVarModel(vlistID, varID);
 
-	  if ( nxdims == 2 )
-	    {
-	      xdimid = xdimids[1];
-	      ydimid = xdimids[0];
-	    }
-	  else if ( nydims == 2 )
-	    {
-	      xdimid = ydimids[1];
-	      ydimid = ydimids[0];
-	    }
-	  else
-	    {
-	      xdimid = xdimids[0];
-	      ydimid = ydimids[0];
-	    }
+  if ( modelID != CDI_UNDEFID )
+    ISEC1_ModelID = modelInqGribID(modelID);
+}
 
-	  if ( ncvars[ncvarid].xvarid != UNDEFID )
-	    xvarid = ncvars[ncvarid].xvarid;
-	  else if ( xdimid != UNDEFID )
-	    xvarid = ncdims[xdimid].ncvarid;
+static
+void cgribexDefParam(int *isec1, int param)
+{
+  int pdis, pcat, pnum;
 
-	  if ( ncvars[ncvarid].yvarid != UNDEFID )
-	    yvarid = ncvars[ncvarid].yvarid;
-	  else if ( ydimid != UNDEFID )
-	    yvarid = ncdims[ydimid].ncvarid;
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
-	  /*
-	  if ( xdimid != UNDEFID )
-	    xvarid = ncdims[xdimid].ncvarid;
-	  if ( xvarid == UNDEFID && ncvars[ncvarid].xvarid != UNDEFID )
-	    xvarid = ncvars[ncvarid].xvarid;
+  if ( pnum < 0 ) pnum = -pnum;
 
-	  if ( ydimid != UNDEFID )
-	    yvarid = ncdims[ydimid].ncvarid;
-	  if ( yvarid == UNDEFID && ncvars[ncvarid].yvarid != UNDEFID )
-	    yvarid = ncvars[ncvarid].yvarid;
-	  */
+  static bool lwarn_pdis = true;
+  if ( pdis != 255 && lwarn_pdis )
+    {
+      char paramstr[32];
+      cdiParamToString(param, paramstr, sizeof(paramstr));
+      Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
+      lwarn_pdis = false;
+    }
 
-	  if ( xdimid != UNDEFID ) xsize = ncdims[xdimid].len;
-	  if ( ydimid != UNDEFID ) ysize = ncdims[ydimid].len;
+  static bool lwarn_pnum = true;
+  if ( pnum > 255 && lwarn_pnum )
+    {
+      Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
+      lwarn_pnum = false;
+      pnum = pnum%256;
+    }
 
-	  if ( ydimid == UNDEFID && yvarid != UNDEFID )
-	    {
-	      if ( ncvars[yvarid].ndims == 1 )
-		{
-		  ydimid = ncvars[yvarid].dimids[0];
-		  ysize  = ncdims[ydimid].len;
-		}
-	    }
+  ISEC1_CodeTable = pcat;
+  ISEC1_Parameter = pnum;
+}
 
-	  if ( ncvars[ncvarid].gridtype == UNDEFID || ncvars[ncvarid].gridtype == GRID_GENERIC )
-	    if ( xdimid != UNDEFID && xdimid == ydimid ) ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
+static
+int cgribexDefTimerange(int tsteptype, int factor, int calendar,
+			int rdate, int rtime, int vdate, int vtime, int *pip1, int *pip2)
+{
+  int timerange = -1;
+  int year, month, day, hour, minute, second;
+  int julday1, secofday1, julday2, secofday2, days, secs;
+  int ip, ip1 = 0, ip2 = 0;
 
-	  grid_init(&grid);
-	  grid_init(&proj);
+  cdiDecodeDate(rdate, &year, &month, &day);
+  cdiDecodeTime(rtime, &hour, &minute, &second);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
-	  grid.prec  = DATATYPE_FLT64;
-	  grid.trunc = ncvars[ncvarid].truncation;
+  cdiDecodeDate(vdate, &year, &month, &day);
+  cdiDecodeTime(vtime, &hour, &minute, &second);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
-	  if ( ncvars[ncvarid].gridtype == GRID_TRAJECTORY )
-	    {
-	      if ( ncvars[ncvarid].xvarid == UNDEFID )
-		Error("Longitude coordinate undefined for %s!", name);
-	      if ( ncvars[ncvarid].yvarid == UNDEFID )
-		Error("Latitude coordinate undefined for %s!", name);
-	    }
-	  else
-	    {
-	      size_t start[3], count[3];
-	      int ltgrid = FALSE;
+  (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
-	      if ( xvarid != UNDEFID && yvarid != UNDEFID )
-		{
-		  if ( ncvars[xvarid].ndims != ncvars[yvarid].ndims )
-		    {
-		      Warning("Inconsistent grid structure for variable %s!", ncvars[ncvarid].name);
-		      ncvars[ncvarid].xvarid = UNDEFID;
-		      ncvars[ncvarid].yvarid = UNDEFID;
-		      xvarid = UNDEFID;
-		      yvarid = UNDEFID;
-		    }
+  if ( !(int) fmod(days*86400.0 + secs, factor) )
+    {
+      ip = (int) ((days*86400.0 + secs)/factor);
 
-		  if ( ncvars[xvarid].ndims > 2 || ncvars[yvarid].ndims > 2 )
-		    {
-		      if ( ncvars[xvarid].ndims == 3 && ncvars[xvarid].dimids[0] == timedimid &&
-			   ncvars[yvarid].ndims == 3 && ncvars[yvarid].dimids[0] == timedimid )
-			{
-			  if ( ltwarn )
-			    Warning("Time varying grids unsupported, using grid at time step 1!");
-			  ltgrid = TRUE;
-			  ltwarn = FALSE;
-			  start[0] = start[1] = start[2] = 0;
-			  count[0] = 1; count[1] = ysize; count[2] = xsize;
-			}
-		      else
-			{
-			  Warning("Unsupported grid structure for variable %s (grid dims > 2)!", ncvars[ncvarid].name);
-			  ncvars[ncvarid].xvarid = UNDEFID;
-			  ncvars[ncvarid].yvarid = UNDEFID;
-			  xvarid = UNDEFID;
-			  yvarid = UNDEFID;
-			}
-		    }
-		}
+      switch ( tsteptype )
+	{
+	case TSTEP_INSTANT:  timerange =  0; ip1 = ip; ip2 = 0;  break;
+	case TSTEP_INSTANT2: timerange =  1; ip1 = 0;  ip2 = 0;  break;
+	case TSTEP_RANGE:    timerange =  2; ip1 = 0;  ip2 = ip; break;
+	case TSTEP_AVG:      timerange =  3; ip1 = 0;  ip2 = ip; break;
+	case TSTEP_ACCUM:    timerange =  4; ip1 = 0;  ip2 = ip; break;
+	case TSTEP_DIFF:     timerange =  5; ip1 = 0;  ip2 = ip; break;
+	case TSTEP_INSTANT3:
+	default:             timerange = 10; ip1 = ip/256; ip2 = ip%256;  break;
+	}
+    }
 
-              if ( xvarid != UNDEFID )
-                {
-                  if ( ncvars[xvarid].ndims > 3 || (ncvars[xvarid].ndims == 3 && ltgrid == FALSE) )
-                    {
-                      Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[xvarid].name, ncvars[xvarid].ndims);
-                      //ncvars[ncvarid].xvarid = UNDEFID;
-                      xvarid = UNDEFID;
-                    }
-                }
+  *pip1 = ip1;
+  *pip2 = ip2;
 
-              if ( yvarid != UNDEFID )
-                {
-                  if ( ncvars[yvarid].ndims > 3 || (ncvars[yvarid].ndims == 3 && ltgrid == FALSE) )
-                    {
-                      Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
-                      //ncvars[ncvarid].yvarid = UNDEFID;
-                      yvarid = UNDEFID;
-                    }
-                }
+  return (timerange);
+}
 
-              if ( xvarid != UNDEFID )
-		{
-                  skipvar = TRUE;
-		  islon = ncvars[xvarid].islon;
-		  ndims = ncvars[xvarid].ndims;
-		  if ( ndims == 2 || ndims == 3 )
-		    {
-		      ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
-		      size = xsize*ysize;
-		      /* Check size of 2 dimensional coordinate variables */
-		      {
-			int dimid;
-			size_t dimsize1, dimsize2;
-			dimid = ncvars[xvarid].dimids[ndims-2];
-			dimsize1 = ncdims[dimid].len;
-			dimid = ncvars[xvarid].dimids[ndims-1];
-			dimsize2 = ncdims[dimid].len;
-			if ( dimsize1*dimsize2 == size ) skipvar = FALSE;
-		      }
-		    }
-		  else if ( ndims == 1 )
-		    {
-		      size = xsize;
-		      /* Check size of 1 dimensional coordinate variables */
-		      {
-			int dimid;
-			size_t dimsize;
-			dimid = ncvars[xvarid].dimids[0];
-			dimsize = ncdims[dimid].len;
-			if ( dimsize == size ) skipvar = FALSE;
-		      }
-		    }
-		  else if ( ndims == 0 && xsize == 0 )
-		    {
-                      xsize = 1;
-		      size = xsize;
-                      skipvar = FALSE;
-		    }
+static
+int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
+{
+  int year, month, day, hour, minute, second;
+  int century = 0;
+  int factor = 1;
 
-                  if ( skipvar )
-                    {
-                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
-                      ncvars[ncvarid].isvar = -1;
-                      continue;
-                    }
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
 
-		  if ( ncvars[xvarid].xtype == NC_FLOAT ) grid.prec = DATATYPE_FLT32;
-		  grid.xvals = (double *) malloc(size*sizeof(double));
+  century =  year / 100;
 
-		  if ( ltgrid )
-		    cdf_get_vara_double(ncvars[xvarid].ncid, xvarid, start, count, grid.xvals);
-		  else
-		    cdf_get_var_double(ncvars[xvarid].ncid, xvarid, grid.xvals);
+  ISEC1_Year = year - century*100;
 
-                  scale_add(size, grid.xvals, ncvars[xvarid].addoffset, ncvars[xvarid].scalefactor);
+  if ( year < 0 )
+    {
+      century = -century;
+      ISEC1_Year = -ISEC1_Year;
+    }
 
-		  strcpy(grid.xname, ncvars[xvarid].name);
-		  strcpy(grid.xlongname, ncvars[xvarid].longname);
-		  strcpy(grid.xunits, ncvars[xvarid].units);
-		  /* don't change the name !!! */
-		  /*
-		  if ( (len = strlen(grid.xname)) > 2 )
-		    if ( grid.xname[len-2] == '_' && isdigit((int) grid.xname[len-1]) )
-		      grid.xname[len-2] = 0;
-		  */
-		  if ( islon && xsize > 1 )
-		    {
-		      xinc = fabs(grid.xvals[0] - grid.xvals[1]);
-		      for ( i = 2; i < (int) xsize; i++ )
-			if ( (fabs(grid.xvals[i-1] - grid.xvals[i]) - xinc) > (xinc/1000) ) break;
+  if ( ISEC1_Year == 0 )
+    {
+      century -= 1;
+      ISEC1_Year = 100;
+    }
 
-		      if ( i < (int) xsize ) xinc = 0;
-		    }
-		}
+  century += 1;
+  if ( year < 0 ) century = -century;
 
-	      if ( yvarid != UNDEFID )
-		{
-                  skipvar = TRUE;
-		  islat = ncvars[yvarid].islat;
-		  ndims = ncvars[yvarid].ndims;
-		  if ( ndims == 2 || ndims == 3 )
-		    {
-		      ncvars[ncvarid].gridtype = GRID_CURVILINEAR;
-		      size = xsize*ysize;
-		      /* Check size of 2 dimensional coordinate variables */
-		      {
-			int dimid;
-			size_t dimsize1, dimsize2;
-			dimid = ncvars[yvarid].dimids[ndims-2];
-			dimsize1 = ncdims[dimid].len;
-			dimid = ncvars[yvarid].dimids[ndims-1];
-			dimsize2 = ncdims[dimid].len;
-			if ( dimsize1*dimsize2 == size ) skipvar = FALSE;
-		      }
-		    }
-		  else if ( ndims == 1 )
-		    {
-		      if ( (int) ysize == 0 ) size = xsize;
-		      else                    size = ysize;
+  ISEC1_Month  = month;
+  ISEC1_Day    = day;
+  ISEC1_Hour   = hour;
+  ISEC1_Minute = minute;
 
-		      /* Check size of 1 dimensional coordinate variables */
-		      {
-			int dimid;
-			size_t dimsize;
-			dimid = ncvars[yvarid].dimids[0];
-			dimsize = ncdims[dimid].len;
-			if ( dimsize == size ) skipvar = FALSE;
-		      }
-		    }
-		  else if ( ndims == 0 && ysize == 0 )
-		    {
-                      ysize = 1;
-		      size = ysize;
-                      skipvar = FALSE;
-		    }
+  ISEC1_Century = century;
 
-                  if ( skipvar )
-                    {
-                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
-                      ncvars[ncvarid].isvar = -1;
-                      continue;
-                    }
+  switch (timeunit)
+    {
+    case TUNIT_MINUTE:    factor =    60; ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE;    break;
+    case TUNIT_QUARTER:   factor =   900; ISEC1_TimeUnit = ISEC1_TABLE4_QUARTER;   break;
+    case TUNIT_30MINUTES: factor =  1800; ISEC1_TimeUnit = ISEC1_TABLE4_30MINUTES; break;
+    case TUNIT_HOUR:      factor =  3600; ISEC1_TimeUnit = ISEC1_TABLE4_HOUR;      break;
+    case TUNIT_3HOURS:    factor = 10800; ISEC1_TimeUnit = ISEC1_TABLE4_3HOURS;    break;
+    case TUNIT_6HOURS:    factor = 21600; ISEC1_TimeUnit = ISEC1_TABLE4_6HOURS;    break;
+    case TUNIT_12HOURS:   factor = 43200; ISEC1_TimeUnit = ISEC1_TABLE4_12HOURS;   break;
+    case TUNIT_DAY:       factor = 86400; ISEC1_TimeUnit = ISEC1_TABLE4_DAY;       break;
+    default:              factor =  3600; ISEC1_TimeUnit = ISEC1_TABLE4_HOUR;      break;
+    }
 
-		  if ( ncvars[yvarid].xtype == NC_FLOAT ) grid.prec = DATATYPE_FLT32;
-		  grid.yvals = (double *) malloc(size*sizeof(double));
+  return (factor);
+}
 
-		  if ( ltgrid )
-		    cdf_get_vara_double(ncvars[yvarid].ncid, yvarid, start, count, grid.yvals);
-		  else
-		    cdf_get_var_double(ncvars[yvarid].ncid, yvarid, grid.yvals);
+static
+void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg, int taxisID)
+{
+  int timetype = TAXIS_ABSOLUTE;
+  int timerange = 0;
+  int timeunit = TUNIT_HOUR;
 
-                  scale_add(size, grid.yvals, ncvars[yvarid].addoffset, ncvars[yvarid].scalefactor);
+  if ( taxisID != -1 )
+    {
+      timetype = taxisInqType(taxisID);
+      timeunit = taxisInqTunit(taxisID);
+    }
 
-		  strcpy(grid.yname, ncvars[yvarid].name);
-		  strcpy(grid.ylongname, ncvars[yvarid].longname);
-		  strcpy(grid.yunits, ncvars[yvarid].units);
-		  /* don't change the name !!! */
-		  /*
-		  if ( (len = strlen(grid.yname)) > 2 )
-		    if ( grid.yname[len-2] == '_' && isdigit((int) grid.yname[len-1]) )
-		      grid.yname[len-2] = 0;
-		  */
-		  if ( islon && (int) ysize > 1 )
-		    {
-		      yinc = fabs(grid.yvals[0] - grid.yvals[1]);
-		      for ( i = 2; i < (int) ysize; i++ )
-			if ( (fabs(grid.yvals[i-1] - grid.yvals[i]) - yinc) > (yinc/1000) ) break;
+  if ( timetype == TAXIS_RELATIVE )
+    {
+      int factor = 1;
+      int rdate, rtime;
+      int ip1 = 0, ip2 = 0;
+      int calendar;
 
-		      if ( i < (int) ysize ) yinc = 0;
-		    }
-		}
+      calendar = taxisInqCalendar(taxisID);
+      rdate    = taxisInqRdate(taxisID);
+      rtime    = taxisInqRtime(taxisID);
 
-	      if      ( (int) ysize == 0 ) size = xsize;
-	      else if ( (int) xsize == 0 ) size = ysize;
-	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize;
-	      else                         size = xsize*ysize;
-	    }
+      factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
 
-	  if ( ncvars[ncvarid].gridtype == UNDEFID ||
-	       ncvars[ncvarid].gridtype == GRID_GENERIC )
-	    {
-	      if ( islat && islon )
-		{
-		  if ( isGaussGrid(ysize, yinc, grid.yvals) )
-                    {
-                      ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
-                      np = ysize/2;
-                    }
-                  else
-		    ncvars[ncvarid].gridtype = GRID_LONLAT;
-		}
-	      else if ( islat && !islon && xsize == 0 )
-		{
-		  if ( isGaussGrid(ysize, yinc, grid.yvals) )
-                    {
-                      ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
-                      np = ysize/2;
-                    }
-                  else
-		    ncvars[ncvarid].gridtype = GRID_LONLAT;
-		}
-	      else if ( islon && !islat && ysize == 0 )
-		{
-		  ncvars[ncvarid].gridtype = GRID_LONLAT;
-		}
-	      else
-		ncvars[ncvarid].gridtype = GRID_GENERIC;
-	    }
+      timerange = cgribexDefTimerange(tsteptype, factor, calendar,
+				      rdate, rtime, vdate, vtime, &ip1, &ip2);
 
-	  switch (ncvars[ncvarid].gridtype)
-	    {
-	    case GRID_GENERIC:
-	    case GRID_LONLAT:
-	    case GRID_GAUSSIAN:
-	    case GRID_UNSTRUCTURED:
-	    case GRID_CURVILINEAR:
-	      {
-		grid.size  = (int)size;
-		grid.xsize = (int)xsize;
-		grid.ysize = (int)ysize;
-                grid.np    = (int)np;
-		if ( xvarid != UNDEFID )
-		  {
-		    grid.xdef  = 1;
-		    if ( ncvars[xvarid].bounds != UNDEFID )
-		      {
-			nbdims = ncvars[ncvars[xvarid].bounds].ndims;
-			if ( nbdims == 2 || nbdims == 3 )
-			  {
-			    nvertex = ncdims[ncvars[ncvars[xvarid].bounds].dimids[nbdims-1]].len;
-			    grid.nvertex = (int) nvertex;
-			    grid.xbounds = (double *) malloc(nvertex*size*sizeof(double));
-			    cdf_get_var_double(ncvars[xvarid].ncid, ncvars[xvarid].bounds, grid.xbounds);
-			  }
-		      }
-		  }
-		if ( yvarid != UNDEFID )
-		  {
-		    grid.ydef  = 1;
-		    if ( ncvars[yvarid].bounds != UNDEFID )
-		      {
-			nbdims = ncvars[ncvars[yvarid].bounds].ndims;
-			if ( nbdims == 2 || nbdims == 3 )
-			  {
-			    nvertex = ncdims[ncvars[ncvars[yvarid].bounds].dimids[nbdims-1]].len;
-			    /*
-			    if ( nvertex != grid.nvertex )
-			      Warning("nvertex problem! nvertex x %d, nvertex y %d",
-				      grid.nvertex, (int) nvertex);
-			    */
-			    grid.ybounds = (double *) malloc(nvertex*size*sizeof(double));
-			    cdf_get_var_double(ncvars[yvarid].ncid, ncvars[yvarid].bounds, grid.ybounds);
-			  }
-		      }
-		  }
+      if ( timerange == -1 || timerange == 3 )
+	{
+	  timetype = TAXIS_ABSOLUTE;
+	}
+      /*
+      else if ( timerange == 10 )
+	{
+	  if ( ip1 < 0 || ip1 > 0xFFFF ) timetype = TAXIS_ABSOLUTE;
+	  if ( ip2 < 0 || ip2 > 0xFFFF ) timetype = TAXIS_ABSOLUTE;
+	}
+      */
+      else
+	{
+	  if ( ip1 < 0 || ip1 > 0xFF   ) timetype = TAXIS_ABSOLUTE;
+	  if ( ip2 < 0 || ip2 > 0xFF   ) timetype = TAXIS_ABSOLUTE;
+	}
 
-		if ( ncvars[ncvarid].cellarea != UNDEFID )
-		  {
-		    grid.area = (double *) malloc(size*sizeof(double));
-		    cdf_get_var_double(ncvars[ncvarid].ncid, ncvars[ncvarid].cellarea, grid.area);
-		  }
+      ISEC1_TimeRange   = timerange;
+      ISEC1_TimePeriod1 = ip1;
+      ISEC1_TimePeriod2 = ip2;
+    }
 
-		break;
-	      }
-	    case GRID_SPECTRAL:
-	      {
-		grid.size = (int)size;
-		grid.lcomplex = 1;
-		break;
-	      }
-	    case GRID_FOURIER:
-	      {
-		grid.size = (int)size;
-		break;
-	      }
-	    case GRID_TRAJECTORY:
-	      {
-		grid.size = 1;
-		break;
-	      }
-	    }
+  if ( timetype == TAXIS_ABSOLUTE )
+    {
+      (void) cgribexDefDateTime(isec1, timeunit, vdate, vtime);
 
-	  grid.type = ncvars[ncvarid].gridtype;
+      /*
+      if ( numavg > 0 )
+	ISEC1_TimeRange = 0;
+      else
+      */
+      if ( ISEC1_TimeRange != 3 )
+	ISEC1_TimeRange   = 10;
 
-	  if ( grid.size == 0 )
-	    {
-	      if ( (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == T_AXIS) ||
-		   (ncvars[ncvarid].ndims == 1 && ncvars[ncvarid].dimtype[0] == Z_AXIS) ||
-		   (ncvars[ncvarid].ndims == 2 && ncvars[ncvarid].dimtype[0] == T_AXIS && ncvars[ncvarid].dimtype[1] == Z_AXIS) )
-		{
-		  grid.type  = GRID_GENERIC;
-		  grid.size  = 1;
-		  grid.xsize = 0;
-		  grid.ysize = 0;
-		}
-	      else
-		{
-		  Warning("Variable %s has an unsupported grid, skipped!", ncvars[ncvarid].name);
-		  ncvars[ncvarid].isvar = -1;
-		  continue;
-		}
-	    }
+      ISEC1_TimePeriod1 = 0;
+      ISEC1_TimePeriod2 = 0;
+    }
 
-	  if ( number_of_grid_used != UNDEFID && (grid.type == UNDEFID || grid.type == GRID_GENERIC) )
-            grid.type   = GRID_UNSTRUCTURED;
+  ISEC1_AvgNum         = numavg;
+  ISEC1_AvgMiss        = 0;
+  ISEC1_DecScaleFactor = 0;
+}
 
-	  if ( number_of_grid_used != UNDEFID && grid.type == GRID_UNSTRUCTURED )
-            grid.number = number_of_grid_used;
+static
+void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID)
+{
+  int gridtype;
+  bool lcurvi = false;
+  static bool lwarning = true;
 
-	  if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
-	    {
-	      cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
+  memset(isec2, 0, 16*sizeof(int));
 
-	      for ( iatt = 0; iatt < nvatts; iatt++ )
-		{
-		  cdf_inq_attname(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, iatt, attname);
-		  cdf_inq_attlen(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, &attlen);
+  ISEC1_Sec2Or3Flag = 128;
 
-		  if ( strcmp(attname, "grid_mapping_name") == 0 )
-		    {
-                      enum {
-                        attstringlen = 8192,
-                      };
-                      char attstring[attstringlen];
+  gridtype = gridInqType(gridID);
 
-		      cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen-1, attstring);
-		      strtolower(attstring);
+  ISEC1_GridDefinition = 255;
 
-		      if ( strcmp(attstring, "rotated_latitude_longitude") == 0 )
-			grid.isRotated = TRUE;
-		      else if ( strcmp(attstring, "sinusoidal") == 0 )
-			grid.type = GRID_SINUSOIDAL;
-		      else if ( strcmp(attstring, "lambert_azimuthal_equal_area") == 0 )
-			grid.type = GRID_LAEA;
-		      else if ( strcmp(attstring, "lambert_conformal_conic") == 0 )
-			grid.type = GRID_LCC2;
-		      else if ( strcmp(attstring, "lambert_cylindrical_equal_area") == 0 )
-			{
-			  proj.type = GRID_PROJECTION;
-			  proj.name = strdup(attstring);
-			}
-		    }
-		  else if ( strcmp(attname, "earth_radius") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
-		      grid.laea_a = datt;
-		      grid.lcc2_a = datt;
-		    }
-		  else if ( strcmp(attname, "longitude_of_projection_origin") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.laea_lon_0);
-		    }
-		  else if ( strcmp(attname, "longitude_of_central_meridian") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.lcc2_lon_0);
-		    }
-		  else if ( strcmp(attname, "latitude_of_projection_origin") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
-		      grid.laea_lat_0 = datt;
-		      grid.lcc2_lat_0 = datt;
-		    }
-		  else if ( strcmp(attname, "standard_parallel") == 0 )
-		    {
-		      if ( attlen == 1 )
-			{
-			  cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &datt);
-			  grid.lcc2_lat_1 = datt;
-			  grid.lcc2_lat_2 = datt;
-			}
-		      else
-			{
-			  double datt2[2];
-			  cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 2, datt2);
-			  grid.lcc2_lat_1 = datt2[0];
-			  grid.lcc2_lat_2 = datt2[1];
-			}
-		    }
-		  else if ( strcmp(attname, "grid_north_pole_latitude") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.ypole);
-		    }
-		  else if ( strcmp(attname, "grid_north_pole_longitude") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.xpole);
-		    }
-		  else if ( strcmp(attname, "north_pole_grid_longitude") == 0 )
-		    {
-		      cdfGetAttDouble(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, 1, &grid.angle);
-		    }
-		}
-	    }
+  if ( gridtype == GRID_GENERIC )
+    {
+      int xsize, ysize, gridsize;
 
-          if ( grid.type == GRID_UNSTRUCTURED )
-            {
-              int zdimid = UNDEFID;
-              int xdimidx = -1, ydimidx = -1;
+      gridsize = gridInqSize(gridID);
+      xsize = gridInqXsize(gridID);
+      ysize = gridInqYsize(gridID);
 
-              for ( i = 0; i < ndims; i++ )
-                {
-                  if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) xdimidx = i;
-                  else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) ydimidx = i;
-                  else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) zdimid = ncvars[ncvarid].dimids[i];
-                }
+      if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
+	    ysize ==  96 || ysize == 160 || ysize == 192 ||
+	    ysize == 240 || ysize == 320 || ysize == 384 ||
+	    ysize == 480 || ysize == 768 ) &&
+	   (xsize == 2*ysize || xsize == 1) )
+	{
+	  gridtype = GRID_GAUSSIAN;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( gridsize == 1 )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+    }
+  else if ( gridtype == GRID_CURVILINEAR )
+    {
+      if ( lwarning && gridInqSize(gridID) > 1 )
+	{
+	  lwarning = false;
+	  Warning("Curvilinear grids are unsupported in GRIB1! Created wrong GDS!");
+	}
+      gridtype = GRID_LONLAT;
+      lcurvi = true;
+    }
 
-              if ( xdimid != UNDEFID && ydimid != UNDEFID && zdimid == UNDEFID )
-                {
-                  if ( grid.xsize > grid.ysize && grid.ysize < 1000 )
-                    {
-                      ncvars[ncvarid].dimtype[ydimidx] = Z_AXIS;
-                      ydimid = UNDEFID;
-                      grid.size  = grid.xsize;
-                      grid.ysize = 0;
-                    }
-                  else if ( grid.ysize > grid.xsize && grid.xsize < 1000 )
-                    {
-                      ncvars[ncvarid].dimtype[xdimidx] = Z_AXIS;
-                      xdimid = ydimid;
-                      ydimid = UNDEFID;
-                      grid.size  = grid.ysize;
-                      grid.xsize = grid.ysize;
-                      grid.ysize = 0;
-                    }
-                }
+  ISEC2_Reduced  = FALSE;
+  ISEC2_ScanFlag = 0;
 
-              if ( grid.size != grid.xsize )
-                {
-                  Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
-                  ncvars[ncvarid].isvar = -1;
-                  continue;
-                }
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+    case GRID_GAUSSIAN_REDUCED:
+    case GRID_TRAJECTORY:
+      {
+	int nlon = 0, nlat;
+	double xfirst = 0, xlast = 0, xinc = 0;
+	double yfirst = 0, ylast = 0, yinc = 0;
 
-              if ( ncvars[ncvarid].position > 0 ) grid.position = ncvars[ncvarid].position;
-              if ( uuidOfHGrid[0] != 0 ) memcpy(grid.uuid, uuidOfHGrid, 16);
-            }
+	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
+          ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN;
+        else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
+	  ISEC2_GridType = GRIB1_GTYPE_LATLON_ROT;
+	else
+	  ISEC2_GridType = GRIB1_GTYPE_LATLON;
 
-#if defined (PROJECTION_TEST)
-	  if ( proj.type == GRID_PROJECTION )
-	    {
-	      if ( grid.type == GRID_GENERIC )
-		{
-		  grid.type = GRID_CURVILINEAR;
-		}
+	nlon = gridInqXsize(gridID);
+	nlat = gridInqYsize(gridID);
 
-	      if ( grid.type == GRID_CURVILINEAR )
-		{
-		  proj.size  = grid.size;
-		  proj.xsize = grid.xsize;
-                  proj.ysize = grid.ysize;
-		}
+	if ( gridtype == GRID_GAUSSIAN_REDUCED )
+	  {
+	    ISEC2_Reduced = TRUE;
+	    nlon = 0;
+	    gridInqRowlon(gridID, ISEC2_RowLonPtr);
+	  }
+	else
+	  {
+	    if ( nlon == 0 )
+	      {
+		nlon = 1;
+	      }
+	    else
+	      {
+		xfirst = gridInqXval(gridID,      0);
+		if ( lcurvi )
+		  xlast  = gridInqXval(gridID, nlon*nlat-1);
+		else
+		  xlast  = gridInqXval(gridID, nlon-1);
+		xinc   = gridInqXinc(gridID);
+	      }
+	  }
 
-	      //  grid.proj = gridGenerate(proj);
-	    }
-#endif
+	if ( nlat == 0 )
+	  {
+	    nlat = 1;
+	  }
+	else
+	  {
+	    yfirst = gridInqYval(gridID,      0);
+	    if ( lcurvi )
+	      ylast  = gridInqYval(gridID, nlon*nlat-1);
+	    else
+	      ylast  = gridInqYval(gridID, nlat-1);
+	    yinc   = gridInqYinc(gridID);
+	    if ( yinc < 0 ) yinc = -yinc;
+	  }
 
-	  if ( CDI_Debug )
-	    {
-	      Message("grid: type = %d, size = %d, nx = %d, ny %d",
-		      grid.type, grid.size, grid.xsize, grid.ysize);
-	      Message("proj: type = %d, size = %d, nx = %d, ny %d",
-		      proj.type, proj.size, proj.xsize, proj.ysize);
-	    }
+	ISEC2_NumLon   = nlon;
+	ISEC2_NumLat   = nlat;
+	ISEC2_FirstLat = (int)lround(yfirst*1000);
+	ISEC2_LastLat  = (int)lround(ylast*1000);
+	if ( gridtype == GRID_GAUSSIAN_REDUCED )
+	  {
+	    ISEC2_FirstLon = 0;
+	    ISEC2_LastLon  = (int)lround(1000*(360.-360./(nlat*2)));
+	    ISEC2_LonIncr  = (int)lround(1000*360./(nlat*2));
+	  }
+	else
+	  {
+	    ISEC2_FirstLon = (int)lround(xfirst*1000);
+	    ISEC2_LastLon  = (int)lround(xlast*1000);
+	    ISEC2_LonIncr  = (int)lround(xinc*1000);
+	  }
 
-#if defined (PROJECTION_TEST)
-	  if ( proj.type == GRID_PROJECTION )
-	    {
-	      ncvars[ncvarid].gridID = varDefGrid(vlistID, &proj, 1);
-	      copy_numeric_projatts(ncvars[ncvarid].gridID, ncvars[ncvarid].gmapid, ncvars[ncvarid].ncid);
-	    }
-	  else
-#endif
-	    ncvars[ncvarid].gridID = varDefGrid(vlistID, &grid, 1);
+	// if ( fabs(xinc*1000 - ISEC2_LonIncr) > FLT_EPSILON ) ISEC2_LonIncr = 0;
 
-          if ( grid.type == GRID_UNSTRUCTURED )
-            {
-              if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
-            }
+	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
+          {
+            int np = gridInqNP(gridID);
+            if ( np == 0 ) np = nlat/2;
+            ISEC2_NumPar = np;
+          }
+	else
+	  {
+	    ISEC2_LatIncr = (int)lround(yinc*1000);
+	    // if ( fabs(yinc*1000 - ISEC2_LatIncr) > FLT_EPSILON ) ISEC2_LatIncr = 0;
 
-          if ( ncvars[ncvarid].chunked ) grid_set_chunktype(&grid, &ncvars[ncvarid]);
+	    if ( ISEC2_LatIncr < 0 ) ISEC2_LatIncr = -ISEC2_LatIncr;
+	  }
 
-	  gridindex = vlistGridIndex(vlistID, ncvars[ncvarid].gridID);
-	  streamptr->xdimID[gridindex] = xdimid;
-	  streamptr->ydimID[gridindex] = ydimid;
-          if ( xdimid == -1 && ydimid == -1 && grid.size == 1 )
-            gridDefHasDims(ncvars[ncvarid].gridID, FALSE);
+	if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
+	  if ( ISEC2_LonIncr != 0 && ISEC2_LatIncr == 0 ) ISEC2_LatIncr = ISEC2_LonIncr;
 
-	  if ( CDI_Debug )
-	    Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
+	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
+	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
 
-	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].gridID == UNDEFID )
-	      {
-		int xdimid2 = UNDEFID, ydimid2 = UNDEFID, zdimid2 = UNDEFID;
-                int xdimidx = -1, ydimidx = -1;
-		int ndims2 = ncvars[ncvarid2].ndims;
+	if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
+	  ISEC2_ResFlag = 0;
+	else
+	  ISEC2_ResFlag = 128;
 
-		for ( i = 0; i < ndims2; i++ )
-		  {
-		    if ( ncvars[ncvarid2].dimtype[i] == X_AXIS )
-		      { xdimid2 = ncvars[ncvarid2].dimids[i]; xdimidx = i; }
-		    else if ( ncvars[ncvarid2].dimtype[i] == Y_AXIS )
-		      { ydimid2 = ncvars[ncvarid2].dimids[i]; ydimidx = i; }
-		    else if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
-		      { zdimid2 = ncvars[ncvarid2].dimids[i]; }
-		  }
+	if ( gridIsRotated(gridID) )
+	  {
+	    ISEC2_LatSP = - (int)lround(gridInqYpole(gridID) * 1000);
+	    ISEC2_LonSP =   (int)lround((gridInqXpole(gridID) + 180) * 1000);
+            FSEC2_RotAngle = gridInqAngle(gridID);
+	  }
 
-                if ( ncvars[ncvarid2].gridtype == UNDEFID && grid.type == GRID_UNSTRUCTURED )
-                  {
-                    if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
-                      {
-                        ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
-                        ydimid2 = UNDEFID;
-                      }
+	/* East -> West */
+	if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
 
-                    if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
-                      {
-                        ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
-                        xdimid2 = ydimid2;
-                        ydimid2 = UNDEFID;
-                      }
-                  }
+	/* South -> North */
+	if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
 
-                if ( xdimid == xdimid2 &&
-		    (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
-		  {
-		    int same_grid = TRUE;
-                    /*
-		    if ( xvarid != -1 && ncvars[ncvarid2].xvarid != UNDEFID &&
-			 xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
+	break;
+      }
+    case GRID_LCC:
+      {
+	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
+	int xsize, ysize;
+	int projflag, scanflag;
 
-		    if ( yvarid != -1 && ncvars[ncvarid2].yvarid != UNDEFID &&
-			 yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
-                    */
-		    if ( ncvars[ncvarid].xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
-		    if ( ncvars[ncvarid].yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
+	xsize = gridInqXsize(gridID);
+	ysize = gridInqYsize(gridID);
 
-		    if ( ncvars[ncvarid].position != ncvars[ncvarid2].position ) same_grid = FALSE;
+	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
+		   &projflag, &scanflag);
 
-		    if ( same_grid )
-		      {
-			if ( CDI_Debug )
-			  Message("Same gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
-			ncvars[ncvarid2].gridID = ncvars[ncvarid].gridID;
-			ncvars[ncvarid2].chunktype = ncvars[ncvarid].chunktype;
-		      }
-		  }
-	      }
+	ISEC2_GridType = GRIB1_GTYPE_LCC;
+	ISEC2_NumLon   = xsize;
+	ISEC2_NumLat   = ysize;
+	ISEC2_FirstLon = (int)lround(originLon * 1000);
+	ISEC2_FirstLat = (int)lround(originLat * 1000);
+	ISEC2_Lambert_Lov    = (int)lround(lonParY * 1000);
+	ISEC2_Lambert_LatS1  = (int)lround(lat1 * 1000);
+	ISEC2_Lambert_LatS2  = (int)lround(lat2 * 1000);
+	ISEC2_Lambert_dx     = (int)lround(xincm);
+	ISEC2_Lambert_dy     = (int)lround(yincm);
+	ISEC2_Lambert_LatSP  = 0;
+	ISEC2_Lambert_LatSP  = 0;
+	ISEC2_Lambert_ProjFlag = projflag;
+	ISEC2_ScanFlag = scanflag;
 
-	  grid_free(&grid);
-	  grid_free(&proj);
-	}
+	break;
+      }
+    case GRID_SPECTRAL:
+      {
+	ISEC2_GridType = GRIB1_GTYPE_SPECTRAL;
+	ISEC2_PentaJ   = gridInqTrunc(gridID);
+	ISEC2_PentaK   = ISEC2_PentaJ;
+	ISEC2_PentaM   = ISEC2_PentaJ;
+	ISEC2_RepType  = 1;
+	isec4[2]       = 128;
+	if ( gridInqComplexPacking(gridID) && ISEC2_PentaJ >= 21 )
+	  {
+	    ISEC2_RepMode  = 2;
+	    isec4[3]       = 64;
+	    isec4[16]      = 0;
+	    isec4[17]      = 20;
+	    isec4[18]      = 20;
+	    isec4[19]      = 20;
+	  }
+	else
+	  {
+	    ISEC2_RepMode  = 1;
+	    isec4[3]       = 0;
+	  }
+	break;
+      }
+    case GRID_GME:
+      {
+	ISEC2_GridType   = GRIB1_GTYPE_GME;
+	ISEC2_GME_ND     = gridInqGMEnd(gridID);
+	ISEC2_GME_NI     = gridInqGMEni(gridID);
+	ISEC2_GME_NI2    = gridInqGMEni2(gridID);
+	ISEC2_GME_NI3    = gridInqGMEni3(gridID);
+	ISEC2_GME_AFlag  = 0;
+	ISEC2_GME_LatPP  = 90000;
+	ISEC2_GME_LonPP  = 0;
+	ISEC2_GME_LonMPL = 0;
+	ISEC2_GME_BFlag  = 0;
+	break;
+      }
+    default:
+      {
+	Warning("The CGRIBEX library can not store fields on the used grid!");
+	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
+      }
     }
 }
 
-/* define all input zaxes */
 static
-void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
-		      size_t vctsize, double *vct, unsigned char *uuidOfVGrid)
+void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int levelID)
 {
-  int ncvarid, ncvarid2;
-  int i, ilev, ndims;
-  int zaxisindex;
-  int zprec;
-  int nbdims, nvertex, nlevel;
-  int positive = 0;
-  char *pname, *plongname, *punits;
+  double level;
+  int ilevel, zaxistype, ltype;
+  static bool lwarning = true;
+  static bool lwarning_vct = true;
+
+  zaxistype = zaxisInqType(zaxisID);
+  ltype = zaxisInqLtype(zaxisID);
+
+  if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
+    {
+      Message("Changed zaxis type from %s to %s",
+	      zaxisNamePtr(zaxistype),
+	      zaxisNamePtr(ZAXIS_PRESSURE));
+      zaxistype = ZAXIS_PRESSURE;
+      zaxisChangeType(zaxisID, zaxistype);
+      zaxisDefUnits(zaxisID, "Pa");
+    }
+
+  ISEC2_NumVCP = 0;
+
+  switch (zaxistype)
+    {
+    case ZAXIS_SURFACE:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_SURFACE;
+	ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_CLOUD_BASE:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUD_BASE;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_CLOUD_TOP:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUD_TOP;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_ISOTHERM_ZERO:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_ISOTHERM0;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_TOA:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_TOA;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_SEA_BOTTOM:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_SEA_BOTTOM;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_ATMOSPHERE:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_ATMOSPHERE;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_MEANSEA:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_MEANSEA;
+	ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_HYBRID:
+    case ZAXIS_HYBRID_HALF:
+      {
+	int vctsize;
+
+	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID_LAYER;
+	    ISEC1_Level1    = (int) zaxisInqLbound(zaxisID, levelID);
+	    ISEC1_Level2    = (int) zaxisInqUbound(zaxisID, levelID);
+	  }
+	else
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID;
+	    ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
+	    ISEC1_Level2    = 0;
+	  }
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].zaxisID == UNDEFID )
-	{
-	  int with_bounds = FALSE;
-	  int zdimid = UNDEFID;
-	  int zvarid = UNDEFID;
-	  int zsize = 1;
-	  double *lbounds = NULL;
-	  double *ubounds = NULL;
-	  int zaxisType;
+	vctsize = zaxisInqVctSize(zaxisID);
+	if ( vctsize == 0 && lwarning )
+	  {
+	    Warning("VCT missing. ( param = %d, zaxisID = %d )", ISEC1_Parameter, zaxisID);
+	    lwarning = false;
+	  }
+	if ( vctsize > 255 )
+	  {
+	    ISEC2_NumVCP = 0;
+	    if ( lwarning_vct )
+	      {
+		Warning("VCT size of %d is too large (maximum is 255). Set to 0!", vctsize);
+		lwarning_vct = false;
+	      }
+	  }
+	else
+	  {
+	    ISEC2_NumVCP = vctsize;
+	    zaxisInqVct(zaxisID, &fsec2[10]);
+	  }
+	break;
+      }
+    case ZAXIS_PRESSURE:
+      {
+	double dum;
+	char units[128];
 
-          positive = 0;
+	level = zaxisInqLevel(zaxisID, levelID);
+	if ( level < 0 )
+	  Warning("Pressure level of %f Pa is below zero!", level);
 
-	  ndims = ncvars[ncvarid].ndims;
-	  for ( i = 0; i < ndims; i++ )
-	    {
-	      if ( ncvars[ncvarid].dimtype[i] == Z_AXIS )
-		zdimid = ncvars[ncvarid].dimids[i];
-	    }
+	zaxisInqUnits(zaxisID, units);
+	if ( memcmp(units, "Pa", 2) != 0 ) level *= 100;
 
-	  if ( zdimid != UNDEFID )
-	    {
-	      zvarid = ncdims[zdimid].ncvarid;
-	      zsize  = (int)ncdims[zdimid].len;
-	    }
+	ilevel = (int) level;
+	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_99;
+	    ISEC1_Level1    = ilevel;
+	    ISEC1_Level2    = 0;
+	  }
+	else
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_ISOBARIC;
+	    ISEC1_Level1    = ilevel/100;
+	    ISEC1_Level2    = 0;
+	  }
+	break;
+      }
+    case ZAXIS_HEIGHT:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-	  if ( CDI_Debug ) Message("nlevs = %d", zsize);
+	ilevel = (int) level;
+	ISEC1_LevelType = GRIB1_LTYPE_HEIGHT;
+	ISEC1_Level1    = ilevel;
+	ISEC1_Level2    = 0;
 
-	  double *zvar = (double *)xmalloc((size_t)zsize * sizeof (double));
+	break;
+      }
+    case ZAXIS_ALTITUDE:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-	  zaxisType = UNDEFID;
+	ilevel = (int) level;
+	ISEC1_LevelType = GRIB1_LTYPE_ALTITUDE;
+	ISEC1_Level1    = ilevel;
+	ISEC1_Level2    = 0;
 
-	  if ( zvarid != UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
+	break;
+      }
+    case ZAXIS_SIGMA:
+      {
+	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_SIGMA_LAYER;
+	    ISEC1_Level1    = (int) zaxisInqLbound(zaxisID, levelID);
+	    ISEC1_Level2    = (int) zaxisInqUbound(zaxisID, levelID);
+	  }
+	else
+	  {
+            level = zaxisInqLevel(zaxisID, levelID);
 
-	  if ( zaxisType == UNDEFID )  zaxisType = ZAXIS_GENERIC;
+            ilevel = (int) level;
+            ISEC1_LevelType = GRIB1_LTYPE_SIGMA;
+            ISEC1_Level1    = ilevel;
+            ISEC1_Level2    = 0;
+          }
 
-	  zprec = DATATYPE_FLT64;
+	break;
+      }
+    case ZAXIS_DEPTH_BELOW_LAND:
+      {
+	char units[128];
+	double factor;
 
-	  if ( zvarid != UNDEFID )
-	    {
-	      positive  = ncvars[zvarid].positive;
-	      pname     = ncvars[zvarid].name;
-	      plongname = ncvars[zvarid].longname;
-	      punits    = ncvars[zvarid].units;
-	      if ( ncvars[zvarid].xtype == NC_FLOAT ) zprec = DATATYPE_FLT32;
-	      /* don't change the name !!! */
-	      /*
-	      if ( (len = strlen(pname)) > 2 )
-		if ( pname[len-2] == '_' && isdigit((int) pname[len-1]) )
-		  pname[len-2] = 0;
-	      */
-	      cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
+	zaxisInqUnits(zaxisID, units);
 
-	      if ( ncvars[zvarid].bounds != UNDEFID )
-		{
-		  nbdims = ncvars[ncvars[zvarid].bounds].ndims;
-		  if ( nbdims == 2 )
-		    {
-		      nlevel  = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
-		      nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1]].len;
-		      if ( nlevel == zsize && nvertex == 2 )
-			{
-			  double *zbounds;
-			  with_bounds = TRUE;
-			  zbounds = (double *) malloc(2*(size_t)nlevel*sizeof(double));
-			  lbounds = (double *) malloc((size_t)nlevel*sizeof(double));
-			  ubounds = (double *) malloc((size_t)nlevel*sizeof(double));
-			  cdf_get_var_double(ncvars[zvarid].ncid, ncvars[zvarid].bounds, zbounds);
-			  for ( i = 0; i < nlevel; ++i )
-			    {
-			      lbounds[i] = zbounds[i*2];
-			      ubounds[i] = zbounds[i*2+1];
-			    }
-			  free(zbounds);
-			}
-		    }
-		}
-	    }
-	  else
-	    {
-	      pname     = NULL;
-	      plongname = NULL;
-	      punits    = NULL;
+        if      ( memcmp(units, "mm", 2) == 0 ) factor =   0.1;
+        else if ( memcmp(units, "cm", 2) == 0 ) factor =   1;
+        else if ( memcmp(units, "dm", 2) == 0 ) factor =  10;
+        else                                    factor = 100; // meter
 
-	      if ( zsize == 1 )
-		{
-                  if ( ncvars[ncvarid].zaxistype != UNDEFID )
-                    zaxisType = ncvars[ncvarid].zaxistype;
-                  else
-                    zaxisType = ZAXIS_SURFACE;
+	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	  {
+            double level1, level2;
+            level1 = zaxisInqLbound(zaxisID, levelID);
+            level2 = zaxisInqUbound(zaxisID, levelID);
+	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH_LAYER;
+	    ISEC1_Level1    = (int) (level1*factor);
+	    ISEC1_Level2    = (int) (level2*factor);
+	  }
+	else
+	  {
+	    level = zaxisInqLevel(zaxisID, levelID);
 
-		  zvar[0] = 0;
-		  /*
-		  if ( zdimid == UNDEFID )
-		    zvar[0] = 9999;
-		  else
-		    zvar[0] = 0;
-		  */
-		}
-	      else
-		{
-		  for ( ilev = 0; ilev < zsize; ilev++ ) zvar[ilev] = ilev + 1;
-		}
-	    }
+	    ilevel = (int) (level*factor);
+	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH;
+	    ISEC1_Level1    = ilevel;
+	    ISEC1_Level2    = 0;
+	  }
 
-      	  ncvars[ncvarid].zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, with_bounds, lbounds, ubounds,
-						(int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
+	break;
+      }
+    case ZAXIS_DEPTH_BELOW_SEA:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-	  if ( uuidOfVGrid[0] != 0 )
-            {
-              // printf("uuidOfVGrid: defined\n");
-              zaxisDefUUID(ncvars[ncvarid].zaxisID, uuidOfVGrid);
-            }
+	ilevel = (int) level;
+	ISEC1_LevelType = GRIB1_LTYPE_SEADEPTH;
+	ISEC1_Level1    = ilevel;
+	ISEC1_Level2    = 0;
 
-          if ( positive > 0 ) zaxisDefPositive(ncvars[ncvarid].zaxisID, positive);
+	break;
+      }
+    case ZAXIS_ISENTROPIC:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-	  free(zvar);
-	  free(lbounds);
-	  free(ubounds);
+	ilevel = (int) level;
+	ISEC1_LevelType = GRIB1_LTYPE_ISENTROPIC;
+	ISEC1_Level1    = ilevel;
+	ISEC1_Level2    = 0;
 
-	  zaxisindex = vlistZaxisIndex(vlistID, ncvars[ncvarid].zaxisID);
-	  streamptr->zaxisID[zaxisindex]  = zdimid;
+	break;
+      }
+    case ZAXIS_GENERIC:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-	  if ( CDI_Debug )
-	    Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
+	ilevel = (int) level;
+	ISEC1_LevelType = ltype;
+	ISEC1_Level1    = ilevel;
+	ISEC1_Level2    = 0;
 
-	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID )
-	      {
-		int zdimid2 = -1;
-		ndims = ncvars[ncvarid2].ndims;
-		for ( i = 0; i < ndims; i++ )
-		  {
-		    if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
-		      zdimid2 = ncvars[ncvarid2].dimids[i];
-		  }
-		if ( zdimid == zdimid2 )
-		  {
-		    if ( CDI_Debug )
-		      Message("zaxisID %d %d %s",
-			      ncvars[ncvarid].zaxisID, ncvarid2, ncvars[ncvarid2].name);
-		    ncvars[ncvarid2].zaxisID = ncvars[ncvarid].zaxisID;
-		  }
-	      }
-	}
+	break;
+      }
+    default:
+      {
+	Error("Unsupported zaxis type: %s", zaxisNamePtr(zaxistype));
+	break;
+      }
     }
 }
 
-struct varinfo
+static
+void cgribexDefaultSec0(int *isec0)
 {
-  int      ncvarid;
-  const char *name;
-};
+  ISEC0_GRIB_Len     = 0;
+  ISEC0_GRIB_Version = 0;
+}
 
 static
-int cmpvarname(const void *s1, const void *s2)
+void cgribexDefaultSec1(int *isec1)
 {
-  const struct varinfo *x = (const struct varinfo *)s1,
-    *y = (const struct varinfo *)s2;
-  return (strcmp(x->name, y->name));
+  ISEC1_CenterID    = 0;
+  ISEC1_SubCenterID = 0;
+  ISEC1_LocalFLag   = 0;
 }
 
-/* define all input data variables */
 static
-void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, int num_ncvars, ncvar_t *ncvars)
+void cgribexDefaultSec4(int *isec4)
 {
-  if ( streamptr->sortname )
-    {
-      struct varinfo *varInfo
-        = (struct varinfo *)xmalloc((size_t)nvars * sizeof (struct varinfo));
-
-      for ( int varID = 0; varID < nvars; varID++ )
-	{
-	  int ncvarid = varids[varID];
-	  varInfo[varID].ncvarid = ncvarid;
-	  varInfo[varID].name = ncvars[ncvarid].name;
-	}
-      qsort(varInfo, (size_t)nvars, sizeof(varInfo[0]), cmpvarname);
-      for ( int varID = 0; varID < nvars; varID++ )
-	{
-	  varids[varID] = varInfo[varID].ncvarid;
-	}
-      free(varInfo);
-    }
-
-  for ( int varID1 = 0; varID1 < nvars; varID1++ )
-    {
-      int gridID, zaxisID;
-
-      int ncvarid = varids[varID1];
-      gridID  = ncvars[ncvarid].gridID;
-      zaxisID = ncvars[ncvarid].zaxisID;
-
-      stream_new_var(streamptr, gridID, zaxisID);
-      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
-
-#if  defined  (HAVE_NETCDF4)
-      if ( ncvars[ncvarid].deflate )
-	vlistDefVarCompType(vlistID, varID, COMPRESS_ZIP);
-
-      if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != UNDEFID )
-        vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
-#endif
-
-      streamptr->vars[varID1].defmiss = 0;
-      streamptr->vars[varID1].ncvarid = ncvarid;
-
-      vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
-      if ( ncvars[ncvarid].param != UNDEFID ) vlistDefVarParam(vlistID, varID, ncvars[ncvarid].param);
-      if ( ncvars[ncvarid].code != UNDEFID )  vlistDefVarCode(vlistID, varID, ncvars[ncvarid].code);
-      if ( ncvars[ncvarid].code != UNDEFID )
-	{
-	  int param;
-	  param = cdiEncodeParam(ncvars[ncvarid].code, ncvars[ncvarid].tabnum, 255);
-	  vlistDefVarParam(vlistID, varID, param);
-	}
-      if ( ncvars[ncvarid].longname[0] )  vlistDefVarLongname(vlistID, varID, ncvars[ncvarid].longname);
-      if ( ncvars[ncvarid].stdname[0] )   vlistDefVarStdname(vlistID, varID, ncvars[ncvarid].stdname);
-      if ( ncvars[ncvarid].units[0] )     vlistDefVarUnits(vlistID, varID, ncvars[ncvarid].units);
-
-      if ( ncvars[ncvarid].lvalidrange )
-        vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
-
-      if ( IS_NOT_EQUAL(ncvars[ncvarid].addoffset, 0) )
-	vlistDefVarAddoffset(vlistID, varID, ncvars[ncvarid].addoffset);
-      if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
-	vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
-
-      vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
-
-      vlistDefVarInstitut(vlistID, varID, instID);
-      vlistDefVarModel(vlistID, varID, modelID);
-      if ( ncvars[ncvarid].tableID != UNDEFID )
-	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
-
-      if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
-        {
-          ncvars[ncvarid].deffillval = TRUE;
-          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
-        }
-
-      if ( ncvars[ncvarid].deffillval == TRUE )
-        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
-
-      if ( CDI_Debug )
-	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
-		vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
-
-      int gridindex = vlistGridIndex(vlistID, gridID);
-      int xdimid = streamptr->xdimID[gridindex];
-      int ydimid = streamptr->ydimID[gridindex];
+  long i;
 
-      int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-      int zdimid = streamptr->zaxisID[zaxisindex];
+  for ( i = 2; i <= 10; ++i ) isec4[i] = 0;
+}
 
-      int ndims = ncvars[ncvarid].ndims;
-      int iodim = 0;
-      int ixyz = 0;
-      int ipow10[4] = {1, 10, 100, 1000};
+static
+void cgribexDefEnsembleVar(int *isec1, int vlistID, int varID)
+{
+  int ensID, ensCount, forecast_type;
 
-      if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
+  /* For Ensemble info  */
 
-      if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
-        {
-          if ( xdimid == ncvars[ncvarid].dimids[ndims-1] )
-            {
-              ixyz = 321;
-            }
-          else
-            {
-              ixyz = 213;
-            }
-        }
-      else
-        {
-          for ( int idim = iodim; idim < ndims; idim++ )
-            {
-              if      ( xdimid == ncvars[ncvarid].dimids[idim] )
-                ixyz += 1*ipow10[ndims-idim-1];
-              else if ( ydimid == ncvars[ncvarid].dimids[idim] )
-                ixyz += 2*ipow10[ndims-idim-1];
-              else if ( zdimid == ncvars[ncvarid].dimids[idim] )
-                ixyz += 3*ipow10[ndims-idim-1];
-            }
-        }
+  //Put1Byte(isec1[36]);        /* MPIM local GRIB use definition identifier  */
+                                /*    (extension identifier)                  */
+  //Put1Byte(isec1[37]);        /* type of ensemble forecast                  */
+  //Put2Byte(isec1[38]);        /* individual ensemble member                 */
+  //Put2Byte(isec1[39]);        /* number of forecasts in ensemble            */
 
-      vlistDefVarXYZ(vlistID, varID, ixyz);
-      /*
-      printf("ixyz %d\n", ixyz);
-      printf("ndims %d\n", ncvars[ncvarid].ndims);
-      for ( int i = 0; i < ncvars[ncvarid].ndims; ++i )
-        printf("dimids: %d %d\n", i, ncvars[ncvarid].dimids[i]);
-      printf("xdimid, ydimid %d %d\n", xdimid, ydimid);
-      */
-      if ( ncvars[ncvarid].ensdata != NULL )
+  if ( vlistInqVarEnsemble(vlistID, varID, &ensID, &ensCount, &forecast_type) )
+    {
+      if ( ISEC1_CenterID == 252 )
         {
-          vlistDefVarEnsemble( vlistID, varID, ncvars[ncvarid].ensdata->ens_index,
-                               ncvars[ncvarid].ensdata->ens_count,
-                               ncvars[ncvarid].ensdata->forecast_init_type );
-          free(ncvars[ncvarid].ensdata);
-          ncvars[ncvarid].ensdata = NULL;
-        }
+          ISEC1_LocalFLag = 1;
+          isec1[36] = 1;
 
-      if ( ncvars[ncvarid].extra[0] != 0 )
-        {
-          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
+          isec1[37] =  forecast_type;
+          isec1[38] =  ensID;
+          isec1[39] =  ensCount;
         }
     }
+}
+#endif
 
-  for ( int varID = 0; varID < nvars; varID++ )
-    {
-      int ncvarid = varids[varID];
-      int ncid = ncvars[ncvarid].ncid;
-
-      if ( ncvars[ncvarid].natts )
-	{
-	  int attnum;
-	  int iatt;
-	  nc_type attrtype;
-	  size_t attlen;
-	  char attname[CDI_MAX_NAME];
-	  const int attstringlen = 8192; char attstring[8192];
-	  int nvatts = ncvars[ncvarid].natts;
-
-	  for ( iatt = 0; iatt < nvatts; iatt++ )
-	    {
-	      attnum = ncvars[ncvarid].atts[iatt];
-	      cdf_inq_attname(ncid, ncvarid, attnum, attname);
-	      cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
-	      cdf_inq_atttype(ncid, ncvarid, attname, &attrtype);
 
-	      if ( attrtype == NC_SHORT || attrtype == NC_INT )
-		{
-		  int *attint = (int *) malloc(attlen*sizeof(int));
-		  cdfGetAttInt(ncid, ncvarid, attname, (int)attlen, attint);
-		  if ( attrtype == NC_SHORT )
-		    vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT16, (int)attlen, attint);
-		  else
-		    vlistDefAttInt(vlistID, varID, attname, DATATYPE_INT32, (int)attlen, attint);
-		  free(attint);
-		}
-	      else if ( attrtype == NC_FLOAT || attrtype == NC_DOUBLE )
-		{
-		  double *attflt = (double *) malloc(attlen*sizeof(double));
-		  cdfGetAttDouble(ncid, ncvarid, attname, (int)attlen, attflt);
-		  if ( attrtype == NC_FLOAT )
-		    vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT32, (int)attlen, attflt);
-		  else
-		    vlistDefAttFlt(vlistID, varID, attname, DATATYPE_FLT64, (int)attlen, attflt);
-		  free(attflt);
-		}
-	      else if ( xtypeIsText(attrtype) )
-		{
-		  cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
-		  vlistDefAttTxt(vlistID, varID, attname, (int)attlen, attstring);
-		}
-	      else
-		{
-		  if ( CDI_Debug ) printf("att: %s.%s = unknown\n", ncvars[ncvarid].name, attname);
-		}
-	    }
+#if  defined  (HAVE_LIBCGRIBEX)
+size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
+		     int vdate, int vtime, int tsteptype, int numavg,
+		     long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize)
+{
+  size_t nbytes = 0;
+  int gribsize;
+  int iret = 0, iword = 0;
+  int isec0[2], isec1[4096], isec2[4096], isec3[2], isec4[512];
+  float fsec2f[512], fsec3f[2];
+  double fsec2[512], fsec3[2];
+  int datatype;
+  int param;
 
-	  free(ncvars[ncvarid].atts);
-          ncvars[ncvarid].atts = NULL;
-	}
-    }
+  memset(isec1, 0, 256*sizeof(int));
+  fsec2[0] = 0; fsec2[1] = 0;
+  fsec2f[0] = 0; fsec2f[1] = 0;
 
-  /* release mem of not freed attributes */
-  for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
-    if ( ncvars[ncvarid].atts ) free(ncvars[ncvarid].atts);
+  gribsize = (int)(gribbuffersize / sizeof(int));
+  param    = vlistInqVarParam(vlistID, varID);
 
-  if ( varids ) free(varids);
+  cgribexDefaultSec0(isec0);
+  cgribexDefaultSec1(isec1);
+  cgribexDefaultSec4(isec4);
 
-  for ( int varID = 0; varID < nvars; varID++ )
+  cgribexDefInstitut(isec1, vlistID, varID);
+  cgribexDefModel(isec1, vlistID, varID);
+
+  datatype = vlistInqVarDatatype(vlistID, varID);
+
+  cgribexDefParam(isec1, param);
+  cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
+  cgribexDefGrid(isec1, isec2, fsec2, isec4, gridID);
+  cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID);
+
+  cgribexDefEnsembleVar(isec1, vlistID, varID);
+
+  ISEC4_NumValues = gridInqSize(gridID);
+  ISEC4_NumBits   = grbBitsPerValue(datatype);
+
+  if ( nmiss > 0 )
     {
-      if ( vlistInqVarCode(vlistID, varID) == -varID-1 )
-	{
-	  const char *pname = vlistInqVarNamePtr(vlistID, varID);
-	  size_t len = strlen(pname);
-	  if ( len > 3 && isdigit((int) pname[3]) )
-	    {
-	      if ( memcmp("var", pname, 3) == 0 )
-		{
-		  vlistDefVarCode(vlistID, varID, atoi(pname+3));
-		  vlistDestroyVarName(vlistID, varID);
-		}
-	    }
-	  else if ( len > 4 && isdigit((int) pname[4]) )
-	    {
-	      if ( memcmp("code", pname, 4) == 0 )
-		{
-		  vlistDefVarCode(vlistID, varID, atoi(pname+4));
-		  vlistDestroyVarName(vlistID, varID);
-		}
-	    }
-	  else if ( len > 5 && isdigit((int) pname[5]) )
-	    {
-	      if ( memcmp("param", pname, 5) == 0 )
-		{
-		  int pnum = -1, pcat = 255, pdis = 255;
-		  sscanf(pname+5, "%d.%d.%d", &pnum, &pcat, &pdis);
-		  vlistDefVarParam(vlistID, varID, cdiEncodeParam(pnum, pcat, pdis));
-		  vlistDestroyVarName(vlistID, varID);
-		}
-	    }
-	}
+      FSEC3_MissVal = vlistInqVarMissval(vlistID, varID);
+      ISEC1_Sec2Or3Flag |= 64;
     }
 
-  for ( int varID = 0; varID < nvars; varID++ )
+  if ( isec4[2] == 128 && isec4[3] == 64 )
     {
-      int instID  = vlistInqVarInstitut(vlistID, varID);
-      int modelID = vlistInqVarModel(vlistID, varID);
-      int tableID = vlistInqVarTable(vlistID, varID);
-      int code = vlistInqVarCode(vlistID, varID);
-      if ( cdiDefaultTableID != UNDEFID )
-	{
-	  if ( tableInqParNamePtr(cdiDefaultTableID, code) )
-	    {
-	      vlistDestroyVarName(vlistID, varID);
-	      vlistDestroyVarLongname(vlistID, varID);
-	      vlistDestroyVarUnits(vlistID, varID);
-
-	      if ( tableID != UNDEFID )
-		{
-		  vlistDefVarName(vlistID, varID, tableInqParNamePtr(cdiDefaultTableID, code));
-		  if ( tableInqParLongnamePtr(cdiDefaultTableID, code) )
-		    vlistDefVarLongname(vlistID, varID, tableInqParLongnamePtr(cdiDefaultTableID, code));
-		  if ( tableInqParUnitsPtr(cdiDefaultTableID, code) )
-		    vlistDefVarUnits(vlistID, varID, tableInqParUnitsPtr(cdiDefaultTableID, code));
-		}
-	      else
-		{
-		  tableID = cdiDefaultTableID;
-		}
-	    }
+      isec4[16] = (int) (1000*calculate_pfactor(data, ISEC2_PentaJ, isec4[17]));
+      if ( isec4[16] < -10000 ) isec4[16] = -10000;
+      if ( isec4[16] >  10000 ) isec4[16] =  10000;
+    }
+  //printf("isec4[16] %d\n", isec4[16]);
 
-	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID  != UNDEFID ) instID  = cdiDefaultInstID;
-	}
-      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
-      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
-      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
+  if ( memtype == MEMTYPE_FLOAT )
+    {
+      size_t numVCP = ISEC2_NumVCP > 0 ? (size_t)ISEC2_NumVCP : (size_t)0;
+      for ( size_t i = 0; i < numVCP; ++i ) fsec2f[10+i] = (float)fsec2[10+i];
+      fsec3f[ 1] = (float)fsec3[ 1];
     }
+
+  if ( memtype == MEMTYPE_FLOAT )
+    gribExSP(isec0, isec1, isec2, fsec2f, isec3, fsec3f, isec4, (float*) data,
+             (int)datasize, (int *) gribbuffer, gribsize, &iword, "C", &iret);
+  else
+    gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, (double*) data,
+             (int)datasize, (int *) gribbuffer, gribsize, &iword, "C", &iret);
+
+  if ( iret ) Error("Problem during GRIB encode (errno = %d)!", iret);
+
+  nbytes = (size_t)iword * sizeof (int);
+  return (nbytes);
 }
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-static
-void scan_global_attributes(int fileID, int vlistID, stream_t *streamptr, int ngatts, int *instID, int *modelID, int *ucla_les, unsigned char *uuidOfHGrid, unsigned char *uuidOfVGrid, char *gridfile, int *number_of_grid_used)
-{
-  nc_type xtype;
-  size_t attlen;
-  char attname[CDI_MAX_NAME];
-  enum {
-    attstringlen = 8192,
-  };
-  char attstring[attstringlen];
-  int iatt;
+#include <stdio.h>
+#include <string.h>
 
-  for ( iatt = 0; iatt < ngatts; iatt++ )
-    {
-      cdf_inq_attname(fileID, NC_GLOBAL, iatt, attname);
-      cdf_inq_atttype(fileID, NC_GLOBAL, attname, &xtype);
-      cdf_inq_attlen(fileID, NC_GLOBAL, attname, &attlen);
 
-      if ( xtypeIsText(xtype) )
-	{
-	  cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen-1, attstring);
 
-          size_t attstrlen = strlen(attstring);
 
-	  if ( attlen > 0 && attstring[0] != 0 )
-	    {
-	      if ( strcmp(attname, "history") == 0 )
-		{
-		  streamptr->historyID = iatt;
-		}
-	      else if ( strcmp(attname, "institution") == 0 )
-		{
-		  *instID = institutInq(0, 0, NULL, attstring);
-		  if ( *instID == UNDEFID )
-		    *instID = institutDef(0, 0, NULL, attstring);
-		}
-	      else if ( strcmp(attname, "source") == 0 )
-		{
-		  *modelID = modelInq(-1, 0, attstring);
-		  if ( *modelID == UNDEFID )
-		    *modelID = modelDef(-1, 0, attstring);
-		}
-	      else if ( strcmp(attname, "Source") == 0 )
-		{
-		  if ( strncmp(attstring, "UCLA-LES", 8) == 0 )
-		    *ucla_les = TRUE;
-		}
-	      /*
-	      else if ( strcmp(attname, "Conventions") == 0 )
-		{
-		}
-	      */
-	      else if ( strcmp(attname, "CDI") == 0 )
-		{
-		}
-	      else if ( strcmp(attname, "CDO") == 0 )
-		{
-		}
-              /*
-	      else if ( strcmp(attname, "forecast_reference_time") == 0 )
-		{
-                  memcpy(fcreftime, attstring, attstrlen+1);
-		}
-              */
-	      else if ( strcmp(attname, "grid_file_uri") == 0 )
-		{
-                  memcpy(gridfile, attstring, attstrlen+1);
-		}
-	      else if ( strcmp(attname, "uuidOfHGrid") == 0 && attstrlen == 36 )
-		{
-                  attstring[36] = 0;
-                  str2uuid(attstring, uuidOfHGrid);
-                  //   printf("uuid: %d %s\n", attlen, attstring);
-		}
-	      else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
-		{
-                  attstring[36] = 0;
-                  str2uuid(attstring, uuidOfVGrid);
-		}
-	      else
-		{
-                  if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
-                    {
-                      memcpy(gridfile, attstring, attstrlen+1);
-                    }
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
 
-		  vlistDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attstrlen, attstring);
-		}
-	    }
-	}
-      else if ( xtype == NC_SHORT || xtype == NC_INT )
-	{
-	  if ( strcmp(attname, "number_of_grid_used") == 0 )
-	    {
-	      (*number_of_grid_used) = UNDEFID;
-	      cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
-	    }
- 	  else
-            {
-              int *attint;
-              attint = (int *) malloc(attlen*sizeof(int));
-              cdfGetAttInt(fileID, NC_GLOBAL, attname, (int)attlen, attint);
-              if ( xtype == NC_SHORT )
-                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
-              else
-                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
-              free(attint);
-            }
-        }
-      else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
-	{
-	  double *attflt;
-	  attflt = (double *) malloc(attlen*sizeof(double));
-	  cdfGetAttDouble(fileID, NC_GLOBAL, attname, (int)attlen, attflt);
-	  if ( xtype == NC_FLOAT )
-	    vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT32, (int)attlen, attflt);
-	  else
-	    vlistDefAttFlt(vlistID, CDI_GLOBAL, attname, DATATYPE_FLT64, (int)attlen, attflt);
-	  free(attflt);
-	}
-    }
-}
+#define SINGLE_PRECISION  4
+#define DOUBLE_PRECISION  8
+
+#if defined (HAVE_LIBEXTRA)
+
+
+typedef struct {
+  int param;
+  int level;
+} extcompvar_t;
 
 static
-int find_leadtime(int nvars, ncvar_t *ncvars)
+int extInqDatatype(int prec, int number)
 {
-  int leadtime_id = UNDEFID;
+  int datatype;
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( number == 2 )
     {
-      if ( ncvars[ncvarid].stdname[0] )
-        {
-          if ( strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
-            {
-              leadtime_id = ncvarid;
-              break;
-            }
-        }
+      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_CPX64;
+      else                            datatype = DATATYPE_CPX32;
+    }
+  else
+    {
+      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+      else                            datatype = DATATYPE_FLT32;
     }
 
-  return (leadtime_id);
+  return (datatype);
 }
 
 static
-void find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, stream_t *streamptr,
-                    int *time_has_units, int *time_has_bounds, int *time_climatology)
+void extDefDatatype(int datatype, int *prec, int *number)
 {
-  int ncvarid;
-
-  if ( timedimid == UNDEFID )
-    {
-      char timeunits[CDI_MAX_NAME];
 
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-        {
-          if ( ncvars[ncvarid].ndims == 0 && strcmp(ncvars[ncvarid].name, "time") == 0 )
-            {
-              if ( ncvars[ncvarid].units[0] )
-                {
-                  strcpy(timeunits, ncvars[ncvarid].units);
-                  strtolower(timeunits);
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 &&
+       datatype != DATATYPE_CPX32 && datatype != DATATYPE_CPX64 )
+    datatype = DATATYPE_FLT32;
 
-                  if ( isTimeUnits(timeunits) )
-                    {
-                      streamptr->basetime.ncvarid = ncvarid;
-                      break;
-                    }
-                }
-            }
-        }
-    }
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    *number = 2;
   else
-    {
-      int ltimevar = FALSE;
+    *number = 1;
 
-      if ( ncdims[timedimid].ncvarid != UNDEFID )
-        {
-          streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
-          ltimevar = TRUE;
-        }
+  if ( datatype == DATATYPE_FLT64 || datatype == DATATYPE_CPX64 )
+    *prec = DOUBLE_PRECISION;
+  else 
+    *prec = SINGLE_PRECISION;
+}
 
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-        if ( ncvarid != streamptr->basetime.ncvarid &&
-             ncvars[ncvarid].ndims == 1 &&
-             timedimid == ncvars[ncvarid].dimids[0] &&
-             !xtypeIsText(ncvars[ncvarid].xtype) &&
-             isTimeAxisUnits(ncvars[ncvarid].units) )
-          {
-            ncvars[ncvarid].isvar = FALSE;
+/* not used
+int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
+{
+  int status;
+  int fileID;
+  int icode, ilevel;
+  int zaxisID = -1;
+  int header[4];
+  int vlistID;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-            if ( !ltimevar )
-              {
-                streamptr->basetime.ncvarid = ncvarid;
-                ltimevar = TRUE;
-                if ( CDI_Debug )
-                  fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
-              }
-            else
-              {
-                Warning("Found more than one time variable, skipped variable %s!", ncvars[ncvarid].name);
-              }
-          }
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-      if ( ltimevar == FALSE ) /* search for WRF time description */
-        {
-          for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-            if ( ncvarid != streamptr->basetime.ncvarid &&
-                 ncvars[ncvarid].ndims == 2 &&
-                 timedimid == ncvars[ncvarid].dimids[0] &&
-                 !xtypeIsText(ncvars[ncvarid].xtype) &&
-                 ncdims[ncvars[ncvarid].dimids[1]].len == 19 )
-              {
-                streamptr->basetime.ncvarid = ncvarid;
-                streamptr->basetime.lwrf    = TRUE;
-                break;
-              }
-        }
+  *varID   = -1;
+  *levelID = -1;
 
-      /* time varID */
-      ncvarid = streamptr->basetime.ncvarid;
+  status = extRead(fileID, extp);
+  if ( status != 0 ) return (0);
 
-      if ( ncvarid == UNDEFID )
-        {
-          Warning("Time variable >%s< not found!", ncdims[timedimid].name);
-        }
-    }
+  extInqHeader(extp, header);
 
-  /* time varID */
-  ncvarid = streamptr->basetime.ncvarid;
+  icode  = header[1];
+  ilevel = header[2];
 
-  if ( ncvarid != UNDEFID && streamptr->basetime.lwrf == FALSE )
-    {
-      if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = TRUE;
+  *varID = vlistInqVarID(vlistID, icode);
 
-      if ( ncvars[ncvarid].bounds != UNDEFID )
-        {
-          int nbdims = ncvars[ncvars[ncvarid].bounds].ndims;
-          if ( nbdims == 2 )
-            {
-              int len = (int) ncdims[ncvars[ncvars[ncvarid].bounds].dimids[nbdims-1]].len;
-              if ( len == 2 && timedimid == ncvars[ncvars[ncvarid].bounds].dimids[0] )
-                {
-                  *time_has_bounds = TRUE;
-                  streamptr->basetime.ncvarboundsid = ncvars[ncvarid].bounds;
-                  if ( ncvars[ncvarid].climatology ) *time_climatology = TRUE;
-                }
-            }
-        }
-    }
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+
+  zaxisID = vlistInqVarZaxis(vlistID, *varID);
+
+  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
+
+  return (1);
 }
+*/
 
-int cdfInqContents(stream_t *streamptr)
+void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
-  int ndims, nvars, ngatts, unlimdimid;
-  int ncvarid;
-  int ncdimid;
-  size_t ntsteps;
-  int timedimid = -1;
-  int *varids;
-  int nvarids;
-  int time_has_units = FALSE;
-  int time_has_bounds = FALSE;
-  int time_climatology = FALSE;
-  int leadtime_id = UNDEFID;
-  int nvars_data;
-  int nvcth_id = UNDEFID, vcta_id = UNDEFID, vctb_id = UNDEFID;
-  size_t vctsize = 0;
-  double *vct = NULL;
-  int instID  = UNDEFID;
-  int modelID = UNDEFID;
-  int taxisID;
-  int i;
-  int calendar = UNDEFID;
-  ncdim_t *ncdims;
-  ncvar_t *ncvars = NULL;
-  int format = 0;
-  int ucla_les = FALSE;
-  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
-  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
-  char gridfile[8912];
-  char fcreftime[CDI_MAX_NAME];
-  int number_of_grid_used = UNDEFID;
+  int vlistID, fileID;
+  int status;
+  int recID, vrecID, tsID;
+  off_t recpos;
+  int header[4];
+  int varID, gridID;
+  int i, size;
+  double missval;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
-  memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
-  gridfile[0] = 0;
-  fcreftime[0] = 0;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+  tsID    = streamptr->curTsID;
+  vrecID  = streamptr->tsteps[tsID].curRecID;
+  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+  recpos  = streamptr->tsteps[tsID].records[recID].position;
+  varID   = streamptr->tsteps[tsID].records[recID].varID;
 
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  fileSetPos(fileID, recpos, SEEK_SET);
 
-  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+  status = extRead(fileID, extp);
+  if ( status != 0 )
+    Error("Failed to read EXTRA record");
 
-#if  defined  (HAVE_NETCDF4)
-  nc_inq_format(fileID, &format);
-#endif
+  extInqHeader(extp, header);
+  extInqDataDP(extp, data);
 
-  cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
 
-  if ( CDI_Debug )
-    Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
+  streamptr->numvals += size;
 
-  if ( ndims == 0 )
+  *nmiss = 0;
+  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
     {
-      Warning("ndims = %d", ndims);
-      return (CDI_EUFSTRUCT);
+      for ( i = 0; i < size; i++ )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
     }
+  else
+    {
+      for ( i = 0; i < 2*size; i+=2 )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
+    }
+}
 
-  /* alloc ncdims */
-  ncdims = (ncdim_t *)xmalloc((size_t)ndims * sizeof (ncdim_t));
-  init_ncdims(ndims, ncdims);
-
-  if ( nvars > 0 )
-    {
-      /* alloc ncvars */
-      ncvars = (ncvar_t *)xmalloc((size_t)nvars * sizeof (ncvar_t));
-      init_ncvars(nvars, ncvars);
 
-      for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
-        ncvars[ncvarid].ncid = fileID;
-    }
+void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+{
+  streamFCopyRecord(streamptr2, streamptr1, "EXTRA");
+}
 
-#if  defined  (TEST_GROUPS)
-#if  defined  (HAVE_NETCDF4)
-  if ( format == NC_FORMAT_NETCDF4 )
-    {
-      int ncid;
-      int numgrps;
-      int ncids[NC_MAX_VARS];
-      char name1[CDI_MAX_NAME];
-      int gndims, gnvars, gngatts, gunlimdimid;
-      nc_inq_grps(fileID, &numgrps, ncids);
-      for ( int i = 0; i < numgrps; ++i )
-        {
-          ncid = ncids[i];
-          nc_inq_grpname (ncid, name1);
-          cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
 
-          if ( CDI_Debug )
-            Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
+void extDefRecord(stream_t *streamptr)
+{
+  int gridID;
+  int header[4];
+  int pdis, pcat, pnum;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-          if ( gndims == 0 )
-            {
-            }
-        }
-    }
-#endif
-#endif
+  gridID   = streamptr->record->gridID;
 
-  if ( nvars == 0 )
-    {
-      Warning("nvars = %d", nvars);
-      return (CDI_EUFSTRUCT);
-    }
+  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
+  header[0] = streamptr->record->date;
+  header[1] = pnum;
+  header[2] = streamptr->record->level;
+  header[3] = gridInqSize(gridID);
 
-  /* scan global attributes */
-  scan_global_attributes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, 
-                         uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
+  extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
 
-  /* find time dim */
-  if ( unlimdimid >= 0 )
-    timedimid = unlimdimid;
-  else
-    timedimid = cdfTimeDimID(fileID, ndims, nvars);
+  extDefHeader(extp, header);
+}
 
-  streamptr->basetime.ncdimid = timedimid;
 
-  if ( timedimid != UNDEFID )
-    cdf_inq_dimlen(fileID, timedimid, &ntsteps);
-  else
-    ntsteps = 0;
+void extWriteRecord(stream_t *streamptr, const double *data)
+{
+  int fileID = streamptr->fileID;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  if ( CDI_Debug ) Message("Number of timesteps = %d", ntsteps);
-  if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
+  extDefDataDP(extp, data);
+  extWrite(fileID, extp);
+}
 
-  /* read ncdims */
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
-      cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name);
-      if ( timedimid == ncdimid )
-	ncdims[ncdimid].dimtype = T_AXIS;
-    }
+static
+void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
+		  size_t recsize, off_t position, int prec, int number)
+{
+  int leveltype;
+  int gridID = CDI_UNDEFID;
+  int levelID = 0;
+  int tsID, recID, varID;
+  record_t *record;
+  grid_t grid;
+  int vlistID;
 
-  if ( CDI_Debug ) printNCvars(ncvars, nvars, "cdfScanVarAttributes");
+  vlistID = streamptr->vlistID;
+  tsID    = streamptr->curTsID;
+  recID   = recordNewEntry(streamptr, tsID);
+  record  = &streamptr->tsteps[tsID].records[recID];
 
-  /* scan attributes of all variables */
-  cdfScanVarAttributes(nvars, ncvars, ncdims, timedimid, modelID, format);
+  (*record).size     = recsize;
+  (*record).position = position;
+  (*record).param     = param;
+  (*record).ilevel   = level;
 
+  memset(&grid, 0, sizeof(grid_t));
+  grid.type  = GRID_GENERIC;
+  grid.size  = xysize;
+  grid.xsize = xysize;
+  grid.ysize = 0;
+  grid.xvals = NULL;
+  grid.yvals = NULL;
+  gridID = varDefGrid(vlistID, &grid, 0);
+  /*
+  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
+  else              leveltype = ZAXIS_GENERIC;
+  */
+  leveltype = ZAXIS_GENERIC;
 
-  if ( CDI_Debug ) printNCvars(ncvars, nvars, "find coordinate vars");
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
+	       extInqDatatype(prec, number), &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
 
-  /* find coordinate vars */
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-	{
-	  if ( ncvars[ncvarid].ndims == 1 )
-	    {
-	      if ( timedimid != UNDEFID && timedimid == ncvars[ncvarid].dimids[0] )
-		{
-		  if ( ncvars[ncvarid].isvar != FALSE ) cdfSetVar(ncvars, ncvarid, TRUE);
-		}
-	      else
-		{
-                  //  if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
-		}
-	      // if ( ncvars[ncvarid].isvar != TRUE ) cdfSetVar(ncvars, ncvarid, FALSE);
+  (*record).varID   = (short)varID;
+  (*record).levelID = (short)levelID;
 
-	      if ( ncdimid == ncvars[ncvarid].dimids[0] && ncdims[ncdimid].ncvarid == UNDEFID )
-		if ( strcmp(ncvars[ncvarid].name, ncdims[ncdimid].name) == 0 )
-		  {
-		    ncdims[ncdimid].ncvarid = ncvarid;
-		    ncvars[ncvarid].isvar = FALSE;
-		  }
-	    }
-	}
-    }
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
 
-  /* find time vars */
-  find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
+  if ( CDI_Debug )
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
+}
 
-  leadtime_id = find_leadtime(nvars, ncvars);
-  if ( leadtime_id != UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
+static
+void extScanTimestep1(stream_t *streamptr)
+{
+  int header[4];
+  int status;
+  int fileID;
+  int rxysize = 0;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int tsID;
+  int varID;
+  long recsize;
+  off_t recpos;
+  int nrecords, nrecs, recID;
+  int taxisID = -1;
+  taxis_t *taxis;
+  int vlistID;
+  extcompvar_t compVar, compVar0;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  /* check ncvars */
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( timedimid != UNDEFID )
-	if ( ncvars[ncvarid].isvar == -1 &&
-	     ncvars[ncvarid].ndims > 1   &&
-	     timedimid == ncvars[ncvarid].dimids[0] )
-	  cdfSetVar(ncvars, ncvarid, TRUE);
+  streamptr->curTsID = 0;
 
-      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
-	cdfSetVar(ncvars, ncvarid, FALSE);
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-      //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
-      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
-	cdfSetVar(ncvars, ncvarid, TRUE);
+  if ( tsID != 0 )
+    Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-      if ( ncvars[ncvarid].isvar == -1 )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
-	  continue;
-	}
+  fileID = streamptr->fileID;
 
-      if ( ncvars[ncvarid].ndims > 4 )
+  nrecs = 0;
+  while ( TRUE )
+    {
+      recpos = fileGetPos(fileID);
+      status = extRead(fileID, extp);
+      if ( status != 0 )
 	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("%d dimensional variables are not supported, skipped variable %s!",
-		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
-	  continue;
+	  streamptr->ntsteps = 1;
+	  break;
 	}
+      recsize = fileGetPos(fileID) - recpos;
 
-      if ( ncvars[ncvarid].ndims == 4 && timedimid == UNDEFID )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
-		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
-	  continue;
-	}
+      extInqHeader(extp, header);
 
-      if ( xtypeIsText(ncvars[ncvarid].xtype) )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  continue;
-	}
+      vdate   = header[0];
+      vtime   = 0;
+      rcode   = header[1];
+      rlevel  = header[2];
+      rxysize = header[3];
 
-      if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
+      param = cdiEncodeParam(rcode, 255, 255);
+
+      if ( nrecs == 0 )
 	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("Variable %s has an unsupported data type, skipped!", ncvars[ncvarid].name);
-	  continue;
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
 	}
-
-      if ( timedimid != UNDEFID && ntsteps == 0 && ncvars[ncvarid].ndims > 0 )
+      else
 	{
-	  if ( timedimid == ncvars[ncvarid].dimids[0] )
+	  datetime.date = vdate;
+	  datetime.time = vtime;
+	  compVar.param = param;
+          compVar.level = rlevel;
+	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
-	      ncvars[ncvarid].isvar = 0;
-	      Warning("Number of time steps undefined, skipped variable %s!", ncvars[ncvarid].name);
-	      continue;
+	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
+	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
+
+	      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 ) break;
 	    }
+	  if ( recID < nrecs ) break;
+	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
+	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
 	}
+
+      nrecs++;
+
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
+
+      extAddRecord(streamptr, param, rlevel, rxysize, (size_t)recsize, recpos, extp->prec, extp->number);
     }
 
-  /* verify coordinate vars - first scan (dimname == varname) */
-  verify_coordinate_vars_1(ndims, ncdims, ncvars, timedimid);
+  streamptr->rtsteps = 1;
 
-  /* verify coordinate vars - second scan (all other variables) */
-  verify_coordinate_vars_2(nvars, ncvars);
+  cdi_generate_vars(streamptr);
 
-  if ( CDI_Debug ) printNCvars(ncvars, nvars, "verify_coordinate_vars");
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  taxis->type  = TAXIS_ABSOLUTE;
+  taxis->vdate = (int)datetime0.date;
+  taxis->vtime = (int)datetime0.time;
 
-  if ( ucla_les == TRUE )
+  vlistID = streamptr->vlistID;
+  vlistDefTaxis(vlistID, taxisID);
+
+  vlist_check_contents(vlistID);
+
+  nrecords = streamptr->tsteps[0].nallrecs;
+  if ( nrecords < streamptr->tsteps[0].recordSize )
     {
-      for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-	{
-	  ncvarid = ncdims[ncdimid].ncvarid;
-	  if ( ncvarid != -1 )
-	    {
-	      if ( ncdims[ncdimid].dimtype == UNDEFID && ncvars[ncvarid].units[0] == 'm' )
-		{
-		  if      ( ncvars[ncvarid].name[0] == 'x' ) ncdims[ncdimid].dimtype = X_AXIS;
-		  else if ( ncvars[ncvarid].name[0] == 'y' ) ncdims[ncdimid].dimtype = Y_AXIS;
-		  else if ( ncvars[ncvarid].name[0] == 'z' ) ncdims[ncdimid].dimtype = Z_AXIS;
-		}
-	    }
-	}
+      streamptr->tsteps[0].recordSize = nrecords;
+      streamptr->tsteps[0].records =
+        (record_t *)xrealloc(streamptr->tsteps[0].records, (size_t)nrecords * sizeof (record_t));
     }
-  /*
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      ncvarid = ncdims[ncdimid].ncvarid;
-      if ( ncvarid != -1 )
-	{
-	  printf("coord var %d %s %s\n", ncvarid, ncvars[ncvarid].name, ncvars[ncvarid].units);
-	  if ( ncdims[ncdimid].dimtype == X_AXIS )
-	    printf("coord var %d %s is x dim\n", ncvarid, ncvars[ncvarid].name);
-	  if ( ncdims[ncdimid].dimtype == Y_AXIS )
-	    printf("coord var %d %s is y dim\n", ncvarid, ncvars[ncvarid].name);
-	  if ( ncdims[ncdimid].dimtype == Z_AXIS )
-	    printf("coord var %d %s is z dim\n", ncvarid, ncvars[ncvarid].name);
-	  if ( ncdims[ncdimid].dimtype == T_AXIS )
-	    printf("coord var %d %s is t dim\n", ncvarid, ncvars[ncvarid].name);
 
-	  if ( ncvars[ncvarid].islon )
-	    printf("coord var %d %s is lon\n", ncvarid, ncvars[ncvarid].name);
-	  if ( ncvars[ncvarid].islat )
-	    printf("coord var %d %s is lat\n", ncvarid, ncvars[ncvarid].name);
-	  if ( ncvars[ncvarid].islev )
-	    printf("coord var %d %s is lev\n", ncvarid, ncvars[ncvarid].name);
-	}
-    }
-  */
+  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
+  streamptr->tsteps[0].nrecs = nrecords;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[0].recIDs[recID] = recID;
 
-  /* Set coordinate varids (att: associate)  */
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( streamptr->ntsteps == -1 )
     {
-      if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].ncoordvars )
-	{
-	  /* ndims = ncvars[ncvarid].ndims; */
-	  ndims = ncvars[ncvarid].ncoordvars;
-	  for ( i = 0; i < ndims; i++ )
-	    {
-	      if ( ncvars[ncvars[ncvarid].coordvarids[i]].islon )
-		ncvars[ncvarid].xvarid = ncvars[ncvarid].coordvarids[i];
-	      else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islat )
-		ncvars[ncvarid].yvarid = ncvars[ncvarid].coordvarids[i];
-	      else if ( ncvars[ncvars[ncvarid].coordvarids[i]].islev )
-		ncvars[ncvarid].zvarid = ncvars[ncvarid].coordvarids[i];
-	    }
-	}
-    }
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-  /* set dim type */
-  setDimType(nvars, ncvars, ncdims);
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
+    }
 
-  /* find VCT */
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( streamptr->ntsteps == 1 )
     {
-      if ( ncvars[ncvarid].ndims == 1 )
+      if ( taxis->vdate == 0 && taxis->vtime == 0 )
 	{
-	  if ( memcmp(ncvars[ncvarid].name, "hyai", 4) == 0 )
-	    {
-	      vcta_id = ncvarid;
-	      nvcth_id = ncvars[ncvarid].dimids[0];
-              ncvars[ncvarid].isvar = FALSE;
-	      continue;
-	    }
-	  if ( memcmp(ncvars[ncvarid].name, "hybi", 4) == 0 )
+	  streamptr->ntsteps = 0;
+	  for ( varID = 0; varID < streamptr->nvars; varID++ )
 	    {
-	      vctb_id = ncvarid;
-	      nvcth_id = ncvars[ncvarid].dimids[0];
-              ncvars[ncvarid].isvar = FALSE;
-	      continue;
+	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	    }
-
-	  if      ( memcmp(ncvars[ncvarid].name, "hyam", 4) == 0 ) ncvars[ncvarid].isvar = FALSE;
-	  else if ( memcmp(ncvars[ncvarid].name, "hybm", 4) == 0 ) ncvars[ncvarid].isvar = FALSE;
 	}
     }
+}
 
-  if ( CDI_Debug ) printNCvars(ncvars, nvars, "define_all_grids");
-
-
-  /* define all grids */
-  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
-
-
-  /* read VCT */
-  if ( nvcth_id != UNDEFID && vcta_id != UNDEFID && vctb_id != UNDEFID )
-    {
-      vctsize = ncdims[nvcth_id].len;
-      vctsize *= 2;
-      vct = (double *) malloc(vctsize*sizeof(double));
-      cdf_get_var_double(fileID, vcta_id, vct);
-      cdf_get_var_double(fileID, vctb_id, vct+vctsize/2);
-    }
-
+static
+int extScanTimestep2(stream_t *streamptr)
+{
+  int header[4];
+  int status;
+  int fileID;
+  // int rxysize = 0;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  int tsID;
+  int varID;
+  off_t recpos = 0;
+  int nrecords, nrecs, recID, rindex;
+  int nextstep;
+  taxis_t *taxis;
+  int vlistID;
+  extcompvar_t compVar, compVar0;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  /* define all zaxes */
-  define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
+  streamptr->curTsID = 1;
 
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
 
-  if ( vct ) free(vct);
+  tsID = streamptr->rtsteps;
+  if ( tsID != 1 )
+    Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  /* select vars */
-  varids = (int *)xmalloc((size_t)nvars * sizeof (int));
-  nvarids = 0;
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-  nvars_data = nvarids;
+  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  if ( CDI_Debug ) Message("time varid = %d", streamptr->basetime.ncvarid);
-  if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
-  if ( CDI_Debug ) Message("nvars_data = %d", nvars_data);
+  cdi_create_records(streamptr, tsID);
 
+  nrecords = streamptr->tsteps[0].nallrecs;
+  streamptr->tsteps[1].recIDs = xmalloc((size_t)nrecords * sizeof (int));
+  streamptr->tsteps[1].nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[1].recIDs[recID] = -1;
 
-  if ( nvars_data == 0 )
+  for ( recID = 0; recID < nrecords; recID++ )
     {
-      streamptr->ntsteps = 0;
-      return (CDI_EUFSTRUCT);
+      varID = streamptr->tsteps[0].records[recID].varID;
+      streamptr->tsteps[tsID].records[recID].position =
+	streamptr->tsteps[0].records[recID].position;
+      streamptr->tsteps[tsID].records[recID].size     =
+	streamptr->tsteps[0].records[recID].size;
     }
 
-  if ( ntsteps == 0 && streamptr->basetime.ncdimid == UNDEFID && streamptr->basetime.ncvarid != UNDEFID )
-    ntsteps = 1;
-
-  streamptr->ntsteps = (long)ntsteps;
-
-  /* define all data variables */
-  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
-
-
-  cdiCreateTimesteps(streamptr);
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
+    {
+      recpos = fileGetPos(fileID);
+      status = extRead(fileID, extp);
+      if ( status != 0 )
+	{
+	  streamptr->ntsteps = 2;
+	  break;
+	}
+      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-  /* time varID */
-  ncvarid = streamptr->basetime.ncvarid;
+      extInqHeader(extp, header);
 
-  if ( time_has_units )
-    {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+      vdate  = header[0];
+      vtime  = 0;
+      rcode  = header[1];
+      rlevel = header[2];
+      // rxysize = header[3];
 
-      if ( setBaseTime(ncvars[ncvarid].units, taxis) == 1 )
-        {
-          ncvarid = UNDEFID;
-          streamptr->basetime.ncvarid = UNDEFID;
-        }
+      param = cdiEncodeParam(rcode, 255, 255);
 
-      if ( leadtime_id != UNDEFID && taxis->type == TAXIS_RELATIVE )
-        {
-          streamptr->basetime.leadtimeid = leadtime_id;
-          taxis->type = TAXIS_FORECAST;
+      if ( rindex == 0 )
+	{
+	  taxis->type  = TAXIS_ABSOLUTE;
+	  taxis->vdate = vdate;
+	  taxis->vtime = vtime;
+	}
 
-          int timeunit = -1;
-          if ( ncvars[leadtime_id].units[0] != 0 ) timeunit = scanTimeUnit(ncvars[leadtime_id].units);
-          if ( timeunit == -1 ) timeunit = taxis->unit;
-          taxis->fc_unit = timeunit;
+      compVar.param = param;
+      compVar.level = rlevel;
+      nextstep = FALSE;
+      for ( recID = 0; recID < nrecords; recID++ )
+	{
+	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-          setForecastTime(fcreftime, taxis);
-        }
-    }
+	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) == 0 )
+	    {
+	      if ( streamptr->tsteps[tsID].records[recID].used )
+		{
+		  nextstep = TRUE;
+		}
+	      else
+		{
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
+		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
+		}
+	      break;
+	    }
+	}
+      if ( recID == nrecords )
+	{
+	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
+	  return (CDI_EUFSTRUCT);
+	}
 
-  if ( time_has_bounds )
-    {
-      streamptr->tsteps[0].taxis.has_bounds = TRUE;
-      if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = TRUE;
-    }
+      if ( nextstep ) break;
 
-  if ( ncvarid != UNDEFID )
-    {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
-      ptaxisDefName(taxis, ncvars[ncvarid].name);
-      if ( ncvars[ncvarid].longname[0] )
-        ptaxisDefLongname(taxis, ncvars[ncvarid].longname);
-    }
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);
 
-  if ( ncvarid != UNDEFID )
-    if ( ncvars[ncvarid].calendar == TRUE )
-      {
-        enum {
-          attstringlen = 8192,
-        };
-        char attstring[attstringlen];
+      streamptr->tsteps[tsID].records[recID].size = recsize;
 
-	cdfGetAttText(fileID, ncvarid, "calendar", attstringlen-1, attstring);
-	strtolower(attstring);
+      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
+      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-	if ( memcmp(attstring, "standard", 8)  == 0 ||
-	     memcmp(attstring, "gregorian", 9) == 0 )
-	  calendar = CALENDAR_STANDARD;
-	else if ( memcmp(attstring, "none", 4) == 0 )
-	  calendar = CALENDAR_NONE;
-	else if ( memcmp(attstring, "proleptic", 9) == 0 )
-	  calendar = CALENDAR_PROLEPTIC;
-	else if ( memcmp(attstring, "360", 3) == 0 )
-	  calendar = CALENDAR_360DAYS;
-	else if ( memcmp(attstring, "365", 3) == 0 ||
-		  memcmp(attstring, "noleap", 6)  == 0 )
-	  calendar = CALENDAR_365DAYS;
-	else if ( memcmp(attstring, "366", 3)  == 0 ||
-		  memcmp(attstring, "all_leap", 8) == 0 )
-	  calendar = CALENDAR_366DAYS;
-	else
-	  Warning("calendar >%s< unsupported!", attstring);
-      }
+      if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
+	{
+	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		  tsID, recID,
+		  streamptr->tsteps[tsID].records[recID].param, param,
+		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	  return (CDI_EUFSTRUCT);
+	}
 
-  if ( streamptr->tsteps[0].taxis.type == TAXIS_FORECAST )
-    {
-      taxisID = taxisCreate(TAXIS_FORECAST);
-    }
-  else if ( streamptr->tsteps[0].taxis.type == TAXIS_RELATIVE )
-    {
-      taxisID = taxisCreate(TAXIS_RELATIVE);
+      streamptr->tsteps[1].records[recID].position = recpos;
     }
-  else
+
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
     {
-      taxisID = taxisCreate(TAXIS_ABSOLUTE);
-      if ( !time_has_units )
+      if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	  taxisDefTunit(taxisID, TUNIT_DAY);
-	  streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
+          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	}
+      else
+	{
+	  nrecs++;
 	}
     }
+  streamptr->tsteps[tsID].nrecs = nrecs;
 
+  streamptr->rtsteps = 2;
 
-  if ( calendar == UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
+  if ( streamptr->ntsteps == -1 )
     {
-      calendar = CALENDAR_STANDARD;
-    }
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-  if ( calendar != UNDEFID )
-    {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
-      taxis->calendar = calendar;
-      taxisDefCalendar(taxisID, calendar);
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
     }
 
-  vlistDefTaxis(vlistID, taxisID);
+  return (0);
+}
 
-  streamptr->curTsID = 0;
-  streamptr->rtsteps = 1;
 
-  (void) cdfInqTimestep(streamptr, 0);
+int extInqContents(stream_t *streamptr)
+{
+  int fileID;
+  int status = 0;
 
-  cdfCreateRecords(streamptr, 0);
+  fileID = streamptr->fileID;
 
-  /* free ncdims */
-  free(ncdims);
+  streamptr->curTsID = 0;
 
-  /* free ncvars */
-  free(ncvars);
+  extScanTimestep1(streamptr);
 
-  return (0);
-}
+  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
 
-static
-void wrf_read_timestep(int fileID, int nctimevarid, int tsID, taxis_t *taxis)
-{
-  size_t start[2], count[2];
-  char stvalue[32];
-  start[0] = (size_t) tsID; start[1] = 0;
-  count[0] = 1; count[1] = 19;
-  stvalue[0] = 0;
-  cdf_get_vara_text(fileID, nctimevarid, start, count, stvalue);
-  stvalue[19] = 0;
-  {
-    int year = 1, month = 1, day = 1 , hour = 0, minute = 0, second = 0;
-    if ( strlen(stvalue) == 19 )
-      sscanf(stvalue, "%d-%d-%d_%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
-    taxis->vdate = cdiEncodeDate(year, month, day);
-    taxis->vtime = cdiEncodeTime(hour, minute, second);
-    taxis->type = TAXIS_ABSOLUTE;
-  }
+  fileSetPos(fileID, 0, SEEK_SET);
+
+  return (status);
 }
 
 static
-double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
+long extScanTimestep(stream_t *streamptr)
 {
-  double timevalue = 0;
-  size_t index = (size_t) tsID;
-
-  if ( tcache )
+  int header[4];
+  int status;
+  int fileID;
+  // int rxysize = 0;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  off_t recpos = 0;
+  int recID;
+  int rindex, nrecs = 0;
+  extcompvar_t compVar, compVar0;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
+  /*
+  if ( CDI_Debug )
     {
-      if ( tcache->size == 0 || (tsID < tcache->startid || tsID > (tcache->startid+tcache->size-1)) )
-        {
-          int maxvals = MAX_TIMECACHE_SIZE;
-          tcache->startid = (tsID/MAX_TIMECACHE_SIZE)*MAX_TIMECACHE_SIZE;
-          if ( (tcache->startid + maxvals) > tcache->maxvals ) maxvals = (tcache->maxvals)%MAX_TIMECACHE_SIZE;
-          tcache->size = maxvals;
-          index = (size_t) tcache->startid;
-          // fprintf(stderr, "fill time cache: %d %d %d %d %d\n", tcache->maxvals, tsID, tcache->startid, tcache->startid+maxvals-1, maxvals);
-          for ( int ival = 0; ival < maxvals; ++ival )
-            {
-              cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
-              tcache->cache[ival] = timevalue;
-              index++;
-            }
-        }
-
-      timevalue = tcache->cache[tsID%MAX_TIMECACHE_SIZE];
+      Message("streamID = %d", streamptr->self);
+      Message("cts = %d", streamptr->curTsID);
+      Message("rts = %d", streamptr->rtsteps);
+      Message("nts = %d", streamptr->ntsteps);
     }
-  else
+  */
+
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+
+  if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-      if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
-    }
+      cdi_create_records(streamptr, tsID);
 
-  return timevalue;
-}
+      nrecs = streamptr->tsteps[1].nrecs;
 
-int cdfInqTimestep(stream_t * streamptr, int tsID)
-{
-  long nrecs = 0;
-  double timevalue;
-  int fileID;
-  taxis_t *taxis;
+      streamptr->tsteps[tsID].nrecs = nrecs;
+      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
+      for ( recID = 0; recID < nrecs; recID++ )
+	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
+      fileID = streamptr->fileID;
 
-  if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
-    {
-      cdfCreateRecords(streamptr, tsID);
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
+	{
+	  recpos = fileGetPos(fileID);
+	  status = extRead(fileID, extp);
+	  if ( status != 0 )
+	    {
+	      streamptr->ntsteps = streamptr->rtsteps + 1;
+	      break;
+	    }
+	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-      taxis = &streamptr->tsteps[tsID].taxis;
-      if ( tsID > 0 )
-	ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
+	  extInqHeader(extp, header);
 
-      timevalue = tsID;
+	  vdate  = header[0];
+	  vtime  = 0;
+	  rcode  = header[1];
+	  rlevel = header[2];
+	  // rxysize = header[3];
 
-      int nctimevarid = streamptr->basetime.ncvarid;
-      if ( nctimevarid != UNDEFID )
-	{
-	  fileID = streamptr->fileID;
-	  size_t index  = (size_t)tsID;
+	  param = cdiEncodeParam(rcode, 255, 255);
 
-	  if ( streamptr->basetime.lwrf )
+	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
+	  if ( rindex == nrecs ) continue;
+	  recID = streamptr->tsteps[tsID].recIDs[rindex];
+
+	  if ( rindex == 0 )
 	    {
-              wrf_read_timestep(fileID, nctimevarid, tsID, taxis);
+	      taxis->type  = TAXIS_ABSOLUTE;
+	      taxis->vdate = vdate;
+	      taxis->vtime = vtime;
 	    }
-	  else
+
+	  compVar.param  = param;
+          compVar.level  = rlevel;
+	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+
+	  if ( memcmp(&compVar0, &compVar, sizeof(extcompvar_t)) != 0 )
 	    {
-#if defined (USE_TIMECACHE)
-              if ( streamptr->basetime.timevar_cache == NULL )
-                {
-                  streamptr->basetime.timevar_cache = (timecache_t *) malloc(MAX_TIMECACHE_SIZE*sizeof(timecache_t));
-                  streamptr->basetime.timevar_cache->size = 0;
-                  streamptr->basetime.timevar_cache->maxvals = streamptr->ntsteps;
-                }
-#endif
-              timevalue = get_timevalue(fileID, nctimevarid, tsID, streamptr->basetime.timevar_cache);
-	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
+	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		      tsID, recID,
+		      streamptr->tsteps[tsID].records[recID].param, param,
+		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	      Error("Invalid, unsupported or inconsistent record structure!");
 	    }
 
-	  int nctimeboundsid = streamptr->basetime.ncvarboundsid;
-	  if ( nctimeboundsid != UNDEFID )
-	    {
-	      size_t start[2], count[2];
-              start[0] = index; count[0] = 1; start[1] = 0; count[1] = 1;
-	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+	  streamptr->tsteps[tsID].records[recID].position = recpos;
+	  streamptr->tsteps[tsID].records[recID].size = recsize;
 
-	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
+	  if ( CDI_Debug )
+	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
+	}
 
-              start[0] = index; count[0] = 1; start[1] = 1; count[1] = 1;
-	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+      streamptr->rtsteps++;
 
-	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
-	    }
+      if ( streamptr->ntsteps != streamptr->rtsteps )
+	{
+	  tsID = tstepsNewEntry(streamptr);
+	  if ( tsID != streamptr->rtsteps )
+	    Error("Internal error. tsID = %d", tsID);
 
-          int leadtimeid = streamptr->basetime.leadtimeid;
-          if ( leadtimeid != UNDEFID )
-            {
-              timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
-              cdiSetForecastPeriod(timevalue, taxis);
-            }
+	  streamptr->tsteps[tsID-1].next   = 1;
+	  streamptr->tsteps[tsID].position = recpos;
 	}
+
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      streamptr->tsteps[tsID].position = recpos;
     }
 
-  streamptr->curTsID = tsID;
-  nrecs = streamptr->tsteps[tsID].nrecs;
+  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+    {
+      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
+      streamptr->ntsteps = tsID;
+    }
 
-  return ((int) nrecs);
+  return (streamptr->ntsteps);
 }
 
 
-void cdfEndDef(stream_t *streamptr)
+int extInqTimestep(stream_t *streamptr, int tsID)
 {
-  int varID;
-  int nvars;
-  int fileID;
-
-  fileID  = streamptr->fileID;
-
-  cdfDefGlobalAtts(streamptr);
-  cdfDefLocalAtts(streamptr);
-
-  if ( streamptr->accessmode == 0 )
-    {
-      nvars =  streamptr->nvars;
-
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+  int nrecs;
+  long ntsteps;
 
-      for ( varID = 0; varID < nvars; varID++ )
-	cdfDefVar(streamptr, varID);
+  if ( tsID == 0 && streamptr->rtsteps == 0 )
+    Error("Call to cdiInqContents missing!");
 
-      if ( streamptr->ncmode == 2 )
-        {
-          extern size_t CDI_netcdf_hdr_pad;
+  if ( CDI_Debug )
+    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-          if ( CDI_netcdf_hdr_pad == 0UL )
-            cdf_enddef(fileID);
-          else
-            cdf__enddef(fileID, CDI_netcdf_hdr_pad);
-        }
+  ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+    ntsteps = extScanTimestep(streamptr);
 
-      streamptr->accessmode = 1;
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
+    {
+      streamptr->curTsID = tsID;
+      nrecs = streamptr->tsteps[tsID].nrecs;
     }
+
+  return (nrecs);
 }
 
 
-static void cdfDefInstitut(stream_t *streamptr)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  int fileID, instID;
-  char *longname;
-  size_t len;
-  int vlistID;
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[4];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  vlistID = streamptr->vlistID;
-  fileID  = streamptr->fileID;
-  instID  = vlistInqInstitut(vlistID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  if ( instID != UNDEFID )
-    {
-      longname = institutInqLongnamePtr(instID);
-      if ( longname )
-	{
-	  len = strlen(longname);
-	  if ( len > 0 )
-	    {
-	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-	      cdf_put_att_text(fileID, NC_GLOBAL, "institution", len, longname);
-	      if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
-	    }
-	}
-    }
-}
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
+  currentfilepos = fileGetPos(fileID);
 
-static void cdfDefSource(stream_t *streamptr)
-{
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-  int modelID = vlistInqModel(vlistID);
+  for (levID = 0; levID < nlevs; levID++)
+    {
+      recID = streamptr->vars[varID].level[levID];
+      recpos = streamptr->tsteps[tsid].records[recID].position;
+      fileSetPos(fileID, recpos, SEEK_SET);
+      extRead(fileID, extp);
+      extInqHeader(extp, header);
+      extInqDataDP(extp, &data[levID*gridsize]);
+    }
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  if ( modelID != UNDEFID )
+  *nmiss = 0;
+  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
     {
-      const char *longname = modelInqNamePtr(modelID);
-      if ( longname )
-	{
-          size_t len = strlen(longname);
-	  if ( len > 0 )
-	    {
-	      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-	      cdf_put_att_text(fileID, NC_GLOBAL, "source", len, longname);
-	      if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
-	    }
-	}
+      for ( i = 0; i < nlevs*gridsize; i++ )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
+    }
+  else
+    {
+      for ( i = 0; i < 2*nlevs*gridsize; i+=2 )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
     }
 }
 
 
-static void cdfDefGlobalAtts(stream_t *streamptr)
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
-  int natts;
-
-  if ( streamptr->globalatts ) return;
-
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  int vlistID, fileID;
+  int nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[4];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  cdfDefSource(streamptr);
-  cdfDefInstitut(streamptr);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
 
-  if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
+  currentfilepos = fileGetPos(fileID);
 
-  defineAttributes(vlistID, CDI_GLOBAL, fileID, NC_GLOBAL);
+  recID = streamptr->vars[varID].level[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
+  fileSetPos(fileID, recpos, SEEK_SET);
+  extRead(fileID, extp);
+  extInqHeader(extp, header);
+  extInqDataDP(extp, data);
 
-  if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  streamptr->globalatts = 1;
+  *nmiss = 0;
+  if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
+    {
+      for ( i = 0; i < gridsize; i++ )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
+    }
+  else
+    {
+      for ( i = 0; i < 2*gridsize; i+=2 )
+	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+	  {
+	    data[i] = missval;
+	    (*nmiss)++;
+	  }
+    }
 }
 
 
-static void cdfDefLocalAtts(stream_t *streamptr)
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
-
-  if ( streamptr->localatts ) return;
-  if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
-
-  streamptr->localatts = 1;
+  int fileID;
+  int levID, nlevs, gridID, gridsize;
+  int zaxisID;
+  double level;
+  int header[4];
+  int tsID;
+  int vlistID;
+  int pdis, pcat, pnum;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  for ( int varID = 0; varID < streamptr->nvars; varID++ )
-    {
-      int instID = vlistInqVarInstitut(vlistID, varID);
-      if ( instID != UNDEFID )
-	{
-          int ncvarid = streamptr->vars[varID].ncvarid;
-  	  const char *name = institutInqNamePtr(instID);
-	  if ( name )
-	    {
-              size_t len = strlen(name);
-	      cdf_put_att_text(fileID, ncvarid, "institution", len, name);
-	    }
-	}
-      }
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  nlevs    = zaxisInqSize(zaxisID);
 
-  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
-}
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-void cdfDefHistory(stream_t *streamptr, int size, const char *history)
-{
-  int ncid = streamptr->fileID;
-  cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
-}
+  header[0] = streamptr->tsteps[tsID].taxis.vdate;
+  header[1] = pnum;
+  header[3] = gridInqSize(gridID);
 
+  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
 
-int cdfInqHistorySize(stream_t *streamptr)
-{
-  size_t size = 0;
-  int ncid = streamptr->fileID;
-  if ( streamptr->historyID != UNDEFID )
-    cdf_inq_attlen(ncid, NC_GLOBAL, "history", &size);
+  for ( levID = 0;  levID < nlevs; levID++ )
+    {
+      level = zaxisInqLevel(zaxisID, levID);
 
-  return ((int) size);
+      header[2] = (int) level;
+      extDefHeader(extp, header);
+      extDefDataDP(extp, &data[levID*gridsize]);
+      extWrite(fileID, extp);
+    }
 }
 
 
-void cdfInqHistoryString(stream_t *streamptr, char *history)
+void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
-  int ncid = streamptr->fileID;
-  if ( streamptr->historyID != UNDEFID )
-    cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
-}
+  int fileID;
+  int gridID;
+  int zaxisID;
+  double level;
+  int header[4];
+  int tsID;
+  int vlistID;
+  int pdis, pcat, pnum;
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  level    = zaxisInqLevel(zaxisID, levID);
 
-void cdfDefVars(stream_t *streamptr)
-{
-  /* int  nvars, ncvarid; */
+  if ( CDI_Debug )
+    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
 
-  int vlistID = streamptr->vlistID;
-  if ( vlistID == UNDEFID )
-    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-  /* nvars  = vlistNvars(vlistID); */
-  int ngrids = vlistNgrids(vlistID);
-  int nzaxis = vlistNzaxis(vlistID);
-  /*
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-  */
-  if (ngrids > 0)
-    for (size_t index = 0; index < (size_t)ngrids; index++ )
-      {
-        int gridID = vlistGrid(vlistID, (int)index);
-        cdfDefGrid(streamptr, gridID);
-      }
+  header[0] = streamptr->tsteps[tsID].taxis.vdate;
+  header[1] = pnum;
+  header[2] = (int) level;
+  header[3] = gridInqSize(gridID);
 
-  if (nzaxis > 0)
-    for (size_t index = 0; index < (size_t)nzaxis; index++ )
-      {
-        int zaxisID = vlistZaxis(vlistID, (int)index);
-        if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
-      }
-  /*
-    define time first!!!
-  for (varID = 0; varID < nvars; varID++ )
-    {
-      ncvarid = cdfDefVar(streamptr, varID);
-    }
-  */
+  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
+
+  extDefHeader(extp, header);
+  extDefDataDP(extp, data);
+  extWrite(fileID, extp);
 }
-#endif
+
+#endif /* HAVE_LIBEXTRA */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -45645,133 +48193,88 @@ void cdfDefVars(stream_t *streamptr)
  * require-trailing-newline: t
  * End:
  */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <string.h>
-
-
-
-
-static
-void streamvar_init_entry(stream_t *streamptr, int varID)
-{
-  streamptr->vars[varID].ncvarid      = CDI_UNDEFID;
-  streamptr->vars[varID].defmiss      = 0;
-  streamptr->vars[varID].nlevs        = 0;
-  streamptr->vars[varID].level        = NULL;
-  streamptr->vars[varID].lindex       = NULL;
+#include <stdlib.h>
 
-  streamptr->vars[varID].gridID       = CDI_UNDEFID;
-  streamptr->vars[varID].zaxisID      = CDI_UNDEFID;
-  streamptr->vars[varID].tsteptype    = CDI_UNDEFID;
-}
 
-static
-int streamvar_new_entry(stream_t *streamptr)
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
+                       const char *container_name)
 {
-  int varID = 0;
-  int streamvarSize;
-  svarinfo_t *streamvar;
-
-  streamvarSize = streamptr->varsAllocated;
-  streamvar     = streamptr->vars;
-  /*
-    Look for a free slot in streamvar.
-    (Create the table the first time through).
-  */
-  if ( ! streamvarSize )
-    {
-      int i;
-
-      streamvarSize = 2;
-      streamvar
-        = (svarinfo_t *)xmalloc((size_t)streamvarSize * sizeof(svarinfo_t));
-      if ( streamvar == NULL )
-	{
-          Message("streamvarSize = %d", streamvarSize);
-	  SysError("Allocation of svarinfo_t failed");
-	}
 
-      for ( i = 0; i < streamvarSize; i++ )
-	streamvar[i].isUsed = FALSE;
-    }
-  else
-    {
-      while ( varID < streamvarSize )
-	{
-	  if ( ! streamvar[varID].isUsed ) break;
-	  varID++;
-	}
-    }
-  /*
-    If the table overflows, double its size.
-  */
-  if ( varID == streamvarSize )
-    {
-      int i;
+  int fileID1 = streamptr1->fileID;
+  int fileID2 = streamptr2->fileID;
 
-      streamvarSize = 2*streamvarSize;
-      streamvar
-        = (svarinfo_t *)xrealloc(streamvar,
-                                 (size_t)streamvarSize * sizeof (svarinfo_t));
-      if ( streamvar == NULL )
-	{
-          Message("streamvarSize = %d", streamvarSize);
-	  SysError("Reallocation of svarinfo_t failed");
-	}
-      varID = streamvarSize/2;
+  int tsID    = streamptr1->curTsID;
+  int vrecID  = streamptr1->tsteps[tsID].curRecID;
+  int recID   = streamptr1->tsteps[tsID].recIDs[vrecID];
+  off_t recpos  = streamptr1->tsteps[tsID].records[recID].position;
+  size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
 
-      for ( i = varID; i < streamvarSize; i++ )
-	streamvar[i].isUsed = FALSE;
-    }
+  if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
+    Error("Cannot seek input file for %s record copy!", container_name);
 
-  streamptr->varsAllocated = streamvarSize;
-  streamptr->vars          = streamvar;
+  char *buffer = xmalloc(recsize);
 
-  streamvar_init_entry(streamptr, varID);
+  if (fileRead(fileID1, buffer, recsize) != recsize)
+    Error("Failed to read record from %s file for copying!", container_name);
 
-  streamptr->vars[varID].isUsed = TRUE;
+  if (fileWrite(fileID2, buffer, recsize) != recsize)
+    Error("Failed to write record to %s file when copying!", container_name);
 
-  return (varID);
+  free(buffer);
 }
 
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_CGRIBEX_H
+#define _STREAM_CGRIBEX_H
 
-int stream_new_var(stream_t *streamptr, int gridID, int zaxisID)
-{
-  int varID;
-  int *level;
-  int *lindex;
-  int nlevs;
-  int levID;
-
-  if ( CDI_Debug )
-    Message("gridID = %d  zaxisID = %d", gridID, zaxisID);
-
-  varID = streamvar_new_entry(streamptr);
+int cgribexScanTimestep1(stream_t * streamptr);
+int cgribexScanTimestep2(stream_t * streamptr);
+int cgribexScanTimestep(stream_t * streamptr);
 
-  streamptr->nvars++;
+int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
+		  int unreduced, int *nmiss, double missval);
 
-  streamptr->vars[varID].gridID  = gridID;
-  streamptr->vars[varID].zaxisID = zaxisID;
+size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
+		     int vdate, int vtime, int tsteptype, int numavg, 
+		     long datasize, const double *data, int nmiss, unsigned char *gribbuffer, size_t gribbuffersize);
 
-  nlevs = zaxisInqSize(zaxisID);
+#endif  /* _STREAM_CGRIBEX_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _STREAM_GRIBAPI_H
+#define _STREAM_GRIBAPI_H
 
-  level  = (int *)xmalloc((size_t)nlevs * sizeof (int));
-  lindex = (int *)xmalloc((size_t)nlevs * sizeof (int));
+#ifndef  _CDI_INT_H
+#endif
 
-  for ( levID = 0; levID < nlevs; levID++ )
-    level[levID] = CDI_UNDEFID;
+int gribapiScanTimestep1(stream_t * streamptr);
+int gribapiScanTimestep2(stream_t * streamptr);
+int gribapiScanTimestep(stream_t * streamptr);
 
-  for ( levID = 0; levID < nlevs; levID++ )
-    lindex[levID] = levID;
+int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
+		  int unreduced, int *nmiss, double missval, int vlistID, int varID);
 
-  streamptr->vars[varID].nlevs  = nlevs;
-  streamptr->vars[varID].level  = level;
-  streamptr->vars[varID].lindex = lindex;
+size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
+		     int vdate, int vtime, int tsteptype, int numavg, 
+		     long datasize, const double *data, int nmiss, unsigned char **gribbuffer, size_t *gribbuffersize,
+		     int ljpeg, void *gribContainer);
 
-  return (varID);
-}
+#endif  /* _STREAM_GRIBAPI_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -45789,16428 +48292,16779 @@ int stream_new_var(stream_t *streamptr, int gridID, int zaxisID)
 
 
 
-
-void recordInitEntry(record_t *record)
-{
-  record->position = CDI_UNDEFID;
-  record->size     = 0;
-  record->param    = 0;
-  record->ilevel   = CDI_UNDEFID;
-  record->used     = FALSE;
-  record->varID    = CDI_UNDEFID;
-  record->levelID  = CDI_UNDEFID;
-  memset(record->varname, 0, sizeof(record->varname));
-}
-
-
-int recordNewEntry(stream_t *streamptr, int tsID)
+int grib1ltypeToZaxisType(int grib_ltype)
 {
-  int recordID = 0;
-  int recordSize = streamptr->tsteps[tsID].recordSize;
-  record_t *records = streamptr->tsteps[tsID].records;
-  /*
-    Look for a free slot in record.
-    (Create the table the first time through).
-  */
-  if ( ! recordSize )
-    {
-      int i;
-      recordSize = 1;   /*  <<<<----  */
-      records = (record_t *)xmalloc((size_t)recordSize * sizeof (record_t));
-      if ( records == NULL )
-	{
-          Message("recordSize = %d", recordSize);
-	  SysError("Allocation of record_tTABLE failed");
-	}
+  int zaxistype = ZAXIS_GENERIC;
 
-      for ( i = 0; i < recordSize; i++ )
-	records[i].used = CDI_UNDEFID;
-    }
-  else
-    {
-      while ( recordID < recordSize )
-	{
-	  if ( records[recordID].used == CDI_UNDEFID ) break;
-	  recordID++;
-	}
-    }
-  /*
-    If the table overflows, double its size.
-  */
-  if ( recordID == recordSize )
+  switch ( grib_ltype )
     {
-      int i;
-
-      recordSize = 2*recordSize;
-      records    = (record_t *)xrealloc(records,
-                                        (size_t)recordSize * sizeof (record_t));
-      if ( records == NULL )
-	{
-          Message("recordSize = %d", recordSize);
-	  SysError("Reallocation of record_tTABLE failed");
-	}
-      recordID = recordSize/2;
-
-      for ( i = recordID; i < recordSize; i++ )
-	records[i].used = CDI_UNDEFID;
+    case GRIB1_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;                break; }
+    case GRIB1_LTYPE_CLOUD_BASE:         { zaxistype = ZAXIS_CLOUD_BASE;             break; }
+    case GRIB1_LTYPE_CLOUD_TOP:          { zaxistype = ZAXIS_CLOUD_TOP;              break; }
+    case GRIB1_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;          break; }
+    case GRIB1_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;                    break; }
+    case GRIB1_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;             break; }
+    case GRIB1_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;             break; }
+    case GRIB1_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;                break; }
+    case GRIB1_LTYPE_99:
+    case GRIB1_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;               break; }
+    case GRIB1_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;                 break; }
+    case GRIB1_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;	             break; }
+    case GRIB1_LTYPE_SIGMA:
+    case GRIB1_LTYPE_SIGMA_LAYER:        { zaxistype = ZAXIS_SIGMA;	             break; }
+    case GRIB1_LTYPE_HYBRID:
+    case GRIB1_LTYPE_HYBRID_LAYER:       { zaxistype = ZAXIS_HYBRID;	             break; }
+    case GRIB1_LTYPE_LANDDEPTH:
+    case GRIB1_LTYPE_LANDDEPTH_LAYER:    { zaxistype = ZAXIS_DEPTH_BELOW_LAND;       break; }
+    case GRIB1_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;             break; }
+    case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;        break; }
+    case GRIB1_LTYPE_LAKE_BOTTOM:        { zaxistype = ZAXIS_LAKE_BOTTOM;            break; }
+    case GRIB1_LTYPE_SEDIMENT_BOTTOM:    { zaxistype = ZAXIS_SEDIMENT_BOTTOM;        break; }
+    case GRIB1_LTYPE_SEDIMENT_BOTTOM_TA: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;     break; }
+    case GRIB1_LTYPE_SEDIMENT_BOTTOM_TW: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;     break; }
+    case GRIB1_LTYPE_MIX_LAYER:          { zaxistype = ZAXIS_MIX_LAYER;              break; }
     }
 
-
-  recordInitEntry(&records[recordID]);
-
-  records[recordID].used = 1;
-
-  streamptr->tsteps[tsID].recordSize = recordSize;
-  streamptr->tsteps[tsID].records    = records;
-
-  return (recordID);
-}
-
-static
-void cdiInitRecord(stream_t *streamptr)
-{
-  streamptr->record = (Record *) malloc(sizeof(Record));
-
-  streamptr->record->param      = 0;
-  streamptr->record->level      = 0;
-  streamptr->record->date       = 0;
-  streamptr->record->time       = 0;
-  streamptr->record->gridID     = 0;
-  streamptr->record->buffer     = NULL;
-  streamptr->record->buffersize = 0;
-  streamptr->record->position   = 0;
-  streamptr->record->varID      = 0;
-  streamptr->record->levelID    = CDI_UNDEFID;
-}
-
-
-void streamInqRecord(int streamID, int *varID, int *levelID)
-{
-  check_parg(varID);
-  check_parg(levelID);
-
-  stream_t *streamptr = stream_to_pointer(streamID);
-  stream_check_ptr(__func__, streamptr);
-
-  cdiDefAccesstype(streamID, TYPE_REC);
-
-  if ( ! streamptr->record ) cdiInitRecord(streamptr);
-
-  int tsID   = streamptr->curTsID;
-  int rindex = streamptr->tsteps[tsID].curRecID + 1;
-
-  if ( rindex >= streamptr->tsteps[tsID].nrecs )
-    Error("record %d not available at timestep %d", rindex+1, tsID+1);
-
-  int recID  = streamptr->tsteps[tsID].recIDs[rindex];
-
-  if ( recID == -1 || recID >= streamptr->tsteps[tsID].nallrecs )
-    Error("Internal problem! tsID = %d recID = %d", tsID, recID);
-
-  *varID   = streamptr->tsteps[tsID].records[recID].varID;
-  int lindex = streamptr->tsteps[tsID].records[recID].levelID;
-
-  *levelID = streamptr->vars[*varID].lindex[lindex];
-
-  if ( CDI_Debug )
-    Message("tsID = %d, recID = %d, varID = %d, levelID = %d\n", tsID, recID, *varID, *levelID);
-
-  streamptr->curTsID = tsID;
-  streamptr->tsteps[tsID].curRecID = rindex;
+  return (zaxistype);
 }
 
-/*
- at Function  streamDefRecord
- at Title     Define the next record
-
- at Prototype void streamDefRecord(int streamID, int varID, int levelID)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  varID     Variable identifier.
-    @Item  levelID   Level identifier.
 
- at Description
-The function streamDefRecord defines the meta-data of the next record.
- at EndFunction
-*/
-void streamDefRecord(int streamID, int varID, int levelID)
+int grib2ltypeToZaxisType(int grib_ltype)
 {
-  stream_t *streamptr = stream_to_pointer(streamID);
-  stream_check_ptr(__func__, streamptr);
-
-  int tsID = streamptr->curTsID;
+  int zaxistype = ZAXIS_GENERIC;
 
-  if ( tsID == CDI_UNDEFID )
+  switch ( grib_ltype )
     {
-      tsID++;
-      streamDefTimestep(streamID, tsID);
+    case GRIB2_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;                break; }
+    case GRIB2_LTYPE_CLOUD_BASE:         { zaxistype = ZAXIS_CLOUD_BASE;             break; }
+    case GRIB2_LTYPE_CLOUD_TOP:          { zaxistype = ZAXIS_CLOUD_TOP;              break; }
+    case GRIB2_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;          break; }
+    case GRIB2_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;                    break; }
+    case GRIB2_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;             break; }
+    case GRIB2_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;             break; }
+    case GRIB2_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;                break; }
+    case GRIB2_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;               break; }
+    case GRIB2_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;                 break; }
+    case GRIB2_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;               break; }
+    case GRIB2_LTYPE_SIGMA:              { zaxistype = ZAXIS_SIGMA;                  break; }
+    case GRIB2_LTYPE_HYBRID:
+ /* case GRIB2_LTYPE_HYBRID_LAYER: */    { zaxistype = ZAXIS_HYBRID;                 break; }
+    case GRIB2_LTYPE_LANDDEPTH:
+ /* case GRIB2_LTYPE_LANDDEPTH_LAYER: */ { zaxistype = ZAXIS_DEPTH_BELOW_LAND;       break; }
+    case GRIB2_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;             break; }
+    case GRIB2_LTYPE_SNOW:               { zaxistype = ZAXIS_SNOW;                   break; }
+    case GRIB2_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;        break; }
+    case GRIB2_LTYPE_LAKE_BOTTOM:        { zaxistype = ZAXIS_LAKE_BOTTOM;            break; }
+    case GRIB2_LTYPE_SEDIMENT_BOTTOM:    { zaxistype = ZAXIS_SEDIMENT_BOTTOM;        break; }
+    case GRIB2_LTYPE_SEDIMENT_BOTTOM_TA: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;     break; }
+    case GRIB2_LTYPE_SEDIMENT_BOTTOM_TW: { zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;     break; }
+    case GRIB2_LTYPE_MIX_LAYER:          { zaxistype = ZAXIS_MIX_LAYER;              break; }
+    case GRIB2_LTYPE_REFERENCE:          { zaxistype = ZAXIS_REFERENCE;              break; }
     }
 
-  if ( ! streamptr->record ) cdiInitRecord(streamptr);
+  return (zaxistype);
+}
 
-  int vlistID = streamptr->vlistID;
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int zaxisID = vlistInqVarZaxis(vlistID, varID);
-  int param   = vlistInqVarParam(vlistID, varID);
-  int level   = (int) zaxisInqLevel(zaxisID, levelID);
 
-  streamptr->record->varID    = varID;
-  streamptr->record->levelID  = levelID;
-  streamptr->record->param    = param;
-  streamptr->record->level    = level;
-  streamptr->record->date     = streamptr->tsteps[tsID].taxis.vdate;
-  streamptr->record->time     = streamptr->tsteps[tsID].taxis.vtime;
-  streamptr->record->gridID   = gridID;
-  streamptr->record->prec     = vlistInqVarDatatype(vlistID, varID);
+int zaxisTypeToGrib1ltype(int zaxistype)
+{
+  int grib_ltype = -1;
 
-  switch (streamptr->filetype)
+  switch (zaxistype)
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      grbDefRecord(streamptr);
-      break;
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      srvDefRecord(streamptr);
-      break;
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      extDefRecord(streamptr);
-      break;
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      iegDefRecord(streamptr);
-      break;
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
-      cdfDefRecord(streamptr);
-      break;
-#endif
-    default:
-      Error("%s support not compiled in!", strfiletype(streamptr->filetype));
-      break;
+    case ZAXIS_SURFACE:               { grib_ltype = GRIB1_LTYPE_SURFACE;            break; }
+    case ZAXIS_MEANSEA:               { grib_ltype = GRIB1_LTYPE_MEANSEA;            break; }
+    case ZAXIS_HEIGHT:                { grib_ltype = GRIB1_LTYPE_HEIGHT;             break; }
+    case ZAXIS_ALTITUDE:              { grib_ltype = GRIB1_LTYPE_ALTITUDE;           break; }
+    case ZAXIS_SIGMA:                 { grib_ltype = GRIB1_LTYPE_SIGMA;              break; }
+    case ZAXIS_DEPTH_BELOW_SEA:       { grib_ltype = GRIB1_LTYPE_SEADEPTH;           break; }
+    case ZAXIS_ISENTROPIC:            { grib_ltype = GRIB1_LTYPE_ISENTROPIC;         break; }
+    case ZAXIS_CLOUD_BASE:            { grib_ltype = GRIB1_LTYPE_CLOUD_BASE;         break; }
+    case ZAXIS_CLOUD_TOP:             { grib_ltype = GRIB1_LTYPE_CLOUD_TOP;          break; }
+    case ZAXIS_ISOTHERM_ZERO:         { grib_ltype = GRIB1_LTYPE_ISOTHERM0;          break; }
+    case ZAXIS_TOA:                   { grib_ltype = GRIB1_LTYPE_TOA;                break; }
+    case ZAXIS_SEA_BOTTOM:            { grib_ltype = GRIB1_LTYPE_SEA_BOTTOM;         break; }
+    case ZAXIS_LAKE_BOTTOM:           { grib_ltype = GRIB1_LTYPE_LAKE_BOTTOM;        break; }
+    case ZAXIS_SEDIMENT_BOTTOM:       { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM;    break; }
+    case ZAXIS_SEDIMENT_BOTTOM_TA:    { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM_TA; break; }
+    case ZAXIS_SEDIMENT_BOTTOM_TW:    { grib_ltype = GRIB1_LTYPE_SEDIMENT_BOTTOM_TW; break; }
+    case ZAXIS_MIX_LAYER:             { grib_ltype = GRIB1_LTYPE_MIX_LAYER;          break; }
+    case ZAXIS_ATMOSPHERE:            { grib_ltype = GRIB1_LTYPE_ATMOSPHERE;         break; }
     }
+
+  return (grib_ltype);
 }
 
 
-void streamReadRecord(int streamID, double *data, int *nmiss)
+int zaxisTypeToGrib2ltype(int zaxistype)
 {
-  check_parg(data);
-  check_parg(nmiss);
-
-  stream_t *streamptr = stream_to_pointer(streamID);
-  stream_check_ptr(__func__, streamptr);
-
-  *nmiss = 0;
+  int grib_ltype = -1;
 
-  switch (streamptr->filetype)
+  switch (zaxistype)
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      grbReadRecord(streamptr, data, nmiss);
-      break;
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      srvReadRecord(streamptr, data, nmiss);
-      break;
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      extReadRecord(streamptr, data, nmiss);
-      break;
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      iegReadRecord(streamptr, data, nmiss);
-      break;
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      cdfReadRecord(streamptr, data, nmiss);
-      break;
-#endif
-    default:
-      {
-	Error("%s support not compiled in!", strfiletype(streamptr->filetype));
-	break;
-      }
+    case ZAXIS_SURFACE:               { grib_ltype = GRIB2_LTYPE_SURFACE;            break; }
+    case ZAXIS_MEANSEA:               { grib_ltype = GRIB2_LTYPE_MEANSEA;            break; }
+    case ZAXIS_HEIGHT:                { grib_ltype = GRIB2_LTYPE_HEIGHT;             break; }
+    case ZAXIS_ALTITUDE:              { grib_ltype = GRIB2_LTYPE_ALTITUDE;           break; }
+    case ZAXIS_SIGMA:                 { grib_ltype = GRIB2_LTYPE_SIGMA;              break; }
+    case ZAXIS_DEPTH_BELOW_SEA:       { grib_ltype = GRIB2_LTYPE_SEADEPTH;           break; }
+    case ZAXIS_ISENTROPIC:            { grib_ltype = GRIB2_LTYPE_ISENTROPIC;         break; }
+    case ZAXIS_CLOUD_BASE:            { grib_ltype = GRIB2_LTYPE_CLOUD_BASE;         break; }
+    case ZAXIS_CLOUD_TOP:             { grib_ltype = GRIB2_LTYPE_CLOUD_TOP;          break; }
+    case ZAXIS_ISOTHERM_ZERO:         { grib_ltype = GRIB2_LTYPE_ISOTHERM0;          break; }
+    case ZAXIS_TOA:                   { grib_ltype = GRIB2_LTYPE_TOA;                break; }
+    case ZAXIS_SEA_BOTTOM:            { grib_ltype = GRIB2_LTYPE_SEA_BOTTOM;         break; }
+    case ZAXIS_LAKE_BOTTOM:           { grib_ltype = GRIB2_LTYPE_LAKE_BOTTOM;        break; }
+    case ZAXIS_SEDIMENT_BOTTOM:       { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM;    break; }
+    case ZAXIS_SEDIMENT_BOTTOM_TA:    { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM_TA; break; }
+    case ZAXIS_SEDIMENT_BOTTOM_TW:    { grib_ltype = GRIB2_LTYPE_SEDIMENT_BOTTOM_TW; break; }
+    case ZAXIS_MIX_LAYER:             { grib_ltype = GRIB2_LTYPE_MIX_LAYER;          break; }
+    case ZAXIS_ATMOSPHERE:            { grib_ltype = GRIB2_LTYPE_ATMOSPHERE;         break; }
     }
+
+  return (grib_ltype);
 }
 
-static void
-stream_write_record(int streamID, int memtype, const void *data, int nmiss)
+
+int grbBitsPerValue(int datatype)
 {
-  check_parg(data);
+  int bitsPerValue = 16;
 
-  stream_t *streamptr = stream_to_pointer(streamID);
-  stream_check_ptr(__func__, streamptr);
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    Error("CDI/GRIB library does not support complex numbers!");
 
-  switch (streamptr->filetype)
+  if ( datatype != CDI_UNDEFID )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      grb_write_record(streamptr, memtype, data, nmiss);
-      break;
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteRecord not implemented for memtype float!");
-      srvWriteRecord(streamptr, (const double *)data);
-      break;
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      if ( memtype == MEMTYPE_FLOAT ) Error("extWriteRecord not implemented for memtype float!");
-      extWriteRecord(streamptr, (const double *)data);
-      break;
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteRecord not implemented for memtype float!");
-      iegWriteRecord(streamptr, (const double *)data);
-      break;
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      {
-	cdf_write_record(streamptr, memtype, data, nmiss);
-	break;
-      }
-#endif
-    default:
-      {
-	Error("%s support not compiled in!", strfiletype(streamptr->filetype));
-	break;
-      }
+      if ( datatype > 0 && datatype <= 32 )
+	bitsPerValue = datatype;
+      else if ( datatype == DATATYPE_FLT64 )
+	bitsPerValue = 24;
+      else
+	bitsPerValue = 16;
     }
+
+  return (bitsPerValue);
 }
 
+
 /*
- at Function  streamWriteRecord
- at Title     Write a horizontal slice of a variable
+int grbInqRecord(stream_t * streamptr, int *varID, int *levelID)
+{
+  int status;
 
- at Prototype void streamWriteRecord(int streamID, const double *data, int nmiss)
- at Parameter
-    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
-    @Item  data      Pointer to a block of double precision floating point data values to be written.
-    @Item  nmiss     Number of missing values.
+  status = cgribexInqRecord(streamptr, varID, levelID);
 
- at Description
-The function streamWriteRecord writes the values of a horizontal slice (record) of a variable to an open dataset.
-The values are converted to the external data type of the variable, if necessary.
- at EndFunction
-*/
-void streamWriteRecord(int streamID, const double *data, int nmiss)
-{
-  stream_write_record(streamID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+  return (status);
 }
+*/
 
-void streamWriteRecordF(int streamID, const float *data, int nmiss)
+void grbDefRecord(stream_t * streamptr)
 {
-  stream_write_record(streamID, MEMTYPE_FLOAT, (const void *) data, nmiss);
+  UNUSED(streamptr);
 }
 
-
-void streamCopyRecord(int streamID2, int streamID1)
+static
+int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
+	      int unreduced, int *nmiss, double missval, int vlistID, int varID)
 {
-  stream_t *streamptr1 = stream_to_pointer(streamID1);
-  stream_t *streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  int filetype1 = streamptr1->filetype;
-  int filetype2 = streamptr2->filetype;
-  int filetype  = FILETYPE_UNDEF;
-
-  if ( filetype1 == filetype2 ) filetype = filetype2;
-  else
-    {
-      switch (filetype1)
-        {
-        case FILETYPE_NC:
-        case FILETYPE_NC2:
-        case FILETYPE_NC4:
-        case FILETYPE_NC4C:
-          switch (filetype2)
-            {
-            case FILETYPE_NC:
-            case FILETYPE_NC2:
-            case FILETYPE_NC4:
-            case FILETYPE_NC4C:
-              Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
-              filetype = filetype2;
-              break;
-            }
-          break;
-        }
-    }
-
-  if ( filetype == FILETYPE_UNDEF )
-    Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
+  int status = 0;
 
-  switch (filetype)
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
     {
-#if  defined  (HAVE_LIBGRIB)
-    case FILETYPE_GRB:
-    case FILETYPE_GRB2:
-      grbCopyRecord(streamptr2, streamptr1);
-      break;
-#endif
-#if  defined  (HAVE_LIBSERVICE)
-    case FILETYPE_SRV:
-      srvCopyRecord(streamptr2, streamptr1);
-      break;
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case FILETYPE_EXT:
-      extCopyRecord(streamptr2, streamptr1);
-      break;
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case FILETYPE_IEG:
-      iegCopyRecord(streamptr2, streamptr1);
-      break;
+#if  defined  (HAVE_LIBGRIB_API)
+      extern int cdiNAdditionalGRIBKeys;
+      if ( cdiNAdditionalGRIBKeys > 0 )
+	Error("CGRIBEX decode does not support reading of additional GRIB keys!");
 #endif
-#if  defined  (HAVE_LIBNETCDF)
-    case FILETYPE_NC:
-    case FILETYPE_NC2:
-    case FILETYPE_NC4:
-    case FILETYPE_NC4C:
-      cdfCopyRecord(streamptr2, streamptr1);
-      break;
+      status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, missval);
+    }
+  else
 #endif
-    default:
-      {
-	Error("%s support not compiled in!", strfiletype(filetype));
-	break;
-      }
+#ifdef HAVE_LIBGRIB_API
+    status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, missval, vlistID, varID);
+#else
+    {
+      (void)vlistID; (void)varID;
+      Error("GRIB_API support not compiled in!");
     }
+#endif
+
+  return (status);
 }
 
 
-void cdi_create_records(stream_t *streamptr, int tsID)
+int grbUnzipRecord(unsigned char *gribbuffer, size_t *gribsize)
 {
-  unsigned nrecords, maxrecords;
-  record_t *records;
-
-  if ( streamptr->tsteps[tsID].records ) return;
-
-  int vlistID  = streamptr->vlistID;
+  int zip = 0;
+  int izip;
+  size_t igribsize;
+  size_t ogribsize;
+  long unzipsize;
 
-  if ( tsID == 0 )
-    {
-      maxrecords = 0;
-      int nvars = streamptr->nvars;
-      for ( int varID = 0; varID < nvars; varID++)
-	maxrecords += (unsigned)streamptr->vars[varID].nlevs;
-    }
-  else
-    maxrecords = (unsigned)streamptr->tsteps[0].recordSize;
+  igribsize = *gribsize;
+  ogribsize = *gribsize;
 
-  if ( tsID == 0 )
-    {
-      nrecords = maxrecords;
-    }
-  else if ( tsID == 1 )
+  if ( (izip = gribGetZip((long)igribsize, gribbuffer, &unzipsize)) > 0 )
     {
-      nrecords = 0;
-      maxrecords = (unsigned)streamptr->tsteps[0].recordSize;
-      for (unsigned recID = 0; recID < maxrecords; recID++ )
+      zip = izip;
+      if ( izip == 128 ) /* szip */
 	{
-	  int varID = streamptr->tsteps[0].records[recID].varID;
-	  nrecords +=
-            (varID == -1 /* varID = -1 for write mode !!! */
-             || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
-	}
-    }
-  else
-    nrecords = (unsigned)streamptr->tsteps[1].nallrecs;
+	  unsigned char *itmpbuffer = NULL;
+	  size_t itmpbuffersize = 0;
 
-  if ( maxrecords > 0 )
-    records = (record_t *) malloc(maxrecords * sizeof(record_t));
-  else
-    records = NULL;
+	  if ( unzipsize < (long) igribsize )
+	    {
+	      fprintf(stderr, "Decompressed size smaller than compressed size (in %ld; out %ld)!\n", (long)igribsize, unzipsize);
+	      return (0);
+	    }
 
-  streamptr->tsteps[tsID].records    = records;
-  streamptr->tsteps[tsID].recordSize = (int)maxrecords;
-  streamptr->tsteps[tsID].nallrecs   = (int)nrecords;
+	  if ( itmpbuffersize < igribsize )
+	    {
+	      itmpbuffersize = igribsize;
+	      itmpbuffer = (unsigned char *) realloc(itmpbuffer, itmpbuffersize);
+	    }
 
-  if ( tsID == 0 )
-    {
-      for ( unsigned recID = 0; recID < maxrecords; recID++ )
-	recordInitEntry(&streamptr->tsteps[tsID].records[recID]);
-    }
-  else
-    {
-      memcpy(streamptr->tsteps[tsID].records,
-	     streamptr->tsteps[0].records,
-	     (size_t)maxrecords * sizeof(record_t));
+	  memcpy(itmpbuffer, gribbuffer, itmpbuffersize);
 
-      for ( unsigned recID = 0; recID < maxrecords; recID++ )
+	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
+
+	  ogribsize = (size_t)gribUnzip(gribbuffer, unzipsize, itmpbuffer, (long)igribsize);
+
+	  free(itmpbuffer);
+
+	  if ( ogribsize <= 0 ) Error("Decompression problem!");
+	}
+      else
 	{
-	  int varID = streamptr->tsteps[0].records[recID].varID;
-	  if ( varID != -1 ) /* varID = -1 for write mode !!! */
-	    if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-	      {
-		streamptr->tsteps[tsID].records[recID].position = CDI_UNDEFID;
-		streamptr->tsteps[tsID].records[recID].size     = 0;
-		streamptr->tsteps[tsID].records[recID].used     = FALSE;
-	      }
+	  Error("Decompression for %d not implemented!", izip);
 	}
     }
+
+  *gribsize = ogribsize;
+
+  return zip;
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
 
 
+void grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
+{
+  int filetype = streamptr->filetype;
+
+  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
+
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
+  int tsID    = streamptr->curTsID;
+  int vrecID  = streamptr->tsteps[tsID].curRecID;
+  int recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+  off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
+  size_t recsize = streamptr->tsteps[tsID].records[recID].size;
+  int varID   = streamptr->tsteps[tsID].records[recID].varID;
+
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int gridsize = gridInqSize(gridID);
+
+  streamptr->numvals += gridsize;
+
+  fileSetPos(fileID, recpos, SEEK_SET);
+
+  if (fileRead(fileID, gribbuffer, recsize) != recsize)
+    Error("Failed to read GRIB record");
+
+  double missval = vlistInqVarMissval(vlistID, varID);
+
+  streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
 
+  grbDecode(filetype, gribbuffer, (int)recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
+}
 
 static
-void tstepsInitEntry(stream_t *streamptr, int tsID)
+int grbScanTimestep1(stream_t * streamptr)
 {
-  streamptr->tsteps[tsID].curRecID     = CDI_UNDEFID;
-  streamptr->tsteps[tsID].position     = 0;
-  streamptr->tsteps[tsID].records      = NULL;
-  streamptr->tsteps[tsID].recordSize   = 0;
-  streamptr->tsteps[tsID].nallrecs     = 0;
-  streamptr->tsteps[tsID].recIDs       = NULL;
-  streamptr->tsteps[tsID].nrecs        = 0;
-  streamptr->tsteps[tsID].next         = 0;
+  int status;
+  int filetype;
 
-  ptaxisInit(&streamptr->tsteps[tsID].taxis);
-}
+  filetype  = streamptr->filetype;
 
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
+    {
+      status = cgribexScanTimestep1(streamptr);
+    }
+  else
+#endif
+    {
+      status = gribapiScanTimestep1(streamptr);
+    }
 
-int tstepsNewEntry(stream_t *streamptr)
+  return (status);
+}
+
+static
+int grbScanTimestep2(stream_t * streamptr)
 {
-  int tsID = 0;
-  int tstepsTableSize;
-  tsteps_t *tstepsTable;
+  int status = 0;
+  int filetype;
 
-  tsID            = streamptr->tstepsNextID++;
-  tstepsTableSize = streamptr->tstepsTableSize;
-  tstepsTable     = streamptr->tsteps;
+  filetype  = streamptr->filetype;
 
-  /*
-    If the table overflows, double its size.
-  */
-  if ( tsID == tstepsTableSize )
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
     {
-      if ( tstepsTableSize == 0 ) tstepsTableSize = 1;
-      tstepsTableSize = 2*tstepsTableSize;
-      tstepsTable = (tsteps_t *)xrealloc(tstepsTable,
-                                         (size_t)tstepsTableSize * sizeof (tsteps_t));
-      if ( tstepsTable == NULL )
-	{
-          Message("tstepsTableSize = %d", tstepsTableSize);
-	  SysError("Reallocation of tsteps_t failed");
-	}
+      status = cgribexScanTimestep2(streamptr);
     }
+#endif
+#if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
+  else
+#endif
+#ifdef HAVE_LIBGRIB_API
+    status = gribapiScanTimestep2(streamptr);
+#endif
 
-  streamptr->tstepsTableSize = tstepsTableSize;
-  streamptr->tsteps          = tstepsTable;
+  return (status);
+}
 
-  tstepsInitEntry(streamptr, tsID);
+static
+int grbScanTimestep(stream_t * streamptr)
+{
+  int status = CDI_EUFTYPE;
+  int filetype;
 
-  streamptr->tsteps[tsID].taxis.used = TRUE;
+  filetype  = streamptr->filetype;
+
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
+    {
+      status = cgribexScanTimestep(streamptr);
+    }
+  else
+#endif
+#ifdef HAVE_LIBGRIB_API
+    status = gribapiScanTimestep(streamptr);
+#else
+    Error("Sufficient GRIB support unavailable!");
+#endif
 
-  return (tsID);
+  return (status);
 }
 
 
-void cdiCreateTimesteps(stream_t *streamptr)
+int grbInqContents(stream_t * streamptr)
 {
-  long ntsteps;
-  long tsID;
-
-  if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
-    return;
+  int fileID;
+  int status = 0;
 
-  if ( streamptr->ntsteps == 0 ) ntsteps = 1;    /* <<<<<-------- */
-  else ntsteps = streamptr->ntsteps;
+  fileID = streamptr->fileID;
 
-  streamptr->tsteps = (tsteps_t *)xmalloc((size_t)ntsteps*sizeof(tsteps_t));
+  streamptr->curTsID = 0;
 
-  streamptr->tstepsTableSize = (int)ntsteps;
-  streamptr->tstepsNextID    = (int)ntsteps;
+  status = grbScanTimestep1(streamptr);
 
-  for ( tsID = 0; tsID < ntsteps; tsID++ )
-    {
-      tstepsInitEntry(streamptr, (int)tsID);
-      streamptr->tsteps[tsID].taxis.used = TRUE;
-    }
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
 
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>  // gettimeofday()
+  fileSetPos(fileID, 0, SEEK_SET);
 
+  return (status);
+}
 
 
-#if ! defined (O_BINARY)
-#define O_BINARY 0
-#endif
+int grbInqTimestep(stream_t * streamptr, int tsID)
+{
+  int ntsteps, nrecs;
 
-#ifndef strdupx
-#ifndef strdup
-char *strdup(const char *s);
-#endif
-#define strdupx  strdup
-/*
-#define strdupx(s)                                \
-({                                                \
-   const char *__old = (s);                       \
-   size_t __len = strlen(__old) + 1;              \
-   char *__new = (char *) malloc(__len);          \
-   (char *) memcpy(__new, __old, __len);          \
-})
-*/
-#endif
+  if ( tsID == 0 && streamptr->rtsteps == 0 )
+    Error("Call to cdiInqContents missing!");
 
+  if ( CDI_Debug )
+    Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-#if defined (HAVE_MMAP)
-#  include <sys/mman.h> /* mmap() is defined in this header */
-#endif
+  ntsteps = CDI_UNDEFID;
+  while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
+    {
+      ntsteps = grbScanTimestep(streamptr);
+      if ( ntsteps == CDI_EUFSTRUCT )
+	{
+	  streamptr->ntsteps = streamptr->rtsteps;
+	  break;
+	}
+    }
 
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
+    {
+      streamptr->curTsID = tsID;
+      nrecs = streamptr->tsteps[tsID].nrecs;
+    }
 
-#if ! defined   (FALSE)
-#  define  FALSE  0
-#endif
+  return (nrecs);
+}
 
-#if ! defined   (TRUE)
-#  define  TRUE   1
-#endif
 
-/* #define  MAX_FILES  FOPEN_MAX */
-#define  MAX_FILES  4096
+void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
+{
+  int filetype = streamptr->filetype;
 
-static int _file_max = MAX_FILES;
+  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-static void file_initialize(void);
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
+  int tsID    = streamptr->curTsID;
 
-static int _file_init = FALSE;
+  int nlevs    = streamptr->vars[varID].nlevs;
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int gridsize = gridInqSize(gridID);
 
-#if  defined  (HAVE_LIBPTHREAD)
-#include <pthread.h>
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-static pthread_once_t  _file_init_thread = PTHREAD_ONCE_INIT;
-static pthread_mutex_t _file_mutex;
+  off_t currentfilepos = fileGetPos(fileID);
 
-#  define FILE_LOCK()         pthread_mutex_lock(&_file_mutex)
-#  define FILE_UNLOCK()       pthread_mutex_unlock(&_file_mutex)
-#  define FILE_INIT()        \
-   if ( _file_init == FALSE ) pthread_once(&_file_init_thread, file_initialize)
+  *nmiss = 0;
+  for (int levelID = 0; levelID < nlevs; levelID++ )
+    {
+      int recID   = streamptr->vars[varID].level[levelID];
+      off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
+      size_t recsize = streamptr->tsteps[tsID].records[recID].size;
 
-#else
+      fileSetPos(fileID, recpos, SEEK_SET);
 
-#  define FILE_LOCK()
-#  define FILE_UNLOCK()
-#  define FILE_INIT()        \
-   if ( _file_init == FALSE ) file_initialize()
+      fileRead(fileID, gribbuffer, recsize);
 
-#endif
+      double missval = vlistInqVarMissval(vlistID, varID);
 
+      int imiss;
 
-typedef struct
-{
-  int        self;
-  int        flag;           /* access and error flag         */
-  int        eof;            /* end of file flag              */
-  int        fd;             /* file descriptor used for read */
-  FILE      *fp;             /* FILE pointer used for write   */
-  int        mode;           /* file access mode              */
-  char      *name;           /* file name                     */
-  off_t      size;           /* file size                     */
-  off_t      position;       /* file position                 */
-  long       access;         /* file access                   */
-  off_t      byteTrans;      /*                               */
-  size_t     blockSize;      /* file block size               */
-  int        type;           /* file type ( 1:open 2:fopen )  */
-  int        bufferType;     /* buffer type ( 1:std 2:mmap )  */
-  size_t     bufferSize;     /* file buffer size              */
-  size_t     mappedSize;     /* mmap buffer size              */
-  char      *buffer;         /* file buffer                   */
-  long       bufferNumFill;  /* number of buffer fill         */
-  char      *bufferPtr;      /* file buffer pointer           */
-  off_t      bufferPos;
-  off_t      bufferStart;
-  off_t      bufferEnd;
-  size_t     bufferCnt;
-  double     time_in_sec;
-}
-bfile_t;
+      streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
 
+      grbDecode(filetype, gribbuffer, (int)recsize, &data[levelID*gridsize], gridsize,
+		streamptr->unreduced, &imiss, missval, vlistID, varID);
 
-enum F_I_L_E_Flags
-  {
-    FILE_READ  =  01,
-    FILE_WRITE =  02,
-    FILE_UNBUF =  04,
-    FILE_EOF   = 010,
-    FILE_ERROR = 020
-  };
+      *nmiss += imiss;
+    }
 
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
+}
 
-static int FileInfo  = FALSE;
 
+void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss)
+{
+  int filetype = streamptr->filetype;
 
-#if ! defined (MIN_BUF_SIZE)
-#  define  MIN_BUF_SIZE  131072L
-#endif
+  unsigned char *gribbuffer = (unsigned char *) streamptr->record->buffer;
 
+  int vlistID = streamptr->vlistID;
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int gridsize = gridInqSize(gridID);
+  int tsID = streamptr->curTsID;
 
-static size_t FileBufferSizeMin = MIN_BUF_SIZE;
-static long   FileBufferSizeEnv = -1;
-static int    FileBufferTypeEnv =  0;
+  if ( CDI_Debug )
+    Message("gridID = %d gridsize = %d", gridID, gridsize);
 
-static int    FileTypeRead  = FILE_TYPE_OPEN;
-static int    FileTypeWrite = FILE_TYPE_FOPEN;
-static int    FileFlagWrite = 0;
+  int fileID = streamptr->fileID;
 
-static int    FILE_Debug = 0;   /* If set to 1, debugging */
+  off_t currentfilepos = fileGetPos(fileID);
 
+  int recID   = streamptr->vars[varID].level[levelID];
+  off_t recpos  = streamptr->tsteps[tsID].records[recID].position;
+  size_t recsize = streamptr->tsteps[tsID].records[recID].size;
 
-static void file_table_print(void);
+  if ( recsize == 0 )
+    Error("Internal problem! Recordsize is zero for record %d at timestep %d",
+	  recID+1, tsID+1);
 
-/*
- * A version string.
- */
-#undef   LIBVERSION
-#define  LIBVERSION      1.8.2
-#define  XSTRING(x)	 #x
-#define  STRING(x) 	 XSTRING(x)
-const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
+  fileSetPos(fileID, recpos, SEEK_SET);
 
-/*
-  21/05/2004  1.3.2 set min I/O Buffersize to 128k
-  31/05/2005  1.4.0 replace fileTable by _fileList
-  26/08/2005  1.4.1 fileClose with return value
-                    checks for all fileptr
-  01/09/2005  1.5.0 thread safe version
-  06/11/2005  1.5.1 add filePtrEOF, filePtr, filePtrGetc
-  03/02/2006  1.5.2 ansi C: define getpagesize and strdupx
-  27/12/2007  1.6.0 add FILE_TYPE_FOPEN
-  24/03/2008  1.6.1 add O_BINARY if available
-                    remove default HAVE_MMAP
-                    use HAVE_STRUCT_STAT_ST_BLKSIZE
-  22/08/2010  1.7.0 refactor
-  11/11/2010  1.7.1 update for changed interface of error.h
-  02/02/2012  1.8.0 cleanup
-  16/11/2012  1.8.1 added support for unbuffered write
-  27/06/2013  1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
- */
+  fileRead(fileID, gribbuffer, recsize);
 
+  double missval = vlistInqVarMissval(vlistID, varID);
 
-typedef struct _filePtrToIdx {
-  int idx;
-  bfile_t *ptr;
-  struct _filePtrToIdx *next;
-} filePtrToIdx;
+  streamptr->tsteps[tsID].records[recID].zip = grbUnzipRecord(gribbuffer, &recsize);
 
+  grbDecode(filetype, gribbuffer, (int)recsize, data, gridsize, streamptr->unreduced, nmiss, missval, vlistID, varID);
 
-static filePtrToIdx *_fileList  = NULL;
-static filePtrToIdx *_fileAvail = NULL;
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
+}
 
 static
-void file_list_new(void)
+size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
+		 int date, int time, int tsteptype, int numavg,
+		 size_t datasize, const double *data, int nmiss, unsigned char **gribbuffer,
+		 int comptype, void *gribContainer)
 {
-  assert(_fileList == NULL);
+  size_t nbytes = 0;
 
-  _fileList = (filePtrToIdx *)xmalloc((size_t)_file_max * sizeof (filePtrToIdx));
-}
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
+    {
+      size_t gribbuffersize = datasize*4+3000;
+      *gribbuffer = (unsigned char *) malloc(gribbuffersize);
 
-static
-void file_list_delete(void)
-{
-  if ( _fileList )
+      nbytes = cgribexEncode(memtype, varID, levelID, vlistID, gridID, zaxisID,
+			     date, time, tsteptype, numavg,
+			     (long)datasize, data, nmiss, *gribbuffer, gribbuffersize);
+    }
+  else
+#endif
+#ifdef HAVE_LIBGRIB_API
     {
-      free(_fileList);
-      _fileList = NULL;
+      if ( memtype == MEMTYPE_FLOAT ) Error("gribapiEncode() not implemented for memtype float!");
+
+      size_t gribbuffersize;
+      nbytes = gribapiEncode(varID, levelID, vlistID, gridID, zaxisID,
+			     date, time, tsteptype, numavg,
+			     (long)datasize, data, nmiss, gribbuffer, &gribbuffersize,
+			     comptype, gribContainer);
     }
+#else
+    Error("GRIB_API support not compiled in!");
+    (void)gribContainer;
+    (void)comptype;
+#endif
+
+
+  return (nbytes);
 }
 
 static
-void file_init_pointer(void)
+size_t grbSzip(int filetype, unsigned char *gribbuffer, size_t gribbuffersize)
 {
-  int  i;
+  size_t nbytes = 0;
+  unsigned char *buffer;
+  size_t buffersize;
+  static int lszip_warn = 1;
 
-  for ( i = 0; i < _file_max; i++ )
+  buffersize = gribbuffersize + 1000; /* compressed record can be greater than source record */
+  buffer = (unsigned char *) malloc(buffersize);
+
+  /*  memcpy(buffer, gribbuffer, gribbuffersize); */
+
+  if ( filetype == FILETYPE_GRB )
     {
-      _fileList[i].next = _fileList + i + 1;
-      _fileList[i].idx  = i;
-      _fileList[i].ptr  = 0;
+      nbytes = (size_t)gribZip(gribbuffer, (long) gribbuffersize, buffer, (long) buffersize);
+    }
+  else
+    {
+      if ( lszip_warn ) Warning("Szip compression of GRIB2 records not implemented!");
+      lszip_warn = 0;
+      nbytes = gribbuffersize;
     }
 
-  _fileList[_file_max-1].next = 0;
+  free(buffer);
 
-  _fileAvail = _fileList;
+  return (nbytes);
 }
 
-static
-bfile_t *file_to_pointer(int idx)
+
+void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
-  bfile_t *fileptr = NULL;
+  size_t nwrite;
+  int fileID;
+  int gridID;
+  int zaxisID;
+  unsigned char *gribbuffer = NULL;
+  int tsID;
+  int vlistID;
+  int date, time;
+  int tsteptype;
+  int numavg = 0;
+  size_t nbytes;
+  int filetype;
+  void *gc = NULL;
 
-  FILE_INIT();
+  filetype  = streamptr->filetype;
+  fileID    = streamptr->fileID;
+  vlistID   = streamptr->vlistID;
+  gridID    = vlistInqVarGrid(vlistID, varID);
+  zaxisID   = vlistInqVarZaxis(vlistID, varID);
+  tsteptype = vlistInqVarTsteptype(vlistID, varID);
 
-  if ( idx >= 0 && idx < _file_max )
-    {
-      FILE_LOCK();
+  int comptype  = streamptr->comptype;
 
-      fileptr = _fileList[idx].ptr;
+  tsID      = streamptr->curTsID;
+  date      = streamptr->tsteps[tsID].taxis.vdate;
+  time      = streamptr->tsteps[tsID].taxis.vtime;
+  if ( vlistInqVarTimave(vlistID, varID) )
+    numavg = streamptr->tsteps[tsID].taxis.numavg;
 
-      FILE_UNLOCK();
+  if ( CDI_Debug )
+    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
+
+  size_t datasize = (size_t)gridInqSize(gridID);
+  /*
+  gribbuffersize = datasize*4+3000;
+  gribbuffer = (unsigned char *) malloc(gribbuffersize);
+  */
+#if  defined  (HAVE_LIBCGRIBEX)
+  if ( filetype == FILETYPE_GRB )
+    {
     }
   else
-    Error("file index %d undefined!", idx);
-
-  return (fileptr);
-}
+#endif
+    {
+#if defined (GRIBCONTAINER2D)
+      gribContainer_t **gribContainers =  (gribContainer_t **) streamptr->gribContainers;
+      gc = (void *) &gribContainers[varID][levelID];
+#else
+      gribContainer_t *gribContainers =  (gribContainer_t *) streamptr->gribContainers;
+      gc = (void *) &gribContainers[varID];
+#endif
+    }
 
-/* Create an index from a pointer */
-static
-int file_from_pointer(bfile_t *ptr)
-{
-  int      idx = -1;
-  filePtrToIdx *newptr;
+  if ( comptype != COMPRESS_JPEG && comptype != COMPRESS_SZIP ) comptype = COMPRESS_NONE;
 
-  if ( ptr )
+  if ( filetype == FILETYPE_GRB && comptype == COMPRESS_JPEG )
     {
-      FILE_LOCK();
+      static int ljpeg_warn = 1;
+      if ( ljpeg_warn ) Warning("JPEG compression of GRIB1 records not available!");
+      ljpeg_warn = 0;
+    }
 
-      if ( _fileAvail )
-	{
-	  newptr       = _fileAvail;
-	  _fileAvail   = _fileAvail->next;
-	  newptr->next = 0;
-	  idx	       = newptr->idx;
-	  newptr->ptr  = ptr;
+  nbytes = grbEncode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
+		     datasize, (const double*) data, nmiss, &gribbuffer, comptype, gc);
 
-	  if ( FILE_Debug )
-	    Message("Pointer %p has idx %d from file list", ptr, idx);
-	}
-      else
-	Warning("Too many open files (limit is %d)!", _file_max);
+  if ( filetype == FILETYPE_GRB && streamptr->comptype == COMPRESS_SZIP )
+    nbytes = grbSzip(filetype, gribbuffer, nbytes);
 
-      FILE_UNLOCK();
+  {
+    size_t (*myFileWrite)(int fileID, const void *restrict buffer,
+                          size_t len, int tsID)
+      = (size_t (*)(int, const void *restrict, size_t, int))
+      namespaceSwitchGet(NSSWITCH_FILE_WRITE).func;
+    nwrite = myFileWrite(fileID, gribbuffer, nbytes, tsID);
+  }
+
+  if ( nwrite != nbytes )
+    {
+      perror(__func__);
+      Error("Failed to write GRIB slice!");
     }
-  else
-    Error("Internal problem (pointer %p undefined)", ptr);
 
-  return (idx);
+  if ( gribbuffer ) free(gribbuffer);
 }
 
-static
-void file_init_entry(bfile_t *fileptr)
-{
-  fileptr->self          = file_from_pointer(fileptr);
-
-  fileptr->flag          = 0;
-  fileptr->fd            = -1;
-  fileptr->fp            = NULL;
-  fileptr->mode          = 0;
-  fileptr->size          = 0;
-  fileptr->name          = NULL;
-  fileptr->access        = 0;
-  fileptr->position      = 0;
-  fileptr->byteTrans     = 0;
-  fileptr->type          = 0;
-  fileptr->bufferType    = 0;
-  fileptr->bufferSize    = 0;
-  fileptr->mappedSize    = 0;
-  fileptr->buffer        = NULL;
-  fileptr->bufferNumFill = 0;
-  fileptr->bufferStart   = 0;
-  fileptr->bufferEnd     = -1;
-  fileptr->bufferPos     = 0;
-  fileptr->bufferCnt     = 0;
-  fileptr->bufferPtr     = NULL;
-  fileptr->time_in_sec   = 0.0;
-}
 
-static
-bfile_t *file_new_entry(void)
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
-  bfile_t *fileptr;
-
-  fileptr = (bfile_t *) malloc(sizeof(bfile_t));
+  int vlistID, gridID, zaxisID, levelID, nlevs;
+  int gridsize;
 
-  if ( fileptr ) file_init_entry(fileptr);
+  vlistID  = streamptr->vlistID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  nlevs    = zaxisInqSize(zaxisID);
 
-  return (fileptr);
+  for ( levelID = 0; levelID < nlevs; levelID++ )
+    {
+      if ( memtype == MEMTYPE_FLOAT )
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((float*)data)+levelID*gridsize, nmiss);
+      else
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
+    }
 }
 
-static
-void file_delete_entry(bfile_t *fileptr)
+
+void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
 {
-  int idx;
+  int filetype = streamptr1->filetype;
 
-  idx = fileptr->self;
+  int fileID1 = streamptr1->fileID;
+  int fileID2 = streamptr2->fileID;
+
+  int tsID    = streamptr1->curTsID;
+  int vrecID  = streamptr1->tsteps[tsID].curRecID;
+  int recID   = streamptr1->tsteps[tsID].recIDs[vrecID];
+  off_t recpos  = streamptr1->tsteps[tsID].records[recID].position;
+  size_t recsize = streamptr1->tsteps[tsID].records[recID].size;
 
-  FILE_LOCK();
+  fileSetPos(fileID1, recpos, SEEK_SET);
 
-  free(fileptr);
+  /* round up recsize to next multiple of 8 */
+  size_t gribbuffersize = ((recsize + 7U) & ~7U);
 
-  _fileList[idx].next = _fileAvail;
-  _fileList[idx].ptr  = 0;
-  _fileAvail   	      = &_fileList[idx];
+  unsigned char *gribbuffer = xmalloc(gribbuffersize);
 
-  FILE_UNLOCK();
+  if (fileRead(fileID1, gribbuffer, recsize) != recsize)
+    Error("Could not read GRIB record for copying!");
 
-  if ( FILE_Debug )
-    Message("Removed idx %d from file list", idx);
-}
+  size_t nbytes = recsize;
 
+  if ( filetype == FILETYPE_GRB )
+    {
+      long unzipsize;
+      int izip = gribGetZip((long)recsize, gribbuffer, &unzipsize);
 
-const char *fileLibraryVersion(void)
-{
-  return (file_libvers);
-}
+      if ( izip == 0 )
+        if ( streamptr2->comptype == COMPRESS_SZIP )
+          nbytes = grbSzip(filetype, gribbuffer, nbytes);
+    }
 
+  while ( nbytes & 7 ) gribbuffer[nbytes++] = 0;
 
-#ifndef POSIXIO_DEFAULT_PAGESIZE
-#define POSIXIO_DEFAULT_PAGESIZE 4096
-#endif
+  size_t nwrite = fileWrite(fileID2, gribbuffer, nbytes);
+  if ( nwrite != nbytes )
+    {
+      perror(__func__);
+      Error("Could not write record for copying!");
+    }
 
-static
-int pagesize(void)
-{
-#if defined(_SC_PAGESIZE)
-  return ((int) sysconf(_SC_PAGESIZE));
-#else
-  return ((int) POSIXIO_DEFAULT_PAGESIZE);
-#endif
+  free(gribbuffer);
 }
 
-static
-double file_time()
-{
-  double tseconds = 0.0;
-  struct timeval mytime;
-  gettimeofday(&mytime, NULL);
-  tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
-  return (tseconds);
-}
 
-void fileDebug(int debug)
+void grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss)
 {
-  FILE_Debug = debug;
+  int varID, levelID;
 
-  if ( FILE_Debug )
-    Message("Debug level %d", debug);
+  varID   = streamptr->record->varID;
+  levelID = streamptr->record->levelID;
+
+  grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 }
 
 
-void *filePtr(int fileID)
+void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
 {
-  bfile_t *fileptr;
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-  fileptr = file_to_pointer(fileID);
+  stream_check_ptr(__func__, streamptr);
 
-  return (fileptr);
-}
+  int filetype = streamptr->filetype;
 
-static
-void file_pointer_info(const char *caller, int fileID)
-{
-  if ( FILE_Debug )
+  if ( filetype == FILETYPE_GRB )
     {
-      fprintf(stdout, "%-18s : ", caller);
-      fprintf(stdout, "The fileID %d underlying pointer is not valid!", fileID);
-      fprintf(stdout, "\n");
+      int tsID     = streamptr->curTsID;
+      int vrecID   = streamptr->tsteps[tsID].curRecID;
+      int recID    = streamptr->tsteps[tsID].recIDs[vrecID];
+      off_t recpos = streamptr->tsteps[tsID].records[recID].position;
+      int zip      = streamptr->tsteps[tsID].records[recID].zip;
+
+      void *gribbuffer = streamptr->record->buffer;
+      size_t gribbuffersize = streamptr->record->buffersize;
+
+      if ( zip > 0 )
+	Error("Compressed GRIB records unsupported!");
+      else
+        grib_info_for_grads(recpos, (long)gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum, bignum);
     }
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
+#include <stdio.h>
 
-int fileSetBufferType(int fileID, int type)
-{
-  int ret = 0;
-  bfile_t *fileptr;
 
-  fileptr = file_to_pointer(fileID);
 
-  if ( fileptr )
-    {
-      switch (type)
-	{
-	case FILE_BUFTYPE_STD:
-	case FILE_BUFTYPE_MMAP:
-	  fileptr->bufferType = type;
-	  break;
-	default:
-	  Error("File type %d not implemented!", type);
-	}
-    }
+#if  defined  (HAVE_LIBGRIB_API)
 
-#if ! defined (HAVE_MMAP)
-  if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
+#  include <grib_api.h>
 #endif
 
-  return (ret);
-}
-
+extern int cdiInventoryMode;
 
-int fileGetBufferType(int fileID)
-{
-  bfile_t *fileptr;
-  int bufferType = 0;
+typedef struct {
+  int param;
+  int level1;
+  int level2;
+  int ltype;
+  int tsteptype;
+  char name[32];
+} compvar2_t;
 
-  fileptr = file_to_pointer(fileID);
 
-  if ( fileptr ) bufferType = fileptr->bufferType;
+#if  defined  (HAVE_LIBGRIB_API)
+static
+int my_grib_set_double(grib_handle* h, const char* key, double val)
+{
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val);
 
-  return (bufferType);
+  return grib_set_double(h, key, val);
 }
 
-
-int fileFlush(int fileID)
+static
+int my_grib_set_long(grib_handle* h, const char* key, long val)
 {
-  bfile_t *fileptr;
-  int retval = 0;
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_long(  \tgrib_handle* h, \"%s\", %ld)\n", key, val);
 
-  fileptr = file_to_pointer(fileID);
+  return grib_set_long(h, key, val);
+}
 
-  if ( fileptr ) retval = fflush(fileptr->fp);
+static
+int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t* length)
+{
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_string(\tgrib_handle* h, \"%s\", \"%s\")\n", key, val);
 
-  return (retval);
+  return grib_set_string(h, key, val, length);
 }
 
-
-void fileClearerr(int fileID)
+static
+int gribapiGetZaxisType(long editionNumber, int grib_ltype)
 {
-  bfile_t *fileptr;
-
-  fileptr = file_to_pointer(fileID);
+  int zaxistype = ZAXIS_GENERIC;
 
-  if ( fileptr )
+  if ( editionNumber <= 1 )
     {
-      if ( fileptr->mode != 'r' )
-	clearerr(fileptr->fp);
+      zaxistype = grib1ltypeToZaxisType(grib_ltype);
+    }
+  else
+    {
+      zaxistype = grib2ltypeToZaxisType(grib_ltype);
     }
-}
 
+  return (zaxistype);
+}
 
-int filePtrEOF(void *vfileptr)
+static
+int getTimeunits(long unitsOfTime)
 {
-  bfile_t *fileptr = (bfile_t *) vfileptr;
-  int retval = 0;
+  int timeunits = -1;
 
-  if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
+  switch (unitsOfTime)
+    {
+    case 13:  timeunits = TUNIT_SECOND;  break;
+    case  0:  timeunits = TUNIT_MINUTE;  break;
+    case  1:  timeunits = TUNIT_HOUR;    break;
+    case 10:  timeunits = TUNIT_3HOURS;  break;
+    case 11:  timeunits = TUNIT_6HOURS;  break;
+    case 12:  timeunits = TUNIT_12HOURS; break;
+    case  2:  timeunits = TUNIT_DAY;     break;
+    default:  timeunits = TUNIT_HOUR;    break;
+    }
 
-  return (retval);
+  return (timeunits);
 }
 
-
-int fileEOF(int fileID)
+static
+double timeunit_factor(int tu1, int tu2)
 {
-  bfile_t *fileptr;
-  int retval = 0;
-
-  fileptr = file_to_pointer(fileID);
+  double factor = 1;
 
-  if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
+  if ( tu2 == TUNIT_HOUR )
+    {
+      switch (tu1)
+        {
+        case TUNIT_SECOND:  factor = 3600;   break;
+        case TUNIT_MINUTE:  factor = 60;     break;
+        case TUNIT_HOUR:    factor = 1;      break;
+        case TUNIT_3HOURS:  factor = 1./3;   break;
+        case TUNIT_6HOURS:  factor = 1./6;   break;
+        case TUNIT_12HOURS: factor = 1./12;  break;
+        case TUNIT_DAY:     factor = 1./24;  break;
+        }
+    }
 
-  return (retval);
+  return (factor);
 }
 
-
-int fileError(int fileID)
+static
+int gribapiGetTimeUnits(grib_handle *gh)
 {
-  bfile_t *fileptr;
-  int retval = 0;
-
-  fileptr = file_to_pointer(fileID);
+  int timeunits = -1;
+  long unitsOfTime = -1;
 
-  if ( fileptr ) retval = (fileptr->flag & FILE_ERROR) != 0;
+  grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime);
 
-  return (retval);
-}
+  GRIB_CHECK(my_grib_set_long(gh, "stepUnits", unitsOfTime), 0);
 
+  timeunits = getTimeunits(unitsOfTime);
 
-void fileRewind(int fileID)
-{
-  fileSetPos(fileID, (off_t) 0, SEEK_SET);
-  fileClearerr(fileID);
+  return (timeunits);
 }
 
-
-off_t fileGetPos(int fileID)
+static
+int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
 {
-  off_t filepos = 0;
-  bfile_t *fileptr;
+  int endStep = startStep;
+  int timeunits2 = timeunits;
 
-  fileptr = file_to_pointer(fileID);
+  long unitsOfTime;
+  int status = grib_get_long(gh, "stepUnits", &unitsOfTime);
+  if ( status == 0 ) timeunits2 = getTimeunits(unitsOfTime);
+  //timeunits2 = gribapiGetTimeUnits(gh);
 
-  if ( fileptr )
-    {
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	filepos = fileptr->position;
-      else
-	filepos = ftell(fileptr->fp);
-    }
+  long lpar;
+  status = grib_get_long(gh, "endStep", &lpar);
 
-  if ( FILE_Debug ) Message("Position %ld", filepos);
+  if ( status == 0 )
+    endStep = (int) (((double)lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
+  // printf("%d %d %d %d %d %g\n", startStep, endStep, lpar, timeunits, timeunits2, timeunit_factor(timeunits, timeunits2));
 
-  return (filepos);
+  return (endStep);
 }
 
-
-int fileSetPos(int fileID, off_t offset, int whence)
+static
+void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
 {
-  int status = 0;
-  bfile_t *fileptr;
+  long lpar;
 
-  fileptr = file_to_pointer(fileID);
+  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
+  *datadate = (int) lpar;
+  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);  //FIXME: This looses the seconds in GRIB2 files.
+  *datatime = (int) lpar*100;
+}
 
-  if ( FILE_Debug ) Message("Offset %8ld  Whence %3d", (long) offset, whence);
+static
+void gribapiSetDataDateTime(grib_handle *gh, int datadate, int datatime)
+{
+  GRIB_CHECK(my_grib_set_long(gh, "dataDate", datadate), 0);
+  GRIB_CHECK(my_grib_set_long(gh, "dataTime", datatime/100), 0);
+}
 
-  if ( fileptr == 0 )
+static
+int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
+{
+  int rdate, rtime;
+  int timeUnits, startStep = 0, endStep;
+  int tstepRange = 0;
+  int range;
+  int status;
+  long lpar;
+  long sigofrtime = 3;
+
+  if ( gribEditionNumber(gh) > 1 )
     {
-      file_pointer_info(__func__, fileID);
-      return (1);
+      GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
+    }
+  else
+    {
+      GRIB_CHECK(grib_get_long(gh, "timeRangeIndicator", &sigofrtime), 0);
     }
 
-  switch (whence)
+  if ( sigofrtime == 3 )        //XXX: This looks like a bug to me, because timeRangeIndicator == 3 does not seem to have the same meaning as significanceOfReferenceTime == 3. I would recommend replacing this condition with `if(!gribapiTimeIsFC())`.
     {
-    case SEEK_SET:
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	{
-	  off_t position = offset;
-	  fileptr->position = position;
-	  if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
-	    {
-	      if ( fileptr->bufferType == FILE_BUFTYPE_STD )
-		fileptr->bufferPos = position;
-	      else
-		fileptr->bufferPos = position - position % pagesize();
+      gribapiGetDataDateTime(gh, vdate, vtime);
+    }
+  else
+    {
+      gribapiGetDataDateTime(gh, &rdate, &rtime);
 
-	      fileptr->bufferCnt = 0;
-	      fileptr->bufferPtr = NULL;
-	    }
-	  else
-	    {
-	      if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
-		{
-		  if ( FILE_Debug )
-		    Message("Reset buffer pos from %ld to %ld",
-			    fileptr->bufferPos, fileptr->bufferEnd + 1);
+      status = grib_get_long(gh, "forecastTime", &lpar);
+      if ( status == 0 ) startStep = (int) lpar;
+      timeUnits = gribapiGetTimeUnits(gh);
+      endStep = gribapiGetEndStep(gh, startStep, timeUnits);
 
-		  fileptr->bufferPos = fileptr->bufferEnd + 1;
-		}
-	      fileptr->bufferCnt = (size_t)(fileptr->bufferEnd - position) + 1;
-	      fileptr->bufferPtr = fileptr->buffer + position - fileptr->bufferStart;
-	    }
-	}
-      else
+      range = endStep - startStep;
+
+      if ( range > 0 )
 	{
-	  status = fseek(fileptr->fp, offset, whence);
+	  if ( startStep == 0 ) tstepRange = -1;
+	  else                  tstepRange =  1;
 	}
-      break;
-    case SEEK_CUR:
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	{
-	  fileptr->position += offset;
-	  off_t position = fileptr->position;
-	  if ( position < fileptr->bufferStart || position > fileptr->bufferEnd )
-	    {
-	      if ( fileptr->bufferType == FILE_BUFTYPE_STD )
-		fileptr->bufferPos = position;
-	      else
-		fileptr->bufferPos = position - position % pagesize();
 
-	      fileptr->bufferCnt = 0;
-	      fileptr->bufferPtr = NULL;
-	    }
-	  else
-	    {
-	      if ( fileptr->bufferPos != fileptr->bufferEnd + 1 )
-		{
-		  if ( FILE_Debug )
-		    Message("Reset buffer pos from %ld to %ld",
-			    fileptr->bufferPos, fileptr->bufferEnd + 1);
+      {
+	static int lprint = TRUE;
+	extern int grib_calendar;
+	int ryear, rmonth, rday, rhour, rminute, rsecond;
+	int julday, secofday;
+	int64_t time_period = endStep;
+        int64_t addsec;
 
-		  fileptr->bufferPos = fileptr->bufferEnd + 1;
-		}
-	      fileptr->bufferCnt -= (size_t)offset;
-	      fileptr->bufferPtr += offset;
-	    }
-	}
-      else
-	{
-	  status = fseek(fileptr->fp, offset, whence);
-	}
-      break;
-    default:
-      Error("Whence = %d not implemented", whence);
-    }
+	cdiDecodeDate(rdate, &ryear, &rmonth, &rday);
+	cdiDecodeTime(rtime, &rhour, &rminute, &rsecond);
 
-  if ( fileptr->position < fileptr->size )
-    if ( (fileptr->flag & FILE_EOF) != 0 )
-      fileptr->flag -= FILE_EOF;
+        if ( rday > 0 )
+          {
+            encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, rsecond, &julday, &secofday);
 
-  return (status);
+            addsec = 0;
+            switch ( timeUnits )
+              {
+              case TUNIT_SECOND:  addsec =         time_period; break;
+              case TUNIT_MINUTE:  addsec =    60 * time_period; break;
+              case TUNIT_HOUR:    addsec =  3600 * time_period; break;
+              case TUNIT_3HOURS:  addsec = 10800 * time_period; break;
+              case TUNIT_6HOURS:  addsec = 21600 * time_period; break;
+              case TUNIT_12HOURS: addsec = 43200 * time_period; break;
+              case TUNIT_DAY:     addsec = 86400 * time_period; break;
+              default:
+                if ( lprint )
+                  {
+                    Warning("Time unit %d unsupported", timeUnits);
+                    lprint = FALSE;
+                  }
+                break;
+              }
+
+            julday_add_seconds(addsec, &julday, &secofday);
+
+            decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &rsecond);
+          }
+
+	*vdate = cdiEncodeDate(ryear, rmonth, rday);
+	*vtime = cdiEncodeTime(rhour, rminute, rsecond);
+      }
+    }
+
+  return (tstepRange);
 }
 
 static
-void file_table_print(void)
+void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
 {
-  int fileID;
-  int lprintHeader = 1;
-  bfile_t *fileptr;
+  *leveltype = 0;
+  *lbounds   = 0;
+  *level1    = 0;
+  *level2    = 0;
 
-  for ( fileID = 0; fileID < _file_max; fileID++ )
+  long lpar;
+  if(!grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar))       //1 byte
     {
-      fileptr = file_to_pointer(fileID);
+      *leveltype = (int) lpar;
 
-      if ( fileptr )
+      switch (*leveltype)
 	{
-	  if ( lprintHeader )
-	    {
-	      fprintf(stderr, "\nFile table:\n");
-	      fprintf(stderr, "+-----+---------+");
-	      fprintf(stderr, "----------------------------------------------------+\n");
-	      fprintf(stderr, "|  ID |  Mode   |");
-	      fprintf(stderr, "  Name                                              |\n");
-	      fprintf(stderr, "+-----+---------+");
-	      fprintf(stderr, "----------------------------------------------------+\n");
-	      lprintHeader = 0;
-	    }
-
-	  fprintf(stderr, "| %3d | ", fileID);
+	case GRIB1_LTYPE_SIGMA_LAYER:
+	case GRIB1_LTYPE_HYBRID_LAYER:
+	case GRIB1_LTYPE_LANDDEPTH_LAYER:
+	  { *lbounds = 1; break; }
+	}
 
-	  switch ( fileptr->mode )
-	    {
-	    case 'r':
-	      fprintf(stderr, "read   ");
-	      break;
-	    case 'w':
-	      fprintf(stderr, "write  ");
-	      break;
-	    case 'a':
-	      fprintf(stderr, "append ");
-	      break;
-	    default:
-	      fprintf(stderr, "unknown");
-	    }
+      if ( *lbounds )
+	{
+	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);  //1 byte
+	  *level1 = (int)lpar;
+	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);       //1 byte
+	  *level2 = (int)lpar;
+	}
+      else
+	{
+          double dlevel;
+	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0); //2 byte
+	  if ( *leveltype == 100 ) dlevel *= 100;
+	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
+	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
 
-          fprintf(stderr, " | %-51s|\n", fileptr->name);
+	  *level1 = (int) dlevel;
+	  *level2 = 0;
 	}
     }
+}
 
-  if ( lprintHeader == 0 )
+static
+double grib2ScaleFactor(long factor)
+{
+  switch(factor)
     {
-      fprintf(stderr, "+-----+---------+");
-      fprintf(stderr, "----------------------------------------------------+\n");
+      case GRIB_MISSING_LONG: return 1;
+      case 0: return 1;
+      case 1: return 0.1;
+      case 2: return 0.01;
+      case 3: return 0.001;
+      case 4: return 0.0001;
+      case 5: return 0.00001;
+      case 6: return 0.000001;
+      case 7: return 0.0000001;
+      case 8: return 0.00000001;
+      case 9: return 0.000000001;
+      default: return 0;
     }
 }
 
+static
+int calcLevel(int level_sf, long factor, long level)
+{
+  double result = 0;
+  if(level != GRIB_MISSING_LONG) result = level*grib2ScaleFactor(factor);
+  if(level_sf) result *= level_sf;
+  return (int)result;
+}
 
-char *fileInqName(int fileID)
+static
+void grib2GetLevel(grib_handle *gh, int *leveltype1, int *leveltype2, int *lbounds, int *level1, 
+                   int *level2, int *level_sf, int *level_unit)
 {
-  bfile_t *fileptr;
-  char *name = NULL;
+  int status;
+  long lpar;
+  long factor;
 
-  fileptr = file_to_pointer(fileID);
+  *leveltype1 = 0;
+  *leveltype2 = -1;
+  *lbounds    = 0;
+  *level1     = 0;
+  *level2     = 0;
+  *level_sf   = 0;
+  *level_unit = 0;
 
-  if ( fileptr ) name = fileptr->name;
+  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar); //1 byte
+  if ( status == 0 )
+    {
+      long llevel;
 
-  return (name);
-}
+      *leveltype1 = (int) lpar;
 
+      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar); //1 byte
+      /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+      if ( status == 0 ) *leveltype2 = (int)lpar;
 
-int fileInqMode(int fileID)
-{
-  bfile_t *fileptr;
-  int mode = 0;
+      if ( *leveltype1 != 255 && *leveltype2 != 255 && *leveltype2 > 0 ) *lbounds = 1;
+      switch(*leveltype1)
+        {
+          case GRIB2_LTYPE_REFERENCE:
+            if(*leveltype2 == 1) *lbounds = 0;
+            break;
 
-  fileptr = file_to_pointer(fileID);
+          case GRIB2_LTYPE_LANDDEPTH:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_M;
+            break;
 
-  if ( fileptr ) mode = fileptr->mode;
+          case GRIB2_LTYPE_ISOBARIC:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_PA;
+            break;
 
-  return (mode);
+          case GRIB2_LTYPE_SIGMA:
+            *level_sf = 1000;
+            *level_unit = 0;
+            break;
+        }
+
+      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);      //1 byte
+      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);      //4 byte
+      *level1 = calcLevel(*level_sf, factor, llevel);
+
+      if ( *lbounds )
+        {
+          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0); //1 byte
+          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0); //4 byte
+          *level2 = calcLevel(*level_sf, factor, llevel);
+        }
+    }
 }
 
 static
-long file_getenv(const char *envName)
+void gribGetLevel(grib_handle *gh, int* leveltype1, int* leveltype2, int* lbounds, int* level1, int* level2, int* level_sf, int* level_unit)
 {
-  char *envString;
-  long envValue = -1;
-  long fact = 1;
-
-  envString = getenv(envName);
-
-  if ( envString )
+  if ( gribEditionNumber(gh) <= 1 )
     {
-      int loop;
-
-      for ( loop = 0; loop < (int) strlen(envString); loop++ )
-	{
-	  if ( ! isdigit((int) envString[loop]) )
-	    {
-	      switch ( tolower((int) envString[loop]) )
-		{
-		case 'k':  fact =       1024;  break;
-		case 'm':  fact =    1048576;  break;
-		case 'g':  fact = 1073741824;  break;
-		default:
-		  fact = 0;
-		  Message("Invalid number string in %s: %s", envName, envString);
-		  Warning("%s must comprise only digits [0-9].",envName);
-		}
-	      break;
-	    }
-	}
-
-      if ( fact ) envValue = fact*atol(envString);
-
-      if ( FILE_Debug ) Message("Set %s to %ld", envName, envValue);
+      grib1GetLevel(gh, leveltype1, lbounds, level1, level2);
+      *leveltype2 = -1;
+      *level_sf = 0;
+      *level_unit = 0;
+    }
+  else
+    {
+      grib2GetLevel(gh, leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
     }
+}
 
-  return (envValue);
+static
+void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t length)
+{
+  string[0] = 0;
+
+  GRIB_CHECK(grib_get_string(gh, key, string, &length), 0);
+  if      ( length == 8 && memcmp(string, "unknown", length) == 0 ) string[0] = 0;
+  else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
 }
 
+#if  defined  (HAVE_LIBGRIB_API)
 static
-void file_initialize(void)
+void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
+                      size_t recsize, off_t position, int datatype, int comptype, const char *varname,
+                      int leveltype1, int leveltype2, int lbounds, int level1, int level2, int level_sf, int level_unit)
 {
-  long value;
-  char *envString;
+  int zaxistype;
+  int gridID = CDI_UNDEFID, varID;
+  int levelID = 0;
+  int tsID, recID;
+  int numavg;
+  int tsteptype;
+  record_t *record;
+  grid_t grid;
+  int vlistID;
+  long lpar;
+  int status;
+  char stdname[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
+  size_t vlen;
+  long ens_index = 0, ens_count = 0, ens_forecast_type = 0;
 
-#if  defined  (HAVE_LIBPTHREAD)
-  /* initialize global API mutex lock */
-  pthread_mutex_init(&_file_mutex, NULL);
-#endif
+  vlistID = streamptr->vlistID;
+  tsID    = streamptr->curTsID;
+  recID   = recordNewEntry(streamptr, tsID);
+  record  = &streamptr->tsteps[tsID].records[recID];
 
-  value = file_getenv("FILE_DEBUG");
-  if ( value >= 0 ) FILE_Debug = (int) value;
+  tsteptype = gribapiGetTsteptype(gh);
+  // numavg  = ISEC1_AvgNum;
+  numavg  = 0;
 
-  value = file_getenv("FILE_MAX");
-  if ( value >= 0 ) _file_max = (int) value;
+  // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
 
-  if ( FILE_Debug )
-    Message("FILE_MAX = %d", _file_max);
+  (*record).size      = recsize;
+  (*record).position  = position;
+  (*record).param     = param;
+  (*record).ilevel    = level1;
+  (*record).ilevel2   = level2;
+  (*record).ltype     = leveltype1;
+  (*record).tsteptype = tsteptype;
 
-  FileInfo  = (int) file_getenv("FILE_INFO");
+  //FIXME: This may leave the variable name unterminated (which is the behavior that I found in the code).
+  //       I don't know precisely how this field is used, so I did not change this behavior to avoid regressions,
+  //       but I think that it would be better to at least add a line
+  //
+  //           record->varname[sizeof(record->varname) - 1] = 0;`
+  //
+  //       after the `strncpy()` call.
+  //
+  //       I would consider using strdup() (that requires POSIX-2008 compliance, though), or a similar homebrew approach.
+  //       I. e. kick the fixed size array and allocate enough space, whatever that may be.
+  strncpy(record->varname, varname, sizeof(record->varname));
 
-  value  = file_getenv("FILE_BUFSIZE");
-  if ( value >= 0 ) FileBufferSizeEnv = value;
-  else
-    {
-      value  = file_getenv("GRIB_API_IO_BUFFER_SIZE");
-      if ( value >= 0 ) FileBufferSizeEnv = value;
-    }
+  gribapiGetGrid(gh, &grid);
 
-  value = file_getenv("FILE_TYPE_READ");
-  if ( value > 0 )
-    {
-      switch (value)
-	{
-	case FILE_TYPE_OPEN:
-	case FILE_TYPE_FOPEN:
-	  FileTypeRead = (int)value;
-	  break;
-	default:
-	  Warning("File type %d not implemented!", value);
-	}
-    }
+  gridID = varDefGrid(vlistID, &grid, 0);
 
-  value = file_getenv("FILE_TYPE_WRITE");
-  if ( value > 0 )
-    {
-      switch (value)
-	{
-	case FILE_TYPE_OPEN:
-	case FILE_TYPE_FOPEN:
-	  FileTypeWrite = (int)value;
-	  break;
-	default:
-	  Warning("File type %d not implemented!", value);
-	}
-    }
+  zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
 
-#if defined (O_NONBLOCK)
-  FileFlagWrite = O_NONBLOCK;
-#endif
-  envString = getenv("FILE_FLAG_WRITE");
-  if ( envString )
+  switch (zaxistype)
     {
-#if defined (O_NONBLOCK)
-      if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
-#endif
-    }
+    case ZAXIS_HYBRID:
+    case ZAXIS_HYBRID_HALF:
+      {
+        int vctsize;
+        size_t dummy;
+        double *vctptr;
 
-  value = file_getenv("FILE_BUFTYPE");
-#if ! defined (HAVE_MMAP)
-  if ( value == FILE_BUFTYPE_MMAP )
-    {
-      Warning("MMAP not available!");
-      value = 0;
-    }
-#endif
-  if ( value > 0 )
-    {
-      switch (value)
-	{
-	case FILE_BUFTYPE_STD:
-	case FILE_BUFTYPE_MMAP:
-	  FileBufferTypeEnv = (int)value;
-	  break;
-	default:
-	  Warning("File buffer type %d not implemented!", value);
-	}
+        GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        vctsize = (int)lpar;
+        if ( vctsize > 0 )
+          {
+            vctptr = (double *) malloc(vctsize*sizeof(double));
+            dummy = (size_t)vctsize;
+            GRIB_CHECK(grib_get_double_array(gh, "pv", vctptr, &dummy), 0);
+            varDefVCT((size_t)vctsize, vctptr);
+            free(vctptr);
+          }
+        break;
+      }
+    case ZAXIS_REFERENCE:
+      {
+        size_t len;
+        unsigned char uuid[CDI_UUID_SIZE];
+        long ltmp;
+        long nhlev, nvgrid;
+
+        GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
+        if ( lpar != 6 )
+          {
+            fprintf(stderr, "Warning ...\n");
+          }
+        GRIB_CHECK(grib_get_long(gh, "nlev", &ltmp), 0);
+        nhlev = ltmp;
+        GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &ltmp), 0);
+        nvgrid = ltmp;
+        len = (size_t)CDI_UUID_SIZE;
+        memset(uuid, 0, CDI_UUID_SIZE);
+        GRIB_CHECK(grib_get_bytes(gh, "uuidOfVGrid", uuid, &len), 0);
+        varDefZAxisReference((int) nhlev, (int) nvgrid, uuid);
+        break;
+      }
     }
 
-  file_list_new();
-  atexit(file_list_delete);
+  // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
+  if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  FILE_LOCK();
+  stdname[0] = 0;
+  longname[0] = 0;
+  units[0] = 0;
 
-  file_init_pointer();
+  if ( varname[0] != 0 )
+    {
+      vlen = CDI_MAX_NAME;
+      gribapiGetString(gh, "name", longname, vlen);
+      vlen = CDI_MAX_NAME;
+      gribapiGetString(gh, "units", units, vlen);
 
-  FILE_UNLOCK();
+      {
+        vlen = CDI_MAX_NAME;
+        status = grib_get_string(gh, "cfName", stdname, &vlen);
+        if ( status != 0 || vlen <= 1 ) stdname[0] = 0;
+        else if ( strncmp(stdname, "unknown", 7) == 0 ) stdname[0] = 0;
+      }
+    }
+  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
 
-  if ( FILE_Debug ) atexit(file_table_print);
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf, level_unit,
+	       datatype, &varID, &levelID, tsteptype, numavg, leveltype1, leveltype2,
+	       varname, stdname, longname, units);
 
-  _file_init = TRUE;
-}
+  (*record).varID   = (short)varID;
+  (*record).levelID = (short)levelID;
 
-static
-void file_set_buffer(bfile_t *fileptr)
-{
-  size_t buffersize = 0;
+  varDefCompType(varID, comptype);
 
-  if ( fileptr->mode == 'r' )
+  /*
+    Get the ensemble Info from the grib-2 Tables and update the intermediate datastructure.
+    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdi_generate_vars"
+  */
+  status = grib_get_long(gh, "typeOfEnsembleForecast", &ens_forecast_type );
+  if ( status == 0 )
     {
-      if ( FileBufferTypeEnv )
-	fileptr->bufferType = FileBufferTypeEnv;
-      else if ( fileptr->bufferType == 0 )
-	fileptr->bufferType = FILE_BUFTYPE_STD;
+      GRIB_CHECK(grib_get_long(gh, "numberOfForecastsInEnsemble", &ens_count ), 0);
+      GRIB_CHECK(grib_get_long(gh, "perturbationNumber", &ens_index ), 0);
+    }
 
-      if ( FileBufferSizeEnv >= 0 )
-	buffersize = (size_t) FileBufferSizeEnv;
-      else if ( fileptr->bufferSize > 0 )
-	buffersize = fileptr->bufferSize;
-      else
-	{
-	  buffersize = fileptr->blockSize * 4;
-	  if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
-	}
+  if ( ens_index > 0 )
+    varDefEnsembleInfo(varID, (int)ens_index, (int)ens_count, (int)ens_forecast_type);
 
-      if ( (size_t) fileptr->size < buffersize )
-	buffersize = (size_t) fileptr->size;
+  long typeOfGeneratingProcess = 0;
+  status = grib_get_long(gh, "typeOfGeneratingProcess", &typeOfGeneratingProcess);
+  if ( status == 0 )
+    varDefTypeOfGeneratingProcess(varID, (int) typeOfGeneratingProcess);
 
-      if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
-	{
-	  size_t blocksize = (size_t) pagesize();
-	  size_t minblocksize = 4 * blocksize;
-	  buffersize = buffersize - buffersize % minblocksize;
+  long productDefinitionTemplate = 0;
+  status = grib_get_long(gh, "productDefinitionTemplateNumber", &productDefinitionTemplate);
+  if ( status == 0 )
+    varDefProductDefinitionTemplate(varID, (int) productDefinitionTemplate);
 
-	  if ( buffersize < (size_t) fileptr->size && buffersize < minblocksize )
-	    buffersize = minblocksize;
-	}
+  int    i;
+  long   lval;
+  double dval;
 
-      if ( buffersize == 0 ) buffersize = 1;
-    }
-  else
-    {
-      fileptr->bufferType = FILE_BUFTYPE_STD;
+  /* we read the additional keys for the first variable record only. */
+  int linitial_field = (varOptGribNentries(varID) == 0);
 
-      if ( FileBufferSizeEnv >= 0 )
-	buffersize = (size_t) FileBufferSizeEnv;
-      else if ( fileptr->bufferSize > 0 )
-	buffersize = fileptr->bufferSize;
-      else
+  for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
+    {
+      if ( linitial_field )
 	{
-	  buffersize = fileptr->blockSize * 4;
-	  if ( buffersize < FileBufferSizeMin ) buffersize = FileBufferSizeMin;
+	  if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
+            varDefOptGribInt(varID, lval, cdiAdditionalGRIBKeys[i]);
+	}
+      if ( linitial_field )
+	{
+	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
+            varDefOptGribDbl(varID, dval, cdiAdditionalGRIBKeys[i]);
 	}
+      /* note: if the key is not defined, we do not throw an error! */
     }
 
-  if ( fileptr->bufferType == FILE_BUFTYPE_STD || fileptr->type == FILE_TYPE_FOPEN )
+  if ( varInqInst(varID) == CDI_UNDEFID )
     {
-      if ( buffersize > 0 )
-        {
-          fileptr->buffer = (char *) malloc(buffersize);
-          if ( fileptr->buffer == NULL )
-            SysError("Allocation of file buffer failed!");
-        }
+      long center, subcenter;
+      int instID;
+      GRIB_CHECK(grib_get_long(gh, "centre", &center), 0);
+      GRIB_CHECK(grib_get_long(gh, "subCentre", &subcenter), 0);
+      instID    = institutInq((int)center, (int)subcenter, NULL, NULL);
+      if ( instID == CDI_UNDEFID )
+	instID = institutDef((int)center, (int)subcenter, NULL, NULL);
+      varDefInst(varID, instID);
     }
 
-  if ( fileptr->type == FILE_TYPE_FOPEN )
-    if ( setvbuf(fileptr->fp, fileptr->buffer, fileptr->buffer ? _IOFBF : _IONBF, buffersize) )
-      SysError("setvbuf failed!");
-
-  fileptr->bufferSize = buffersize;
-}
-
-static
-int file_fill_buffer(bfile_t *fileptr)
-{
-  ssize_t nread;
-  int fd;
-  long offset = 0;
-  off_t retseek;
-
-  if ( FILE_Debug )
-    Message("file ptr = %p  Cnt = %ld", fileptr, fileptr->bufferCnt);
-
-  if ( (fileptr->flag & FILE_EOF) != 0 ) return (EOF);
-
-  if ( fileptr->buffer == NULL ) file_set_buffer(fileptr);
-
-  if ( fileptr->bufferSize == 0 ) return (EOF);
-
-  fd = fileptr->fd;
-
-#if defined (HAVE_MMAP)
-  if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
+  if ( varInqModel(varID) == CDI_UNDEFID )
     {
-      if ( fileptr->bufferPos >= fileptr->size )
+      int modelID;
+      long processID;
+      status = grib_get_long(gh, "generatingProcessIdentifier", &processID);
+      if ( status == 0 )
 	{
-	  nread = 0;
+          /* FIXME: assert(processID >= INT_MIN && processID <= INT_MAX) */
+	  modelID = modelInq(varInqInst(varID), (int)processID, NULL);
+	  if ( modelID == CDI_UNDEFID )
+	    modelID = modelDef(varInqInst(varID), (int)processID, NULL);
+	  varDefModel(varID, modelID);
 	}
-      else
-	{
-          xassert(fileptr->bufferSize <= SSIZE_MAX);
-	  nread = (ssize_t)fileptr->bufferSize;
-	  if ( (nread + fileptr->bufferPos) > fileptr->size )
-	    nread = fileptr->size - fileptr->bufferPos;
+    }
 
-	  if ( fileptr->buffer )
-	    {
-              int ret;
-	      ret = munmap(fileptr->buffer, fileptr->mappedSize);
-	      if ( ret == -1 ) SysError("munmap error for read %s", fileptr->name);
-	      fileptr->buffer = NULL;
-	    }
+  if ( varInqTable(varID) == CDI_UNDEFID )
+    {
+      int pdis, pcat, pnum;
 
-	  fileptr->mappedSize = (size_t)nread;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
-	  fileptr->buffer = (char*) mmap(NULL, (size_t) nread, PROT_READ, MAP_PRIVATE, fd, fileptr->bufferPos);
+      if ( pdis == 255 )
+	{
+	  int tableID;
+	  int tabnum = pcat;
 
-	  if ( fileptr->buffer == MAP_FAILED ) SysError("mmap error for read %s", fileptr->name);
+	  tableID = tableInq(varInqModel(varID), tabnum, NULL);
 
-	  offset = fileptr->position - fileptr->bufferPos;
+	  if ( tableID == CDI_UNDEFID )
+	    tableID = tableDef(varInqModel(varID), tabnum, NULL);
+	  varDefTable(varID, tableID);
 	}
     }
-  else
-#endif
-    {
-      retseek = lseek(fileptr->fd, fileptr->bufferPos, SEEK_SET);
-      if ( retseek == (off_t)-1 )
-	SysError("lseek error at pos %ld file %s", (long) fileptr->bufferPos, fileptr->name);
 
-      nread = read(fd, fileptr->buffer, fileptr->bufferSize);
-    }
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
 
-  if ( nread <= 0 )
-    {
-      if ( nread == 0 )
-	fileptr->flag |= FILE_EOF;
-      else
-	fileptr->flag |= FILE_ERROR;
+  if ( CDI_Debug )
+    Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
+	    varID, param, zaxistype, gridID, levelID);
+}
+#endif
 
-      fileptr->bufferCnt = 0;
-      return (EOF);
-    }
+static
+compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype, char *name)
+{
+  compvar2_t compVar;
+  size_t maxlen = sizeof(compVar.name);
+  size_t len = strlen(name);
+  if ( len > maxlen ) len = maxlen;
 
-  fileptr->bufferPtr = fileptr->buffer;
-  fileptr->bufferCnt = (size_t)nread;
+  compVar.param     = param;
+  compVar.level1    = level1;
+  compVar.level2    = level2;
+  compVar.ltype     = leveltype;
+  compVar.tsteptype = tsteptype;
+  memset(compVar.name, 0, maxlen);
+  memcpy(compVar.name, name, len);
 
-  fileptr->bufferStart = fileptr->bufferPos;
-  fileptr->bufferPos  += nread;
-  fileptr->bufferEnd   = fileptr->bufferPos - 1;
+  return (compVar);
+}
+#endif
 
-  if ( FILE_Debug )
-    {
-      Message("fileID = %d  Val     = %d",  fileptr->self, (int) fileptr->buffer[0]);
-      Message("fileID = %d  Start   = %ld", fileptr->self, fileptr->bufferStart);
-      Message("fileID = %d  End     = %ld", fileptr->self, fileptr->bufferEnd);
-      Message("fileID = %d  nread   = %ld", fileptr->self, nread);
-      Message("fileID = %d  offset  = %ld", fileptr->self, offset);
-      Message("fileID = %d  Pos     = %ld", fileptr->self, fileptr->bufferPos);
-      Message("fileID = %d  postion = %ld", fileptr->self, fileptr->position);
-    }
+static
+int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
+{
+  compvar2_t compVar0;
+  size_t maxlen = sizeof(compVar.name);
+
+  compVar0.param     = record.param;
+  compVar0.level1    = record.ilevel;
+  compVar0.level2    = record.ilevel2;
+  compVar0.ltype     = record.ltype;
+  compVar0.tsteptype = record.tsteptype;
+  memcpy(compVar0.name, record.varname, maxlen);
 
-  if ( offset > 0 )
+  if ( flag == 0 )
     {
-      if ( offset > nread )
-	Error("Internal problem with buffer handling. nread = %d offset = %d", nread, offset);
-
-      fileptr->bufferPtr += offset;
-      fileptr->bufferCnt -= (size_t)offset;
+      if ( compVar0.tsteptype == TSTEP_INSTANT  && compVar.tsteptype == TSTEP_INSTANT3 ) compVar0.tsteptype = TSTEP_INSTANT3;
+      if ( compVar0.tsteptype == TSTEP_INSTANT3 && compVar.tsteptype == TSTEP_INSTANT  ) compVar0.tsteptype = TSTEP_INSTANT;
     }
 
-  fileptr->bufferNumFill++;
+  int rstatus = memcmp(&compVar0, &compVar, sizeof(compvar2_t));
 
-  return ((unsigned char) *fileptr->bufferPtr);
+  return (rstatus);
+}
+
+static void ensureBufferSize(size_t requiredSize, size_t* curSize, unsigned char** buffer) {
+  if ( *curSize < requiredSize )
+    {
+      *curSize = requiredSize;
+      *buffer = realloc(*buffer, *curSize);
+    }
 }
 
+#if  defined  (HAVE_LIBGRIB_API)
 static
-void file_copy_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
+grib_handle* gribapiGetDiskRepresentation(long recsize, size_t* buffersize, unsigned char** gribbuffer, int* outDatatype, int* outCompressionType, long* outUnzipsize)
 {
-  if ( FILE_Debug )
-    Message("size = %ld  Cnt = %ld", size, fileptr->bufferCnt);
+  int lieee = FALSE;
 
-  if ( fileptr->bufferCnt < size )
-    Error("Buffer too small. bufferCnt = %d", fileptr->bufferCnt);
+  grib_handle* gh = grib_handle_new_from_message(NULL, (void *) *gribbuffer, recsize);
+  if(gribEditionNumber(gh) > 1)
+    {
+      size_t len = 256;
+      char typeOfPacking[256];
 
-  if ( size == 1 )
+      if ( grib_get_string(gh, "packingType", typeOfPacking, &len) == 0 )
+        {
+          // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
+          if      ( strncmp(typeOfPacking, "grid_jpeg", len) == 0 ) *outCompressionType = COMPRESS_JPEG;
+          else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = COMPRESS_SZIP;
+          else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = TRUE;
+        }
+    }
+  else
     {
-      ((char *)ptr)[0] = fileptr->bufferPtr[0];
+      if( gribGetZip(recsize, *gribbuffer, outUnzipsize) > 0 )
+        {
+          *outCompressionType = COMPRESS_SZIP;
+          ensureBufferSize(*outUnzipsize + 100, buffersize, gribbuffer);
+        }
+      else
+        {
+          *outCompressionType = COMPRESS_NONE;
+        }
+    }
 
-      fileptr->bufferPtr++;
-      fileptr->bufferCnt--;
+  if ( lieee )
+    {
+      *outDatatype = DATATYPE_FLT64;
+      long precision;
+      int status = grib_get_long(gh, "precision", &precision);
+      if ( status == 0 && precision == 1 ) *outDatatype = DATATYPE_FLT32;
     }
   else
     {
-      memcpy(ptr, fileptr->bufferPtr, size);
+      *outDatatype = DATATYPE_PACK;
+      long bitsPerValue;
+      if ( grib_get_long(gh, "bitsPerValue", &bitsPerValue) == 0 )
+        {
+          if ( bitsPerValue > 0 && bitsPerValue <= 32 ) *outDatatype = (int)bitsPerValue;
+        }
+    }
+  return gh;
+}
+#endif
 
-      fileptr->bufferPtr += size;
-      fileptr->bufferCnt -= size;
+typedef enum { CHECKTIME_OK, CHECKTIME_SKIP, CHECKTIME_STOP, CHECKTIME_INCONSISTENT } checkTimeResult;
+static checkTimeResult checkTime(stream_t* streamptr, compvar2_t compVar, const DateTime* verificationTime, const DateTime* expectedVTime) {
+  //First determine whether the current record exists already.
+  int recID = 0;
+  for ( ; recID < streamptr->nrecs; recID++ )
+    {
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
+    }
+  int recordExists = recID < streamptr->nrecs;
+
+  //Then we need to know whether the verification time is consistent.
+  int consistentTime = !memcmp(verificationTime, expectedVTime, sizeof(*verificationTime));
+
+  //Finally, we make a decision.
+  if ( cdiInventoryMode == 1 )
+    {
+      if ( recordExists ) return CHECKTIME_STOP;
+      if ( !consistentTime ) return CHECKTIME_INCONSISTENT;
+    }
+  else
+    {
+      if ( !consistentTime ) return CHECKTIME_STOP;
+      if ( recordExists ) return CHECKTIME_SKIP;
     }
+  return CHECKTIME_OK;
 }
 
-static
-size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
+#define gribWarning(text, nrecs, timestep, varname, param, level1, level2) do \
+  { \
+    char paramstr[32]; \
+    cdiParamToString(param, paramstr, sizeof(paramstr)); \
+    Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text); \
+  } \
+while(0)
+
+int gribapiScanTimestep1(stream_t * streamptr)
 {
-  size_t nread, rsize;
-  size_t offset = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  off_t recpos = 0;
+  unsigned char *gribbuffer = NULL;
+  size_t buffersize = 0;
+  DateTime datetime0 = { .date = 10101, .time = 0 };
+  int nrecs_scanned = 0;        //Only used for debug output.
+  int warn_time = TRUE;
+  // int warn_numavg = TRUE;
+  int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
+  grib_handle *gh = NULL;
 
-  if ( FILE_Debug )
-    Message("size = %ld  Cnt = %ld", size, (long) fileptr->bufferCnt);
+  streamptr->curTsID = 0;
 
-  if ( ((long)fileptr->bufferCnt) < 0L )
-    Error("Internal problem. bufferCnt = %ld", (long) fileptr->bufferCnt);
+  int tsID  = tstepsNewEntry(streamptr);
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-  rsize = size;
+  if ( tsID != 0 )
+    Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  while ( fileptr->bufferCnt < rsize )
+  int fileID = streamptr->fileID;
+
+  int nrecs = 0;
+  while ( TRUE )
     {
-      nread = fileptr->bufferCnt;
-      /*
-      fprintf(stderr, "rsize = %d nread = %d\n", (int) rsize, (int) nread);
-      */
-      if ( nread > (size_t) 0 )
-	file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
-      offset += nread;
-      if ( nread < rsize )
-	rsize -= nread;
-      else
-	rsize = 0;
+      int level1 = 0, level2 = 0;
+      size_t recsize = (size_t)gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
 
-      if ( file_fill_buffer(fileptr) == EOF ) break;
-    }
+      if ( recsize == 0 )
+        {
+          streamptr->ntsteps = 1;
+          break;
+        }
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-  nread = size - offset;
+      size_t readsize = recsize;
+      int rstatus = gribRead(fileID, gribbuffer, &readsize);        //Search for next 'GRIB', read the following record, and position file offset after it.
+      if ( rstatus ) break;
 
-  if ( fileptr->bufferCnt < nread ) nread = fileptr->bufferCnt;
+      int datatype, comptype = 0;
+      long unzipsize;
+      gh = gribapiGetDiskRepresentation(recsize, &buffersize, &gribbuffer, &datatype, &comptype, &unzipsize);
 
-  if ( nread > (unsigned) 0 )
-    file_copy_from_buffer(fileptr, (char *)ptr+offset, nread);
+      nrecs_scanned++;
+      GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-  return (nread+offset);
-}
+      int param = gribapiGetParam(gh);
+      int leveltype1 = -1, leveltype2 = -1, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
+      char varname[256];
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
-void fileSetBufferSize(int fileID, long buffersize)
-{
-  bfile_t *fileptr = file_to_pointer(fileID);
-  xassert(buffersize >= 0);
-  if ( fileptr ) fileptr->bufferSize = (size_t)buffersize;
-}
+      int tsteptype = gribapiGetTsteptype(gh);
+      int vdate = 0, vtime = 0;
+      gribapiGetValidityDateTime(gh, &vdate, &vtime);
+      DateTime datetime = { .date = vdate, .time = vtime };
+      /*
+      printf("%d %d %d\n", vdate, vtime, leveltype1);
+      */
 
-/*
- *   Open a file. Returns file ID, or -1 on error
- */
-int fileOpen(const char *filename, const char *mode)
-{
-  int (*myFileOpen)(const char *filename, const char *mode)
-    = (int (*)(const char *, const char *))
-    namespaceSwitchGet(NSSWITCH_FILE_OPEN).func;
-  return myFileOpen(filename, mode);
-}
+      if( datetime0.date == 10101 && datetime0.time == 0 )
+        {
+          if( memcmp(&datetime, &datetime0, sizeof(datetime)) || !nrecs )       //Do we really need this condition? I have included it in order not to change the number of times gribapiGetDataDateTime() etc. get called. But if those are sideeffect-free, this condition should be removed.
+            {
+              datetime0 = datetime;
 
-int fileOpen_serial(const char *filename, const char *mode)
-{
-  FILE *fp = NULL;    /* file pointer    (used for write) */
-  int fd = -1;        /* file descriptor (used for read)  */
-  int fileID = FILE_UNDEFID;
-  int fmode = 0;
-  struct stat filestat;
-  bfile_t *fileptr = NULL;
+              gribapiGetDataDateTime(gh, &rdate, &rtime);
 
-  FILE_INIT();
+              fcast = gribapiTimeIsFC(gh);
+              if ( fcast ) tunit = gribapiGetTimeUnits(gh);
+            }
+        }
 
-  fmode = tolower((int) mode[0]);
+      if(nrecs)
+        {
+          checkTimeResult result = checkTime(streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname), &datetime, &datetime0);
+          if(result == CHECKTIME_STOP)
+            {
+              break;
+            }
+          else if(result == CHECKTIME_SKIP)
+            {
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              continue;
+            }
+          else if(result == CHECKTIME_INCONSISTENT && warn_time)
+            {
+              gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              warn_time = FALSE;
+            }
+          assert(result == CHECKTIME_OK || result == CHECKTIME_INCONSISTENT);
+        }
+      /*
+      if ( ISEC1_AvgNum )
+        {
+          if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
+            {
+              Message("Change numavg from %d to %d not allowed!",
+                      taxis->numavg, ISEC1_AvgNum);
+              warn_numavg = FALSE;
+            }
+          else
+            {
+              taxis->numavg = ISEC1_AvgNum;
+            }
+        }
+      */
+      nrecs++;
 
-  switch ( fmode )
-    {
-    case 'r':
-      if ( FileTypeRead == FILE_TYPE_FOPEN )
-	fp = fopen(filename, "rb");
-      else
-	fd =  open(filename, O_RDONLY | O_BINARY);
-      break;
-    case 'x':  fp = fopen(filename, "rb");      break;
-    case 'w':
-      if ( FileTypeWrite == FILE_TYPE_FOPEN )
-        fp = fopen(filename, "wb");
-      else
-	fd =  open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
-      break;
-    case 'a':  fp = fopen(filename, "ab");      break;
-    default:   Error("Mode %c unexpected!", fmode);
+      if ( CDI_Debug )
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+                nrecs, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
+
+      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, varname,
+                       leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
+
+      grib_handle_delete(gh);
+      gh = NULL;
     }
 
-  if ( FILE_Debug )
-    if ( fp == NULL && fd == -1 )
-      Message("Open failed on %s mode %c errno %d", filename, fmode, errno);
+  if ( gh ) grib_handle_delete(gh);
 
-  if ( fp )
-    {
-      if ( stat(filename, &filestat) != 0 ) return (fileID);
+  streamptr->rtsteps = 1;
 
-      fileptr = file_new_entry();
-      if ( fileptr )
-	{
-	  fileID = fileptr->self;
-	  fileptr->fp = fp;
-	}
+  if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
+
+  cdi_generate_vars(streamptr);
+
+  int taxisID = -1;
+  if ( fcast )
+    {
+      taxisID = taxisCreate(TAXIS_RELATIVE);
+      taxis->type  = TAXIS_RELATIVE;
+      taxis->rdate = rdate;
+      taxis->rtime = rtime;
+      taxis->unit  = tunit;
     }
-  else if ( fd >= 0 )
+  else
     {
-      if ( fstat(fd, &filestat) != 0 ) return (fileID);
-
-      fileptr = file_new_entry();
-      if ( fileptr )
-	{
-	  fileID = fileptr->self;
-	  fileptr->fd = fd;
-	}
+      taxisID = taxisCreate(TAXIS_ABSOLUTE);
+      taxis->type  = TAXIS_ABSOLUTE;
     }
 
-  if ( fileID >= 0 )
+  taxis->vdate = (int)datetime0.date;
+  taxis->vtime = (int)datetime0.time;
+
+  int vlistID = streamptr->vlistID;
+  vlistDefTaxis(vlistID, taxisID);
+
+  int nrecords = streamptr->tsteps[0].nallrecs;
+  if ( nrecords < streamptr->tsteps[0].recordSize )
     {
-      fileptr->mode = fmode;
-      fileptr->name = strdupx(filename);
+      streamptr->tsteps[0].recordSize = nrecords;
+      streamptr->tsteps[0].records =
+      (record_t *) realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
+    }
 
-#if defined (HAVE_STRUCT_STAT_ST_BLKSIZE)
-      fileptr->blockSize = (size_t) filestat.st_blksize;
-#else
-      fileptr->blockSize = (size_t) 4096;
-#endif
+  streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
+  streamptr->tsteps[0].nrecs = nrecords;
+  for ( int recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[0].recIDs[recID] = recID;
 
-      if ( fmode == 'r' )
-        fileptr->type = FileTypeRead;
-      else if ( fmode == 'w' )
-        fileptr->type = FileTypeWrite;
-      else
-	fileptr->type = FILE_TYPE_FOPEN;
+  streamptr->record->buffer     = gribbuffer;
+  streamptr->record->buffersize = buffersize;
 
-      if ( fmode == 'r' ) fileptr->size = filestat.st_size;
+  if ( streamptr->ntsteps == -1 )
+    {
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+        Error("Internal error. tsID = %d", tsID);
 
-      if ( fileptr->type == FILE_TYPE_FOPEN ) file_set_buffer(fileptr);
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
+    }
 
-      if ( FILE_Debug )
-	Message("File %s opened with ID %d", filename, fileID);
+  if ( streamptr->ntsteps == 1 )
+    {
+      if ( taxis->vdate == 0 && taxis->vtime == 0 )
+        {
+          streamptr->ntsteps = 0;
+          for ( int varID = 0; varID < streamptr->nvars; varID++ )
+            {
+              vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+            }
+        }
     }
+#else
+  (void)streamptr;
+  Error("GRIB_API support not compiled in!");
+#endif
 
-  return (fileID);
+  return (0);
 }
 
-/*
- *   Close a file.
- */
-int fileClose(int fileID)
-{
-  int (*myFileClose)(int fileID)
-    = (int (*)(int))namespaceSwitchGet(NSSWITCH_FILE_CLOSE).func;
-  return myFileClose(fileID);
-}
 
-int fileClose_serial(int fileID)
+#ifdef HAVE_LIBGRIB_API
+int gribapiScanTimestep2(stream_t * streamptr)
 {
-  char *name;
-  int ret;
-  char *fbtname[] = {"unknown", "standard", "mmap"};
-  char *ftname[] = {"unknown", "open", "fopen"};
-  bfile_t *fileptr = file_to_pointer(fileID);
-  double rout = 0;
-
-  if ( fileptr == NULL )
-    {
-      file_pointer_info(__func__, fileID);
-      return (1);
-    }
+  int rstatus = 0;
+  off_t recpos = 0;
+  unsigned char *gribbuffer = NULL;
+  size_t buffersize = 0;
+  int fileID;
+  DateTime datetime0;
+  // int gridID;
+  int recID;
+  //  int warn_numavg = TRUE;
+  grib_handle *gh = NULL;
 
-  name = fileptr->name;
+  streamptr->curTsID = 1;
 
-  if ( FILE_Debug )
-    Message("fileID = %d  filename = %s", fileID, name);
+  fileID  = streamptr->fileID;
+  int vlistID = streamptr->vlistID;
+  int taxisID = vlistInqTaxis(vlistID);
 
-  if ( FileInfo > 0 )
-    {
-      fprintf(stderr, "____________________________________________\n");
-      fprintf(stderr, " file ID          : %d\n",  fileID);
-      fprintf(stderr, " file name        : %s\n",  fileptr->name);
-      fprintf(stderr, " file type        : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
+  gribbuffer = (unsigned char *) streamptr->record->buffer;
+  buffersize = streamptr->record->buffersize;
 
-      if ( fileptr->type == FILE_TYPE_FOPEN )
-	fprintf(stderr, " file pointer     : %p\n",  (void *) fileptr->fp);
-      else
-        {
-          fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
-          fprintf(stderr, " file flag        : %d\n", FileFlagWrite);
-        }
-      fprintf(stderr, " file mode        : %c\n",  fileptr->mode);
+  int tsID = streamptr->rtsteps;
+  if ( tsID != 1 )
+    Error("Internal problem! unexpected timestep %d", tsID+1);
 
-      if ( sizeof(off_t) > sizeof(long) )
-	{
-#if defined (_WIN32)
-	  fprintf(stderr, " file size        : %I64d\n", (long long) fileptr->size);
-	  if ( fileptr->type == FILE_TYPE_OPEN )
-	    fprintf(stderr, " file position    : %I64d\n", (long long) fileptr->position);
-	  fprintf(stderr, " bytes transfered : %I64d\n", (long long) fileptr->byteTrans);
-#else
-	  fprintf(stderr, " file size        : %lld\n", (long long) fileptr->size);
-	  if ( fileptr->type == FILE_TYPE_OPEN )
-	    fprintf(stderr, " file position    : %lld\n", (long long) fileptr->position);
-	  fprintf(stderr, " bytes transfered : %lld\n", (long long) fileptr->byteTrans);
-#endif
-	}
-      else
-	{
-	  fprintf(stderr, " file size        : %ld\n", (long) fileptr->size);
-	  if ( fileptr->type == FILE_TYPE_OPEN )
-	    fprintf(stderr, " file position    : %ld\n", (long) fileptr->position);
-	  fprintf(stderr, " bytes transfered : %ld\n", (long) fileptr->byteTrans);
-	}
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-      if ( fileptr->time_in_sec > 0 )
-        {
-          rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
-        }
+  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      fprintf(stderr, " wall time [s]    : %.2f\n", fileptr->time_in_sec);
-      fprintf(stderr, " data rate [MB/s] : %.1f\n", rout);
+  cdi_create_records(streamptr, tsID);
 
-      fprintf(stderr, " file access      : %ld\n", fileptr->access);
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	{
-	  fprintf(stderr, " buffer type      : %d (%s)\n", fileptr->bufferType, fbtname[fileptr->bufferType]);
-	  fprintf(stderr, " num buffer fill  : %ld\n", fileptr->bufferNumFill);
-	}
-      fprintf(stderr, " buffer size      : %lu\n", (unsigned long) fileptr->bufferSize);
-      fprintf(stderr, " block size       : %lu\n", (unsigned long) fileptr->blockSize);
-      fprintf(stderr, " page size        : %d\n",  pagesize());
-      fprintf(stderr, "--------------------------------------------\n");
-    }
+  int nrecords = streamptr->tsteps[tsID].nallrecs;
+  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
+  streamptr->tsteps[1].nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[1].recIDs[recID] = -1;
 
-  if ( fileptr->type == FILE_TYPE_FOPEN )
+  for ( recID = 0; recID < nrecords; recID++ )
     {
-      ret = fclose(fileptr->fp);
-      if ( ret == EOF )
-	SysError("EOF returned for close of %s!", name);
+      streamptr->tsteps[tsID].records[recID].position = streamptr->tsteps[0].records[recID].position;
+      streamptr->tsteps[tsID].records[recID].size     = streamptr->tsteps[0].records[recID].size;
     }
-  else
+
+  int nrecs_scanned = nrecords; //Only used for debug output
+  int rindex = 0;
+  while ( TRUE )
     {
-#if defined (HAVE_MMAP)
-      if ( fileptr->buffer && fileptr->mappedSize )
+      if ( rindex > nrecords ) break;
+
+      size_t recsize = (size_t)gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
+      if ( recsize == 0 )
 	{
-	  ret = munmap(fileptr->buffer, fileptr->mappedSize);
-	  if ( ret == -1 ) SysError("munmap error for close %s", fileptr->name);
-	  fileptr->buffer = NULL;
+	  streamptr->ntsteps = 2;
+	  break;
 	}
-#endif
-      ret = close(fileptr->fd);
-      if ( ret == -1 )
-	SysError("EOF returned for close of %s!", name);
-    }
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-  if ( fileptr->name )    free((void*) fileptr->name);
-  if ( fileptr->buffer )  free((void*) fileptr->buffer);
+      size_t readsize = recsize;
+      rstatus = gribRead(fileID, gribbuffer, &readsize);
+      if ( rstatus ) break;
 
-  file_delete_entry(fileptr);
+      long unzipsize;
+      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
-  return (0);
-}
+      nrecs_scanned++;
+      gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
+      GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
+      int param = gribapiGetParam(gh);
+      int level1 = 0, level2 = 0, leveltype1, leveltype2, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
-int filePtrGetc(void *vfileptr)
-{
-  int ivalue = EOF;
-  int fillret = 0;
-  bfile_t *fileptr = (bfile_t *) vfileptr;
+      char varname[256];
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
-  if ( fileptr )
-    {
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	{
-	  if ( fileptr->bufferCnt == 0 ) fillret = file_fill_buffer(fileptr);
+      int vdate = 0, vtime = 0;
+      gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
-	  if ( fillret >= 0 )
+      if ( rindex == 0 )
+	{
+	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 	    {
-	      ivalue = (unsigned char) *fileptr->bufferPtr++;
-	      fileptr->bufferCnt--;
-	      fileptr->position++;
+	      taxis->type  = TAXIS_RELATIVE;
 
-	      fileptr->byteTrans++;
-	      fileptr->access++;
+              gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
+
+	      taxis->unit  = gribapiGetTimeUnits(gh);
+	    }
+	  else
+	    {
+	      taxis->type  = TAXIS_ABSOLUTE;
 	    }
+	  taxis->vdate = vdate;
+	  taxis->vtime = vtime;
+
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
 	}
-      else
+
+      int tsteptype = gribapiGetTsteptype(gh);
+      /*
+      if ( ISEC1_AvgNum )
 	{
-	  ivalue = fgetc(fileptr->fp);
-	  if ( ivalue >= 0 )
+	  if (  taxis->numavg && warn_numavg &&
+		(taxis->numavg != ISEC1_AvgNum) )
 	    {
-	      fileptr->byteTrans++;
-	      fileptr->access++;
+	      warn_numavg = FALSE;
 	    }
 	  else
-	    fileptr->flag |= FILE_EOF;
+	    {
+	      taxis->numavg = ISEC1_AvgNum;
+	    }
 	}
-    }
-
-  return (ivalue);
-}
-
-
-int fileGetc(int fileID)
-{
-  int ivalue;
-  bfile_t *fileptr;
-
-  fileptr = file_to_pointer(fileID);
-
-  ivalue = filePtrGetc((void *)fileptr);
-
-  return (ivalue);
-}
+      */
+      DateTime datetime = {
+        .date = vdate,
+        .time = vtime
+      };
 
+      compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
-size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
-{
-  size_t nread = 0;
-  bfile_t *fileptr = (bfile_t *) vfileptr;
+      for ( recID = 0; recID < nrecords; recID++ )
+        if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
 
-  if ( fileptr )
-    {
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	nread = file_read_from_buffer(fileptr, ptr, size);
-      else
+      if ( recID == nrecords )
 	{
-	  nread = fread(ptr, 1, size, fileptr->fp);
-	  if ( nread != size )
+	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+	  return (CDI_EUFSTRUCT);
+	}
+
+      if ( streamptr->tsteps[tsID].records[recID].used )
+        {
+          if ( cdiInventoryMode == 1 ) break;
+          else
 	    {
-	      if ( nread == 0 )
-		fileptr->flag |= FILE_EOF;
-	      else
-		fileptr->flag |= FILE_ERROR;
+	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
+
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+	      continue;
 	    }
 	}
 
-      fileptr->position  += (off_t)nread;
-      fileptr->byteTrans += (off_t)nread;
-      fileptr->access++;
-    }
+      streamptr->tsteps[tsID].records[recID].used = TRUE;
+      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
-  if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
+      if ( CDI_Debug )
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+                  nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
 
-  return (nread);
-}
+      streamptr->tsteps[tsID].records[recID].size = recsize;
 
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
+	{
+	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		  tsID, recID,
+		  streamptr->tsteps[tsID].records[recID].param, param,
+		  streamptr->tsteps[tsID].records[recID].ilevel, level1);
+	  return (CDI_EUFSTRUCT);
+	}
 
-size_t fileRead(int fileID, void *restrict ptr, size_t size)
-{
-  size_t nread = 0;
-  bfile_t *fileptr;
+      streamptr->tsteps[1].records[recID].position = recpos;
+      int varID = streamptr->tsteps[tsID].records[recID].varID;
+      /*
+      gridID = vlistInqVarGrid(vlistID, varID);
+      if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
+	{
+	  if ( IS_NOT_EQUAL(gridInqXval(gridID, 0),ISEC2_FirstLon*0.001) ||
+	       IS_NOT_EQUAL(gridInqYval(gridID, 0),ISEC2_FirstLat*0.001) )
+	    gridChangeType(gridID, GRID_TRAJECTORY);
+	}
+      */
+      if ( tsteptype != vlistInqVarTsteptype(vlistID, varID) )
+	vlistDefVarTsteptype(vlistID, varID, tsteptype);
 
-  fileptr = file_to_pointer(fileID);
+      grib_handle_delete(gh);
+      gh = NULL;
 
-  if ( fileptr )
-    {
-      double t_begin = 0.0;
+      rindex++;
+    }
 
-      if ( FileInfo ) t_begin = file_time();
+  if ( gh ) grib_handle_delete(gh);
 
-      if ( fileptr->type == FILE_TYPE_OPEN )
-	nread = file_read_from_buffer(fileptr, ptr, size);
+  int nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    {
+      if ( ! streamptr->tsteps[tsID].records[recID].used )
+	{
+	  int varID = streamptr->tsteps[tsID].records[recID].varID;
+	  vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	}
       else
 	{
-	  nread = fread(ptr, 1, size, fileptr->fp);
-	  if ( nread != size )
-	    {
-	      if ( nread == 0 )
-		fileptr->flag |= FILE_EOF;
-	      else
-		fileptr->flag |= FILE_ERROR;
-	    }
+	  nrecs++;
 	}
+    }
+  streamptr->tsteps[tsID].nrecs = nrecs;
 
-      if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
+  streamptr->rtsteps = 2;
 
-      fileptr->position  += (off_t)nread;
-      fileptr->byteTrans += (off_t)nread;
-      fileptr->access++;
+  if ( streamptr->ntsteps == -1 )
+    {
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
+
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
     }
 
-  if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
+  streamptr->record->buffer     = gribbuffer;
+  streamptr->record->buffersize = buffersize;
 
-  return (nread);
+  return (rstatus);
 }
+#endif
 
 
-size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
+#if  defined  (HAVE_LIBGRIB_API)
+int gribapiScanTimestep(stream_t * streamptr)
 {
-  size_t nwrite = 0;
-  bfile_t *fileptr;
-
-  fileptr = file_to_pointer(fileID);
+  int vrecID, recID;
+  //int warn_numavg = TRUE;
+  int nrecs = 0;
+  int vlistID = streamptr->vlistID;
 
-  if ( fileptr )
+  if ( CDI_Debug )
     {
-      double t_begin = 0.0;
-
-      /* if ( fileptr->buffer == NULL ) file_set_buffer(fileptr); */
-
-      if ( FileInfo ) t_begin = file_time();
-
-      if ( fileptr->type == FILE_TYPE_FOPEN )
-        nwrite = fwrite(ptr, 1, size, fileptr->fp);
-      else
-        {
-          ssize_t temp = write(fileptr->fd, ptr, size);
-          if (temp == -1)
-            {
-              perror("error writing to file");
-              nwrite = 0;
-            }
-          else
-            nwrite = (size_t)temp;
-        }
-
-      if ( FileInfo ) fileptr->time_in_sec += file_time() - t_begin;
-
-      fileptr->position  += (off_t)nwrite;
-      fileptr->byteTrans += (off_t)nwrite;
-      fileptr->access++;
+      Message("streamID = %d", streamptr->self);
+      Message("cts = %d", streamptr->curTsID);
+      Message("rts = %d", streamptr->rtsteps);
+      Message("nts = %d", streamptr->ntsteps);
     }
 
-  return (nwrite);
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-
-/* Automatically generated by m214003 at 2014-12-03, do not edit */
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-/* CGRIBEXLIB_VERSION="1.7.0" */
+  if ( streamptr->tsteps[tsID].recordSize == 0 )
+    {
+      unsigned char* gribbuffer = (unsigned char *) streamptr->record->buffer;
+      size_t buffersize = streamptr->record->buffersize;
 
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic push
-#endif
-#ifdef __GNUC__
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Wsign-conversion"
-#pragma GCC diagnostic warning "-Wstrict-overflow"
-#endif
+      cdi_create_records(streamptr, tsID);
 
-#ifdef _ARCH_PWR6
-#pragma options nostrict
-#endif
+      nrecs = streamptr->tsteps[1].nrecs;
 
-#if defined (HAVE_CONFIG_H)
-#endif
+      streamptr->tsteps[tsID].nrecs = nrecs;
+      streamptr->tsteps[tsID].recIDs = (int *) malloc(nrecs*sizeof(int));
+      for ( recID = 0; recID < nrecs; recID++ )
+	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <inttypes.h>
+      int fileID = streamptr->fileID;
 
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
+      int nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);    //Only used for debug output.
+      int rindex = 0;
+      off_t recpos = 0;
+      DateTime datetime0;
+      grib_handle *gh = NULL;
+      char varname[256];
+      while ( TRUE )
+	{
+	  if ( rindex > nrecs ) break;
 
-#ifndef _TEMPLATES_H
-#define _TEMPLATES_H
+	  size_t recsize = (size_t)gribGetSize(fileID);
+	  recpos  = fileGetPos(fileID);
+	  if ( recsize == 0 )
+	    {
+	      streamptr->ntsteps = streamptr->rtsteps + 1;
+	      break;
+	    }
 
-#define CAT(X,Y)      X##_##Y
-#define TEMPLATE(X,Y) CAT(X,Y)
+	  if ( rindex >= nrecs ) break;
 
-#endif 
-#ifndef _GRIB_INT_H
-#define _GRIB_INT_H
+          ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-#if defined (HAVE_CONFIG_H)
-#endif
+	  size_t readsize = recsize;
+	  if (gribRead(fileID, gribbuffer, &readsize))
+	    {
+	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
+		      streamptr->tsteps[tsID].recordSize);
+	      break;
+	    }
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
+          long unzipsize;
+	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
+          nrecs_scanned++;
+	  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
+	  GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-#if ! defined   (_CGRIBEX_H)
-#endif
-#if ! defined   (_ERROR_H)
-#endif
-#if ! defined   (_DTYPES_H)
-#endif
+          int param = gribapiGetParam(gh);
+          int level1 = 0, level2 = 0, leveltype1, leveltype2 = -1, lbounds, level_sf, level_unit;
+          gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
-#if ! defined   (FALSE)
-#  define  FALSE  0
-#endif
+          varname[0] = 0;
+	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
-#if ! defined   (TRUE)
-#  define  TRUE  1
-#endif
+          int vdate = 0, vtime = 0;
+	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
-#if ! defined   (UCHAR)
-#  define  UCHAR  unsigned char
-#endif
+	  if ( rindex == nrecs ) break;
 
+	  if ( rindex == 0 )
+	    {
+              int taxisID = vlistInqTaxis(vlistID);
+	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
+		{
+		  taxis->type  = TAXIS_RELATIVE;
 
-#if defined (CRAY) || defined (SX) || defined (__uxpch__)
-#  define VECTORCODE
-#endif
+                  gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
 
+		  taxis->unit  = gribapiGetTimeUnits(gh);
+		}
+	      else
+		{
+		  taxis->type  = TAXIS_ABSOLUTE;
+		}
+	      taxis->vdate = vdate;
+	      taxis->vtime = vtime;
 
-#if defined (VECTORCODE)
-#if  defined  (INT32)
-#  define  GRIBPACK     unsigned INT32
-#  define  PACK_GRIB    packInt32
-#  define  UNPACK_GRIB  unpackInt32
-#else
-#  define  GRIBPACK     unsigned INT64
-#  define  PACK_GRIB    packInt64
-#  define  UNPACK_GRIB  unpackInt64
-#endif
-#else
-#  define  GRIBPACK     unsigned char
-#endif
+	      datetime0.date = vdate;
+	      datetime0.time = vtime;
+	    }
+	  /*
+	  if ( ISEC1_AvgNum )
+	    {
+	      if (  taxis->numavg && warn_numavg &&
+		   (taxis->numavg != ISEC1_AvgNum) )
+		{
+		  warn_numavg = FALSE;
+		}
+	      else
+		{
+		  taxis->numavg = ISEC1_AvgNum;
+		}
+	    }
+	  */
+          DateTime datetime = {
+            .date  = vdate,
+            .time  = vtime
+          };
 
-#define  U_BYTEORDER     static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
-#define  IS_BIGENDIAN()  (u_byteorder.c[sizeof(long) - 1])
+          int tsteptype = gribapiGetTsteptype(gh);
 
-#if defined (__xlC__) /* performance problems on IBM */
-#ifndef DBL_IS_NAN
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#else
-#ifndef DBL_IS_NAN
-#if  defined  (HAVE_DECL_ISNAN)
-#  define DBL_IS_NAN(x)     (isnan(x))
-#elif  defined  (FP_NAN)
-#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
-#else
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#endif
-#endif
+          compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
-#ifndef DBL_IS_EQUAL
-/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
-#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
-#endif
+	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
+	    {
+	      recID   = streamptr->tsteps[1].recIDs[vrecID];
+	      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
+	    }
 
-#ifndef IS_EQUAL
-#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
-#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
-#endif
+	  if ( vrecID == nrecs )
+	    {
+	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
-/* dummy use of unused parameters to silence compiler warnings */
-#define  UNUSED(x) (void)x
+	      if ( cdiInventoryMode == 1 )
+		return (CDI_EUFSTRUCT);
+	      else
+		continue;
+	    }
 
-#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (---> 8388607)  */
+	  if ( cdiInventoryMode != 1 )
+	    {
+	      if ( streamptr->tsteps[tsID].records[recID].used )
+		{
+		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
-#define  POW_2_M24  0.000000059604644775390625  /*  pow(2.0, -24.0) */
+		  if ( CDI_Debug )
+                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
-double intpow2(int x);
+		  continue;
+		}
+	    }
 
-int gribrec_len(int b1, int b2, int b3);
-int correct_bdslen(int bdslen, long recsize, long gribpos);
+          streamptr->tsteps[tsID].records[recID].used = TRUE;
+          streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
-/* CDI converter routines */
+	  if ( CDI_Debug )
+	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
-/* param format:  DDDCCCNNN */
+	  if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
+	    {
+	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		      tsID, recID,
+		      streamptr->tsteps[tsID].records[recID].param, param,
+		      streamptr->tsteps[tsID].records[recID].ilevel, level1);
+	      Error("Invalid, unsupported or inconsistent record structure");
+	    }
 
-void    cdiDecodeParam(int param, int *dis, int *cat, int *num);
-int     cdiEncodeParam(int dis, int cat, int num);
+	  streamptr->tsteps[tsID].records[recID].position = recpos;
+	  streamptr->tsteps[tsID].records[recID].size = recsize;
 
-/* date format:  YYYYMMDD */
-/* time format:  hhmmss   */
+	  if ( CDI_Debug )
+	    Message("%4d %8d %4d %8d %8d %6d", rindex, (int)recpos, param, level1, vdate, vtime);
 
-void    cdiDecodeDate(int date, int *year, int *month, int *day);
-int     cdiEncodeDate(int year, int month, int day);
+	  grib_handle_delete(gh);
+	  gh = NULL;
 
-void    cdiDecodeTime(int time, int *hour, int *minute, int *second);
-int     cdiEncodeTime(int hour, int minute, int second);
+	  rindex++;
+	}
 
-/* CALENDAR types */
+      if ( gh ) grib_handle_delete(gh);
 
-#define  CALENDAR_STANDARD        0  /* don't change this value (used also in cgribexlib)! */
-#define  CALENDAR_PROLEPTIC       1
-#define  CALENDAR_360DAYS         2
-#define  CALENDAR_365DAYS         3
-#define  CALENDAR_366DAYS         4
-#define  CALENDAR_NONE            5
+      for ( vrecID = 0; vrecID < nrecs; vrecID++ )
+	{
+	  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+	  if ( ! streamptr->tsteps[tsID].records[recID].used ) break;
+	}
 
-extern FILE *grprsm;
+      if ( vrecID < nrecs )
+	{
+	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, streamptr->tsteps[tsID].records[recID].param,
+                      streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
+	  return (CDI_EUFSTRUCT);
+	}
 
-extern int  CGRIBEX_Debug;
+      streamptr->rtsteps++;
 
-void   gprintf(const char *caller, const char *fmt, ...);
+      if ( streamptr->ntsteps != streamptr->rtsteps )
+	{
+	  tsID = tstepsNewEntry(streamptr);
+	  if ( tsID != streamptr->rtsteps )
+	    Error("Internal error. tsID = %d", tsID);
 
-void   grsdef(void);
+	  streamptr->tsteps[tsID-1].next   = 1;
+	  streamptr->tsteps[tsID].position = recpos;
+	}
 
-void   prtbin(int kin, int knbit, int *kout, int *kerr);
-void   confp3(double pval, int *kexp, int *kmant, int kbits, int kround);
-double decfp2(int kexp, int kmant);
-void   ref2ibm(double *pref, int kbits);
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      streamptr->tsteps[tsID].position = recpos;
 
-void   scale_complex_double(double *fpdata, int pcStart, int pcScale, int trunc, int inv);
-void   scale_complex_float(float *fpdata, int pcStart, int pcScale, int trunc, int inv);
-void   scatter_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
-void   scatter_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
-void   gather_complex_double(double *fpdata, int pcStart, int trunc, int nsp);
-void   gather_complex_float(float *fpdata, int pcStart, int trunc, int nsp);
+      streamptr->record->buffer     = gribbuffer;
+      streamptr->record->buffersize = buffersize;
+    }
 
-void   scm0_double(double *pdl, double *pdr, double *pfl, double *pfr, int klg);
-int    qu2reg2(double *pfield, int *kpoint, int klat, int klon,
-	       double *ztemp, double msval, int *kret);
-int    qu2reg3_double(double *pfield, int *kpoint, int klat, int klon,
-		      double msval, int *kret, int omisng, int operio, int oveggy);
-int    qu2reg3_float(float *pfield, int *kpoint, int klat, int klon,
-		     float msval, int *kret, int omisng, int operio, int oveggy);
+  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+    {
+      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
+      streamptr->ntsteps = tsID;
+    }
 
-#if  defined  (INT32)
-long   packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc);
+  return (int)streamptr->ntsteps;
+}
 #endif
-long   packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc);
-#if  defined  (INT32)
-long   unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc);
+
+#ifdef gribWarning
+#undef gribWarning
 #endif
-long   unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc);
 
-void  grib_encode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
-			 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
-			 int kleng, int *kword, int efunc, int *kret);
-void  grib_encode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
-			float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
-			int kleng, int *kword, int efunc, int *kret);
+#ifdef HAVE_LIBGRIB_API
+int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
+		  int unreduced, int *nmiss, double missval, int vlistID, int varID)
+{
+  int status = 0;
+  long lpar;
+  long numberOfPoints;
+  size_t datasize, dummy, recsize;
+  grib_handle *gh = NULL;
 
-void  grib_decode_double(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
-			 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
-			 int kleng, int *kword, int dfunc, int *kret);
-void  grib_decode_float(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
-			float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
-			int kleng, int *kword, int dfunc, int *kret);
+  UNUSED(vlistID);
+  UNUSED(varID);
 
+  if ( unreduced )
+    {
+      static int lwarn = 1;
 
-int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
-		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
-int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
-		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
-		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
+      if ( lwarn )
+	{
+	  lwarn = 0;
+	  Warning("Conversion of gaussian reduced grids unsupported!");
+	}
+    }
 
-#endif  /* _GRIB_INT_H */
-#ifndef _GRIBDECODE_H
-#define _GRIBDECODE_H
+  recsize = (size_t)gribsize;
+  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
+  GRIB_CHECK(my_grib_set_double(gh, "missingValue", missval), 0);
 
-#define  UNDEFINED          9.999e20
+  /* get the size of the values array*/
+  GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
+  GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
 
+  // printf("values_size = %d  numberOfPoints = %ld\n", datasize, numberOfPoints);
 
-#define  GET_INT3(a,b,c)    ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
-#define  GET_INT2(a,b)      ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 8) + b))
-#define  GET_INT1(a)        ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (a&127))
+  if ( gridsize != (int) datasize )
+    Error("Internal problem: gridsize(%d) != datasize(%d)!", gridsize, datasize);
+  dummy = datasize;
+  GRIB_CHECK(grib_get_double_array(gh, "values", data, &dummy), 0);
 
-/* this requires a 32-bit default integer machine */
-#define  GET_UINT4(a,b,c,d) ((int) ((a << 24) + (b << 16) + (c << 8) + (d)))
-#define  GET_UINT3(a,b,c)   ((int) ((a << 16) + (b << 8)  + (c)))
-#define  GET_UINT2(a,b)     ((int) ((a << 8)  + (b)))
-#define  GET_UINT1(a)       ((int)  (a))
+  int gridtype;
+  GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
+  gridtype = (int) lpar;
 
-#define  BUDG_START(s)      (s[0]=='B' && s[1]=='U' && s[2]=='D' && s[3]=='G')
-#define  TIDE_START(s)      (s[0]=='T' && s[1]=='I' && s[2]=='D' && s[3]=='E')
-#define  GRIB_START(s)      (s[0]=='G' && s[1]=='R' && s[2]=='I' && s[3]=='B')
-#define  GRIB_FIN(s)        (s[0]=='7' && s[1]=='7' && s[2]=='7' && s[3]=='7')
+  *nmiss = 0;
+  if ( gridtype < 50 || gridtype > 53 )
+    {
+      GRIB_CHECK(grib_get_long(gh, "numberOfMissing", &lpar), 0);
+      *nmiss = (int) lpar;
+      // printf("gridtype %d, nmiss %d\n", gridtype, nmiss);
+    }
+
+  grib_handle_delete(gh);
+
+  return (status);
+}
+#endif
 
-/* GRIB1 Section 0: Indicator Section (IS) */
 
-#define  GRIB1_SECLEN(s)     GET_INT3(s[ 4], s[ 5], s[ 6])
-#define  GRIB_EDITION(s)     GET_UINT1(s[ 7])
+#if  defined  (HAVE_LIBGRIB_API)
+static
+void gribapiDefInstitut(grib_handle *gh, int vlistID, int varID)
+{
+  int instID;
 
-/* GRIB1 Section 1: Product Definition Section (PDS) */
+  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
+    instID = vlistInqInstitut(vlistID);
+  else
+    instID = vlistInqVarInstitut(vlistID, varID);
 
-#define  PDS_Len             GET_UINT3(pds[ 0], pds[ 1], pds[ 2])
-#define  PDS_CodeTable       GET_UINT1(pds[ 3])
-#define  PDS_CenterID        GET_UINT1(pds[ 4])
-#define  PDS_ModelID         GET_UINT1(pds[ 5])
-#define  PDS_GridDefinition  GET_UINT1(pds[ 6])
-#define  PDS_Sec2Or3Flag     GET_UINT1(pds[ 7])
-#define  PDS_HAS_GDS         ((pds[7] & 128) != 0)
-#define  PDS_HAS_BMS         ((pds[7] &  64) != 0)
-#define  PDS_Parameter       GET_UINT1(pds[ 8])
-#define  PDS_LevelType       GET_UINT1(pds[ 9])
-#define  PDS_Level1          (pds[10])
-#define  PDS_Level2	     (pds[11])
-#define  PDS_Level	     GET_UINT2(pds[10], pds[11])
-#define  PDS_Year            GET_INT1(pds[12])
-#define  PDS_Month           GET_UINT1(pds[13])
-#define  PDS_Day             GET_UINT1(pds[14])
-#define  PDS_Hour            GET_UINT1(pds[15])
-#define  PDS_Minute          GET_UINT1(pds[16])
-#define  PDS_Date            (PDS_Year*10000+PDS_Month*100+PDS_Day)
-#define  PDS_Time            (PDS_Hour*100+PDS_Minute)
-#define  PDS_TimeUnit        GET_UINT1(pds[17])
-#define  PDS_TimePeriod1     GET_UINT1(pds[18])
-#define  PDS_TimePeriod2     GET_UINT1(pds[19])
-#define  PDS_TimeRange       GET_UINT1(pds[20])
-#define  PDS_AvgNum          GET_UINT2(pds[21], pds[22])
-#define  PDS_AvgMiss         GET_UINT1(pds[23])
-#define  PDS_Century         GET_UINT1(pds[24])
-#define  PDS_Subcenter       GET_UINT1(pds[25])
-#define  PDS_DecimalScale    GET_INT2(pds[26],pds[27])
+  if ( instID != CDI_UNDEFID )
+    {
+      long center, subcenter;
+      long center0, subcenter0;
 
+      center    = institutInqCenter(instID);
+      subcenter = institutInqSubcenter(instID);
 
-/* GRIB1 Section 2: Grid Description Section (GDS) */
+      GRIB_CHECK(grib_get_long(gh, "centre", &center0), 0);
+      GRIB_CHECK(grib_get_long(gh, "subCentre", &subcenter0), 0);
 
-#define  GDS_Len             ((gds) == NULL ? 0 : GET_UINT3(gds[ 0], gds[ 1], gds[ 2]))
-#define  GDS_NV              GET_UINT1(gds[ 3])
-#define  GDS_PVPL            GET_UINT1(gds[ 4])
-#define  GDS_PV	             ((gds[3] ==    0) ? -1 : (int) gds[4] - 1)
-#define  GDS_PL	             ((gds[4] == 0xFF) ? -1 : (int) gds[3] * 4 + (int) gds[4] - 1)
-#define  GDS_GridType        GET_UINT1(gds[ 5])
+      if ( center != center0 )
+	GRIB_CHECK(my_grib_set_long(gh, "centre", center), 0);
+      if ( subcenter != subcenter0 )
+	GRIB_CHECK(my_grib_set_long(gh, "subCentre", subcenter), 0);
+    }
+}
 
+static
+void gribapiDefModel(grib_handle *gh, int vlistID, int varID)
+{
+  int modelID;
 
-/* GRIB1 Triangular grid of DWD */
-#define  GDS_GME_NI2         GET_UINT2(gds[ 6], gds[ 7])
-#define  GDS_GME_NI3         GET_UINT2(gds[ 8], gds[ 9])
-#define  GDS_GME_ND          GET_UINT3(gds[10], gds[11], gds[12])
-#define  GDS_GME_NI          GET_UINT3(gds[13], gds[14], gds[15])
-#define  GDS_GME_AFlag       GET_UINT1(gds[16])
-#define  GDS_GME_LatPP       GET_INT3(gds[17], gds[18], gds[19])
-#define  GDS_GME_LonPP       GET_INT3(gds[20], gds[21], gds[22])
-#define  GDS_GME_LonMPL      GET_INT3(gds[23], gds[24], gds[25])
-#define  GDS_GME_BFlag       GET_UINT1(gds[27])
+  if ( vlistInqModel(vlistID) != CDI_UNDEFID )
+    modelID = vlistInqModel(vlistID);
+  else
+    modelID = vlistInqVarModel(vlistID, varID);
 
-/* GRIB1 Spectral */
-#define  GDS_PentaJ          GET_UINT2(gds[ 6], gds[ 7])
-#define  GDS_PentaK          GET_UINT2(gds[ 8], gds[ 9])
-#define  GDS_PentaM          GET_UINT2(gds[10], gds[11])
-#define  GDS_RepType         GET_UINT1(gds[12])
-#define  GDS_RepMode         GET_UINT1(gds[13])
+  if ( modelID != CDI_UNDEFID )
+    GRIB_CHECK(my_grib_set_long(gh, "generatingProcessIdentifier", modelInqGribID(modelID)), 0);
+}
 
-/* GRIB1 Regular grid */
-#define  GDS_NumLon          GET_UINT2(gds[ 6], gds[ 7])
-#define  GDS_NumLat          GET_UINT2(gds[ 8], gds[ 9])
-#define  GDS_FirstLat        GET_INT3(gds[10], gds[11], gds[12])
-#define  GDS_FirstLon        GET_INT3(gds[13], gds[14], gds[15])
-#define  GDS_ResFlag         GET_UINT1(gds[16])
-#define  GDS_LastLat         GET_INT3(gds[17], gds[18], gds[19])
-#define  GDS_LastLon         GET_INT3(gds[20], gds[21], gds[22])
-#define  GDS_LonIncr         GET_UINT2(gds[23], gds[24])
-#define  GDS_LatIncr         GET_UINT2(gds[25], gds[26])
-#define  GDS_NumPar          GET_UINT2(gds[25], gds[26])
-#define  GDS_ScanFlag        GET_UINT1(gds[27])
-#define  GDS_LatSP           GET_INT3(gds[32], gds[33], gds[34])
-#define  GDS_LonSP           GET_INT3(gds[35], gds[36], gds[37])
-#define  GDS_RotAngle        GET_Real(&(gds[38]))
+static
+void gribapiDefParam(int editionNumber, grib_handle *gh, int param, const char *name, const char *stdname)
+{
+  bool ldefined = false;
 
-/* GRIB1 Lambert */
-#define  GDS_Lambert_Lov     GET_INT3(gds[17], gds[18], gds[19])
-#define  GDS_Lambert_dx	     GET_INT3(gds[20], gds[21], gds[22])
-#define  GDS_Lambert_dy	     GET_INT3(gds[23], gds[24], gds[25])
-#define  GDS_Lambert_ProjFlag GET_UINT1(gds[26])
-#define  GDS_Lambert_LatS1   GET_INT3(gds[28], gds[29], gds[30])
-#define  GDS_Lambert_LatS2   GET_INT3(gds[31], gds[32], gds[33])
-#define  GDS_Lambert_LatSP   GET_INT3(gds[34], gds[35], gds[36])
-#define  GDS_Lambert_LonSP   GET_INT3(gds[37], gds[37], gds[37])
+  int pdis, pcat, pnum;
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
-/* GRIB1 Section 3: Bit Map Section (BMS) */
+  if ( pnum < 0 )
+    {
+      size_t len;
+      len = strlen(stdname);
+      if ( len )
+        {
+          int status = my_grib_set_string(gh, "cfName", stdname, &len);
+          if ( status == 0 ) ldefined = true;
+          else Warning("grib_api: No match for cfName=%s", stdname);
+        }
 
-#define  BMS_Len	     ((bms) == NULL ? 0 : (int) (bms[0]<<16)+(bms[1]<<8)+bms[2])
-#define  BMS_UnusedBits      (bms[3])
-#define  BMS_Numeric         
-#define  BMS_Bitmap	     ((bms) == NULL ? NULL : (bms)+6)
-#define  BMS_BitmapSize      (((((bms[0]<<16)+(bms[1]<<8)+bms[2]) - 6)<<3) - bms[3])
+      if ( ldefined == false )
+        {
+          len = strlen(name);
+          int status = my_grib_set_string(gh, "shortName", name, &len);
+          if ( status == 0 ) ldefined = true;
+          else Warning("grib_api: No match for shortName=%s", name);
+        }
+    }
 
-/* GRIB1 Section 4: Binary Data Section (BDS) */
+  if ( ldefined == false )
+    {
+      if ( pnum < 0 ) pnum = -pnum;
 
-#define  BDS_Len	    ((int) ((bds[0]<<16)+(bds[1]<<8)+bds[2]))
-#define  BDS_Flag	    (bds[3])
-#define  BDS_BinScale       GET_INT2(bds[ 4], bds[ 5])
-#define  BDS_RefValue       decfp2((int)bds[ 6], GET_UINT3(bds[ 7], bds[ 8], bds[ 9]))
-#define  BDS_NumBits        ((int) bds[10])
-#define  BDS_RealCoef       decfp2((int)bds[zoff+11], GET_UINT3(bds[zoff+12], bds[zoff+13], bds[zoff+14]))
-#define  BDS_PackData       ((int) ((bds[zoff+11]<<8) + bds[zoff+12]))
-#define  BDS_Power          GET_INT2(bds[zoff+13], bds[zoff+14])
-#define  BDS_Z              (bds[13])
+      if ( editionNumber <= 1 )
+	{
+          static bool lwarn_pdis = true;
+	  if ( pdis != 255 && lwarn_pdis )
+	    {
+	      char paramstr[32];
+	      cdiParamToString(param, paramstr, sizeof(paramstr));
+	      Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
+              lwarn_pdis = false;
+	    }
 
-/* GRIB1 Section 5: End Section (ES) */
+          static bool lwarn_pnum = true;
+          if ( pnum > 255 && lwarn_pnum )
+            {
+              Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
+              lwarn_pnum = false;
+              pnum = pnum%256;
+            }
 
-/* GRIB2 */
+	  GRIB_CHECK(my_grib_set_long(gh, "table2Version",        pcat), 0);
+	  GRIB_CHECK(my_grib_set_long(gh, "indicatorOfParameter", pnum), 0);
+	}
+      else
+	{
+	  GRIB_CHECK(my_grib_set_long(gh, "discipline",        pdis), 0);
+	  GRIB_CHECK(my_grib_set_long(gh, "parameterCategory", pcat), 0);
+	  GRIB_CHECK(my_grib_set_long(gh, "parameterNumber",   pnum), 0);
+	}
+    }
 
-#define  GRIB2_SECLEN(section)   (GET_UINT4(section[0], section[1], section[2], section[3]))
-#define  GRIB2_SECNUM(section)   (GET_UINT1(section[4]))
+  // printf("param: %d.%d.%d %s\n", pnum, pcat, pdis, name);
+}
 
-#endif  /* _GRIBDECODE_H */
-#ifndef _GRIB_ENCODE_H
-#define _GRIB_ENCODE_H
+static
+int getTimeunitFactor(int timeunit)
+{
+  int factor = 1;
 
+  switch (timeunit)
+    {
+    case TUNIT_SECOND:  factor =     1;  break;
+    case TUNIT_MINUTE:  factor =    60;  break;
+    case TUNIT_HOUR:    factor =  3600;  break;
+    case TUNIT_3HOURS:  factor = 10800;  break;
+    case TUNIT_6HOURS:  factor = 21600;  break;
+    case TUNIT_12HOURS: factor = 43200;  break;
+    case TUNIT_DAY:     factor = 86400;  break;
+    default:            factor =  3600;  break;
+    }
 
-#define PutnZero(n) \
-{ \
-  int i; \
-  for ( i = z; i < z+n; i++ ) lGrib[i] = 0; \
-  z += n; \
+  return (factor);
 }
 
-#define Put1Byte(Value)  (lGrib[z++] = (Value))
-#define Put2Byte(Value) ((lGrib[z++] = (Value) >>  8), \
-                         (lGrib[z++] = (Value)))
-#define Put3Byte(Value) ((lGrib[z++] = (Value) >> 16), \
-                         (lGrib[z++] = (Value) >>  8), \
-                         (lGrib[z++] = (Value)))
-#define Put4Byte(Value) ((lGrib[z++] = (Value) >> 24), \
-                         (lGrib[z++] = (Value) >> 16), \
-                         (lGrib[z++] = (Value) >>  8), \
-                         (lGrib[z++] = (Value)))
+static
+void gribapiDefStepUnits(grib_handle *gh, int timeunit, int proDefTempNum, int gcinit)
+{
+  long unitsOfTime;
 
-#define Put1Int(Value)  {ival = Value; if ( ival < 0 ) ival =     0x80 - ival; Put1Byte(ival);}
-#define Put2Int(Value)  {ival = Value; if ( ival < 0 ) ival =   0x8000 - ival; Put2Byte(ival);}
-#define Put3Int(Value)  {ival = Value; if ( ival < 0 ) ival = 0x800000 - ival; Put3Byte(ival);}
+  switch (timeunit)
+    {
+    case TUNIT_SECOND:  unitsOfTime = 13;  break;
+    case TUNIT_MINUTE:  unitsOfTime =  0;  break;
+    case TUNIT_HOUR:    unitsOfTime =  1;  break;
+    case TUNIT_3HOURS:  unitsOfTime = 10;  break;
+    case TUNIT_6HOURS:  unitsOfTime = 11;  break;
+    case TUNIT_12HOURS: unitsOfTime = 12;  break;
+    case TUNIT_DAY:     unitsOfTime =  2;  break;
+    default:            unitsOfTime =  1;  break;
+    }
 
-#define Put1Real(Value)          \
-{                                \
-  confp3(Value, &exponent, &mantissa, BitsPerInt, 1); \
-  Put1Byte(exponent);            \
-  Put3Byte(mantissa);            \
+  if ( !gcinit )
+    {
+      GRIB_CHECK(my_grib_set_long(gh, "stepUnits", unitsOfTime), 0);
+      if ( proDefTempNum == 8 || proDefTempNum == 11 )
+        GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitForTimeRange", unitsOfTime), 0);
+      GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
+    }
 }
 
-#endif  /* _GRIB_ENCODE_H */
-#include <stdio.h>
-#include <math.h>
+static
+int gribapiDefSteptype(int editionNumber, grib_handle *gh, int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int gcinit)
+{
+  long proDefTempNum = 0;
+  size_t len = 64;
+  char stepType[len];
+
+  switch ( tsteptype )
+    {
+    case TSTEP_AVG:      strcpy(stepType, "avg");     proDefTempNum = 8; break;
+    case TSTEP_ACCUM:    strcpy(stepType, "accum");   proDefTempNum = 8; break;
+    case TSTEP_MAX:      strcpy(stepType, "max");     proDefTempNum = 8; break;
+    case TSTEP_MIN:      strcpy(stepType, "min");     proDefTempNum = 8; break;
+    case TSTEP_DIFF:     strcpy(stepType, "diff");    proDefTempNum = 8; break;
+    case TSTEP_RMS:      strcpy(stepType, "rms");     proDefTempNum = 8; break;
+    case TSTEP_SD:       strcpy(stepType, "sd");      proDefTempNum = 8; break;
+    case TSTEP_COV:      strcpy(stepType, "cov");     proDefTempNum = 8; break;
+    case TSTEP_RATIO:    strcpy(stepType, "ratio");   proDefTempNum = 8; break;
+    case TSTEP_INSTANT:  strcpy(stepType, "instant"); proDefTempNum = 0; break;
+    default:             strcpy(stepType, "instant"); proDefTempNum = 0; break;
+    }
 
+  if ( typeOfGeneratingProcess == 4 )
+    {
+      if ( proDefTempNum == 8 ) proDefTempNum = 11;
+      else                      proDefTempNum = 1;
+    }
 
-const double _pow2tab[158] = {
- /* pow(2.0,  0.0) */  1.0,
- /* pow(2.0,  1.0) */  2.0,
- /* pow(2.0,  2.0) */  4.0,
- /* pow(2.0,  3.0) */  8.0,
- /* pow(2.0,  4.0) */  16.0,
- /* pow(2.0,  5.0) */  32.0,
- /* pow(2.0,  6.0) */  64.0,
- /* pow(2.0,  7.0) */  128.0,
- /* pow(2.0,  8.0) */  256.0,
- /* pow(2.0,  9.0) */  512.0,
- /* pow(2.0, 10.0) */  1024.0,
- /* pow(2.0, 11.0) */  2048.0,
- /* pow(2.0, 12.0) */  4096.0,
- /* pow(2.0, 13.0) */  8192.0,
- /* pow(2.0, 14.0) */  16384.0,
- /* pow(2.0, 15.0) */  32768.0,
- /* pow(2.0, 16.0) */  65536.0,
- /* pow(2.0, 17.0) */  131072.0,
- /* pow(2.0, 18.0) */  262144.0,
- /* pow(2.0, 19.0) */  524288.0,
- /* pow(2.0, 20.0) */  1048576.0,
- /* pow(2.0, 21.0) */  2097152.0,
- /* pow(2.0, 22.0) */  4194304.0,
- /* pow(2.0, 23.0) */  8388608.0,
- /* pow(2.0, 24.0) */  16777216.0,
- /* pow(2.0, 25.0) */  33554432.0,
- /* pow(2.0, 26.0) */  67108864.0,
- /* pow(2.0, 27.0) */  134217728.0,
- /* pow(2.0, 28.0) */  268435456.0,
- /* pow(2.0, 29.0) */  536870912.0,
- /* pow(2.0, 30.0) */  1073741824.0,
- /* pow(2.0, 31.0) */  2147483648.0,
- /* pow(2.0, 32.0) */  4294967296.0,
- /* pow(2.0, 33.0) */  8589934592.0,
- /* pow(2.0, 34.0) */  17179869184.0,
- /* pow(2.0, 35.0) */  34359738368.0,
- /* pow(2.0, 36.0) */  68719476736.0,
- /* pow(2.0, 37.0) */  137438953472.0,
- /* pow(2.0, 38.0) */  274877906944.0,
- /* pow(2.0, 39.0) */  549755813888.0,
- /* pow(2.0, 40.0) */  1099511627776.0,
- /* pow(2.0, 41.0) */  2199023255552.0,
- /* pow(2.0, 42.0) */  4398046511104.0,
- /* pow(2.0, 43.0) */  8796093022208.0,
- /* pow(2.0, 44.0) */  17592186044416.0,
- /* pow(2.0, 45.0) */  35184372088832.0,
- /* pow(2.0, 46.0) */  70368744177664.0,
- /* pow(2.0, 47.0) */  140737488355328.0,
- /* pow(2.0, 48.0) */  281474976710656.0,
- /* pow(2.0, 49.0) */  562949953421312.0,
- /* pow(2.0, 50.0) */  1125899906842624.0,
- /* pow(2.0, 51.0) */  2251799813685248.0,
- /* pow(2.0, 52.0) */  4503599627370496.0,
- /* pow(2.0, 53.0) */  9007199254740992.0,
- /* pow(2.0, 54.0) */  18014398509481984.0,
- /* pow(2.0, 55.0) */  36028797018963968.0,
- /* pow(2.0, 56.0) */  72057594037927936.0,
- /* pow(2.0, 57.0) */  144115188075855872.0,
- /* pow(2.0, 58.0) */  288230376151711744.0,
- /* pow(2.0, 59.0) */  576460752303423488.0,
- /* pow(2.0, 60.0) */  1152921504606846976.0,
- /* pow(2.0, 61.0) */  2305843009213693952.0,
- /* pow(2.0, 62.0) */  4611686018427387904.0,
- /* pow(2.0, 63.0) */  9223372036854775808.0,
- /* pow(2.0, 64.0) */  18446744073709551616.0,
- /* pow(2.0, 65.0) */  36893488147419103232.0,
- /* pow(2.0, 66.0) */  73786976294838206464.0,
- /* pow(2.0, 67.0) */  147573952589676412928.0,
- /* pow(2.0, 68.0) */  295147905179352825856.0,
- /* pow(2.0, 69.0) */  590295810358705651712.0,
- /* pow(2.0, 70.0) */  1180591620717411303424.0,
- /* pow(2.0, 71.0) */  2361183241434822606848.0,
- /* pow(2.0, 72.0) */  4722366482869645213696.0,
- /* pow(2.0, 73.0) */  9444732965739290427392.0,
- /* pow(2.0, 74.0) */  18889465931478580854784.0,
- /* pow(2.0, 75.0) */  37778931862957161709568.0,
- /* pow(2.0, 76.0) */  75557863725914323419136.0,
- /* pow(2.0, 77.0) */  151115727451828646838272.0,
- /* pow(2.0, 78.0) */  302231454903657293676544.0,
- /* pow(2.0, 79.0) */  604462909807314587353088.0,
- /* pow(2.0, 80.0) */  1208925819614629174706176.0,
- /* pow(2.0, 81.0) */  2417851639229258349412352.0,
- /* pow(2.0, 82.0) */  4835703278458516698824704.0,
- /* pow(2.0, 83.0) */  9671406556917033397649408.0,
- /* pow(2.0, 84.0) */  19342813113834066795298816.0,
- /* pow(2.0, 85.0) */  38685626227668133590597632.0,
- /* pow(2.0, 86.0) */  77371252455336267181195264.0,
- /* pow(2.0, 87.0) */  154742504910672534362390528.0,
- /* pow(2.0, 88.0) */  309485009821345068724781056.0,
- /* pow(2.0, 89.0) */  618970019642690137449562112.0,
- /* pow(2.0, 90.0) */  1237940039285380274899124224.0,
- /* pow(2.0, 91.0) */  2475880078570760549798248448.0,
- /* pow(2.0, 92.0) */  4951760157141521099596496896.0,
- /* pow(2.0, 93.0) */  9903520314283042199192993792.0,
- /* pow(2.0, 94.0) */  19807040628566084398385987584.0,
- /* pow(2.0, 95.0) */  39614081257132168796771975168.0,
- /* pow(2.0, 96.0) */  79228162514264337593543950336.0,
- /* pow(2.0, 97.0) */  158456325028528675187087900672.0,
- /* pow(2.0, 98.0) */  316912650057057350374175801344.0,
- /* pow(2.0, 99.0) */  633825300114114700748351602688.0,
- /* pow(2.0, 100.0) */  1267650600228229401496703205376.0,
- /* pow(2.0, 101.0) */  2535301200456458802993406410752.0,
- /* pow(2.0, 102.0) */  5070602400912917605986812821504.0,
- /* pow(2.0, 103.0) */  10141204801825835211973625643008.0,
- /* pow(2.0, 104.0) */  20282409603651670423947251286016.0,
- /* pow(2.0, 105.0) */  40564819207303340847894502572032.0,
- /* pow(2.0, 106.0) */  81129638414606681695789005144064.0,
- /* pow(2.0, 107.0) */  162259276829213363391578010288128.0,
- /* pow(2.0, 108.0) */  324518553658426726783156020576256.0,
- /* pow(2.0, 109.0) */  649037107316853453566312041152512.0,
- /* pow(2.0, 110.0) */  1298074214633706907132624082305024.0,
- /* pow(2.0, 111.0) */  2596148429267413814265248164610048.0,
- /* pow(2.0, 112.0) */  5192296858534827628530496329220096.0,
- /* pow(2.0, 113.0) */  10384593717069655257060992658440192.0,
- /* pow(2.0, 114.0) */  20769187434139310514121985316880384.0,
- /* pow(2.0, 115.0) */  41538374868278621028243970633760768.0,
- /* pow(2.0, 116.0) */  83076749736557242056487941267521536.0,
- /* pow(2.0, 117.0) */  166153499473114484112975882535043072.0,
- /* pow(2.0, 118.0) */  332306998946228968225951765070086144.0,
- /* pow(2.0, 119.0) */  664613997892457936451903530140172288.0,
- /* pow(2.0, 120.0) */  1329227995784915872903807060280344576.0,
- /* pow(2.0, 121.0) */  2658455991569831745807614120560689152.0,
- /* pow(2.0, 122.0) */  5316911983139663491615228241121378304.0,
- /* pow(2.0, 123.0) */  10633823966279326983230456482242756608.0,
- /* pow(2.0, 124.0) */  21267647932558653966460912964485513216.0,
- /* pow(2.0, 125.0) */  42535295865117307932921825928971026432.0,
- /* pow(2.0, 126.0) */  85070591730234615865843651857942052864.0,
- /* pow(2.0, 127.0) */  170141183460469231731687303715884105728.0,
- /* pow(2.0, 128.0) */  340282366920938463463374607431768211456.0,
- /* pow(2.0, 129.0) */  680564733841876926926749214863536422912.0,
- /* pow(2.0, 130.0) */  1361129467683753853853498429727072845824.0,
- /* pow(2.0, 131.0) */  2722258935367507707706996859454145691648.0,
- /* pow(2.0, 132.0) */  5444517870735015415413993718908291383296.0,
- /* pow(2.0, 133.0) */  10889035741470030830827987437816582766592.0,
- /* pow(2.0, 134.0) */  21778071482940061661655974875633165533184.0,
- /* pow(2.0, 135.0) */  43556142965880123323311949751266331066368.0,
- /* pow(2.0, 136.0) */  87112285931760246646623899502532662132736.0,
- /* pow(2.0, 137.0) */  174224571863520493293247799005065324265472.0,
- /* pow(2.0, 138.0) */  348449143727040986586495598010130648530944.0,
- /* pow(2.0, 139.0) */  696898287454081973172991196020261297061888.0,
- /* pow(2.0, 140.0) */  1393796574908163946345982392040522594123776.0,
- /* pow(2.0, 141.0) */  2787593149816327892691964784081045188247552.0,
- /* pow(2.0, 142.0) */  5575186299632655785383929568162090376495104.0,
- /* pow(2.0, 143.0) */  11150372599265311570767859136324180752990208.0,
- /* pow(2.0, 144.0) */  22300745198530623141535718272648361505980416.0,
- /* pow(2.0, 145.0) */  44601490397061246283071436545296723011960832.0,
- /* pow(2.0, 146.0) */  89202980794122492566142873090593446023921664.0,
- /* pow(2.0, 147.0) */  178405961588244985132285746181186892047843328.0,
- /* pow(2.0, 148.0) */  356811923176489970264571492362373784095686656.0,
- /* pow(2.0, 149.0) */  713623846352979940529142984724747568191373312.0,
- /* pow(2.0, 150.0) */  1427247692705959881058285969449495136382746624.0,
- /* pow(2.0, 151.0) */  2854495385411919762116571938898990272765493248.0,
- /* pow(2.0, 152.0) */  5708990770823839524233143877797980545530986496.0,
- /* pow(2.0, 153.0) */  11417981541647679048466287755595961091061972992.0,
- /* pow(2.0, 154.0) */  22835963083295358096932575511191922182123945984.0,
- /* pow(2.0, 155.0) */  45671926166590716193865151022383844364247891968.0,
- /* pow(2.0, 156.0) */  91343852333181432387730302044767688728495783936.0,
- /* pow(2.0, 157.0) */  182687704666362864775460604089535377456991567872.0,
-};
+  if ( productDefinitionTemplate != -1 ) proDefTempNum = productDefinitionTemplate;
 
+  if ( !gcinit )
+    {
+      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "productDefinitionTemplateNumber", proDefTempNum), 0);
+      len = strlen(stepType);
+      GRIB_CHECK(my_grib_set_string(gh, "stepType", stepType, &len), 0);
+    }
 
-const double _pow16tab[71] = {
- /* pow(16.0,  0.0) */  1.0,
- /* pow(16.0,  1.0) */  16.0,
- /* pow(16.0,  2.0) */  256.0,
- /* pow(16.0,  3.0) */  4096.0,
- /* pow(16.0,  4.0) */  65536.0,
- /* pow(16.0,  5.0) */  1048576.0,
- /* pow(16.0,  6.0) */  16777216.0,
- /* pow(16.0,  7.0) */  268435456.0,
- /* pow(16.0,  8.0) */  4294967296.0,
- /* pow(16.0,  9.0) */  68719476736.0,
- /* pow(16.0, 10.0) */  1099511627776.0,
- /* pow(16.0, 11.0) */  17592186044416.0,
- /* pow(16.0, 12.0) */  281474976710656.0,
- /* pow(16.0, 13.0) */  4503599627370496.0,
- /* pow(16.0, 14.0) */  72057594037927936.0,
- /* pow(16.0, 15.0) */  1152921504606846976.0,
- /* pow(16.0, 16.0) */  18446744073709551616.0,
- /* pow(16.0, 17.0) */  295147905179352825856.0,
- /* pow(16.0, 18.0) */  4722366482869645213696.0,
- /* pow(16.0, 19.0) */  75557863725914323419136.0,
- /* pow(16.0, 20.0) */  1208925819614629174706176.0,
- /* pow(16.0, 21.0) */  19342813113834066795298816.0,
- /* pow(16.0, 22.0) */  309485009821345068724781056.0,
- /* pow(16.0, 23.0) */  4951760157141521099596496896.0,
- /* pow(16.0, 24.0) */  79228162514264337593543950336.0,
- /* pow(16.0, 25.0) */  1267650600228229401496703205376.0,
- /* pow(16.0, 26.0) */  20282409603651670423947251286016.0,
- /* pow(16.0, 27.0) */  324518553658426726783156020576256.0,
- /* pow(16.0, 28.0) */  5192296858534827628530496329220096.0,
- /* pow(16.0, 29.0) */  83076749736557242056487941267521536.0,
- /* pow(16.0, 30.0) */  1329227995784915872903807060280344576.0,
- /* pow(16.0, 31.0) */  21267647932558653966460912964485513216.0,
- /* pow(16.0, 32.0) */  340282366920938463463374607431768211456.0,
- /* pow(16.0, 33.0) */  5444517870735015415413993718908291383296.0,
- /* pow(16.0, 34.0) */  87112285931760246646623899502532662132736.0,
- /* pow(16.0, 35.0) */  1393796574908163946345982392040522594123776.0,
- /* pow(16.0, 36.0) */  22300745198530623141535718272648361505980416.0,
- /* pow(16.0, 37.0) */  356811923176489970264571492362373784095686656.0,
- /* pow(16.0, 38.0) */  5708990770823839524233143877797980545530986496.0,
- /* pow(16.0, 39.0) */  91343852333181432387730302044767688728495783936.0,
- /* pow(16.0, 40.0) */  1461501637330902918203684832716283019655932542976.0,
- /* pow(16.0, 41.0) */  23384026197294446691258957323460528314494920687616.0,
- /* pow(16.0, 42.0) */  374144419156711147060143317175368453031918731001856.0,
- /* pow(16.0, 43.0) */  5986310706507378352962293074805895248510699696029696.0,
- /* pow(16.0, 44.0) */  95780971304118053647396689196894323976171195136475136.0,
- /* pow(16.0, 45.0) */  1532495540865888858358347027150309183618739122183602176.0,
- /* pow(16.0, 46.0) */  24519928653854221733733552434404946937899825954937634816.0,
- /* pow(16.0, 47.0) */  392318858461667547739736838950479151006397215279002157056.0,
- /* pow(16.0, 48.0) */  6277101735386680763835789423207666416102355444464034512896.0,
- /* pow(16.0, 49.0) */  100433627766186892221372630771322662657637687111424552206336.0,
- /* pow(16.0, 50.0) */  1606938044258990275541962092341162602522202993782792835301376.0,
- /* pow(16.0, 51.0) */  25711008708143844408671393477458601640355247900524685364822016.0,
- /* pow(16.0, 52.0) */  411376139330301510538742295639337626245683966408394965837152256.0,
- /* pow(16.0, 53.0) */  6582018229284824168619876730229402019930943462534319453394436096.0,
- /* pow(16.0, 54.0) */  105312291668557186697918027683670432318895095400549111254310977536.0,
- /* pow(16.0, 55.0) */  1684996666696914987166688442938726917102321526408785780068975640576.0,
- /* pow(16.0, 56.0) */  26959946667150639794667015087019630673637144422540572481103610249216.0,
- /* pow(16.0, 57.0) */  431359146674410236714672241392314090778194310760649159697657763987456.0,
- /* pow(16.0, 58.0) */  6901746346790563787434755862277025452451108972170386555162524223799296.0,
- /* pow(16.0, 59.0) */  110427941548649020598956093796432407239217743554726184882600387580788736.0,
- /* pow(16.0, 60.0) */  1766847064778384329583297500742918515827483896875618958121606201292619776.0,
- /* pow(16.0, 61.0) */  28269553036454149273332760011886696253239742350009903329945699220681916416.0,
- /* pow(16.0, 62.0) */  452312848583266388373324160190187140051835877600158453279131187530910662656.0,
- /* pow(16.0, 63.0) */  7237005577332262213973186563042994240829374041602535252466099000494570602496.0,
- /* pow(16.0, 64.0) */  115792089237316195423570985008687907853269984665640564039457584007913129639936.0,
- /* pow(16.0, 65.0) */  1852673427797059126777135760139006525652319754650249024631321344126610074238976.0,
- /* pow(16.0, 66.0) */  29642774844752946028434172162224104410437116074403984394101141506025761187823616.0,
- /* pow(16.0, 67.0) */  474284397516047136454946754595585670566993857190463750305618264096412179005177856.0,
- /* pow(16.0, 68.0) */  7588550360256754183279148073529370729071901715047420004889892225542594864082845696.0,
- /* pow(16.0, 69.0) */  121416805764108066932466369176469931665150427440758720078238275608681517825325531136.0,
- /* pow(16.0, 70.0) */  1942668892225729070919461906823518906642406839052139521251812409738904285205208498176.0,
-};
+  return ((int)proDefTempNum);
+}
+
+static
+void gribapiDefDateTimeAbs(int editionNumber, grib_handle *gh, int date, int time, int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int gcinit)
+{
+  (void ) gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
 
-static int _pow2tab_size = sizeof(_pow2tab)/sizeof(double);
+  if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "significanceOfReferenceTime", 0), 0);
+  if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "stepRange", 0), 0);
 
-void gen_pow2tab(void)
+  if ( date == 0 ) date = 10101;
+  gribapiSetDataDateTime(gh, date, time);
+}
+
+static
+int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rtime, int vdate, int vtime,
+                          int productDefinitionTemplate, int typeOfGeneratingProcess, int tsteptype, int timeunit, int calendar, int gcinit)
 {
-  int jloop;
+  int status = -1;
+  int year, month, day, hour, minute, second;
+  int julday1, secofday1, julday2, secofday2, days, secs;
+  int factor;
+  long startStep = 0, endStep;
 
-  for ( jloop = 0; jloop < 158; jloop++ )
-    printf(" /* pow(2.0, %2d.0) */  %.1f,\n", jloop,  pow(2.0, (double) jloop));
-}
+  cdiDecodeDate(rdate, &year, &month, &day);
+  cdiDecodeTime(rtime, &hour, &minute, &second);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
+  if ( vdate == 0 && vtime == 0 ) { vdate = rdate; vtime = rtime; }
 
-void gen_pow16tab(void)
-{
-  double pval;
-  int iexp;
+  cdiDecodeDate(vdate, &year, &month, &day);
+  cdiDecodeTime(vtime, &hour, &minute, &second);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
-  for ( iexp = 0; iexp < 71; iexp++ )
+  (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
+
+  factor = getTimeunitFactor(timeunit);
+
+  if ( !(int) fmod(days*86400.0 + secs, factor) )
     {
-      pval = pow(16.0, (double)(iexp));
-      printf(" /* pow(16.0, %2d.0) */  %.1f,\n", iexp, pval);
-    }
-}
+      int proDefTempNum = gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
 
+      gribapiDefStepUnits(gh, timeunit, proDefTempNum, gcinit);
 
-double intpow2(int x)
-{
-  if ( x < _pow2tab_size )
-    return (_pow2tab[x]);
-  else
-    return (pow(2.0, (double) x));
-}
-/* 
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL minmax_val.c
- result on bailung (gcc 4.8.2):
-  orig    : fmin: -500000  fmax: 499999  time:   4.82s
-  sse2    : fmin: -500000  fmax: 499999  time:   4.83s
+      endStep = (int) ((days*86400.0 + secs)/factor);
 
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD minmax_val.c
- result on thunder5 (gcc 4.8.2):
-  orig    : fmin: -500000  fmax: 499999  time:   3.10s
-  simd    : fmin: -500000  fmax: 499999  time:   3.10s # omp simd in gcc 4.9
-  avx     : fmin: -500000  fmax: 499999  time:   2.84s
+      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "significanceOfReferenceTime", 1), 0);
+      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "stepRange", 0), 0);
 
-icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
- result on thunder5 (icc 14.0.2):
-  orig    : fmin: -500000  fmax: 499999  time:   2.83s
-  simd    : fmin: -500000  fmax: 499999  time:   2.83s
-  avx     : fmin: -500000  fmax: 499999  time:   2.92s
+      if ( rdate == 0 ) rdate = 10101;
+      gribapiSetDataDateTime(gh, rdate, rtime);
 
-xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_MINMAXVAL minmax_val.c
- result on blizzard (xlc 12):
-  orig    : fmin: -500000  fmax: 499999  time:   7.26s
-  pwr6u6  : fmin: -500000  fmax: 499999  time:   5.92s
-*/
-#if defined(_ARCH_PWR6)
-#pragma options nostrict
-#endif
+      // printf(">>>>> tsteptype %d  startStep %ld  endStep %ld\n", tsteptype, startStep, endStep);
 
-#include <stdlib.h>
+      // Product Definition Template Number: defined in GRIB_API file 4.0.table
+      // point in time products:
+      if ( (proDefTempNum >= 0 && proDefTempNum <=  7) || 
+           proDefTempNum == 55 || proDefTempNum == 40055 ) // Tile
+        startStep = endStep;
 
-//#undef _GET_X86_COUNTER
-//#undef _GET_IBM_COUNTER
-//#undef _GET_MACH_COUNTER
-//#undef _ARCH_PWR6
+      if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "forecastTime", startStep), 0);
+      GRIB_CHECK(my_grib_set_long(gh, "endStep", endStep), 0);
 
-#if defined(_GET_IBM_COUNTER)
-#include <libhpc.h>
-#elif defined(_GET_X86_COUNTER)
-#include <x86intrin.h>
-#elif defined(_GET_MACH_COUNTER)
-#include <mach/mach_time.h>
-#endif
+      status = 0;
+    }
 
-#if   defined(__GNUC__) && !defined(__ICC) && !defined(__clang__)
-#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 4)
-#define GNUC_PUSH_POP
-#endif
-#endif
+  return (status);
+}
 
-#if   defined(__GNUC__) && (__GNUC__ >= 4)
-#elif defined(__ICC)    && (__ICC >= 1100)
-#elif defined(__clang__)
-#else
-#define DISABLE_SIMD
-#endif
+static
+void gribapiDefTime(int editionNumber, int productDefinitionTemplate, int typeOfGeneratingProcess, grib_handle *gh,
+                    int vdate, int vtime, int tsteptype, int numavg, int taxisID, int gcinit)
+{
+  int taxistype = -1;
 
-#if !defined(TEST_MINMAXVAL)
-#define DISABLE_SIMD
-#endif
+  UNUSED(numavg);
 
-#if defined(DISABLE_SIMD)
-# if defined(ENABLE_AVX)
-#  define _ENABLE_AVX
-# endif
-# if defined(ENABLE_SSE2)
-#  define _ENABLE_SSE2
-# endif
-#endif
+  if ( taxisID != -1 ) taxistype = taxisInqType(taxisID);
 
-#if !defined(DISABLE_SIMD)
-# if defined(__AVX__)
-#  define _ENABLE_AVX
-# endif
-# if defined(__SSE2__)
-#  define _ENABLE_SSE2
-# endif
-#endif
+  if ( typeOfGeneratingProcess == 196 )
+    {
+      vdate = 10101;
+      vtime = 0;
+      taxistype = TAXIS_ABSOLUTE;
+    }
+  /*
+  else if ( typeOfGeneratingProcess == 9 )
+    {
+    }
+  */
 
-#include <float.h>
-#include <stdint.h>
-#include <inttypes.h>
+  if ( taxistype == TAXIS_RELATIVE )
+    {
+      int status;
+      int calendar = taxisInqCalendar(taxisID);
+      int rdate    = taxisInqRdate(taxisID);
+      int rtime    = taxisInqRtime(taxisID);
+      int timeunit = taxisInqTunit(taxisID);
 
-#if defined(_ENABLE_AVX)
-#include <immintrin.h>
-#elif defined(_ENABLE_SSE2)
-#include <emmintrin.h>
-#endif
+      status = gribapiDefDateTimeRel(editionNumber, gh, rdate, rtime, vdate, vtime,
+                                     productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, timeunit, calendar, gcinit);
 
+      if ( status != 0 ) taxistype = TAXIS_ABSOLUTE;
+    }
 
-#if defined(_ENABLE_AVX)
+  if ( taxistype == TAXIS_ABSOLUTE )
+    {
+      gribapiDefDateTimeAbs(editionNumber, gh, vdate, vtime, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
+    }
+}
 
 static
-void avx_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
+void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, int lieee, int datatype, int nmiss, int gcinit)
 {
-  double fmin[4], fmax[4];
-  __m256d current_max, current_min, work;
+  int gridtype;
+  int status;
+  static short lwarn = TRUE;
+  size_t len;
+  char *mesg;
 
-  // load max and min values into all four slots of the YMM registers
-  current_min = _mm256_set1_pd(*min);
-  current_max = _mm256_set1_pd(*max);
+  UNUSED(nmiss);
 
-  // Work input until "buf" reaches 32 byte alignment
-  while ( ((unsigned long)buf) % 32 != 0 && nframes > 0) {
+  gridtype = gridInqType(gridID);
 
-    // Load the next double into the work buffer
-    work = _mm256_set1_pd(*buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf++;
-    nframes--;
-  }
+  if ( editionNumber <= 1 )
+    if ( gridtype == GRID_GME || gridtype == GRID_UNSTRUCTURED )
+      gridtype = -1;
 
-  while (nframes >= 16) {
+  if ( gridtype == GRID_GENERIC )
+    {
+      int xsize, ysize, gridsize;
 
-    (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
+      gridsize = gridInqSize(gridID);
+      xsize = gridInqXsize(gridID);
+      ysize = gridInqYsize(gridID);
 
-    work = _mm256_load_pd(buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf += 4;
+      if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
+	    ysize ==  96 || ysize == 160 || ysize == 192 ||
+	    ysize == 240 || ysize == 320 || ysize == 384 ||
+	    ysize == 480 || ysize == 768 ) &&
+	   (xsize == 2*ysize || xsize == 1) )
+	{
+	  gridtype = GRID_GAUSSIAN;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( gridsize == 1 )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+    }
+  else if ( gridtype == GRID_CURVILINEAR )
+    {
+      if ( lwarn && gridInqSize(gridID) > 1 )
+	{
+	  lwarn = FALSE;
+	  Warning("Curvilinear grids are unsupported in GRIB format! Created wrong GDS!");
+	}
+      gridtype = GRID_LONLAT;
+    }
 
-    work = _mm256_load_pd(buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf += 4;
+  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
+    {
+      if ( editionNumber != 2 || lieee ) { comptype = 0; }
 
-    (void) _mm_prefetch((const char *)(buf+8), _MM_HINT_NTA);
+      if ( comptype )
+        {
+          if ( comptype == COMPRESS_JPEG )
+            {
+              mesg = "grid_jpeg"; len = strlen(mesg);
+              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+            }
+          else if ( comptype == COMPRESS_SZIP )
+            {
+              mesg = "grid_ccsds"; len = strlen(mesg);
+              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+            }
+          else
+            {
+              mesg = "grid_simple"; len = strlen(mesg);
+              GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+            }
+        }
+    }
 
-    work = _mm256_load_pd(buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf += 4;
+  if ( gcinit ) return;
 
-    work = _mm256_load_pd(buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf += 4;
-    nframes -= 16;
-  }
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+    case GRID_GAUSSIAN_REDUCED:
+    case GRID_TRAJECTORY:
+      {
+	int nlon = 0, nlat;
+	double xfirst = 0, xlast = 0, xinc = 0;
+	double yfirst = 0, ylast = 0, yinc = 0;
+	double latIncr;
 
-  // work through aligned buffers
-  while (nframes >= 4) {
-    work = _mm256_load_pd(buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf += 4;
-    nframes -= 4;
-  }
+	if ( gridtype == GRID_GAUSSIAN )
+	  {
+	    mesg = "regular_gg"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+	  }
+	else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+	  {
+	    mesg = "reduced_gg"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+	  }
+	else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
+	  {
+	    mesg = "rotated_ll"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+	  }
+	else
+	  {
+	    mesg = "regular_ll"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+	  }
 
-  // work through the remainung values
-  while ( nframes > 0) {
-    work = _mm256_set1_pd(*buf);
-    current_min = _mm256_min_pd(current_min, work);
-    current_max = _mm256_max_pd(current_max, work);
-    buf++;
-    nframes--;
-  }
+	nlon = gridInqXsize(gridID);
+	nlat = gridInqYsize(gridID);
 
-  // find min & max value through shuffle tricks
+	if ( gridtype == GRID_GAUSSIAN_REDUCED )
+	  {
+	    int *rowlon, i;
+	    long *pl = NULL;
 
-  work = current_min;
-  work = _mm256_shuffle_pd(work, work, 5);
-  work = _mm256_min_pd (work, current_min);
-  current_min = work;
-  work = _mm256_permute2f128_pd(work, work, 1);
-  work = _mm256_min_pd (work, current_min);
-  _mm256_storeu_pd(fmin, work);
+	    nlon = 0;
 
-  work = current_max;
-  work = current_max;
-  work = _mm256_shuffle_pd(work, work, 5);
-  work = _mm256_max_pd (work, current_max);
-  current_max = work;
-  work = _mm256_permute2f128_pd(work, work, 1);
-  work = _mm256_max_pd (work, current_max);
-  _mm256_storeu_pd(fmax, work);
+	    rowlon = (int *) malloc(nlat*sizeof(int));
+	    pl     = (long *) malloc(nlat*sizeof(long));
+	    gridInqRowlon(gridID, rowlon);
+	    for ( i = 0; i < nlat; ++i ) pl[i] = rowlon[i];
 
-  *min = fmin[0];
-  *max = fmax[0];
+	    // GRIB_CHECK(my_grib_set_long_array(gh, "pl", pl, nlat), 0);
 
-  return;
-}
+	    free(pl);
+	    free(rowlon);
+	  }
+	else
+	  {
+	    if ( nlon == 0 )
+	      {
+		nlon = 1;
+	      }
+	    else
+	      {
+		xfirst = gridInqXval(gridID,      0);
+		xlast  = gridInqXval(gridID, nlon-1);
+		xinc   = gridInqXinc(gridID);
+	      }
+	  }
 
-#elif defined(_ENABLE_SSE2)
+	if ( nlat == 0 )
+	  {
+	    nlat = 1;
+	  }
+	else
+	  {
+	    yfirst = gridInqYval(gridID,      0);
+	    ylast  = gridInqYval(gridID, nlat-1);
+	    yinc   = gridInqYinc(gridID);
+	  }
 
-static
-void sse2_minmax_val_double(const double *restrict buf, size_t nframes, double *min, double *max)
-{
-  __m128d current_max, current_min, work;
-  
-  // load starting max and min values into all slots of the XMM registers
-  current_min = _mm_set1_pd(*min);
-  current_max = _mm_set1_pd(*max);
-  
-  // work on input until buf reaches 16 byte alignment
-  while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) {
-    
-    // load one double and replicate
-    work = _mm_set1_pd(*buf);    
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);    
-    buf++;
-    nframes--;
-  }
-  
-  while (nframes >= 8) {
-    // use 64 byte prefetch for double octetts
-    // __builtin_prefetch(buf+64,0,0); // for GCC 4.3.2 +
+	GRIB_CHECK(my_grib_set_long(gh, "Ni", nlon), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "Nj", nlat), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", xfirst), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfLastGridPointInDegrees",  xlast), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees",  yfirst), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees",   ylast), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "iDirectionIncrementInDegrees", xinc), 0);
 
-    work = _mm_load_pd(buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf += 2;
-    work = _mm_load_pd(buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf += 2;
-    work = _mm_load_pd(buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf += 2;
-    work = _mm_load_pd(buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf += 2;
-    nframes -= 8;
-  }
+        {
+          long jscan = 0;
+          if ( yfirst < ylast ) jscan = 1;
+          GRIB_CHECK(my_grib_set_long(gh, "jScansPositively", jscan), 0);
+        }
+	/*
+	if ( fabs(xinc*1000 - ISEC2_LonIncr) > FLT_EPSILON )
+	  ISEC2_LonIncr = 0;
+	*/
+	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
+          {
+            int np = gridInqNP(gridID);
+            if ( np == 0 ) np = nlat/2;
+            GRIB_CHECK(my_grib_set_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", np), 0);
+          }
+	else
+	  {
+	    latIncr = yinc;
+	    if ( latIncr < 0 ) latIncr = -latIncr;
+	    GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", latIncr), 0);
+	    /*
+	    if ( fabs(yinc*1000 - ISEC2_LatIncr) > FLT_EPSILON )
+	      ISEC2_LatIncr = 0;
+	    */
+	  }
+	/*
+	if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
+	  if ( ISEC2_LonIncr != 0 && ISEC2_LatIncr == 0 ) ISEC2_LatIncr = ISEC2_LonIncr;
 
-  // work through smaller chunks of aligned buffers without prefetching
-  while (nframes >= 2) {
-    work = _mm_load_pd(buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf += 2;
-    nframes -= 2;
-  }
+	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
+	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
 
-  // work through the remaining value
-  while ( nframes > 0) {
-    // load the last double and replicate
-    work = _mm_set1_pd(*buf);
-    current_min = _mm_min_pd(current_min, work);
-    current_max = _mm_max_pd(current_max, work);
-    buf++;
-    nframes--;
-  }
+	if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
+	  ISEC2_ResFlag = 0;
+	else
+	  ISEC2_ResFlag = 128;
+	*/
+	if ( gridIsRotated(gridID) )
+	  {
+	    double xpole, ypole, angle;
+	    xpole = gridInqXpole(gridID);
+	    ypole = gridInqYpole(gridID);
+	    angle = gridInqAngle(gridID);
+	    /* change from north to south pole */
+	    ypole = -ypole;
+	    xpole =  xpole + 180;
+	    GRIB_CHECK(my_grib_set_double(gh, "latitudeOfSouthernPoleInDegrees",  ypole), 0);
+	    GRIB_CHECK(my_grib_set_double(gh, "longitudeOfSouthernPoleInDegrees", xpole), 0);
+	    GRIB_CHECK(my_grib_set_double(gh, "angleOfRotation", angle), 0);
+	  }
+
+	/* East -> West */
+	//if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
+
+	/* South -> North */
+	//if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
+
+        if ( editionNumber != 2 ) { lieee = 0; comptype = 0; }
+
+        if ( lieee )
+          {
+            mesg = "grid_ieee"; len = strlen(mesg);
+            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+
+	    if ( datatype == DATATYPE_FLT64 )
+	      GRIB_CHECK(my_grib_set_long(gh, "precision", 2), 0);
+	    else
+	      GRIB_CHECK(my_grib_set_long(gh, "precision", 1), 0);
+          }
+        else
+	  {
+            if ( comptype == COMPRESS_JPEG )
+              {
+                mesg = "grid_jpeg"; len = strlen(mesg);
+                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+              }
+            else if ( comptype == COMPRESS_SZIP )
+              {
+                mesg = "grid_ccsds"; len = strlen(mesg);
+                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+              }
+            else
+              {
+                mesg = "grid_simple"; len = strlen(mesg);
+                GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+              }
+	  }
 
-  // find final min and max value through shuffle tricks
-  work = current_min;
-  work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
-  work = _mm_min_pd (work, current_min);
-  _mm_store_sd(min, work);
-  work = current_max;
-  work = _mm_shuffle_pd(work, work, _MM_SHUFFLE2(0, 1));
-  work = _mm_max_pd (work, current_max);
-  _mm_store_sd(max, work);
+	break;
+      }
+    case GRID_LCC:
+      {
+	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
+	int xsize, ysize;
+	int projflag, scanflag;
 
-  return;
-}
+	xsize = gridInqXsize(gridID);
+	ysize = gridInqYsize(gridID);
 
-#endif // SIMD
+	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
+		   &projflag, &scanflag);
 
-#if defined(_ARCH_PWR6)
-static
-void pwr6_minmax_val_double_unrolled6(const double *restrict data, long idatasize, double *fmin, double *fmax)
-{
-#define __UNROLL_DEPTH_1 6
-  size_t datasize = idatasize;
+        mesg = "lambert"; len = strlen(mesg);
+        GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
 
-  // to allow pipelining we have to unroll 
+	GRIB_CHECK(my_grib_set_long(gh, "Nx", xsize), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "Ny", ysize), 0);
 
-  {
-    size_t i, j;
-    size_t residual =  datasize % __UNROLL_DEPTH_1;
-    size_t ofs = datasize - residual;
-    double register dmin[__UNROLL_DEPTH_1];
-    double register dmax[__UNROLL_DEPTH_1];
+	GRIB_CHECK(my_grib_set_double(gh, "DxInMetres", lround(xincm)), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "DyInMetres", lround(yincm)), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", originLon), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", originLat), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "LoVInDegrees", lonParY), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "Latin1InDegrees", lat1), 0);
+	GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat2), 0);
 
-    for ( j = 0; j < __UNROLL_DEPTH_1; j++) 
-      {
-	dmin[j] = data[0];
-	dmax[j] = data[0];
+        if ( editionNumber <= 1 )
+          {
+            GRIB_CHECK(my_grib_set_long(gh, "projectionCenterFlag", projflag), 0);
+            GRIB_CHECK(my_grib_set_long(gh, "scanningMode", scanflag), 0);
+          }
+        /*
+	ISEC2_Lambert_LatSP  = 0;
+	ISEC2_Lambert_LatSP  = 0;
+        */
+	break;
       }
-    
-    for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_1 ) 
+    case GRID_SPECTRAL:
       {
-	for (j = 0; j < __UNROLL_DEPTH_1; j++) 
+	int trunc = gridInqTrunc(gridID);
+
+	mesg = "sh"; len = strlen(mesg);
+	GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+
+	GRIB_CHECK(my_grib_set_long(gh, "J", trunc), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "K", trunc), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "M", trunc), 0);
+
+	// GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridInqSize(gridID)), 0);
+        /*
+        if ( lieee )
+          {
+            printf("spectral_ieee\n");
+            if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridInqSize(gridID)), 0);
+            mesg = "spectral_ieee"; len = strlen(mesg);
+            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+          }
+        else */ if ( gridInqComplexPacking(gridID) )
 	  {
-	    dmin[j] = __fsel(dmin[j] - data[i+j], data[i+j], dmin[j]);
-	    dmax[j] = __fsel(data[i+j] - dmax[j], data[i+j], dmax[j]);
+	    if ( editionNumber == 2 ) GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridInqSize(gridID)), 0);
+	    mesg = "spectral_complex"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+
+	    GRIB_CHECK(my_grib_set_long(gh, "JS", 20), 0);
+	    GRIB_CHECK(my_grib_set_long(gh, "KS", 20), 0);
+	    GRIB_CHECK(my_grib_set_long(gh, "MS", 20), 0);
+	  }
+	else
+	  {
+	    mesg = "spectral_simple"; len = strlen(mesg);
+	    GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
 	  }
-      }
 
-    for (j = 0; j < residual; j++) 
-      {
-	dmin[j] = __fsel(dmin[j] - data[ofs+j], data[ofs+j], dmin[j]);
-	dmax[j] = __fsel(data[ofs+j] - dmax[j], data[ofs+j], dmax[j]);
+	break;
       }
-
-    for ( j = 0; j < __UNROLL_DEPTH_1; j++) 
+    case GRID_GME:
       {
-	*fmin = __fsel(*fmin - dmin[j], dmin[j], *fmin);
-	*fmax = __fsel(dmax[j] - *fmax, dmax[j], *fmax);
+	GRIB_CHECK(my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_GME), 0);
+
+	GRIB_CHECK(my_grib_set_long(gh, "nd", gridInqGMEnd(gridID)), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "Ni", gridInqGMEni(gridID)), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "n2", gridInqGMEni2(gridID)), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "n3", gridInqGMEni3(gridID)), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "latitudeOfThePolePoint", 90000000), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "longitudeOfThePolePoint", 0), 0);
+
+	GRIB_CHECK(my_grib_set_long(gh, "numberOfDataPoints", gridInqSize(gridID)), 0);
+	GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", gridInqSize(gridID)), 0);
+
+        if ( comptype == COMPRESS_SZIP )
+          {
+            mesg = "grid_ccsds"; len = strlen(mesg);
+            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+          }
+
+	break;
       }
-  }
-#undef __UNROLL_DEPTH_1
-}
-#endif
+    case GRID_UNSTRUCTURED:
+      {
+	static int warning = 1;
 
-#if defined(TEST_MINMAXVAL) && defined(__GNUC__)
-static
-void minmax_val_double_orig(const double *restrict data, long idatasize, double *fmin, double *fmax) __attribute__ ((noinline));
-#endif
+	status = my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_UNSTRUCTURED);
+	if ( status != 0 && warning )
+	  {
+	    warning = 0;
+	    Warning("Can't write reference grid!");
+	    Warning("gridDefinitionTemplateNumber %d not found (grib2/template.3.%d.def)!",
+		    GRIB2_GTYPE_UNSTRUCTURED, GRIB2_GTYPE_UNSTRUCTURED);
+	  }
+	else
+	  {
+            unsigned char uuid[CDI_UUID_SIZE];
+            int position = gridInqPosition(gridID);
+            int number = gridInqNumber(gridID);
+            if ( position < 0 ) position = 0;
+            if ( number < 0 ) number = 0;
+	    GRIB_CHECK(my_grib_set_long(gh, "numberOfGridUsed", number), 0);
+	    GRIB_CHECK(my_grib_set_long(gh, "numberOfGridInReference", position), 0);
+            len = CDI_UUID_SIZE;
+            gridInqUUID(gridID, uuid);
+	    if (grib_set_bytes(gh, "uuidOfHGrid", uuid, &len) != 0)
+	      Warning("Can't write UUID!");
+	  }
 
-#if defined(GNUC_PUSH_POP)
-#pragma GCC push_options
-#pragma GCC optimize ("O3", "fast-math")
-#endif
-static
-void minmax_val_double_orig(const double *restrict data, long idatasize, double *fmin, double *fmax)
-{
-  size_t i;
-  size_t datasize = idatasize;
-  double dmin = *fmin, dmax = *fmax;
+        if ( comptype == COMPRESS_SZIP )
+          {
+            mesg = "grid_ccsds"; len = strlen(mesg);
+            GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+          }
 
-#if   defined(CRAY)
-#pragma _CRI ivdep
-#elif defined(SX)
-#pragma vdir nodep
-#elif defined(__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-  for ( i = 0; i < datasize; ++i )
-    {
-      dmin = dmin < data[i] ? dmin : data[i];
-      dmax = dmax > data[i] ? dmax : data[i];
+	break;
+      }
+    default:
+      {
+	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
+      }
     }
-
-  *fmin = dmin;
-  *fmax = dmax;
 }
 
 static
-void minmax_val_float(const float *restrict data, long idatasize, float *fmin, float *fmax)
+void getLevelFactor(double level, long *factor, long *out_scaled_value)
 {
-  size_t i;
-  size_t datasize = idatasize;
-  float dmin = *fmin, dmax = *fmax;
+  double scaled_value  = level;
+  /* FIXME: lround might be better here */
+  long   iscaled_value = (long) round(scaled_value);
+  long   i;
 
-#if   defined(CRAY)
-#pragma _CRI ivdep
-#elif defined(SX)
-#pragma vdir nodep
-#elif defined(__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-  for ( i = 0; i < datasize; ++i )
+  const double eps = 1.e-8;
+  for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
     {
-      dmin = dmin < data[i] ? dmin : data[i];
-      dmax = dmax > data[i] ? dmax : data[i];
+      scaled_value *= 10.;
+      /* FIXME: lround might be better here */
+      iscaled_value = (long)round(scaled_value);
     }
 
-  *fmin = dmin;
-  *fmax = dmax;
+  (*factor)           = i;
+  (*out_scaled_value) = iscaled_value;
 }
-#if defined(GNUC_PUSH_POP)
-#pragma GCC pop_options
-#endif
-
-// TEST
-#if defined(OMP_SIMD)
 
-//#pragma omp declare reduction(xmin : double : omp_out = omp:in > omp_out ? omp_out : omp_in)
-// initializer( omp_priv = { largenumber })
-//#pragma omp declare reduction(xmax : double : omp_out = omp:in < omp_out ? omp_out : omp_in)
-// initializer( omp_priv = { -largenumber })
-
-#if defined(GNUC_PUSH_POP)
-#pragma GCC push_options
-#pragma GCC optimize ("O3", "fast-math")
-#endif
 static
-void minmax_val_double_simd(const double *restrict data, long idatasize, double *fmin, double *fmax)
+void gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
 {
-  size_t i;
-  size_t datasize = idatasize;
-  double dmin = *fmin, dmax = *fmax;
-
-#if defined(_OPENMP)
-  //#pragma omp simd reduction(xmin:dmin) reduction(xmax:dmax)
-#pragma omp simd
-#endif
-  for ( i = 0; i < datasize; ++i )
-    {
-      dmin = dmin < data[i] ? dmin : data[i];
-      dmax = dmax > data[i] ? dmax : data[i];
-    }
-
-  *fmin = dmin;
-  *fmax = dmax;
+  if ( !gcinit ) GRIB_CHECK(my_grib_set_long(gh, keyname, leveltype), 0);
 }
-#if defined(GNUC_PUSH_POP)
-#pragma GCC pop_options
-#endif
-#endif
 
 static
-void minmax_val_double(const double *restrict data, long idatasize, double *fmin, double *fmax)
+void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2, int lbounds, double level, double dlevel1, double dlevel2)
 {
-#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER) 
-  uint64_t start_minmax, end_minmax;
-#endif
-  size_t datasize = idatasize;
-
-  if ( idatasize < 1 ) return;
-
-#if defined(_GET_X86_COUNTER) 
-  start_minmax = _rdtsc();
-#endif
-#if defined(_GET_MACH_COUNTER) 
-  start_minmax = mach_absolute_time();
-#endif
-
-#if defined(_ENABLE_AVX)
-
-  avx_minmax_val_double(data, datasize, fmin, fmax);
-
-#elif defined(_ENABLE_SSE2)
-
-  sse2_minmax_val_double(data, datasize, fmin, fmax);
-
-#else
-
-#if defined(_ARCH_PWR6)
-#define __UNROLL_DEPTH_1 6
-
-  // to allow pipelining we have to unroll 
-
-#if defined(_GET_IBM_COUNTER)
-  hpmStart(1, "minmax fsel");
-#endif
-
-  pwr6_minmax_val_double_unrolled6(data, datasize, fmin, fmax);
-
-#if defined(_GET_IBM_COUNTER) 
-  hpmStop(1);
-#endif
-
-#undef __UNROLL_DEPTH_1
-
-#else // original loop
-
-#if defined(_GET_IBM_COUNTER) 
-  hpmStart(1, "minmax base");
-#endif
-
-  minmax_val_double_orig(data, datasize, fmin, fmax);
+  long scaled_level;
+  long factor;
 
-#if defined(_GET_IBM_COUNTER) 
-  hpmStop(1);
-#endif
+  gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", leveltype1);
+  if ( lbounds ) gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", leveltype2);
 
-#endif // _ARCH_PWR6 && original loop
-#endif // SIMD
+  if ( !lbounds ) dlevel1 = level;
 
-#if defined(_GET_X86_COUNTER) || defined(_GET_MACH_COUNTER)
-#if defined(_GET_X86_COUNTER) 
-  end_minmax = _rdtsc();
-#endif
-#if defined(_GET_MACH_COUNTER) 
-  end_minmax = mach_absolute_time();
-#endif
-#if defined(_ENABLE_AVX)
-  printf("AVX minmax cycles:: %" PRIu64 "\n",  end_minmax-start_minmax);
-  fprintf (stderr, "AVX min: %lf max: %lf\n", *fmin, *fmax);
-#elif defined(_ENABLE_SSE2)
-  printf("SSE2 minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-  fprintf (stderr, "SSE2 min: %lf max: %lf\n", *fmin, *fmax);
-#else
-  printf("loop minmax cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-  fprintf (stderr, "loop min: %lf max: %lf\n", *fmin, *fmax);
-#endif
-#endif
+  getLevelFactor(dlevel1, &factor, &scaled_level);
+  GRIB_CHECK(my_grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
+  GRIB_CHECK(my_grib_set_long(gh, "scaledValueOfFirstFixedSurface", scaled_level), 0);
 
-  return;
+  if ( lbounds )
+    {
+      getLevelFactor(dlevel2, &factor, &scaled_level);
+      GRIB_CHECK(my_grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
+      GRIB_CHECK(my_grib_set_long(gh, "scaledValueOfSecondFixedSurface", scaled_level), 0);
+    }
 }
 
-#if defined(TEST_MINMAXVAL)
-
-#include <stdio.h>
-#include <sys/time.h>
-
 static
-double dtime()
-{
-  double tseconds = 0.0;
-  struct timeval mytime;
-  gettimeofday(&mytime, NULL);
-  tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
-  return (tseconds);
-}
-
-#define NRUN 10000
-
-int main(void)
+void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
-  long datasize = 1000000;
-  double t_begin, t_end;
+  int lbounds = 0;
+  static int warning = 1;
+  double dlevel1 = 0, dlevel2 = 0;
 
-#if   defined(_OPENMP)
-  printf("_OPENMP=%d\n", _OPENMP);
-#endif
+  int zaxistype = zaxisInqType(zaxisID);
+  int ltype = zaxisInqLtype(zaxisID);
+  int ltype2 = zaxisInqLtype2(zaxisID);
+  double level = zaxisInqLevel(zaxisID, levelID);
 
-#if   defined(__ICC)
-  printf("icc\n");
-#elif defined(__clang__)
-  printf("clang\n");
-#elif defined(__GNUC__)
-  printf("gcc\n");
-#endif
+  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      lbounds = 1;
+      dlevel1 = zaxisInqLbound(zaxisID, levelID);
+      dlevel2 = zaxisInqUbound(zaxisID, levelID);
+    }
+  else
+    {
+      dlevel1 = level;
+      dlevel2 = 0;
+    }
 
-  {
-    float fmin, fmax;
-    float *data_sp = (float*) malloc(datasize*sizeof(float));
+  if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
+    {
+      Message("Changed zaxis type from %s to %s", zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
+      zaxistype = ZAXIS_PRESSURE;
+      zaxisChangeType(zaxisID, zaxistype);
+      zaxisDefUnits(zaxisID, "Pa");
+    }
 
-    for ( long i = 0; i < datasize/2; i++ )        data_sp[i] = (float) (i);
-    for ( long i = datasize/2; i < datasize; i++ ) data_sp[i] = (float) (-datasize + i);
+  int grib2ltype = zaxisTypeToGrib2ltype(zaxistype);
 
-    printf("float:\n");
+  switch (zaxistype)
+    {
+    case ZAXIS_SURFACE:
+    case ZAXIS_MEANSEA:
+    case ZAXIS_HEIGHT:
+    case ZAXIS_ALTITUDE:
+    case ZAXIS_SIGMA:
+    case ZAXIS_DEPTH_BELOW_SEA:
+    case ZAXIS_ISENTROPIC:
+      {
+	if ( editionNumber <= 1 )
+          {
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+            GRIB_CHECK(my_grib_set_long(gh, "level", (long)level), 0);
+          }
+        else
+          {
+            grib2DefLevel(gh, gcinit, grib2ltype, grib2ltype, lbounds, level, dlevel1, dlevel2);
+          }
 
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
+	break;
+      }
+    case ZAXIS_CLOUD_BASE:
+    case ZAXIS_CLOUD_TOP:
+    case ZAXIS_ISOTHERM_ZERO:
+    case ZAXIS_TOA:
+    case ZAXIS_SEA_BOTTOM:
+    case ZAXIS_LAKE_BOTTOM:
+    case ZAXIS_SEDIMENT_BOTTOM:
+    case ZAXIS_SEDIMENT_BOTTOM_TA:
+    case ZAXIS_SEDIMENT_BOTTOM_TW:
+    case ZAXIS_MIX_LAYER:
+    case ZAXIS_ATMOSPHERE:
       {
-	fmin = fmax = data_sp[0];
-	minmax_val_float(data_sp, datasize, &fmin, &fmax);
+        if ( editionNumber <= 1 )
+          {
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+            if ( lbounds )
+              {
+                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
+              }
+            else
+              {
+                GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
+              }
+          }
+        else
+          {
+            grib2DefLevel(gh, gcinit, grib2ltype, grib2ltype, lbounds, level, dlevel1, dlevel2);
+          }
+
+        break;
       }
-    t_end = dtime();
-    printf("minmax_val: fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-    free(data_sp);
-  }
+    case ZAXIS_HYBRID:
+    case ZAXIS_HYBRID_HALF:
+      {
+        if ( editionNumber <= 1 )
+          {
+            if ( lbounds )
+              {
+                gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
+                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
+              }
+            else
+              {
+                gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
+                GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
+              }
+          }
+        else
+          {
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_HYBRID, GRIB2_LTYPE_HYBRID, lbounds, level, dlevel1, dlevel2);
+          }
+
+        if ( !gcinit )
+          {
+            int vctsize = zaxisInqVctSize(zaxisID);
+            if ( vctsize == 0 && warning )
+              {
+                char paramstr[32];
+                cdiParamToString(param, paramstr, sizeof(paramstr));
+                Warning("VCT missing ( param = %s, zaxisID = %d )", paramstr, zaxisID);
+                warning = 0;
+              }
+            GRIB_CHECK(my_grib_set_long(gh, "PVPresent", 1), 0);
+            GRIB_CHECK(grib_set_double_array(gh, "pv", zaxisInqVctPtr(zaxisID), (size_t)vctsize), 0);
+          }
 
-  {
-    double fmin, fmax;
-    double *data_dp = (double*) malloc(datasize*sizeof(double));
+	break;
+      }
+    case ZAXIS_PRESSURE:
+      {
+	double dum;
+	char units[128];
 
-    // for ( long i = datasize-1; i >= 0; i-- ) data[i] = (double) (-datasize/2 + i);
-    for ( long i = 0; i < datasize/2; i++ )        data_dp[i] = (double) (i);
-    for ( long i = datasize/2; i < datasize; i++ ) data_dp[i] = (double) (-datasize + i);
+	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
 
-    printf("double:\n");
+	zaxisInqUnits(zaxisID, units);
+	if ( memcmp(units, "Pa", 2) != 0 )
+          {
+            level   *= 100;
+            dlevel1 *= 100;
+            dlevel2 *= 100;
+          }
 
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
-      {
-	fmin = fmax = data_dp[0];
-	minmax_val_double(data_dp, datasize, &fmin, &fmax);
-      }
-    t_end = dtime();
-    printf("minmax_val: fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+        if ( editionNumber <= 1 )
+          {
+            long leveltype = GRIB1_LTYPE_ISOBARIC;
 
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
-      {
-	fmin = fmax = data_dp[0];
-	minmax_val_double_orig(data_dp, datasize, &fmin, &fmax);
-      }
-    t_end = dtime();
-    printf("orig      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
+            if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
+              leveltype = GRIB1_LTYPE_99;
+            else
+              level /= 100;
 
-#if defined(OMP_SIMD)
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
-      {
-	fmin = fmax = data_dp[0];
-	minmax_val_double_simd(data_dp, datasize, &fmin, &fmax);
-      }
-    t_end = dtime();
-    printf("simd      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", leveltype);
+            GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
+	  }
+	else
+	  {
+            if ( ltype2 == -1 ) ltype2 = GRIB2_LTYPE_ISOBARIC;
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_ISOBARIC, ltype2, lbounds, level, dlevel1, dlevel2);
+	  }
 
-#if defined(_ENABLE_AVX)
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
-      {
-	fmin = fmax = data_dp[0];
-	avx_minmax_double_val(data_dp, datasize, &fmin, &fmax);
+	break;
       }
-    t_end = dtime();
-    printf("avx       : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#elif defined(_ENABLE_SSE2)
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
+    case ZAXIS_SNOW:
       {
-	fmin = fmax = data_dp[0];
-	sse2_minmax_val_double(data_dp, datasize, &fmin, &fmax);
+        if ( editionNumber <= 1 )
+          ; // not available
+	else
+          {
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_SNOW, GRIB2_LTYPE_SNOW, lbounds, level, dlevel1, dlevel2);
+          }
+
+	break;
       }
-    t_end = dtime();
-    printf("sse2      : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
-#if defined(_ARCH_PWR6)
-    t_begin = dtime();
-    for ( int i = 0; i < NRUN; ++i )
+    case ZAXIS_DEPTH_BELOW_LAND:
       {
-	fmin = fmax = data_dp[0];
-	pwr6_minmax_val_double_unrolled6(data_dp, datasize, &fmin, &fmax);
-      }
-    t_end = dtime();
-    printf("pwr6u6  : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
-#endif
-    free(data_dp);
-  }
-
-  return (0);
-}
-#endif // TEST_MINMAXVAL
-
-#undef DISABLE_SIMD
-#undef _ENABLE_AVX
-#undef _ENABLE_SSE2
-#undef GNUC_PUSH_POP
-/* 
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
- result on hama (gcc 4.8.2):
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 16.0471s
-  sse41   : val1: 1  val2: 1  val3: 2  valn: 66  time: 15.4391s
-
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
- result on bailung (gcc 4.7):
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 8.4166s
-  sse41   : val1: 1  val2: 1  val3: 2  valn: 66  time: 7.1522s
-
-gcc -g -Wall -O3 -march=native -std=c99 -DTEST_ENCODE encode_array.c
- result on thunder5 (gcc 4.7):
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 6.21976s
-  avx     : val1: 1  val2: 1  val3: 2  valn: 66  time: 4.54485s
+	char units[128];
 
-icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_ENCODE encode_array.c
- result on thunder5 (icc 13.2):
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 14.6279s
-  avx     : val1: 1  val2: 1  val3: 2  valn: 66  time:  4.9776s
+	zaxisInqUnits(zaxisID, units);
 
-xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_ENCODE encode_array.c
- result on blizzard (xlc 12):
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 132.25s
-  unrolled: val1: 1  val2: 1  val3: 2  valn: 66  time:  27.202s
-  orig    : val1: 1  val2: 1  val3: 2  valn: 66  time: 106.627s  // without -qhot
-  unrolled: val1: 1  val2: 1  val3: 2  valn: 66  time:  39.929s  // without -qhot
-*/
-#ifdef _ARCH_PWR6
-#pragma options nostrict
-#endif
+	if ( editionNumber <= 1 )
+	  {
+            double scalefactor;
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor =   0.1;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor =   1; // cm
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor =  10;
+	    else                                    scalefactor = 100;
 
-#ifdef TEST_ENCODE
-#include <stdio.h>
-#include <stdlib.h>
-#define  GRIBPACK     unsigned char
-#define  IS_BIGENDIAN()  (u_byteorder.c[sizeof(long) - 1])
-#define  U_BYTEORDER     static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1}
-#define  Error(x,y)
-#endif
+	    gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH);
+	    GRIB_CHECK(my_grib_set_double(gh, "level", level*scalefactor), 0);
+	  }
+	else
+	  {
+            double scalefactor;
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor = 0.001;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor = 0.01;
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor = 0.1;
+	    else                                    scalefactor = 1; // meter
 
-//#undef _GET_X86_COUNTER
-//#undef _GET_MACH_COUNTER
-//#undef _GET_IBM_COUNTER
-//#undef _ARCH_PWR6
+            level   *= scalefactor;
+            dlevel1 *= scalefactor;
+            dlevel2 *= scalefactor;
 
-#if defined _GET_IBM_COUNTER
-#include <libhpc.h>
-#elif defined _GET_X86_COUNTER
-#include <x86intrin.h>
-#elif defined _GET_MACH_COUNTER
-#include <mach/mach_time.h>
-#endif
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_LANDDEPTH, GRIB2_LTYPE_LANDDEPTH, lbounds, level, dlevel1, dlevel2);
+	  }
 
-#include <stdint.h>
+	break;
+      }
+    case ZAXIS_REFERENCE:
+      {
+        unsigned char uuid[CDI_UUID_SIZE];
 
-#if   defined(__GNUC__) && (__GNUC__ >= 4)
-#elif defined(__ICC)    && (__ICC >= 1100)
-#elif defined(__clang__)
-#else
-#define DISABLE_SIMD
-#endif
+        if ( !gcinit )
+          {
+            GRIB_CHECK(my_grib_set_long(gh, "genVertHeightCoords", 1), 0);
+          }
 
-//#define DISABLE_SIMD
+        if ( lbounds )
+          {
+            if ( editionNumber <= 1 )
+              ; // not available
+            else
+              {
+                int number = zaxisInqNumber(zaxisID);
+                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
+                gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_REFERENCE);
+                GRIB_CHECK(my_grib_set_long(gh, "NV", 6), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "numberOfVGridUsed", number), 0);
+                size_t len = CDI_UUID_SIZE;
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
+                  {
+                    Warning("Can't write UUID!");
+                  }
+                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
+              }
+          }
+        else
+          {
+            if ( editionNumber <= 1 )
+              ; // not available
+            else
+              {
+                int number = zaxisInqNumber(zaxisID);
+                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
+                GRIB_CHECK(my_grib_set_long(gh, "NV", 6), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "numberOfVGridUsed", number), 0);
+                size_t len = CDI_UUID_SIZE;
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
+                  {
+                    Warning("Can't write UUID!");
+                  }
+                GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
+              }
+          }
 
-#ifdef DISABLE_SIMD
-# ifdef ENABLE_AVX
-#  define _ENABLE_AVX
-# endif
-# ifdef ENABLE_SSE4_1
-#  define _ENABLE_SSE4_1
-# endif
-#endif
+        break;
+      }
+    case ZAXIS_GENERIC:
+      {
+	if ( editionNumber <= 1 )
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", ltype);
+        else
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", ltype);
 
-#ifndef DISABLE_SIMD
-# ifdef __AVX__
-#  define _ENABLE_AVX
-# endif
-# ifdef __SSE4_1__
-#  define _ENABLE_SSE4_1
-# endif
-#endif
+	GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
 
-#if defined _ENABLE_AVX
-#include <immintrin.h>
-#elif defined _ENABLE_SSE4_1
-#include <smmintrin.h>
+	break;
+      }
+    default:
+      {
+	Error("Unsupported zaxis type: %s", zaxisNamePtr(zaxistype));
+	break;
+      }
+    }
+}
 #endif
 
-#if defined _ENABLE_AVX
+/* #define GRIBAPIENCODETEST 1 */
 
-static
-void avx_encode_array_2byte_double(size_t datasize, 
-				   unsigned char * restrict lGrib,
-				   const double * restrict data, 
-				   double zref, double factor, size_t *gz) 
+#ifdef HAVE_LIBGRIB_API
+size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
+		     int vdate, int vtime, int tsteptype, int numavg,
+		     long datasize, const double *data, int nmiss, unsigned char **gribbuffer, size_t *gribbuffersize,
+		     int comptype, void *gribContainer)
 {
-  size_t i, j, residual;
-  const double *dval = data;
-  __m128i *sgrib = (__m128i *) (lGrib+(*gz));
+  size_t recsize = 0;
+  void *dummy = NULL;
+  int lieee = FALSE;
+  /*  int ensID, ensCount, forecast_type; *//* Ensemble Data */
+  int typeOfGeneratingProcess;
+  int productDefinitionTemplate;
+  long bitsPerValue;
+  long editionNumber = 2;
+  char name[256];
+  char stdname[256];
+  gribContainer_t *gc = (gribContainer_t *) gribContainer;
+  // extern unsigned char _grib_template_GRIB2[];
 
-  const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  int param    = vlistInqVarParam(vlistID, varID);
+  int datatype = vlistInqVarDatatype(vlistID, varID);
+  typeOfGeneratingProcess = vlistInqVarTypeOfGeneratingProcess(vlistID, varID);
+  productDefinitionTemplate = vlistInqVarProductDefinitionTemplate(vlistID, varID);
 
-  const __m256d c0 = _mm256_set1_pd(zref);
-  const __m256d c1 = _mm256_set1_pd(factor);
-  const __m256d c2 = _mm256_set1_pd(0.5);
-  
-  __m256d d0, d3, d2, d1;
-  __m128i i0, i1, i2, i3;
-  __m128i s0, s1;  
+  vlistInqVarName(vlistID, varID, name);
+  vlistInqVarStdname(vlistID, varID, stdname);
 
-  residual = datasize % 16;
+#if defined(GRIBAPIENCODETEST)
+  grib_handle *gh = (grib_handle *) gribHandleNew(editionNumber);
+#else
+  grib_handle *gh = gc->gribHandle;
+#endif
+  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-  for (i = 0; i < (datasize-residual); i += 16)
+  if ( editionNumber == 2 )
     {
-      (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
-      //_____________________________________________________________________________
-
-      d0 = _mm256_loadu_pd (dval);
-      d0 = _mm256_sub_pd (d0, c0);
-      d0 = _mm256_mul_pd (d0, c1);
-      d0 = _mm256_add_pd (d0, c2);
-
-      i0 = _mm256_cvttpd_epi32 (d0);
-      
-      //_____________________________________________________________________________
-      
-      d1 = _mm256_loadu_pd (dval+4);
-      d1 = _mm256_sub_pd (d1, c0);
-      d1 = _mm256_mul_pd (d1, c1);
-      d1 = _mm256_add_pd (d1, c2);
-      
-      i1 = _mm256_cvttpd_epi32 (d1);
-
-      //_____________________________________________________________________________
-
-      s0 = _mm_packus_epi32(i0, i1);
-      s0 = _mm_shuffle_epi8 (s0, swap);
-      (void) _mm_storeu_si128 (sgrib, s0);
-
-      //_____________________________________________________________________________
-
-      (void) _mm_prefetch(dval+16, _MM_HINT_NTA);
+      if ( typeOfGeneratingProcess == -1 ) typeOfGeneratingProcess = 0;
+      if ( ! gc->init ) GRIB_CHECK(my_grib_set_long(gh, "typeOfGeneratingProcess", typeOfGeneratingProcess), 0);
+    }
 
-      //_____________________________________________________________________________
-      
-      d2 = _mm256_loadu_pd (dval+8);
-      d2 = _mm256_sub_pd (d2, c0);
-      d2 = _mm256_mul_pd (d2, c1);
-      d2 = _mm256_add_pd (d2, c2);
-      
-      i2 = _mm256_cvttpd_epi32 (d2);
+  /*
+  if( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
+    {
+      GRIB_CHECK(my_grib_set_long(gh, "typeOfEnsembleForecast", forecast_type ), 0);
+      GRIB_CHECK(my_grib_set_long(gh, "numberOfForecastsInEnsemble", ensCount ), 0);
+      GRIB_CHECK(my_grib_set_long(gh, "perturbationNumber", ensID ), 0);
+    }
+  */
 
-      //_____________________________________________________________________________
-      
-      d3 = _mm256_loadu_pd (dval+12);
-      d3 = _mm256_sub_pd (d3, c0);
-      d3 = _mm256_mul_pd (d3, c1);
-      d3 = _mm256_add_pd (d3, c2);
-      
-      i3 = _mm256_cvttpd_epi32 (d3);
+  gribapiDefTime((int)editionNumber, productDefinitionTemplate, typeOfGeneratingProcess, gh, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID), gc->init);
 
-      //_____________________________________________________________________________
+  if ( ! gc->init ) gribapiDefInstitut(gh, vlistID, varID);
+  if ( ! gc->init ) gribapiDefModel(gh, vlistID, varID);
 
-      s1 = _mm_packus_epi32(i2, i3);
-      s1 = _mm_shuffle_epi8 (s1, swap);
-      (void) _mm_storeu_si128 (sgrib+1, s1);
+  if ( ! gc->init ) gribapiDefParam(editionNumber, gh, param, name, stdname);
 
-      //_____________________________________________________________________________
-           
-      dval += 16;
-      sgrib += 2;
-    }
+  if ( editionNumber == 2 && (datatype == DATATYPE_FLT32 || datatype == DATATYPE_FLT64) ) lieee = TRUE;
 
-  if (i != datasize)
+  /* bitsPerValue have to be defined before call to DefGrid (complex packing) */
+  //  if ( lieee == FALSE )
     {
-      uint16_t ui16;
-      for ( j = i; j < datasize; j++ )
-	{
-	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
-	  lGrib[*gz+2*j  ] = ui16 >>  8;
-	  lGrib[*gz+2*j+1] = ui16;
-	}
+      bitsPerValue = grbBitsPerValue(datatype);
+      GRIB_CHECK(my_grib_set_long(gh, "bitsPerValue", bitsPerValue), 0);
     }
-  
-  *gz += 2*datasize;
-
-  return;
-}
 
-#elif defined _ENABLE_SSE4_1
+  gribapiDefGrid((int)editionNumber, gh, gridID, comptype, lieee, datatype, nmiss, gc->init);
 
-static
-void sse41_encode_array_2byte_double(size_t datasize, 
-				     unsigned char * restrict lGrib,
-				     const double * restrict data, 
-				     double zref, double factor, size_t *gz) 
-{
-  size_t i, j, residual;
-  const double *dval = data;
-  __m128i *sgrib = (__m128i *) (lGrib+(*gz));
+  gribapiDefLevel((int)editionNumber, gh, param, zaxisID, levelID, gc->init);
 
-  const __m128i swap = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
 
-  const __m128d c0 = _mm_set1_pd(zref);
-  const __m128d c1 = _mm_set1_pd(factor);
-  const __m128d c2 = _mm_set1_pd(0.5);
-  
-  __m128d d0, d4, d3, d2, d1;
-  __m128i i0, i1, i2, i3, i4;
-  __m128i s0, s1;  
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  //if (!gc->init)
+  {
+    for ( int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++ )
+      {
+        if ( vlistptr->vars[varID].opt_grib_dbl_update[i] )
+          {
+            //DR: Fix for multi-level fields (otherwise only the 1st level is correct)
+            if ( zaxisInqSize(zaxisID)==(levelID+1) ) vlistptr->vars[varID].opt_grib_dbl_update[i] = FALSE;
+            int ret = my_grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+                                         vlistptr->vars[varID].opt_grib_dbl_val[i]);
+            if (ret != 0) {
+              fprintf(stderr, "key \"%s\"  :   value = %g\n",
+                      vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+                      vlistptr->vars[varID].opt_grib_dbl_val[i]);
+            }
+            GRIB_CHECK(ret, 0);
+          }
+      }
+    for ( int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++ )
+      {
+        if ( vlistptr->vars[varID].opt_grib_int_update[i] )
+          {
+            //DR: Fix for multi-level fields (otherwise only the 1st level is correct)
+            if ( zaxisInqSize(zaxisID)==(levelID+1) ) vlistptr->vars[varID].opt_grib_int_update[i] = FALSE;
+            int ret = my_grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
+                                       vlistptr->vars[varID].opt_grib_int_val[i]);
+            if (ret != 0) {
+              fprintf(stderr, "key \"%s\"  :   value = %d\n",
+                      vlistptr->vars[varID].opt_grib_int_keyword[i],
+                      vlistptr->vars[varID].opt_grib_int_val[i]);
+            }
+            GRIB_CHECK(ret, 0);
+          }
+      }
+  }
 
-  residual = datasize % 16;
 
-  for (i = 0; i < (datasize-residual); i += 16)
+  if ( nmiss > 0 )
     {
-      (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
-      //_____________________________________________________________________________
-
-      d0 = _mm_loadu_pd (dval);
-      d0 = _mm_sub_pd (d0, c0);
-      d0 = _mm_mul_pd (d0, c1);
-      d0 = _mm_add_pd (d0, c2);
-      
-      d4 = _mm_loadu_pd (dval+2);
-      d4 = _mm_sub_pd (d4, c0);
-      d4 = _mm_mul_pd (d4, c1);
-      d4 = _mm_add_pd (d4, c2);
-
-      i0 = _mm_cvttpd_epi32 (d0);
-      i4 = _mm_cvttpd_epi32 (d4);  
-      i0 = _mm_unpacklo_epi64 (i0, i4);
-
-      //_____________________________________________________________________________
-      
-      d1 = _mm_loadu_pd (dval+4);
-      d1 = _mm_sub_pd (d1, c0);
-      d1 = _mm_mul_pd (d1, c1);
-      d1 = _mm_add_pd (d1, c2);
-      
-      d4 = _mm_loadu_pd (dval+6);
-      d4 = _mm_sub_pd (d4, c0);
-      d4 = _mm_mul_pd (d4, c1);
-      d4 = _mm_add_pd (d4, c2);
-      
-      i1 = _mm_cvttpd_epi32 (d1);
-      i4 = _mm_cvttpd_epi32 (d4);  
-      i1 = _mm_unpacklo_epi64 (i1, i4);
+      GRIB_CHECK(my_grib_set_long(gh, "bitmapPresent", 1), 0);
+      GRIB_CHECK(my_grib_set_double(gh, "missingValue", vlistInqVarMissval(vlistID, varID)), 0);
+    }
 
-      //_____________________________________________________________________________
+  GRIB_CHECK(grib_set_double_array(gh, "values", data, (size_t)datasize), 0);
 
-      s0 = _mm_packus_epi32(i0, i1);
-      s0 = _mm_shuffle_epi8 (s0, swap);
-      (void) _mm_storeu_si128 (sgrib, s0);
+  /* get the size of coded message  */
+  GRIB_CHECK(grib_get_message(gh, (const void **)&dummy, &recsize), 0);
+  recsize += 512; /* add some space for possible filling */
+  *gribbuffersize = recsize;
+  *gribbuffer = (unsigned char *) malloc(*gribbuffersize);
 
-      //_____________________________________________________________________________
+  /* get a copy of the coded message */
+  GRIB_CHECK(grib_get_message_copy(gh, *gribbuffer, &recsize), 0);
 
-      (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
+#if defined(GRIBAPIENCODETEST)
+  gribHandleDelete(gh);
+#endif
 
-      //_____________________________________________________________________________
-      
-      d2 = _mm_loadu_pd (dval+8);
-      d2 = _mm_sub_pd (d2, c0);
-      d2 = _mm_mul_pd (d2, c1);
-      d2 = _mm_add_pd (d2, c2);
-      
-      d4 = _mm_loadu_pd (dval+10);
-      d4 = _mm_sub_pd (d4, c0);
-      d4 = _mm_mul_pd (d4, c1);
-      d4 = _mm_add_pd (d4, c2);
-      
-      i2 = _mm_cvttpd_epi32 (d2);
-      i4  = _mm_cvttpd_epi32 (d4);  
-      i2 = _mm_unpacklo_epi64 (i2, i4);
+  gc->init = TRUE;
 
-      //_____________________________________________________________________________
-      
-      d3 = _mm_loadu_pd (dval+12);
-      d3 = _mm_sub_pd (d3, c0);
-      d3 = _mm_mul_pd (d3, c1);
-      d3 = _mm_add_pd (d3, c2);
-      
-      d4 = _mm_loadu_pd (dval+14);
-      d4 = _mm_sub_pd (d4, c0);
-      d4 = _mm_mul_pd (d4, c1);
-      d4 = _mm_add_pd (d4, c2);
-      
-      i3 = _mm_cvttpd_epi32 (d3);
-      i4 = _mm_cvttpd_epi32 (d4);  
-      i3 = _mm_unpacklo_epi64 (i3, i4);
+  return (recsize);
+}
+#endif
 
-      //_____________________________________________________________________________
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-      s1 = _mm_packus_epi32(i2, i3);
-      s1 = _mm_shuffle_epi8 (s1, swap);
-      (void) _mm_storeu_si128 (sgrib+1, s1);
 
-      //_____________________________________________________________________________
-           
-      dval += 16;
-      sgrib += 2;
-    }
 
-  if (i != datasize) 
+void streamDefHistory(int streamID, int length, const char *history)
+{
+#ifdef HAVE_LIBNETCDF
+  stream_t *streamptr = stream_to_pointer(streamID);
+
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
     {
-      uint16_t ui16;
-      for ( j = i; j < datasize; j++ )
+      char *histstring;
+      size_t len;
+      if ( history )
 	{
-	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
-	  lGrib[*gz+2*j  ] = ui16 >>  8;
-	  lGrib[*gz+2*j+1] = ui16;
+	  len = strlen(history);
+	  if ( len )
+	    {
+              /* FIXME: what's the point of strdupx? Why not use
+               * history argument directly? */
+	      histstring = strdupx(history);
+	      cdfDefHistory(streamptr, length, histstring);
+	      free(histstring);
+	    }
 	}
     }
-
-  *gz += 2*datasize;
-  
-  return;
+#else
+  (void)streamID; (void)length; (void)history;
+#endif
 }
 
-#endif // SIMD variants
 
+int streamInqHistorySize(int streamID)
+{
+  int size = 0;
+#ifdef HAVE_LIBNETCDF
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-#ifdef TEST_ENCODE
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
+    {
+      size = cdfInqHistorySize(streamptr);
+    }
+#else
+  (void)streamID;
+#endif
+  return (size);
+}
 
-#define CAT(X,Y)      X##_##Y
-#define TEMPLATE(X,Y) CAT(X,Y)
 
-#ifdef T
-#undef T
-#endif
-#define T double
+void streamInqHistoryString(int streamID, char *history)
+{
+#ifdef HAVE_LIBNETCDF
+  stream_t *streamptr = stream_to_pointer(streamID);
 
-#ifdef T
-#undef T
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
+    {
+      cdfInqHistoryString(streamptr, history);
+    }
+#else
+  (void)streamID; (void)history;
+#endif
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
 #endif
-#define T float
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
 
-#include <sys/time.h>
 
-static
-double dtime()
-{
-  double tseconds = 0.0;
-  struct timeval mytime;
-  gettimeofday(&mytime, NULL);
-  tseconds = (double) (mytime.tv_sec + (double)mytime.tv_usec*1.0e-6);
-  return (tseconds);
-}
 
-#define NRUN 10000
 
-static
-void pout(char *name, int s, unsigned char *lgrib, long datasize, double tt)
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+#define SINGLE_PRECISION  4
+#define DOUBLE_PRECISION  8
+
+#if defined (HAVE_LIBIEG)
+
+
+typedef struct {
+  int param;
+  int level;
+} IEGCOMPVAR;
+
+
+int iegInqDatatype(int prec)
 {
-  printf("%8s: val1: %d  val2: %d  val3: %d  valn: %d  time: %gs\n", name, (int) lgrib[s*1+1], (int) lgrib[s*2+1], (int) lgrib[s*3+1], (int) lgrib[2*datasize-1], tt);
+  int datatype;
+
+  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+  else                            datatype = DATATYPE_FLT32;
+
+  return (datatype);
 }
 
-int main(void)
+
+int iegDefDatatype(int datatype)
 {
-  long datasize = 1000000;
-  float *dataf = NULL;
-  double *data = NULL;
-  double t_begin, t_end;
-  unsigned char *lgrib;
+  int prec;
 
-  dataf = (float*) malloc(datasize*sizeof(float));
-  data  = (double*) malloc(datasize*sizeof(double));
-  lgrib = (unsigned char*) malloc(2*datasize*sizeof(unsigned char));
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    Error("CDI/IEG library does not support complex numbers!");
 
-  for ( long i = 0; i < datasize; ++i ) dataf[i] = (float) (-datasize/2 + i);
-  for ( long i = 0; i < datasize; ++i ) data[i] = (double) (-datasize/2 + i);
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
+    datatype = DATATYPE_FLT32;
 
-  int PackStart = 0;
-  int nbpv = 16;
-  double zref = data[0];
-  size_t z;
-  double factor = 0.00390625;
-  int s = 256;
+  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
+  else                              prec = SINGLE_PRECISION;
 
-  if ( 0 )
-    {
-      encode_array_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
-      encode_array_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
-    }
+  return (prec);
+}
 
+/* not used
+int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
+{
+  int status;
+  int fileID;
+  int icode, ilevel;
+  int zaxisID = -1;
+  int vlistID;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-#if   defined(__ICC)
-  printf("icc\n");
-#elif defined(__clang__)
-  printf("clang\n");
-#elif defined(__GNUC__)
-  printf("gcc\n");
-#endif
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  printf("float:\n");
+  *varID   = -1;
+  *levelID = -1;
 
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      encode_array_2byte_float(datasize, lgrib, dataf, (float)zref, (float)factor, &z);
-    }
-  t_end = dtime();
-  pout("orig", s, lgrib, datasize, t_end-t_begin);
+  status = iegRead(fileID, iegp);
+  if ( status != 0 ) return (0);
 
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      encode_array_unrolled_float(nbpv, PackStart, datasize, lgrib, dataf, (float)zref, (float)factor, &z);
-    }
-  t_end = dtime();
-  pout("unrolled", s, lgrib, datasize, t_end-t_begin);
+  icode  = IEG_P_Parameter(iegp->ipdb);
+  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
+    ilevel = IEG_P_Level1(iegp->ipdb);
+  else
+    ilevel = IEG_P_Level2(iegp->ipdb);
 
-  printf("double:\n");
+  *varID = vlistInqVarID(vlistID, icode);
 
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
-    }
-  t_end = dtime();
-  pout("orig", s, lgrib, datasize, t_end-t_begin);
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
 
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      encode_array_unrolled_double(nbpv, PackStart, datasize, lgrib, data, zref, factor, &z);
-    }
-  t_end = dtime();
-  pout("unrolled", s, lgrib, datasize, t_end-t_begin);
+  zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
-#if defined _ENABLE_AVX
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      avx_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
-    }
-  t_end = dtime();
-  pout("avx", s, lgrib, datasize, t_end-t_begin);
-#elif defined _ENABLE_SSE4_1
-  t_begin = dtime();
-  for ( int i = 0; i < NRUN; ++i )
-    {
-      z = 0;
-      sse41_encode_array_2byte_double(datasize, lgrib, data, zref, factor, &z);
-    }
-  t_end = dtime();
-  pout("sse41", s, lgrib, datasize, t_end-t_begin);
-#endif
+  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
 
-  return 0;
+  return (1);
 }
-#endif // TEST_ENCODE
-
-#undef DISABLE_SIMD
-#undef _ENABLE_AVX
-#undef _ENABLE_SSE4_1
-//#undef _GET_X86_COUNTER
-//#undef _GET_MACH_COUNTER
-//#undef _GET_IBM_COUNTER
-//#undef _ARCH_PWR6
+*/
 
-#if defined _GET_IBM_COUNTER
-#include <libhpc.h>
-#elif defined _GET_X86_COUNTER
-#include <x86intrin.h>
-#elif defined _GET_MACH_COUNTER
-#include <mach/mach_time.h>
-#endif
+void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int status;
+  int recID, vrecID, tsID;
+  off_t recpos;
+  int varID, gridID;
+  int i, size;
+  double missval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+  tsID    = streamptr->curTsID;
+  vrecID  = streamptr->tsteps[tsID].curRecID;
+  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+  recpos  = streamptr->tsteps[tsID].records[recID].position;
+  varID   = streamptr->tsteps[tsID].records[recID].varID;
 
-#if   defined(__GNUC__) && (__GNUC__ >= 4)
-#elif defined(__ICC)    && (__ICC >= 1100)
-#elif defined(__clang__)
-#else
-#define DISABLE_SIMD
-#endif
+  fileSetPos(fileID, recpos, SEEK_SET);
 
-#define DISABLE_SIMD
+  status = iegRead(fileID, iegp);
+  if ( status != 0 )
+    Error("Could not read IEG record!");
 
-#ifdef DISABLE_SIMD
-# ifdef ENABLE_AVX
-#  define _ENABLE_AVX
-# endif
-# ifdef ENABLE_SSE4_1
-#  define _ENABLE_SSE4_1
-# endif
-#endif
+  iegInqDataDP(iegp, data);
 
-#ifndef DISABLE_SIMD
-# ifdef __AVX__
-#  define _ENABLE_AVX
-# endif
-# ifdef __SSE4_1__
-#  define _ENABLE_SSE4_1
-# endif
-#endif
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
 
-#if defined _ENABLE_AVX
-#include <immintrin.h>
-#elif defined _ENABLE_SSE4_1
-#include <smmintrin.h>
-#endif
+  streamptr->numvals += size;
 
-#if defined _ENABLE_AVX
+  *nmiss = 0;
+  for ( i = 0; i < size; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
+}
 
 static
-void avx_decode_array_2byte_double(size_t datasize, const unsigned char * restrict igrib,
-				     double * restrict fpdata, double fmin, double zscale)
+int iegGetZaxisType(int iegleveltype)
 {
-  size_t i, j;
-  size_t nframes = datasize;
-  size_t residual;
-  size_t ofs;
+  int leveltype = 0;
 
-  double dval;
+  switch ( iegleveltype )
+    {
+    case IEG_LTYPE_SURFACE:
+      {
+	leveltype = ZAXIS_SURFACE;
+	break;
+      }
+    case IEG_LTYPE_99:
+    case IEG_LTYPE_ISOBARIC:
+      {
+	leveltype = ZAXIS_PRESSURE;
+	break;
+      }
+    case IEG_LTYPE_HEIGHT:
+      {
+	leveltype = ZAXIS_HEIGHT;
+	break;
+      }
+    case IEG_LTYPE_ALTITUDE:
+      {
+	leveltype = ZAXIS_ALTITUDE;
+	break;
+      }
+    case IEG_LTYPE_HYBRID:
+    case IEG_LTYPE_HYBRID_LAYER:
+      {
+	leveltype = ZAXIS_HYBRID;
+	break;
+      }
+    case IEG_LTYPE_LANDDEPTH:
+    case IEG_LTYPE_LANDDEPTH_LAYER:
+      {
+	leveltype = ZAXIS_DEPTH_BELOW_LAND;
+	break;
+      }
+    case IEG_LTYPE_SEADEPTH:
+      {
+	leveltype = ZAXIS_DEPTH_BELOW_SEA;
+	break;
+      }
+    default:
+      {
+	leveltype = ZAXIS_GENERIC;
+	break;
+      }
+    }
 
-  double *data = fpdata;
-  __m128i *sgrib;
-  
-  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  return (leveltype);
+}
 
-  __m256d ymm0 = _mm256_set1_pd(fmin);
-  __m256d ymm1 = _mm256_set1_pd(zscale);
-  
-  __m128i xmm0, xmm1, xmm2, xmm3;
-  __m256d ymm2, ymm3;
 
-  i = -1;
-  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+void iegDefTime(int *pdb, int date, int time, int taxisID)
+{
+  int year, month, day, hour, minute, second;
+  int timetype = -1;
+
+  if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
+
+  if ( timetype == TAXIS_ABSOLUTE || timetype == TAXIS_RELATIVE )
     {
-      i++;
-      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
-      fpdata[i] = fmin + zscale * dval;
-      data++;
-      nframes--;
-    }
-  
-  if (i == -1) i = 0;
-  sgrib = (__m128i *) (igrib+i);
+      cdiDecodeDate(date, &year, &month, &day);
+      cdiDecodeTime(time, &hour, &minute, &second);
 
-  while (nframes >= 16)
-    { 
-      xmm0 = _mm_loadu_si128((__m128i *) sgrib);
-      xmm0 = _mm_shuffle_epi8(xmm0, mask);
-      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
-      xmm2 = _mm_cvtepu16_epi32(xmm0);
-      xmm3 = _mm_cvtepu16_epi32(xmm1);
+      IEG_P_Year(pdb)     = year;
+      IEG_P_Month(pdb)    = month;
+      IEG_P_Day(pdb)      = day;
+      IEG_P_Hour(pdb)     = hour;
+      IEG_P_Minute(pdb)   = minute;
 
-      ymm2 = _mm256_cvtepi32_pd(xmm2);
-      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
-      (void) _mm256_stream_pd(data, ymm2);
-      ymm3 = _mm256_cvtepi32_pd(xmm3);
-      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
-      (void) _mm256_stream_pd(data+4, ymm3);  
-      
-      xmm0 = _mm_loadu_si128((__m128i *) sgrib + 1);
-      xmm0 = _mm_shuffle_epi8(xmm0, mask);
-      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
-      xmm2 = _mm_cvtepu16_epi32(xmm0);
-      xmm3 = _mm_cvtepu16_epi32(xmm1);
-      
-      ymm2 = _mm256_cvtepi32_pd(xmm2);
-      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
-      (void) _mm256_stream_pd(data+8, ymm2);
-      ymm3 = _mm256_cvtepi32_pd(xmm3);
-      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
-      (void) _mm256_stream_pd(data+12, ymm3);  
-      
-      data += 16;
-      sgrib += 2;
-      nframes -= 16;
+      pdb[15] = 1;
+      pdb[16] = 0;
+      pdb[17] = 0;
+      pdb[18] = 10;
+      pdb[36] = 1;
     }
 
-  residual = nframes;
-  ofs = datasize - residual;
-  for ( j = 0; j < residual; j++ )
+  pdb[5] = 128;
+}
+
+static
+int calc_resfac(double xfirst, double xlast, double xinc, double yfirst, double ylast, double yinc)
+{
+  int i, j;
+  int iresfac = 1000;
+  int ifact;
+  int ifacarr[5] = {1000, 10000, 100000, 1000000, 10000000};
+  double vals[6] = {xfirst, xlast, xinc, yfirst, ylast, yinc};
+
+  for ( j = 0; j < 5; ++j )
     {
-      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
-      fpdata[ofs+j] = fmin + zscale * dval;
+      ifact = ifacarr[j];
+      for ( i = 0; i < 6; ++i )
+        {
+          if ( fabs(vals[i]*ifact - round(vals[i]*ifact)) > FLT_EPSILON ) break;
+        }
+      if ( i == 6 )
+        {
+          iresfac = ifact;
+          break;
+        }
     }
 
-  return;
+  return (iresfac);
 }
 
-#elif defined _ENABLE_SSE4_1
-
 static
-void sse41_decode_array_2byte_double(size_t datasize, const unsigned char * restrict igrib,
-				     double * restrict fpdata, double fmin, double zscale)
+void iegDefGrid(int *gdb, int gridID)
 {
-  size_t i, j;
-  size_t nframes = datasize;
-  size_t residual;
-  size_t ofs;
-
-  double dval;
+  int gridtype;
 
-  double *data = fpdata;
-  __m128i *sgrib;
-  
-  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
-  __m128d dmm8 = _mm_set1_pd(fmin);
-  __m128d dmm9 = _mm_set1_pd(zscale);
-  
-  __m128i xmm4, xmm5;
-  __m128i xmm6, xmm7;
-  
-  __m128d dmm0, dmm1, dmm2, dmm3;
-  __m128d dmm4, dmm5, dmm6, dmm7;
+  gridtype = gridInqType(gridID);
 
-  i = -1;
-  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
-    {
-      i++;
-      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
-      fpdata[i] = fmin + zscale * dval;
-      data++;
-      nframes--;
-    }
-  
-  if (i == -1) i = 0;
-  sgrib = (__m128i *) (igrib+i);
-  
-  while (nframes >= 16)
+  if ( gridtype == GRID_GENERIC )
     {
-      xmm5 = _mm_loadu_si128((__m128i *) sgrib);
-      xmm5 = _mm_shuffle_epi8(xmm5, mask);
-      xmm4 = _mm_srli_si128(xmm5, 8);
-      xmm6 = _mm_cvtepu16_epi32(xmm5);
-      dmm0 = _mm_cvtepi32_pd(xmm6);
-      dmm0 = _mm_add_pd(_mm_mul_pd(dmm0, dmm9), dmm8);
-      (void) _mm_stream_pd(data, dmm0);
-      xmm7 = _mm_srli_si128(xmm6, 8);
-      dmm1 = _mm_cvtepi32_pd(xmm7);
-      dmm1 = _mm_add_pd(_mm_mul_pd(dmm1, dmm9), dmm8);
-      (void) _mm_stream_pd(data+2, dmm1);
-      xmm6 = _mm_cvtepu16_epi32(xmm4);
-      dmm2 = _mm_cvtepi32_pd(xmm6);
-      dmm2 = _mm_add_pd(_mm_mul_pd(dmm2, dmm9), dmm8);
-      (void) _mm_stream_pd(data+4, dmm2);
-      xmm7 = _mm_srli_si128(xmm6, 8);
-      dmm3 = _mm_cvtepi32_pd(xmm7);
-      dmm3 = _mm_add_pd(_mm_mul_pd(dmm3, dmm9), dmm8);
-      (void) _mm_stream_pd(data+6, dmm3);
-      
-      xmm5 = _mm_loadu_si128((__m128i *) sgrib+1);
-      xmm5 = _mm_shuffle_epi8(xmm5, mask);
-      xmm4 = _mm_srli_si128(xmm5, 8);
-      xmm6 = _mm_cvtepu16_epi32(xmm5);
-      dmm4 = _mm_cvtepi32_pd(xmm6);
-      dmm4 = _mm_add_pd(_mm_mul_pd(dmm4, dmm9), dmm8);
-      (void) _mm_stream_pd(data+8, dmm4);
-      xmm7 = _mm_srli_si128(xmm6, 8);
-      dmm5 = _mm_cvtepi32_pd(xmm7);
-      dmm5 = _mm_add_pd(_mm_mul_pd(dmm5, dmm9), dmm8);
-      (void) _mm_stream_pd(data+10, dmm5);
-      xmm6 = _mm_cvtepu16_epi32(xmm4);
-      dmm6 = _mm_cvtepi32_pd(xmm6);
-      dmm6 = _mm_add_pd(_mm_mul_pd(dmm6, dmm9), dmm8);
-      (void) _mm_stream_pd(data+12, dmm6);
-      xmm7 = _mm_srli_si128(xmm6, 8);
-      dmm7 = _mm_cvtepi32_pd(xmm7);
-      dmm7 = _mm_add_pd(_mm_mul_pd(dmm7, dmm9), dmm8);
-      (void) _mm_stream_pd(data+14, dmm7);
+      int xsize, ysize;
 
-      data += 16;
-      sgrib += 2;
-      nframes -= 16;
-    }
+      xsize = gridInqXsize(gridID);
+      ysize = gridInqYsize(gridID);
 
-  residual = nframes;
-  ofs = datasize - residual;
-  for ( j = 0; j < residual; j++ )
+      if ( (ysize == 32  || ysize == 48 || ysize == 64 ||
+	    ysize == 96  || ysize == 160) &&
+	   (xsize == 2*ysize || xsize == 1) )
+	{
+	  gridtype = GRID_GAUSSIAN;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( (xsize == 1 && ysize == 1) || (xsize == 0 && ysize == 0) )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+      else if ( gridInqXvals(gridID, NULL) && gridInqYvals(gridID, NULL) )
+	{
+	  gridtype = GRID_LONLAT;
+	  gridChangeType(gridID, gridtype);
+	}
+    }
+  else if ( gridtype == GRID_CURVILINEAR )
     {
-      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
-      fpdata[ofs+j] = fmin + zscale * dval;
+      gridtype = GRID_LONLAT;
     }
 
-  return;
-}
-
-#endif
+  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
+    {
+      double xfirst = 0, xlast = 0, xinc = 0;
+      double yfirst = 0, ylast = 0, yinc = 0;
 
-#undef DISABLE_SIMD
-#undef _ENABLE_AVX
-#undef _ENABLE_SSE4_1
+      int nlon = gridInqXsize(gridID),
+        nlat = gridInqYsize(gridID);
 
+      if ( nlon == 0 )
+	{
+	  nlon = 1;
+	}
+      else
+	{
+	  xfirst = gridInqXval(gridID,      0);
+	  xlast  = gridInqXval(gridID, nlon-1);
+	  xinc   = gridInqXinc(gridID);
+	}
 
-void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
-{
-  /*
+      if ( nlat == 0 )
+	{
+	  nlat = 1;
+	}
+      else
+	{
+	  yfirst = gridInqYval(gridID,      0);
+	  ylast  = gridInqYval(gridID, nlat-1);
+	  yinc   = gridInqYinc(gridID);
+	}
 
-    Purpose:
-    --------
+      if ( gridtype == GRID_GAUSSIAN )
+	IEG_G_GridType(gdb) = 4;
+      else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
+	IEG_G_GridType(gdb) = 10;
+      else
+	IEG_G_GridType(gdb) = 0;
 
-    Convert floating point number from machine
-    representation to GRIB representation.
+      int iresfac = calc_resfac(xfirst, xlast, xinc, yfirst, ylast, yinc);
+      double resfac = (double) iresfac;
+      if ( iresfac == 1000 ) iresfac = 0;
 
-    Input Parameters:
-    -----------------
+      IEG_G_ResFac(gdb)   = iresfac;
 
-       pval    - Floating point number to be converted.
-       kbits   - Number of bits in computer word.
-       kround  - Conversion type.
-                 0 , Closest number in GRIB format less than
-                     original number.
-                 1 , Closest number in GRIB format to the
-                     original number (equal to, greater than or
-                     less than original number).
+      IEG_G_NumLon(gdb)   = nlon;
+      IEG_G_NumLat(gdb)   = nlat;
+      IEG_G_FirstLat(gdb) = (int)lround(yfirst*resfac);
+      IEG_G_LastLat(gdb)  = (int)lround(ylast*resfac);
+      IEG_G_FirstLon(gdb) = (int)lround(xfirst*resfac);
+      IEG_G_LastLon(gdb)  = (int)lround(xlast*resfac);
+      IEG_G_LonIncr(gdb)  = (int)lround(xinc*resfac);
+      if ( fabs(xinc*resfac - IEG_G_LonIncr(gdb)) > FLT_EPSILON )
+	IEG_G_LonIncr(gdb) = 0;
 
-    Output Parameters:
-    ------------------
+      if ( gridtype == GRID_GAUSSIAN )
+	IEG_G_LatIncr(gdb) = nlat/2;
+      else
+	{
+	  IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
+	  if ( fabs(yinc*resfac - IEG_G_LatIncr(gdb)) > FLT_EPSILON )
+	    IEG_G_LatIncr(gdb) = 0;
 
-       kexp    - 8 Bit signed exponent.
-       kmant   - 24 Bit mantissa.
+	  if ( IEG_G_LatIncr(gdb) < 0 ) IEG_G_LatIncr(gdb) = -IEG_G_LatIncr(gdb);
+	}
 
-    Method:
-    -------
+      if ( IEG_G_NumLon(gdb) > 1 && IEG_G_NumLat(gdb) == 1 )
+	if ( IEG_G_LonIncr(gdb) != 0 && IEG_G_LatIncr(gdb) == 0 ) IEG_G_LatIncr(gdb) = IEG_G_LonIncr(gdb);
 
-    Floating point number represented as 8 bit signed
-    exponent and 24 bit mantissa in integer values.
+      if ( IEG_G_NumLon(gdb) == 1 && IEG_G_NumLat(gdb) > 1 )
+	if ( IEG_G_LonIncr(gdb) == 0 && IEG_G_LatIncr(gdb) != 0 ) IEG_G_LonIncr(gdb) = IEG_G_LatIncr(gdb);
 
-    Externals.
-    ----------
+      if ( IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0 )
+	IEG_G_ResFlag(gdb) = 0;
+      else
+	IEG_G_ResFlag(gdb) = 128;
 
-    decfp2    - Decode from IBM floating point format.
+      if ( gridIsRotated(gridID) )
+	{
+	  IEG_G_LatSP(gdb) = - (int)lround(gridInqYpole(gridID) * resfac);
+	  IEG_G_LonSP(gdb) =   (int)lround((gridInqXpole(gridID) + 180) * resfac);
+	  IEG_G_Size(gdb)  = 42;
+	}
+      else
+	{
+	  IEG_G_Size(gdb)  = 32;
+	}
+    }
+  else
+    {
+      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+    }
 
-    Reference:
-    ----------
+  IEG_G_ScanFlag(gdb) = 64;
+}
 
-    WMO Manual on Codes re GRIB representation.
+static
+void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
+{
+  double level;
+  int ilevel, leveltype;
+  static int warning = 1;
+  static int vct_warning = 1;
 
-    Comments:
-    ---------
+  leveltype = zaxisInqType(zaxisID);
 
-    Routine aborts if an invalid conversion type parameter
-    is used or if a 24 bit mantissa is not produced.
+  if ( leveltype == ZAXIS_GENERIC )
+    {
+      Message("Changed zaxis type from %s to %s",
+	      zaxisNamePtr(leveltype),
+	      zaxisNamePtr(ZAXIS_PRESSURE));
+      leveltype = ZAXIS_PRESSURE;
+      zaxisChangeType(zaxisID, leveltype);
+      zaxisDefUnits(zaxisID, "Pa");
+    }
 
-    Author:
-    -------
-     
-    John Hennessy   ECMWF   18.06.91
+  /*  IEG_G_NumVCP(gdb) = 0; */
 
-    Modifications:
-    --------------
+  switch (leveltype)
+    {
+    case ZAXIS_SURFACE:
+      {
+	IEG_P_LevelType(pdb) = IEG_LTYPE_SURFACE;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
+	break;
+      }
+    case ZAXIS_HYBRID:
+      {
+	int vctsize;
 
-    Uwe Schulzweida   MPIfM   01/04/2001
+	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID_LAYER;
+	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
+	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
+	  }
+	else
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = (int) zaxisInqLevel(zaxisID, levelID);
+	  }
 
-    Convert to C from EMOS library version 130
+	vctsize = zaxisInqVctSize(zaxisID);
+	if ( vctsize == 0 && warning )
+	  {
+	    Warning("VCT missing. ( code = %d, zaxisID = %d )",
+		    IEG_P_Parameter(pdb), zaxisID);
+	    warning = 0;
+	  }
+	if ( vctsize > 100 )
+	  {
+	    /*	    IEG_G_NumVCP(gdb) = 0; */
+	    if ( vct_warning )
+	      {
+		Warning("VCT size of %d is too large (maximum is 100). Set to 0!", vctsize);
+		vct_warning = 0;
+	      }
+	  }
+	else
+	  {
+	    IEG_G_Size(gdb) += (vctsize*4);
+	    memcpy(vct, zaxisInqVctPtr(zaxisID), (size_t)vctsize/2*sizeof(double));
+	    memcpy(vct+50, zaxisInqVctPtr(zaxisID)+vctsize/2, (size_t)vctsize/2*sizeof(double));
+	  }
+	break;
+      }
+    case ZAXIS_PRESSURE:
+      {
+	double dum;
+	char units[128];
 
-    Uwe Schulzweida   MPIfM   02/08/2002
+	level = zaxisInqLevel(zaxisID, levelID);
+	if ( level < 0 )
+	  Warning("pressure level of %f Pa is below 0.", level);
 
-     - speed up by factor 1.6 on NEC SX6
-        - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
-  */
+	zaxisInqUnits(zaxisID, units);
+	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
+	  level = level*100;
 
-  double rpowref;
-  double zref, zeps;
-  int iexp, isign;
-  int iround;
-  // extern int CGRIBEX_Debug;
-  extern const double _pow16tab[71];
+	ilevel = (int) level;
+	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_99;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = ilevel;
+	  }
+	else
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_ISOBARIC;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = ilevel/100;
+	  }
+	break;
+      }
+    case ZAXIS_HEIGHT:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 1 . Initialise                                          */
-  /* ----------------------------------------------------------------- */
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_HEIGHT;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
 
-  /*  Check conversion type parameter. */
+	break;
+      }
+    case ZAXIS_ALTITUDE:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-  iround = kround;
-  if ( iround != 0 && iround != 1 )
-    {
-      Error("Invalid conversion type = %d", iround);
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_ALTITUDE;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
 
-      /*  If not aborting, arbitrarily set rounding to 'up'. */
-     iround = 1;
-    }
+	break;
+      }
+    case ZAXIS_DEPTH_BELOW_LAND:
+      {
+	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH_LAYER;
+	    IEG_P_Level1(pdb)    = (int) zaxisInqLbound(zaxisID, levelID);
+	    IEG_P_Level2(pdb)    = (int) zaxisInqUbound(zaxisID, levelID);
+	  }
+	else
+	  {
+	    level = zaxisInqLevel(zaxisID, levelID);
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 2 . Convert value of zero.                              */
-  /* ----------------------------------------------------------------- */
+	    ilevel = (int) level;
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = ilevel;
+	  }
 
-  if ( ! (fabs(pval) > 0))
-    {
-      *kexp  = 0;
-      *kmant = 0;
-      iexp   = 0;
-      isign  = 0;
-      goto LABEL900;
-    }
+	break;
+      }
+    case ZAXIS_DEPTH_BELOW_SEA:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 3 . Convert other values.                               */
-  /* ----------------------------------------------------------------- */
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_SEADEPTH;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
 
-  zeps = 1.0e-12;
-  if ( kbits == 32 ) zeps = 1.0e-8;
-  zref = pval;
+	break;
+      }
+    case ZAXIS_ISENTROPIC:
+      {
+	level = zaxisInqLevel(zaxisID, levelID);
 
-  /*  Sign of value. */
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = 113;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
 
-  isign = 0;
-  if ( zref < 0.0 )
-    {
-      isign = 128;
-      zref  = - zref;
+	break;
+      }
+    default:
+      {
+	Error("Unsupported zaxis type: %s", zaxisNamePtr(leveltype));
+	break;
+      }
     }
+}
 
-  /*  Exponent. */
-
-  iexp = (int) (log(zref)/log(16.0) + 65.0 + zeps);
 
-  /* only ANSI C99 has log2 */
-  /* iexp = (int) (log2(zref) * 0.25 + 65.0 + zeps); */
+void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+{
+  streamFCopyRecord(streamptr2, streamptr1, "IEG");
+}
 
-  if ( iexp < 0   ) iexp = 0;
-  if ( iexp > 127 ) iexp = 127;
 
-  /*
-  rpowref = zref / pow(16.0, (double)(iexp - 70));
-  */
+void iegDefRecord(stream_t *streamptr)
+{
+  int vlistID;
+  int gridID;
+  int date, time;
+  int datatype;
+  int i;
+  int param, pdis, pcat, pnum;
+  int varID, levelID, tsID, zaxisID;
+  int byteorder;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-  if ( (iexp - 70) < 0 )
-    rpowref = zref * _pow16tab[-(iexp - 70)];
-  else
-    rpowref = zref / _pow16tab[(iexp - 70)];
+  vlistID = streamptr->vlistID;
+  byteorder = streamptr->byteorder;
 
-  /*  Mantissa. */
+  varID   = streamptr->record->varID;
+  levelID = streamptr->record->levelID;
+  tsID    = streamptr->curTsID;
 
-  if ( iround == 0 )
-    {
-      /*  Closest number in GRIB format less than original number. */
-      /*  Truncate for positive numbers. */
-      /*  Round up for negative numbers. */
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  zaxisID = vlistInqVarZaxis(vlistID, varID);
 
-      if ( isign == 0 )
-	*kmant = (int)rpowref;
-      else
-	*kmant = (int)lround(rpowref + 0.5);
-    }
-  else
-    {
-      /*  Closest number in GRIB format to the original number   */
-      /*  (equal to, greater than or less than original number). */
+  iegInitMem(iegp);
+  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
-      *kmant = (int)lround(rpowref);
-    }
+  iegp->byteswap = getByteswap(byteorder);
 
-  /*  Check that mantissa value does not exceed 24 bits. */
-  /*  If it does, adjust the exponent upwards and recalculate */
-  /*  the mantissa. */
-  /*  16777215 = 2**24 - 1 */
+  param =  vlistInqVarParam(vlistID, varID);
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  IEG_P_Parameter(iegp->ipdb) = pnum;
+  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
+  date     = streamptr->tsteps[tsID].taxis.vdate;
+  time     = streamptr->tsteps[tsID].taxis.vtime;
 
-  if ( *kmant > 16777215 )
-    {
+  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
+  iegDefGrid(iegp->igdb, gridID);
+  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);
 
-    LABEL350:
+  datatype = streamptr->record->prec;
 
-      ++iexp;
+  iegp->dprec = iegDefDatatype(datatype);
+}
 
-      /*  Check for exponent overflow during adjustment  */
 
-      if ( iexp > 127 )
-	{
-          Message("Exponent overflow");
-          Message("Original number = %30.20f", pval);
-          Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
-		  isign, iexp, *kmant);
+void iegWriteRecord(stream_t *streamptr, const double *data)
+{
+  int fileID;
+  int i, gridsize, gridID;
+  double refval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-	  Error("Exponent overflow");
+  fileID = streamptr->fileID;
+  gridID = streamptr->record->gridID;
 
-	  /*  If not aborting, arbitrarily set value to zero  */
+  gridsize = gridInqSize(gridID);
 
-          Message("Value arbitrarily set to zero.");
-          *kexp  = 0;
-          *kmant = 0;
-          iexp  = 0;
-          isign = 0;
-          goto LABEL900;
-	}
+  refval = data[0];
+  for ( i = 1; i < gridsize; i++ )
+    if ( data[i] < refval ) refval = data[i];
 
-      if ( (iexp - 70) < 0 )
-	rpowref = zref * _pow16tab[-(iexp - 70)];
-      else
-	rpowref = zref / _pow16tab[(iexp - 70)];
+  iegp->refval = refval;
 
-      if ( iround == 0 )
-	{
-	  /*  Closest number in GRIB format less than original number. */
-	  /*  Truncate for positive numbers. */
-	  /*  Round up for negative numbers. */
+  iegDefDataDP(iegp, data);
 
-	  if ( isign == 0 )
-	    *kmant = (int)rpowref;
-	  else
-	    *kmant = (int)lround(rpowref + 0.5);
-	}
-      else
-	{
-	  /*  Closest number in GRIB format to the original number */
-	  /*  (equal to, greater or less than original number). */
+  iegWrite(fileID, iegp);
+}
 
-	  *kmant = (int)lround(rpowref);
-	}
+static
+void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
+		  size_t recsize, off_t position, int prec)
+{
+  int leveltype;
+  int gridID = UNDEFID;
+  int levelID = 0;
+  int tsID, recID, varID;
+  int datatype;
+  int level1, level2;
+  int gridtype;
+  int lbounds = 0;
+  record_t *record;
+  grid_t grid;
+  int vlistID;
 
-      /*  Repeat calculation (with modified exponent) if still have */
-      /*  mantissa overflow. */
+  vlistID = streamptr->vlistID;
+  tsID    = streamptr->curTsID;
+  recID   = recordNewEntry(streamptr, tsID);
+  record  = &streamptr->tsteps[tsID].records[recID];
 
-      if ( *kmant > 16777215 ) goto LABEL350;
+  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER )
+    {
+      level1 = IEG_P_Level1(pdb);
+      level2 = IEG_P_Level2(pdb);
+    }
+  else
+    {
+      level1 = IEG_P_Level2(pdb);
+      level2 = 0;
+      if ( IEG_P_LevelType(pdb) == 100 ) level1 *= 100;
     }
 
-  /*  Add sign bit to exponent. */
+  record->size     = recsize;
+  record->position = position;
+  record->param    = param;
+  record->ilevel   = level1;
+  record->ilevel2  = level2;
+  record->ltype    = IEG_P_LevelType(pdb);
 
-  *kexp = iexp + isign;
+  if ( IEG_G_GridType(gdb) == 0 || IEG_G_GridType(gdb) == 10 )
+    gridtype = GRID_LONLAT;
+  else if ( IEG_G_GridType(gdb) == 4 )
+    gridtype = GRID_GAUSSIAN;
+  else
+    gridtype = GRID_GENERIC;
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 9. Return                                               */
-  /* ----------------------------------------------------------------- */
+  memset(&grid, 0, sizeof(grid_t));
+  grid.type  = gridtype;
+  grid.size  = IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb);
+  grid.xsize = IEG_G_NumLon(gdb);
+  grid.ysize = IEG_G_NumLat(gdb);
+  grid.xinc  = 0;
+  grid.yinc  = 0;
+  grid.xdef  = 0;
 
-LABEL900:
+  int iresfac = IEG_G_ResFac(gdb);
+  if ( iresfac == 0 ) iresfac = 1000;
+  double resfac = 1./(double) iresfac;
+
+  /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
+  {
+    if ( grid.xsize > 1 )
+      {
+	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
+	  grid.xinc = IEG_G_LonIncr(gdb) * resfac;
+	else
+	  grid.xinc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (grid.xsize - 1);
+
+	/* correct xinc if necessary */
+	if ( IEG_G_FirstLon(gdb) == 0 && IEG_G_LastLon(gdb) > 354000 )
+	  {
+	    double xinc = 360. / grid.xsize;
+            /* FIXME: why not use grid.xinc != xinc as condition? */
+	    if ( fabs(grid.xinc-xinc) > 0.0 )
+	      {
+		grid.xinc = xinc;
+		if ( CDI_Debug ) Message("set xinc to %g", grid.xinc);
+	      }
+	  }
+      }
+    grid.xfirst = IEG_G_FirstLon(gdb) * resfac;
+    grid.xlast  = IEG_G_LastLon(gdb)  * resfac;
+    grid.xdef   = 2;
+  }
+  grid.ydef  = 0;
+  /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
+  {
+    if ( grid.ysize > 1 )
+      {
+	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
+	  grid.yinc = IEG_G_LatIncr(gdb) * resfac;
+	else
+	  grid.yinc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (grid.ysize - 1);
+      }
+    grid.yfirst = IEG_G_FirstLat(gdb) * resfac;
+    grid.ylast  = IEG_G_LastLat(gdb)  * resfac;
+    grid.ydef   = 2;
+  }
   /*
-  if ( CGRIBEX_Debug )
+  grid.xfirst= IEG_G_FirstLon(gdb) * resfac;
+  grid.xlast = IEG_G_LastLon(gdb) * resfac;
+  grid.xinc  = IEG_G_LonIncr(gdb) * resfac;
+  grid.xdef  = 2;
+  grid.yfirst= IEG_G_FirstLat(gdb) * resfac;
+  grid.ylast = IEG_G_LastLat(gdb) * resfac;
+  grid.yinc  = IEG_G_LatIncr(gdb) * resfac;
+  grid.ydef  = 2;
+  */
+  grid.xvals = NULL;
+  grid.yvals = NULL;
+
+  grid.isRotated = FALSE;
+  if ( IEG_G_GridType(gdb) == 10 )
     {
-      double zval;
+      grid.isRotated = TRUE;
+      grid.ypole     = - IEG_G_LatSP(gdb) * resfac;
+      grid.xpole     =   IEG_G_LonSP(gdb) * resfac - 180;
+      grid.angle     = 0;
+    }
 
-      Message("Conversion type parameter = %4d", kround);
-      Message("Original number = %30.20f", pval);
+  gridID = varDefGrid(vlistID, &grid, 0);
 
-      zval = decfp2(*kexp, *kmant);
+  leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
 
-      Message("Converted to      %30.20f", zval);
-      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
+  if ( leveltype == ZAXIS_HYBRID )
+    {
+      double tmpvct[100];
+      size_t vctsize = (size_t)IEG_G_NumVCP(gdb);
+
+      for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i] = vct[i];
+      for (size_t i = 0; i < vctsize/2; i++ ) tmpvct[i+vctsize/2] = vct[i+50];
+
+      varDefVCT(vctsize, tmpvct);
     }
-  */
-  return;
-} /* confp3 */
 
+  if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER ) lbounds = 1;
 
-double decfp2(int kexp, int kmant)
-{
-  /*
+  datatype = iegInqDatatype(prec);
 
-    Purpose:
-    --------
+  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
+	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
 
-    Convert GRIB representation of a floating point
-    number to machine representation.
+  record->varID   = (short)varID;
+  record->levelID = (short)levelID;
 
-    Input Parameters:
-    -----------------
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
 
-    kexp    - 8 Bit signed exponent.
-    kmant   - 24 Bit mantissa.
+  if ( CDI_Debug )
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
+}
 
-    Output Parameters:
-    ------------------
+#if 0
+static
+void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
+		  int level, int xsize, int ysize)
+{
+  int varID = 0;
+  int levelID = 0;
+  record_t *record;
 
-    Return value   - Floating point number represented
-                     by kexp and kmant.
+  record  = &streamptr->tsteps[tsID].records[recID];
 
-    Method:
-    -------
+  if ( param != (*record).param || level != (*record).ilevel )
+    Error("inconsistent timestep");
 
-    Floating point number represented as 8 bit exponent
-    and 24 bit mantissa in integer values converted to
-    machine floating point format.
+  (*record).position = position;
+  /*
+  varID   = (*record).varID;
+  levelID = (*record).levelID;
 
-    Externals:
-    ----------
+  streamptr->vars[varID].level[levelID] = recID;
 
-    None.
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
+  */
+  if ( CDI_Debug )
+    Message("varID = %d levelID = %d", varID, levelID);
+}
+#endif
 
-    Reference:
-    ----------
+void iegDateTime(int *pdb, int *date, int *time)
+{
+  int ryear, rmonth, rday, rhour, rminute;
 
-    WMO Manual on Codes re GRIB representation.
+  ryear   = IEG_P_Year(pdb);
 
-    Comments:
-    ---------
+  rmonth  = IEG_P_Month(pdb);
+  rday    = IEG_P_Day(pdb);
 
-    Rewritten from DECFP, to conform to programming standards.
-    Sign bit on 0 value now ignored, if present.
-    If using 32 bit reals, check power of 16 is not so small as to
-    cause overflows (underflows!); this causes warning to be given
-    on Fujitsus.
+  rhour   = IEG_P_Hour(pdb);
+  rminute = IEG_P_Minute(pdb);
 
-    Author:
-    -------
+  if ( rminute == -1 ) rminute = 0;
 
-    John Hennessy   ECMWF   18.06.91
+  *date = cdiEncodeDate(ryear, rmonth, rday);
+  *time = cdiEncodeTime(rhour, rminute, 0);
+}
 
-    Modifications:
-    --------------
+static
+void iegScanTimestep1(stream_t *streamptr)
+{
+  int prec = 0;
+  int status;
+  int fileID;
+  int tabnum;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int tsID;
+  int varID;
+  size_t recsize;
+  off_t recpos;
+  int nrecords, nrecs, recID;
+  int taxisID = -1;
+  taxis_t *taxis;
+  int vlistID;
+  IEGCOMPVAR compVar, compVar0;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-    Uwe Schulzweida   MPIfM   01/04/2001
+  streamptr->curTsID = 0;
 
-     - Convert to C from EMOS library version 130
-     
-    Uwe Schulzweida   MPIfM   02/08/2002
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-     - speed up by factor 2 on NEC SX6
-        - replace pow(2.0, -24.0) by constant POW_2_M24
-        - replace pow(16.0, (double)(iexp - 64)) by pow16m64tab[iexp]
-  */
+  if ( tsID != 0 )
+    Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  double pval;
-  int iexp, isign;
-  //extern int CGRIBEX_Debug;
-  extern const double _pow16tab[71];
-  
-  /* ----------------------------------------------------------------- */
-  /*   Section 1 . Convert value of 0.0. Ignore sign bit.              */
-  /* ----------------------------------------------------------------- */
+  fileID = streamptr->fileID;
 
-  //if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
-  /*
-  if ( (kexp == 128 || kexp == 0) && kmant == 0 )
-  */
-  if ( (kexp == 128) || (kexp == 0) || (kexp == 255) )
+  nrecs = 0;
+  while ( TRUE )
     {
-      pval = 0.0;
-      goto LABEL900;
-    }
+      recpos = fileGetPos(fileID);
+      status = iegRead(fileID, iegp);
+      if ( status != 0 )
+	{
+	  streamptr->ntsteps = 1;
+	  break;
+	}
+      recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 2 . Convert other values.                               */
-  /* ----------------------------------------------------------------- */
+      prec   = iegp->dprec;
+      rcode  = IEG_P_Parameter(iegp->ipdb);
+      tabnum = IEG_P_CodeTable(iegp->ipdb);
+      param  = cdiEncodeParam(rcode, tabnum, 255);
 
-  /*  Sign of value. */
+      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
+	rlevel = IEG_P_Level1(iegp->ipdb);
+      else
+	rlevel = IEG_P_Level2(iegp->ipdb);
 
-  iexp  = kexp;
-  isign = 1;
+      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-  if ( iexp >= 128 )
-    {
-      iexp -= 128;
-      isign = -1;
-    }
+      iegDateTime(iegp->ipdb, &vdate, &vtime);
 
-  /*  Decode value. */
+      if ( nrecs == 0 )
+	{
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
+	}
+      else
+	{
+	  datetime.date = vdate;
+	  datetime.time = vtime;
+	  compVar.param = param;
+          compVar.level = rlevel;
+	  for ( recID = 0; recID < nrecs; recID++ )
+	    {
+	      compVar0.param = streamptr->tsteps[0].records[recID].param;
+	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
 
-  /* pval = isign * pow(2.0, -24.0) * kmant * pow(16.0, (double)(iexp - 64)); */
+	      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 ) break;
+	    }
+	  if ( recID < nrecs ) break;
+	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
+	    Warning("Inconsistent verification time for param %d level %d", param, rlevel);
+	}
 
-  iexp -= 64;
+      nrecs++;
 
-  if ( iexp < 0 )
-    pval = 1./_pow16tab[-iexp];
-  else
-    pval = _pow16tab[iexp];
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, param, rlevel, vdate, vtime);
 
-  pval *= isign * POW_2_M24 * kmant;
+      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
+    }
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 9. Return to calling routine.                           */
-  /* ----------------------------------------------------------------- */
+  streamptr->rtsteps = 1;
 
-LABEL900:
+  cdi_generate_vars(streamptr);
 
-  //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  taxis->type  = TAXIS_ABSOLUTE;
+  taxis->vdate = (int)datetime0.date;
+  taxis->vtime = (int)datetime0.time;
 
-  return (pval);
-} /* decfp2 */
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdarg.h>
+  vlistID = streamptr->vlistID;
+  vlistDefTaxis(vlistID, taxisID);
 
+  vlist_check_contents(vlistID);
 
+  nrecords = streamptr->tsteps[0].nallrecs;
+  if ( nrecords < streamptr->tsteps[0].recordSize )
+    {
+      streamptr->tsteps[0].recordSize = nrecords;
+      streamptr->tsteps[0].records =
+	(record_t *)xrealloc(streamptr->tsteps[0].records,
+                             (size_t)nrecords * sizeof (record_t));
+    }
 
-int gribRefDate(int *isec1)
-{
-  int date, ryear, rmonth, rday;
-  int century;
+  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
+  streamptr->tsteps[0].nrecs = nrecords;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[0].recIDs[recID] = recID;
 
-  century = ISEC1_Century;
-  if ( century < 0 ) century = -century;
-  century -= 1;
+  if ( streamptr->ntsteps == -1 )
+    {
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-  ryear   = ISEC1_Year;
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
+    }
 
-  /* if ( century != 0 ) */
+  if ( streamptr->ntsteps == 1 )
     {
-      if ( ryear == 100 )
-	{
-	  ryear = 0;
-	  century += 1;
-	}
-
-      if ( ryear != 255 )
+      if ( taxis->vdate == 0 && taxis->vtime == 0 )
 	{
-	  ryear = century*100 + ryear;
-	  if ( ISEC1_Century < 0 ) ryear = -ryear;
+	  streamptr->ntsteps = 0;
+	  for ( varID = 0; varID < streamptr->nvars; varID++ )
+	    {
+	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	    }
 	}
-      else
-	ryear = 1;
     }
-
-  rmonth  = ISEC1_Month;
-  rday    = ISEC1_Day;
-
-  date = cdiEncodeDate(ryear, rmonth, rday);
-
-  return (date) ;
 }
 
+static
+int iegScanTimestep2(stream_t *streamptr)
+{
+  int status;
+  int fileID;
+  int tabnum;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  int tsID;
+  int varID;
+  size_t recsize;
+  off_t recpos = 0;
+  int nrecords, nrecs, recID, rindex;
+  int nextstep;
+  taxis_t *taxis;
+  int vlistID;
+  IEGCOMPVAR compVar, compVar0;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-int gribRefTime(int *isec1)
-{
-  int time, rhour, rminute;
+  streamptr->curTsID = 1;
 
-  rhour   = ISEC1_Hour;
-  rminute = ISEC1_Minute;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  time = cdiEncodeTime(rhour, rminute, 0);
+  tsID = streamptr->rtsteps;
+  if ( tsID != 1 )
+    Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  return (time) ;
-}
+  taxis = &streamptr->tsteps[tsID].taxis;
 
+  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-int gribTimeIsFC(int *isec1)
-{
-  int isFC = FALSE;
-  int time_period;
+  cdi_create_records(streamptr, tsID);
 
-  if ( ISEC1_TimeRange == 10 )
-    time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
-  else
-    time_period = ISEC1_TimePeriod1;
+  nrecords = streamptr->tsteps[0].nallrecs;
+  streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof(int));
+  streamptr->tsteps[1].nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[1].recIDs[recID] = -1;
 
-  if ( time_period > 0 && ISEC1_Day > 0 )
+  for ( recID = 0; recID < nrecords; recID++ )
     {
-      if ( ISEC1_TimeRange == 0 || ISEC1_TimeRange == 10 ) isFC = TRUE;
+      varID = streamptr->tsteps[0].records[recID].varID;
+      streamptr->tsteps[tsID].records[recID].position =
+	streamptr->tsteps[0].records[recID].position;
+      streamptr->tsteps[tsID].records[recID].size     =
+	streamptr->tsteps[0].records[recID].size;
     }
 
-  return (isFC);
-}
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
+    {
+      recpos = fileGetPos(fileID);
+      status = iegRead(fileID, iegp);
+      if ( status != 0 )
+	{
+	  streamptr->ntsteps = 2;
+	  break;
+	}
+      recsize = (size_t)(fileGetPos(fileID) - recpos);
 
+      rcode  = IEG_P_Parameter(iegp->ipdb);
+      tabnum = IEG_P_CodeTable(iegp->ipdb);
+      param  = cdiEncodeParam(rcode, tabnum, 255);
 
-void gribDateTime(int *isec1, int *date, int *time)
-{
-  static int lprint = TRUE;
-  int ryear, rmonth, rday, rhour, rminute, second;
-  int julday, secofday;
-  int64_t addsec = 0;
-  int64_t time_period = 0;
-  int century;
-  extern int grib_calendar;
+      if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
+	rlevel = IEG_P_Level1(iegp->ipdb);
+      else
+	rlevel = IEG_P_Level2(iegp->ipdb);
 
-  century = ISEC1_Century;
-  if ( century < 0 ) century = -century;
-  century -= 1;
+      if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-  ryear   = ISEC1_Year;
+      iegDateTime(iegp->ipdb, &vdate, &vtime);
 
-  /* if ( century != 0 ) */
-    {
-      if ( ryear == 100 )
+      if ( rindex == 0 )
 	{
-	  ryear = 0;
-	  century += 1;
+	  taxis->type  = TAXIS_ABSOLUTE;
+	  taxis->vdate = vdate;
+	  taxis->vtime = vtime;
 	}
 
-      if ( ryear != 255 )
+      compVar.param = param;
+      compVar.level = rlevel;
+      nextstep = FALSE;
+      for ( recID = 0; recID < nrecords; recID++ )
 	{
-	  ryear = century*100 + ryear;
-	  if ( ISEC1_Century < 0 ) ryear = -ryear;
+	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+
+	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 )
+	    {
+	      if ( streamptr->tsteps[tsID].records[recID].used )
+		{
+		  nextstep = TRUE;
+		}
+	      else
+		{
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
+		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
+		}
+	      break;
+	    }
+	}
+      if ( recID == nrecords )
+	{
+	  char paramstr[32];
+	  cdiParamToString(param, paramstr, sizeof(paramstr));
+	  Warning("param %s level %d not defined at timestep 1", paramstr, rlevel);
+	  return (CDI_EUFSTRUCT);
 	}
-      else
-	ryear = 1;
-    }
 
-  rmonth  = ISEC1_Month;
-  rday    = ISEC1_Day;
+      if ( nextstep ) break;
 
-  rhour   = ISEC1_Hour;
-  rminute = ISEC1_Minute;
-  second  = 0;
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, param, rlevel, vdate, vtime);
 
-  /* printf("ref %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute); */
+      streamptr->tsteps[tsID].records[recID].size = recsize;
 
-  if ( ISEC1_TimeRange == 10 )
-    time_period = (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2;
-  else if ( ISEC1_TimeRange >=2 && ISEC1_TimeRange <= 5 )
-    time_period = ISEC1_TimePeriod2;
-  else if ( ISEC1_TimeRange == 0 )
-    time_period = ISEC1_TimePeriod1;
+      compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-  if ( time_period > 0 && rday > 0 )
-    {
-      encode_caldaysec(grib_calendar, ryear, rmonth, rday, rhour, rminute, second, &julday, &secofday);
+      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
+	{
+	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		  tsID, recID,
+		  streamptr->tsteps[tsID].records[recID].param, param,
+		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	  return (CDI_EUFSTRUCT);
+	}
 
-      addsec = 0;
-      switch ( ISEC1_TimeUnit )
+      streamptr->tsteps[1].records[recID].position = recpos;
+    }
+
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    {
+      if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	case ISEC1_TABLE4_MINUTE:    addsec =    60 * time_period; break;
-	case ISEC1_TABLE4_QUARTER:   addsec =   900 * time_period; break;
-	case ISEC1_TABLE4_30MINUTES: addsec =  1800 * time_period; break;
-	case ISEC1_TABLE4_HOUR:      addsec =  3600 * time_period; break;
-	case ISEC1_TABLE4_3HOURS:    addsec = 10800 * time_period; break;
-	case ISEC1_TABLE4_6HOURS:    addsec = 21600 * time_period; break;
-	case ISEC1_TABLE4_12HOURS:   addsec = 43200 * time_period; break;
-	case ISEC1_TABLE4_DAY:       addsec = 86400 * time_period; break;
-	default:
-	  if ( lprint )
-	    {
-	      gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
-	      lprint = FALSE;
-	    }
-	  break;
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
+          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	}
+      else
+	{
+	  nrecs++;
 	}
+    }
+  streamptr->tsteps[tsID].nrecs = nrecs;
 
-      julday_add_seconds(addsec, &julday, &secofday);
+  streamptr->rtsteps = 2;
 
-      decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &second);
+  if ( streamptr->ntsteps == -1 )
+    {
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
+
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
     }
-  /*
-  printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
-  */
-  *date = cdiEncodeDate(ryear, rmonth, rday);
-  *time = cdiEncodeTime(rhour, rminute, 0);
 
-  return;
+  return (0);
 }
 
 
-void gprintf(const char *caller, const char *fmt, ...)
+int iegInqContents(stream_t *streamptr)
 {
-  va_list args;
+  int fileID;
+  int status = 0;
 
-  if ( grprsm == NULL ) Error("GRIBEX initialization missing!");
-	
-  va_start(args, fmt);
+  fileID = streamptr->fileID;
 
-   fprintf(grprsm, "%-18s : ", caller);
-  vfprintf(grprsm, fmt, args);
-   fprintf(grprsm, "\n");
+  streamptr->curTsID = 0;
 
-  va_end(args);
-}
+  iegScanTimestep1(streamptr);
 
+  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
 
-void
-gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
-	 double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
-	 int kleng, int *kword, char *hoper, int *kret)
-{
-  int yfunc = *hoper;
+  fileSetPos(fileID, 0, SEEK_SET);
 
-  if ( yfunc == 'C' )
-    {
-      grib_encode_double(isec0, isec1, isec2, fsec2, isec3,
-			 fsec3, isec4, fsec4, klenp, kgrib,
-			 kleng, kword, yfunc, kret);
-    }
-  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
-    {
-      grib_decode_double(isec0, isec1, isec2, fsec2, isec3,
-			 fsec3, isec4, fsec4, klenp, kgrib,
-			 kleng, kword, yfunc, kret);
-    }
-  else if ( yfunc == 'V' )
-    {
-      fprintf(stderr, "  cgribex: Version is %s\n", cgribexLibraryVersion());
-    }
-  else
-    {
-      Error("oper %c unsupported!", yfunc);
-      *kret=-9;
-    }
+  return (status);
 }
 
-
-void
-gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
-	 float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
-	 int kleng, int *kword, char *hoper, int *kret)
+static
+long iegScanTimestep(stream_t *streamptr)
 {
-  int yfunc = *hoper;
+  int status;
+  int fileID;
+  int tsID;
+  int tabnum;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  size_t recsize = 0;
+  off_t recpos = 0;
+  int recID;
+  taxis_t *taxis;
+  int rindex, nrecs = 0;
+  IEGCOMPVAR compVar, compVar0;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-  if ( yfunc == 'C' )
-    {
-      grib_encode_float(isec0, isec1, isec2, fsec2, isec3,
-			fsec3, isec4, fsec4, klenp, kgrib,
-			kleng, kword, yfunc, kret);
-    }
-  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
-    {
-      grib_decode_float(isec0, isec1, isec2, fsec2, isec3,
-			fsec3, isec4, fsec4, klenp, kgrib,
-			kleng, kword, yfunc, kret);
-    }
-  else if ( yfunc == 'V' )
-    {
-      fprintf(stderr, " cgribex: Version is %s\n", cgribexLibraryVersion());
-    }
-  else
+  if ( CDI_Debug )
     {
-      Error("oper %c unsupported!", yfunc);
-      *kret=-9;
+      Message("streamID = %d", streamptr->self);
+      Message("cts = %d", streamptr->curTsID);
+      Message("rts = %d", streamptr->rtsteps);
+      Message("nts = %d", streamptr->ntsteps);
     }
-}
-
-
-void
-gribExSP_old(int *isec0, int *isec1, int *isec2, float *fsec2sp, int *isec3,
-	     float *fsec3sp, int *isec4, float *fsec4sp, int klenp, int *kgrib,
-	     int kleng, int *kword, char *hoper, int *kret)
-{
-  int inum, j;
-  double fsec2dp[1024];
-  double fsec3dp[2];
-  double *fsec4dp = NULL;
-  int yfunc = *hoper;
-
-  if ( yfunc == 'C' )
-    {
-      inum = 10 + isec2[11];
-      for ( j = 0; j < inum; j++ ) fsec2dp[j] = fsec2sp[j];
-
-      fsec3dp[0] = fsec3sp[0];
-      fsec3dp[1] = fsec3sp[1];
-
-      inum = isec4[0];
-      fsec4dp = (double*) malloc(inum*sizeof(double));
-      if ( fsec4dp == NULL ) SysError("No Memory!");
 
-      for ( j = 0; j < inum; j++ ) fsec4dp[j] = fsec4sp[j];
+  if ( streamptr->rtsteps == 0 )
+    Error("Internal problem! Missing contents.");
 
-      gribExDP(isec0, isec1, isec2, fsec2dp, isec3,
-	       fsec3dp, isec4, fsec4dp, klenp, kgrib,
-	       kleng, kword, hoper, kret);
+  tsID  = streamptr->rtsteps;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-      free(fsec4dp);
-    }
-  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+  if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      if ( yfunc == 'D' || yfunc == 'R' )
-	{
-	  fsec4dp = (double*) malloc(klenp*sizeof(double));
-	  if ( fsec4dp == NULL ) SysError("No Memory!");
-	}
+      cdi_create_records(streamptr, tsID);
 
-      for ( j = 0; j < 10; j++ ) fsec2dp[j] = 0.0;
-      for ( j = 0; j <  2; j++ ) fsec3dp[j] = 0.0;
+      nrecs = streamptr->tsteps[1].nrecs;
 
-      gribExDP(isec0, isec1, isec2, fsec2dp, isec3,
-	       fsec3dp, isec4, fsec4dp, klenp, kgrib,
-	       kleng, kword, hoper, kret);
+      streamptr->tsteps[tsID].nrecs = nrecs;
+      streamptr->tsteps[tsID].recIDs
+        = (int *)xmalloc((size_t)nrecs * sizeof (int));
+      for ( recID = 0; recID < nrecs; recID++ )
+	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      inum = 10 + isec2[11];
-      for ( j = 0; j < inum; j++ ) fsec2sp[j] = fsec2dp[j];
+      fileID = streamptr->fileID;
 
-      fsec3sp[0] = fsec3dp[0];
-      fsec3sp[1] = fsec3dp[1];
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      if ( yfunc == 'D' || yfunc == 'R' )
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
 	{
-	  inum = isec4[0];
-	  for ( j = 0; j < inum; j++ )
+	  recpos = fileGetPos(fileID);
+	  status = iegRead(fileID, iegp);
+	  if ( status != 0 )
 	    {
-	      if ( fsec4dp[j] > -FLT_MIN && fsec4dp[j] < FLT_MIN )
-		fsec4sp[j] = 0;
-	      else if ( fsec4dp[j] > FLT_MAX )
-		fsec4sp[j] = FLT_MAX;
-	      else if ( fsec4dp[j] < -FLT_MAX )
-		fsec4sp[j] = -FLT_MAX;
-	      else
-		fsec4sp[j] = fsec4dp[j];
+	      streamptr->ntsteps = streamptr->rtsteps + 1;
+	      break;
 	    }
+	  recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-	  free(fsec4dp);
-	}
-    }
-  else if ( yfunc == 'V' )
-    fprintf(stderr, " c-gribex: Version is %s\n", cgribexLibraryVersion());
-  else
-    {
-      Error("oper %c unsupported!", yfunc);
-      *kret=-9;
-    }
-}
-
-int CGRIBEX_Fix_ZSE  = 0;    /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
-int CGRIBEX_Const    = 0;    /* 1: Don't pack constant fields on regular grids */
-int CGRIBEX_Debug    = 0;    /* 1: Debugging */
-
-void gribSetDebug(int debug)
-{
-  CGRIBEX_Debug = debug;
+	  rcode  = IEG_P_Parameter(iegp->ipdb);
+	  tabnum = IEG_P_CodeTable(iegp->ipdb);
+	  param  = cdiEncodeParam(rcode, tabnum, 255);
 
-  if ( CGRIBEX_Debug )
-    Message("debug level %d", debug);
-}
+	  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
+	    rlevel = IEG_P_Level1(iegp->ipdb);
+	  else
+	    rlevel = IEG_P_Level2(iegp->ipdb);
 
+	  if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-void gribFixZSE(int flag)
-{
-  CGRIBEX_Fix_ZSE = flag;
+	  iegDateTime(iegp->ipdb, &vdate, &vtime);
 
-  if ( CGRIBEX_Debug )
-    Message("Fix ZeroShiftError set to %d", flag);
-}
+	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
+	  if ( rindex == nrecs ) continue;
+	  recID = streamptr->tsteps[tsID].recIDs[rindex];
 
+	  if ( rindex == 0 )
+	    {
+	      taxis->type  = TAXIS_ABSOLUTE;
+	      taxis->vdate = vdate;
+	      taxis->vtime = vtime;
+	    }
 
-void gribSetConst(int flag)
-{
-  CGRIBEX_Const = flag;
+	  compVar.param = param;
+          compVar.level = rlevel;
+	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-  if ( CGRIBEX_Debug )
-    Message("Const set to %d", flag);
-}
+	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
+	    {
+	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		      tsID, recID,
+		      streamptr->tsteps[tsID].records[recID].param, param,
+		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	      Error("Invalid, unsupported or inconsistent record structure");
+	    }
 
+	  streamptr->tsteps[tsID].records[recID].position = recpos;
+	  streamptr->tsteps[tsID].records[recID].size = recsize;
 
-void gribSetRound(int round)
-{
-  UNUSED(round);
-}
+	  if ( CDI_Debug )
+	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, param, rlevel, vdate, vtime);
+	}
 
+      streamptr->rtsteps++;
 
-void gribSetRefDP(double refval)
-{
-  UNUSED(refval);
-}
+      if ( streamptr->ntsteps != streamptr->rtsteps )
+	{
+	  tsID = tstepsNewEntry(streamptr);
+	  if ( tsID != streamptr->rtsteps )
+	    Error("Internal error. tsID = %d", tsID);
 
+	  streamptr->tsteps[tsID-1].next   = 1;
+	  streamptr->tsteps[tsID].position = recpos;
+	}
 
-void gribSetRefSP(float refval)
-{
-  gribSetRefDP((double) refval);
-}
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      streamptr->tsteps[tsID].position = recpos;
+    }
 
+  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
+    {
+      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
+      streamptr->ntsteps = tsID;
+    }
 
-void gribSetValueCheck(int vcheck)
-{
-  UNUSED(vcheck);
+  return (streamptr->ntsteps);
 }
-#include <string.h>
-#include <math.h>
-
 
 
-void gribPrintSec0(int *isec0)
+int iegInqTimestep(stream_t *streamptr, int tsID)
 {
-  /*
-
-    Print the information in the Indicator
-    Section (Section 0) of decoded GRIB data.
-
-    Input Parameters:
-
-       isec0 - Array of decoded integers from Section 0
-
+  int nrecs;
 
-    Converted from EMOS routine GRPRS0.
+  if ( tsID == 0 && streamptr->rtsteps == 0 )
+    Error("Call to cdiInqContents missing!");
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  if ( CDI_Debug )
+    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-  */
+  long ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+    ntsteps = iegScanTimestep(streamptr);
 
-  grsdef();
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
+    {
+      streamptr->curTsID = tsID;
+      nrecs = streamptr->tsteps[tsID].nrecs;
+    }
 
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " Section 0 - Indicator Section.       \n");
-  fprintf(grprsm, " -------------------------------------\n");
-  fprintf(grprsm, " Length of GRIB message (octets).     %9d\n", ISEC0_GRIB_Len);
-  fprintf(grprsm, " GRIB Edition Number.                 %9d\n", ISEC0_GRIB_Version);
+  return (nrecs);
 }
 
-void gribPrintSec1(int *isec0, int *isec1)
+
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  /*
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-    Print the information in the Product Definition
-    Section (Section 1) of decoded GRIB data.
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-    Input Parameters:
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-       isec0 - Array of decoded integers from Section 0
+  currentfilepos = fileGetPos(fileID);
 
-       isec1 - Array of decoded integers from Section 1
+  for (levID = 0; levID < nlevs; levID++)
+    {
+      recID = streamptr->vars[varID].level[levID];
+      recpos = streamptr->tsteps[tsid].records[recID].position;
+      fileSetPos(fileID, recpos, SEEK_SET);
+      iegRead(fileID, iegp);
+      iegInqDataDP(iegp, &data[levID*gridsize]);
+    }
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-    Comments:
+  *nmiss = 0;
+  for ( i = 0; i < nlevs*gridsize; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
+}
 
-       When decoding data from Experimental Edition or Edition 0,
-       routine GRIBEX adds the additional fields available in
-       Edition 1.
 
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-    Converted from EMOS routine GRPRS1.
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
 
-  */
+  currentfilepos = fileGetPos(fileID);
 
-  int iprev, icurr, ioffset;
-  int ibit, ierr, iout, iyear;
-  int jloop, jiloop;
-  float value;
+  recID = streamptr->vars[varID].level[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
+  fileSetPos(fileID, recpos, SEEK_SET);
+  iegRead(fileID, iegp);
+  iegInqDataDP(iegp, data);
 
-  char hversion[9];
-  /*
-  char hfirst[121], hsecond[121], hthird[121], hfourth[121];
-  */
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  grsdef();
+  *nmiss = 0;
+  for ( i = 0; i < gridsize; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
+}
 
-  /*
-    -----------------------------------------------------------------
-    Section 0 . Print required information.
-    -----------------------------------------------------------------
-  */
 
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " Section 1 - Product Definition Section.\n");
-  fprintf(grprsm, " ---------------------------------------\n");
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
+{
+  int fileID;
+  int levID, nlevs, gridID, gridsize;
+  int zaxisID;
+  int datatype;
+  int tsID;
+  int vlistID;
+  int i;
+  int date, time;
+  int param, pdis, pcat, pnum;
+  double refval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-  fprintf(grprsm, " Code Table 2 Version Number.         %9d\n", isec1[0]);
-  fprintf(grprsm, " Originating centre identifier.       %9d\n", isec1[1]);
-  fprintf(grprsm, " Model identification.                %9d\n", isec1[2]);
-  fprintf(grprsm, " Grid definition.                     %9d\n", isec1[3]);
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  ibit = 8;
-  prtbin(isec1[4], ibit, &iout, &ierr);
-  fprintf(grprsm, " Flag (Code Table 1)                   %8.8d\n", iout);
-  fprintf(grprsm, " Parameter identifier (Code Table 2). %9d\n", isec1[5]);
+  iegInitMem(iegp);
+  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
-  /*
-      IERR = CHKTAB2(ISEC1,HFIRST,HSECOND,HTHIRD,HFOURTH)
-      IF( IERR .EQ. 0 ) THEN
-       DO JLOOP = 121, 1, -1
-          IF( HSECOND(JLOOP:JLOOP).NE.' ' ) THEN
-            IOFFSET = JLOOP
-            GOTO 110
-          ENDIF
-        ENDDO
-        GOTO 120
- 110    CONTINUE
-        WRITE(*,'(2H ",A,1H")') HSECOND(1:IOFFSET)
- 120    CONTINUE
-      ENDIF
-  */
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  nlevs    = zaxisInqSize(zaxisID);
 
-  if ( isec1[5] != 127 )
-    {
-      fprintf(grprsm, " Type of level (Code Table 3).        %9d\n", isec1[6]);
-      fprintf(grprsm, " Value 1 of level (Code Table 3).     %9d\n", isec1[7]);
-      fprintf(grprsm, " Value 2 of level (Code Table 3).     %9d\n", isec1[8]);
-    }
-  else
-    {
-      fprintf(grprsm, " Satellite identifier.                %9d\n", isec1[6]);
-      fprintf(grprsm, " Spectral band.                       %9d\n", isec1[7]);
-    }
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-  iyear = isec1[9];
-  if ( iyear != 255 )
-    {
-      int date, time;
-      /* iyear  = ((isec1[20]-1)*100 + isec1[9]); */
-      gribDateTime(isec1, &date, &time);
-      iyear = date/10000;
-      fprintf(grprsm, " Year of reference time of data.      %9d  (%4d)\n", isec1[9], iyear);
-    }
-  else
-    {
-      fprintf(grprsm, " Year of reference time of data MISSING  (=255)\n");
-    }
+  param    = vlistInqVarParam(vlistID, varID);
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  IEG_P_Parameter(iegp->ipdb) = pnum;
+  if ( pdis == 255 ) IEG_P_CodeTable(iegp->ipdb) = pcat;
+  date     = streamptr->tsteps[tsID].taxis.vdate;
+  time     = streamptr->tsteps[tsID].taxis.vtime;
 
-  fprintf(grprsm, " Month of reference time of data.     %9d\n", isec1[10]);
-  fprintf(grprsm, " Day of reference time of data.       %9d\n", isec1[11]);
-  fprintf(grprsm, " Hour of reference time of data.      %9d\n", isec1[12]);
-  fprintf(grprsm, " Minute of reference time of data.    %9d\n", isec1[13]);
-  fprintf(grprsm, " Time unit (Code Table 4).            %9d\n", isec1[14]);
-  fprintf(grprsm, " Time range one.                      %9d\n", isec1[15]);
-  fprintf(grprsm, " Time range two.                      %9d\n", isec1[16]);
-  fprintf(grprsm, " Time range indicator (Code Table 5)  %9d\n", isec1[17]);
-  fprintf(grprsm, " Number averaged.                     %9d\n", isec1[18]);
-  fprintf(grprsm, " Number missing from average.         %9d\n", isec1[19]);
-  /*
-     All ECMWF data in GRIB Editions before Edition 1 is decoded
-     as 20th century data. Other centres are decoded as missing.
-  */
-  if ( isec0[1] < 1 && isec1[1] != 98 )
-    fprintf(grprsm, " Century of reference time of data.   Not given\n");
-  else
-    fprintf(grprsm, " Century of reference time of data.   %9d\n", isec1[20]);
+  iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
+  iegDefGrid(iegp->igdb, gridID);
 
-  /*   Print sub-centre  */
-  fprintf(grprsm, " Sub-centre identifier.               %9d\n", ISEC1_SubCenterID);
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
-  /*   Decimal scale factor  */
-  fprintf(grprsm, " Units decimal scaling factor.        %9d\n", isec1[22]);
+  iegp->dprec = iegDefDatatype(datatype);
 
-  /*
-    -----------------------------------------------------------------
-    Section 1 . Print local DWD information.
-    -----------------------------------------------------------------
-  */
-  if ( (ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250) &&
-       (isec1[36] == 253     || isec1[36] == 254) )
+  for ( levID = 0;  levID < nlevs; levID++ )
     {
-      fprintf(grprsm, " DWD local usage identifier.          %9d\n", isec1[36]);
-      if ( isec1[36] == 253 )
-	fprintf(grprsm, " (Database labelling and ensemble forecast)\n");
-      if ( isec1[36] == 254 )
-	fprintf(grprsm, " (Database labelling)\n");
+      iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
 
-      fprintf(grprsm, " Year of database entry                     %3d  (%4d)\n", isec1[43], 1900+isec1[43]);
-      fprintf(grprsm, " Month of database entry                    %3d\n", isec1[44]);
-      fprintf(grprsm, " Day of database entry                      %3d\n", isec1[45]);
-      fprintf(grprsm, " Hour of database entry                     %3d\n", isec1[46]);
-      fprintf(grprsm, " Minute of database entry                   %3d\n", isec1[47]);
-      fprintf(grprsm, " DWD experiment number                %9d\n",isec1[48]);
-      fprintf(grprsm, " DWD run type                         %9d\n",isec1[49]);
-      if ( isec1[36] == 253 ) 
-	{
-	  fprintf(grprsm, " User id                              %9d\n",isec1[50]);
-	  fprintf(grprsm, " Experiment identifier                %9d\n",isec1[51]);
-	  fprintf(grprsm, " Ensemble identification type         %9d\n",isec1[52]);
-	  fprintf(grprsm, " Number of ensemble members           %9d\n",isec1[53]);
-	  fprintf(grprsm, " Actual number of ensemble member     %9d\n",isec1[54]);
-	  fprintf(grprsm, " Model version                            %2d.%2.2d\n",isec1[55],isec1[56]);
-	}
-    }
+      refval = data[0];
+      for ( i = 1; i < gridsize; i++ )
+	if ( data[levID*gridsize+i] < refval ) refval = data[levID*gridsize+i];
 
-  /*
-    -----------------------------------------------------------------
-    Section 2 . Print local ECMWF information.
-    -----------------------------------------------------------------
-  */
-  /*
-    Regular MARS labelling, or reformatted Washington EPS products.
-  */
-  if ( (ISEC1_CenterID    == 98 && ISEC1_LocalFLag ==  1) ||
-       (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag ==  1) ||
-       (ISEC1_CenterID    ==  7 && ISEC1_SubCenterID == 98) )
-    {
-      /*   Parameters common to all definitions.  */
+      iegp->refval = refval;
 
-      fprintf(grprsm, " ECMWF local usage identifier.        %9d\n", isec1[36]);
-      if ( isec1[36] == 1 )
-	fprintf(grprsm, " (Mars labelling or ensemble forecast)\n");
-      if ( isec1[36] == 2 )
-        fprintf(grprsm, " (Cluster means and standard deviations)\n");
-      if ( isec1[36] == 3 )
-        fprintf(grprsm, " (Satellite image data)\n");
-      if ( isec1[36] == 4 )
-        fprintf(grprsm, " (Ocean model data)\n");
-      if ( isec1[36] == 5 )
-        fprintf(grprsm, " (Forecast probability data)\n");
-      if ( isec1[36] == 6 )
-        fprintf(grprsm, " (Surface temperature data)\n");
-      if ( isec1[36] == 7 )
-        fprintf(grprsm, " (Sensitivity data)\n");
-      if ( isec1[36] == 8 )
-        fprintf(grprsm, " (ECMWF re-analysis data)\n");
-      if ( isec1[36] == 9 )
-        fprintf(grprsm, " (Singular vectors and ensemble perturbations)\n");
-      if ( isec1[36] == 10 )
-        fprintf(grprsm, " (EPS tubes)\n");
-      if ( isec1[36] == 11 )
-        fprintf(grprsm, " (Supplementary data used by analysis)\n");
-      if ( isec1[36] == 13 )
-        fprintf(grprsm, " (Wave 2D spectra direction and frequency)\n");
+      iegDefDataDP(iegp, &data[levID*gridsize]);
+      iegWrite(fileID, iegp);
+    }
+}
 
-      fprintf(grprsm, " Class.                               %9d\n", isec1[37]);
-      fprintf(grprsm, " Type.                                %9d\n", isec1[38]);
-      fprintf(grprsm, " Stream.                              %9d\n", isec1[39]);
-      sprintf(hversion, "%4s", (char*)&isec1[40]); hversion[4] = 0;
-      fprintf(grprsm, " Version number or Experiment identifier.  %4s\n", hversion);
-      /*
-	ECMWF Local definition 1.
-	(MARS labelling or ensemble forecast data)
-      */
-      if ( isec1[36] == 1 )
-	{
-	  fprintf(grprsm, " Forecast number.                     %9d\n", isec1[41]);
-	  if ( isec1[39] != 1090 )
-	    fprintf(grprsm, " Total number of forecasts.           %9d\n", isec1[42]);
 
-	  return;
-	}
-      /*
-	ECMWF Local definition 2.
-	(Cluster means and standard deviations)
-      */
-      if ( isec1[36] == 2 )
-	{
-	  fprintf(grprsm, " Cluster number.                      %9d\n", isec1[41]);
-	  fprintf(grprsm, " Total number of clusters.            %9d\n", isec1[42]);
-	  fprintf(grprsm, " Clustering method.                   %9d\n", isec1[43]);
-	  fprintf(grprsm, " Start time step when clustering.     %9d\n", isec1[44]);
-	  fprintf(grprsm, " End time step when clustering.       %9d\n", isec1[45]);
-	  fprintf(grprsm, " Northern latitude of domain.         %9d\n", isec1[46]);
-	  fprintf(grprsm, " Western longitude of domain.         %9d\n", isec1[47]);
-	  fprintf(grprsm, " Southern latitude of domain.         %9d\n", isec1[48]);
-	  fprintf(grprsm, " Eastern longitude of domain.         %9d\n", isec1[49]);
-	  fprintf(grprsm, " Operational forecast in cluster      %9d\n", isec1[50]);
-	  fprintf(grprsm, " Control forecast in cluster          %9d\n", isec1[51]);
-	  fprintf(grprsm, " Number of forecasts in cluster.      %9d\n", isec1[52]);
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+{
+  int fileID;
+  int gridID;
+  int zaxisID;
+  /* double level; */
+  int datatype;
+  /* int tsID; */
+  int vlistID;
+  /* int param, date, time, datasize; */
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-	  for (jloop = 0; jloop < isec1[52]; jloop++)
-	    fprintf(grprsm, " Forecast number                      %9d\n", isec1[jloop+53]);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  /* tsID     = streamptr->curTsID; */
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  (void)levID;
+  /* level    = zaxisInqLevel(zaxisID, levID); */
 
-	  return;
-	}
-      /*
-	ECMWF Local definition 3.
-	(Satellite image data)
-      */
-      if ( isec1[36] == 3 )
-	{
-	  fprintf(grprsm, " Satellite spectral band.             %9d\n", isec1[41]);
-	  fprintf(grprsm, " Function code.                       %9d\n", isec1[42]);
-	  return;
-	}
-      /*
-	ECMWF Local definition 4.
-	(Ocean model data)
-      */
-      if ( isec1[36] == 4 )
-	{
-	  fprintf(grprsm, " Satellite spectral band.             %9d\n", isec1[41]);
-	  if ( isec1[39] != 1090 )
-	    fprintf(grprsm, " Function code.                       %9d\n", isec1[42]);
-	  fprintf(grprsm, " Coordinate structure definition.\n");
-	  fprintf(grprsm, " Fundamental spatial reference system.%9d\n", isec1[43]);
-	  fprintf(grprsm, " Fundamental time reference.          %9d\n", isec1[44]);
-	  fprintf(grprsm, " Space unit flag.                     %9d\n", isec1[45]);
-	  fprintf(grprsm, " Vertical coordinate definition.      %9d\n", isec1[46]);
-	  fprintf(grprsm, " Horizontal coordinate definition.    %9d\n", isec1[47]);
-	  fprintf(grprsm, " Time unit flag.                      %9d\n", isec1[48]);
-	  fprintf(grprsm, " Time coordinate definition.          %9d\n", isec1[49]);
-	  fprintf(grprsm, " Position definition.     \n");
-	  fprintf(grprsm, " Mixed coordinate field flag.         %9d\n", isec1[50]);
-	  fprintf(grprsm, " Coordinate 1 flag.                   %9d\n", isec1[51]);
-	  fprintf(grprsm, " Averaging flag.                      %9d\n", isec1[52]);
-	  fprintf(grprsm, " Position of level 1.                 %9d\n", isec1[53]);
-	  fprintf(grprsm, " Position of level 2.                 %9d\n", isec1[54]);
-	  fprintf(grprsm, " Coordinate 2 flag.                   %9d\n", isec1[55]);
-	  fprintf(grprsm, " Averaging flag.                      %9d\n", isec1[56]);
-	  fprintf(grprsm, " Position of level 1.                 %9d\n", isec1[57]);
-	  fprintf(grprsm, " Position of level 2.                 %9d\n", isec1[58]);
-	  fprintf(grprsm, " Grid Definition.\n");
-	  fprintf(grprsm, " Coordinate 3 flag (x-axis)           %9d\n", isec1[59]);
-	  fprintf(grprsm, " Coordinate 4 flag (y-axis)           %9d\n", isec1[60]);
-	  fprintf(grprsm, " Coordinate 4 of first grid point.    %9d\n", isec1[61]);
-	  fprintf(grprsm, " Coordinate 3 of first grid point.    %9d\n", isec1[62]);
-	  fprintf(grprsm, " Coordinate 4 of last grid point.     %9d\n", isec1[63]);
-	  fprintf(grprsm, " Coordinate 3 of last grid point.     %9d\n", isec1[64]);
-	  fprintf(grprsm, " i - increment.                       %9d\n", isec1[65]);
-	  fprintf(grprsm, " j - increment.                       %9d\n", isec1[66]);
-	  fprintf(grprsm, " Flag for irregular grid coordinates. %9d\n", isec1[67]);
-	  fprintf(grprsm, " Flag for normal or staggered grids.  %9d\n", isec1[68]);
-	  fprintf(grprsm, " Further information.\n");
-	  fprintf(grprsm, " Further information flag.            %9d\n", isec1[69]);
-	  fprintf(grprsm, " Auxiliary information.\n");
-	  fprintf(grprsm, " No. entries in horizontal coordinate %9d\n", isec1[70]);
-	  fprintf(grprsm, " No. entries in mixed coordinate defn.%9d\n", isec1[71]);
-	  fprintf(grprsm, " No. entries in grid coordinate list. %9d\n", isec1[72]);
-	  fprintf(grprsm, " No. entries in auxiliary array.      %9d\n", isec1[73]);
-	  /*
-	    Horizontal coordinate supplement.
-	  */
-	  fprintf(grprsm, " Horizontal coordinate supplement.\n");
-	  if ( isec1[70] == 0 )
-	    {
-	      fprintf(grprsm, "(None).\n");
-	    }
-	  else
-	    {
-	      fprintf(grprsm, "Number of items = %d\n", isec1[70]);
-	      for (jloop = 0; jloop < isec1[70]; jloop++)
-		fprintf(grprsm, "         %12d\n", isec1[74+jloop]);
-	    }
-	  /*
-	    Mixed coordinate definition.
-	  */
-	  fprintf(grprsm, " Mixed coordinate definition.\n");
-	  if ( isec1[71] == 0 )
-	    {
-	      fprintf(grprsm, "(None).\n");
-	    }
-	  else
-	    {
-	      fprintf(grprsm, "Number of items = %d\n", isec1[71]);
-	      ioffset = 74 + isec1[70];
-	      for (jloop = 0; jloop < isec1[71]; jloop++)
-		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
-	    }
-	  /*
-	    Grid coordinate list.
-	  */
-	  fprintf(grprsm, " Grid coordinate list. \n");
-	  if ( isec1[72] == 0 )
-	    {
-	      fprintf(grprsm, "(None).\n");
-	    }
-	  else
-	    {
-	      fprintf(grprsm, "Number of items = %d\n", isec1[72]);
-	      ioffset = 74 + isec1[70] + isec1[71];
-	      for (jloop = 0; jloop < isec1[72]; jloop++)
-		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
-	    }
-	  /*
-	    Auxiliary array.
-	  */
-	  fprintf(grprsm, " Auxiliary array.      \n");
-	  if ( isec1[73] == 0 )
-	    {
-	      fprintf(grprsm, "(None).\n");
-	    }
-	  else
-	    {
-	      fprintf(grprsm, "Number of items = %d\n", isec1[73]);
-	      ioffset = 74 + isec1[70] + isec1[71] + isec1[72];
-	      for (jloop = 0; jloop < isec1[73]; jloop++)
-		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
-	    }
-	  /*
-	    Post-auxiliary array.
-	  */
-	  fprintf(grprsm, " Post-auxiliary array. \n");
-	  ioffset = 74 + isec1[70] + isec1[71] + isec1[72] + isec1[73];
-	  if ( isec1[ioffset] == 0 )
-	    {
-	      fprintf(grprsm, "(None).\n");
-	    }
-	  else
-	    {
-	      fprintf(grprsm, "Number of items = %d\n", isec1[ioffset]);
-	      for (jloop = 1; jloop < isec1[ioffset]; jloop++)
-		fprintf(grprsm, "         %12d\n", isec1[ioffset+jloop]);
-	    }
+  if ( CDI_Debug )
+    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
 
-	  return;
-	}
-      /*
-	ECMWF Local definition 5.
-	(Forecast probability data)
-      */
-      if ( isec1[36] == 5 )
-	{
-	  fprintf(grprsm, " Forecast probability number          %9d\n", isec1[41]);
-	  fprintf(grprsm, " Total number of forecast probabilities %7d\n", isec1[42]);
-	  fprintf(grprsm, " Threshold units decimal scale factor %9d\n", isec1[43]);
-	  fprintf(grprsm, " Threshold indicator(1=lower,2=upper,3=both) %2d\n", isec1[44]);
-	  if ( isec1[44]  !=  2 )
-	    fprintf(grprsm, " Lower threshold value                %9d\n", isec1[45]);
-	  if ( isec1[44]  !=  1 )
-	    fprintf(grprsm, " Upper threshold value                %9d\n", isec1[46]);
-	  return;
-	}
-      /*
-	ECMWF Local definition 6.
-	(Surface temperature data)
-      */
-      if ( isec1[36] == 6 )
-	{
-	  iyear = isec1[43];
-	  if ( iyear > 100 )
-	    {
-	      if ( iyear < 19000000 ) iyear = iyear + 19000000;
-	      fprintf(grprsm, " Date of SST field used               %9d\n", iyear);
-	    }
-	  else
-	    fprintf(grprsm, "Date of SST field used               Not given\n");
-	}
-      if ( isec1[44] == 0 )
-	fprintf(grprsm, " Type of SST field (= climatology)    %9d\n", isec1[44]);
-      if ( isec1[44] == 1 )
-	fprintf(grprsm, " Type of SST field (= 1/1 degree)     %9d\n", isec1[44]);
-      if ( isec1[44] == 2 )
-	fprintf(grprsm, " Type of SST field (= 2/2 degree)     %9d\n", isec1[44]);
+  /* param = vlistInqVarParam(vlistID, varID); */
+  /* date = streamptr->tsteps[tsID].taxis.vdate; */
+  /* time = streamptr->tsteps[tsID].taxis.vtime; */
+  /* datasize = gridInqSize(gridID); */
 
-      fprintf(grprsm, " Number of ICE fields used:           %9d\n", isec1[45]);
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
-      for (jloop = 1; jloop <= isec1[45]; jloop++)
-	{
-	  iyear = isec1[44+(jloop*2)];
-	  if ( iyear > 100 )
-	    {
-              if ( iyear < 19000000 ) iyear = iyear + 19000000;
-	      fprintf(grprsm, " Date of ICE field%3d                 %9d\n", jloop, iyear);
-	      fprintf(grprsm, " Satellite number (ICE field%3d)      %9d\n", jloop,
-		     isec1[45+(jloop*2)]);
-	    }
-	  else
-	    fprintf(grprsm, "Date of SST field used               Not given\n");
-	}
-      /*
-	ECMWF Local definition 7.
-	(Sensitivity data)
-      */
-      if ( isec1[36] == 7 )
-	{
-	  if ( isec1[38]  ==  51 )
-	    fprintf(grprsm, " Forecast number                      %9d\n", isec1[41]);
-	  if ( isec1[38]  !=  51 )
-	    fprintf(grprsm, " Iteration number                     %9d\n", isec1[41]);
-	  if ( isec1[38]  !=  52 )
-	    fprintf(grprsm, " Total number of diagnostics          %9d\n", isec1[42]);
-	  if ( isec1[38]  ==  52 )
-	    fprintf(grprsm, " No.interations in diag. minimisation %9d\n", isec1[42]);
-	  fprintf(grprsm, " Domain(0=Global,1=Europe,2=N.Hem.,3=S.Hem.) %2d\n", isec1[43]);
-	  fprintf(grprsm, " Diagnostic number                    %9d\n", isec1[44]);
-	}
-      /*
-	ECMWF Local definition 8.
-	(ECMWF re-analysis data)
-      */
-      if ( isec1[36] == 8 )
+  iegp->dprec = iegDefDatatype(datatype);
+
+  iegDefDataDP(iegp, data);
+  iegWrite(fileID, iegp);
+}
+
+#endif /* HAVE_LIBIEG */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+
+
+
+void recordInitEntry(record_t *record)
+{
+  record->position = CDI_UNDEFID;
+  record->size     = 0;
+  record->param    = 0;
+  record->ilevel   = CDI_UNDEFID;
+  record->used     = FALSE;
+  record->varID    = CDI_UNDEFID;
+  record->levelID  = CDI_UNDEFID;
+  memset(record->varname, 0, sizeof(record->varname));
+}
+
+
+int recordNewEntry(stream_t *streamptr, int tsID)
+{
+  int recordID = 0;
+  int recordSize = streamptr->tsteps[tsID].recordSize;
+  record_t *records = streamptr->tsteps[tsID].records;
+  /*
+    Look for a free slot in record.
+    (Create the table the first time through).
+  */
+  if ( ! recordSize )
+    {
+      int i;
+      recordSize = 1;   /*  <<<<----  */
+      records = (record_t *)xmalloc((size_t)recordSize * sizeof (record_t));
+      if ( records == NULL )
 	{
-	  if ( (isec1[39] == 1043) ||
-	       (isec1[39] == 1070) ||
-	       (isec1[39] == 1071) )
-	    {
-	      fprintf(grprsm, " Interval between reference times     %9d\n", isec1[41]);
-	      for (jloop = 43; jloop <= 54; jloop++)
-		{
-		  jiloop = jloop + 8;
-		  fprintf(grprsm, " ERA section 1 octet %2d.              %9d\n",
-			 jiloop, isec1[jloop-1]);
-		}
-	    }
-	  else
-	    {
-	      for (jloop = 42; jloop <= 54; jloop++)
-		{
-		  jiloop = jloop + 8;
-		  fprintf(grprsm, " ERA section 1 octet %2d.              %9d\n",
-			 jiloop, isec1[jloop-1]);
-		}
-	    }
-	  return;
+          Message("recordSize = %d", recordSize);
+	  SysError("Allocation of records failed");
 	}
 
-      if ( isec1[38] > 4  && isec1[38] < 9 )
+      for ( i = 0; i < recordSize; i++ )
+	records[i].used = CDI_UNDEFID;
+    }
+  else
+    {
+      while ( recordID < recordSize )
 	{
-	  fprintf(grprsm, " Simulation number.                   %9d\n", isec1[41]);
-	  fprintf(grprsm, " Total number of simulations.         %9d\n", isec1[42]);
+	  if ( records[recordID].used == CDI_UNDEFID ) break;
+	  recordID++;
 	}
-      /*
-	ECMWF Local definition 9.
-	(Singular vectors and ensemble perturbations)
-      */
-      if ( isec1[36] == 9 )
+    }
+  /*
+    If the table overflows, double its size.
+  */
+  if ( recordID == recordSize )
+    {
+      int i;
+
+      recordSize = 2*recordSize;
+      records    = (record_t *)xrealloc(records,
+                                        (size_t)recordSize * sizeof (record_t));
+      if ( records == NULL )
 	{
-	  if ( isec1[38] == 60 )
-	    fprintf(grprsm, " Perturbed ensemble forecast number   %9d\n", isec1[41]);
-	  if ( isec1[38] == 61 )
-	    fprintf(grprsm, " Initial state perturbation number    %9d\n", isec1[41]);
-	  if ( isec1[38] == 62 )
-	    fprintf(grprsm, " Singular vector number               %9d\n", isec1[41]);
-	  if ( isec1[38] == 62 )
-	    {
-	      fprintf(grprsm, " Number of iterations                 %9d\n", isec1[42]);
-	      fprintf(grprsm, " Number of singular vectors computed  %9d\n", isec1[43]);
-	      fprintf(grprsm, " Norm used at initial time            %9d\n", isec1[44]);
-	      fprintf(grprsm, " Norm used at final time              %9d\n", isec1[45]);
-	      fprintf(grprsm, " Multiplication factor                %9d\n", isec1[46]);
-    	      fprintf(grprsm, " Latitude of north-west corner        %9d\n", isec1[47]);
-    	      fprintf(grprsm, " Longitude of north-west corner       %9d\n", isec1[48]);
-	      fprintf(grprsm, " Latitude of south-east corner        %9d\n", isec1[49]);
-	      fprintf(grprsm, " Longitude of south-east corner       %9d\n", isec1[50]);
-	      fprintf(grprsm, " Accuracy                             %9d\n", isec1[51]);
-	      fprintf(grprsm, " Number of singular vectors evolved   %9d\n", isec1[52]);
-	      fprintf(grprsm, " Ritz number one                      %9d\n", isec1[53]);
-	      fprintf(grprsm, " Ritz number two                      %9d\n", isec1[54]);
-	    }
+          Message("recordSize = %d", recordSize);
+	  SysError("Reallocation of records failed");
 	}
-      /*
-	ECMWF Local definition 10.
-	(EPS tubes)
-      */
-      if ( isec1[36] == 10 )
-	{
-	  fprintf(grprsm, " Tube number                          %9d\n", isec1[41]);
-          fprintf(grprsm, " Total number of tubes                %9d\n", isec1[42]);
-          fprintf(grprsm, " Central cluster definition           %9d\n", isec1[43]);
-          fprintf(grprsm, " Parameter                            %9d\n", isec1[44]);
-          fprintf(grprsm, " Type of level                        %9d\n", isec1[45]);
-          fprintf(grprsm, " Northern latitude of domain of tubing%9d\n", isec1[46]);
-          fprintf(grprsm, " Western longitude of domain of tubing%9d\n", isec1[47]);
-          fprintf(grprsm, " Southern latitude of domain of tubing%9d\n", isec1[48]);
-          fprintf(grprsm, " Eastern longitude of domain of tubing%9d\n", isec1[49]);
-          fprintf(grprsm, " Tube number of operational forecast  %9d\n", isec1[50]);
-          fprintf(grprsm, " Tube number of control forecast      %9d\n", isec1[51]);
-          fprintf(grprsm, " Height/pressure of level             %9d\n", isec1[52]);
-          fprintf(grprsm, " Reference step                       %9d\n", isec1[53]);
-          fprintf(grprsm, " Radius of central cluster            %9d\n", isec1[54]);
-          fprintf(grprsm, " Ensemble standard deviation          %9d\n", isec1[55]);
-          fprintf(grprsm, " Dist.of tube extreme to ensemble mean%9d\n", isec1[56]);
-          fprintf(grprsm, " Number of forecasts in the tube      %9d\n", isec1[57]);
+      recordID = recordSize/2;
 
-          fprintf(grprsm, " List of ensemble forecast numbers:\n");
-          for (jloop = 1; jloop <=  isec1[57]; jloop++)
-	    fprintf(grprsm, "    %9d\n", isec1[57+jloop]);
-	}
-      /*
-	ECMWF Local definition 11.
-	(Supplementary data used by the analysis)
-      */
-      if ( isec1[36] == 11 )
-	{
-	  fprintf(grprsm, " Details of analysis which used the supplementary data:\n");
-	  fprintf(grprsm, "   Class                              %9d\n", isec1[41]);
-	  fprintf(grprsm, "   Type                               %9d\n", isec1[42]);
-	  fprintf(grprsm, "   Stream                             %9d\n", isec1[43]);
-	  /*
-	  sprintf(hversion, "%8d", isec1[44]);
-	  fprintf(grprsm, "   Version number/experiment identifier:   %4s\n", &hversion[4]);
-	  */
-	  iyear = isec1[45];
-	  if ( iyear > 50 )
-	    iyear = iyear + 1900;
-	  else
-	    iyear = iyear + 2000;
+      for ( i = recordID; i < recordSize; i++ )
+	records[i].used = CDI_UNDEFID;
+    }
 
-	  fprintf(grprsm, "   Year                               %9d\n", iyear);
-	  fprintf(grprsm, "   Month                              %9d\n", isec1[46]);
-	  fprintf(grprsm, "   Day                                %9d\n", isec1[47]);
-	  fprintf(grprsm, "   Hour                               %9d\n", isec1[48]);
-	  fprintf(grprsm, "   Minute                             %9d\n", isec1[49]);
-	  fprintf(grprsm, "   Century                            %9d\n", isec1[50]);
-	  fprintf(grprsm, "   Originating centre                 %9d\n", isec1[51]);
-	  fprintf(grprsm, "   Sub-centre                         %9d\n", isec1[52]);
-	}
-      /*
-	ECMWF Local definition 12.
-      */
-      if ( isec1[36] == 12 )
-	{
-	  fprintf(grprsm, " (Mean, average, etc)\n");
-          fprintf(grprsm, " Start date of the period              %8d\n", isec1[41]);
-          fprintf(grprsm, " Start time of the period                  %4.4d\n", isec1[42]);
-          fprintf(grprsm, " Finish date of the period             %8d\n", isec1[43]);
-          fprintf(grprsm, " Finish time of the period                 %4.4d\n", isec1[44]);
-          fprintf(grprsm, " Verifying date of the period          %8d\n", isec1[45]);
-          fprintf(grprsm, " Verifying time of the period              %4.4d\n", isec1[46]);
-          fprintf(grprsm, " Code showing method                   %8d\n", isec1[47]);
-          fprintf(grprsm, " Number of different time intervals used  %5d\n", isec1[48]);
-          fprintf(grprsm, " List of different time intervals used:\n");
-          iprev  = isec1[49];
-          icurr  = 0;
-          unsigned icount = 0;
-          for (jloop = 1; jloop <= isec1[48]; jloop++)
-	    {
-	      icurr = isec1[48+jloop];
-	      if ( icurr != iprev )
-		{
-		  if ( icount == 1 )
-		    fprintf(grprsm, "  - interval %5.4d used       once\n", iprev);
-		  if ( icount == 2 )
-		    fprintf(grprsm, "  - interval %5.4d used       twice\n", iprev);
-		  if ( icount > 2 )
-		    fprintf(grprsm, "  - interval %5.4d used %5u times\n",  iprev, icount);
-		  iprev  = icurr;
-		  icount = 1;
-		}
-	      else
-		icount = icount + 1;
-	    }
-	  if ( icount == 1 )
-	    fprintf(grprsm, "  - interval %5.4d used       once\n", iprev);
-	  if ( icount == 2 )
-	    fprintf(grprsm, "  - interval %5.4d used       twice\n", iprev);
-	  if ( icount > 2 )
-	    fprintf(grprsm, "  - interval %5.4d used %5u times\n",  iprev, icount);
-	}
-      /*
-	ECMWF Local definition 13.
-	(Wave 2D spectra direction and frequency)
-      */
-      if ( isec1[36] == 13 )
-	{
-          fprintf(grprsm, " Direction number                     %9d\n", isec1[43]);
-	  fprintf(grprsm, " Frequency number                     %9d\n", isec1[44]);
-	  fprintf(grprsm, " Total number of directions           %9d\n", isec1[45]);
-	  fprintf(grprsm, " Total number of frequencies          %9d\n", isec1[46]);
-	  fprintf(grprsm, " Scale factor applied to directions   %9d\n", isec1[47]);
-	  fprintf(grprsm, " Scale factor applied to frequencies  %9d\n", isec1[48]);
-	  fprintf(grprsm, " List of directions:\n");
-          for (jloop = 1; jloop <= isec1[45]; jloop++)
-            {
-	      value = (float)(isec1[48+jloop])/(float)(isec1[47]);
-	      if ( isec1[43] == jloop )
-		fprintf(grprsm, " %2.2d:%15.7f   <-- this field value\n",  jloop, value);
-	      else
-		fprintf(grprsm, "%2.2d:%15.7f\n",  jloop, value);
-            }
-	  fprintf(grprsm, " List of frequencies:\n");
-          for (jloop = 1; jloop <= isec1[46]; jloop++)
-	    {
-	      value = (float)(isec1[48+isec1[45]+jloop])/(float)(isec1[48]);
-	      if ( isec1[44] == jloop )
-		fprintf(grprsm, " %2.2d:%15.7f   <-- this field value\n",  jloop, value);
-	      else
-		fprintf(grprsm, "%2.2d:%15.7f\n",  jloop, value);
+  recordInitEntry(&records[recordID]);
 
-	      if ( isec1[49+isec1[45]+isec1[46]] != 0 )
-		{
-		  fprintf(grprsm, " System number (65535 = missing)      %9d\n",
-			 isec1[49+isec1[45]+isec1[46]]);
-		  fprintf(grprsm, " Method number (65535 = missing)      %9d\n",
-			 isec1[50+isec1[45]+isec1[46]]);
-		}
-	    }
-	  /*
-	    ECMWF Local definition 14.
-	    (Brightness temperature)
-	  */
-	  if ( isec1[36] == 14 )
-	    {
-	      fprintf(grprsm, " Channel number                       %9d\n", isec1[43]);
-	      fprintf(grprsm, " Scale factor applied to frequencies  %9d\n", isec1[44]);
-	      fprintf(grprsm, " Total number of frequencies          %9d\n", isec1[45]);
-	      fprintf(grprsm, " List of frequencies:\n");
-              for (jloop = 1; jloop <= isec1[45]; jloop++)
-		{
-		  value = (float)(isec1[45+jloop])/(float)(isec1[44]);
-		  if ( isec1[43] == jloop )
-		    fprintf(grprsm, " %3d:%15.9f   <-- this channel\n", jloop, value);
-		  else
-		    fprintf(grprsm, " %3d:%15.9f\n", jloop, value);
-		}
-	    }
-	  /*
-	    ECMWF Local definition 15.
-	    (Ocean ensemble seasonal forecast)
-	  */
-	  if ( isec1[36] == 15 )
-	    {
-	      fprintf(grprsm, " Ensemble member number               %9d\n", isec1[41]);
-	      fprintf(grprsm, " System number                        %9d\n", isec1[42]);
-	      fprintf(grprsm, " Method number                        %9d\n", isec1[43]);
-	    }
-	  /*
-	    ECMWF Local definition 16.
-	    (Seasonal forecast monthly mean atmosphere data)
-	  */
-        if ( isec1[36] == 16 )
-	  {
-	    fprintf(grprsm, " Ensemble member number               %9d\n", isec1[41]);
-	    fprintf(grprsm, " System number                        %9d\n", isec1[43]);
-	    fprintf(grprsm, " Method number                        %9d\n", isec1[44]);
-	    fprintf(grprsm, " Verifying month                      %9d\n", isec1[45]);
-	    fprintf(grprsm, " Averaging period                     %9d\n", isec1[46]);
-	  }
-	/*
-	  ECMWF Local definition 17.
-	  (Sst or sea-ice used by analysis)
-	*/
-        if ( isec1[36] == 17 )
-	  {
-	    iyear = isec1[43];
-	    if ( iyear > 100 )
-	      {
-		if ( iyear < 19000000 ) iyear = iyear + 19000000;
-		fprintf(grprsm, " Date of sst/ice field used           %9d\n", iyear);
-	      }
-	    else
-              fprintf(grprsm, " Date of sst/ice field used           Not given\n");
-      
-	    if ( isec1[44] == 0 )
-	      fprintf(grprsm, " Type of sst/ice field (= climatology)%9d\n", isec1[44]);
-	    if ( isec1[44] == 1 )
-	      fprintf(grprsm, " Type of sst/ice field (= 1/1 degree) %9d\n", isec1[44]);
-	    if ( isec1[44] == 2 )
-	      fprintf(grprsm, " Type of sst/ice field (= 2/2 degree) %9d\n", isec1[44]);
+  records[recordID].used = 1;
+
+  streamptr->tsteps[tsID].recordSize = recordSize;
+  streamptr->tsteps[tsID].records    = records;
+
+  return (recordID);
+}
+
+static
+void cdiInitRecord(stream_t *streamptr)
+{
+  streamptr->record = (Record *) malloc(sizeof(Record));
+
+  streamptr->record->param      = 0;
+  streamptr->record->level      = 0;
+  streamptr->record->date       = 0;
+  streamptr->record->time       = 0;
+  streamptr->record->gridID     = 0;
+  streamptr->record->buffer     = NULL;
+  streamptr->record->buffersize = 0;
+  streamptr->record->position   = 0;
+  streamptr->record->varID      = 0;
+  streamptr->record->levelID    = CDI_UNDEFID;
+}
+
+
+void streamInqRecord(int streamID, int *varID, int *levelID)
+{
+  check_parg(varID);
+  check_parg(levelID);
+
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+
+  cdiDefAccesstype(streamID, TYPE_REC);
+
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
+
+  int tsID   = streamptr->curTsID;
+  int rindex = streamptr->tsteps[tsID].curRecID + 1;
+
+  if ( rindex >= streamptr->tsteps[tsID].nrecs )
+    Error("record %d not available at timestep %d", rindex+1, tsID+1);
+
+  int recID  = streamptr->tsteps[tsID].recIDs[rindex];
+
+  if ( recID == -1 || recID >= streamptr->tsteps[tsID].nallrecs )
+    Error("Internal problem! tsID = %d recID = %d", tsID, recID);
+
+  *varID   = streamptr->tsteps[tsID].records[recID].varID;
+  int lindex = streamptr->tsteps[tsID].records[recID].levelID;
+
+  *levelID = streamptr->vars[*varID].lindex[lindex];
+
+  if ( CDI_Debug )
+    Message("tsID = %d, recID = %d, varID = %d, levelID = %d\n", tsID, recID, *varID, *levelID);
+
+  streamptr->curTsID = tsID;
+  streamptr->tsteps[tsID].curRecID = rindex;
+}
+
+/*
+ at Function  streamDefRecord
+ at Title     Define the next record
+
+ at Prototype void streamDefRecord(int streamID, int varID, int levelID)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  varID     Variable identifier.
+    @Item  levelID   Level identifier.
+
+ at Description
+The function streamDefRecord defines the meta-data of the next record.
+ at EndFunction
+*/
+void streamDefRecord(int streamID, int varID, int levelID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+
+  int tsID = streamptr->curTsID;
+
+  if ( tsID == CDI_UNDEFID )
+    {
+      tsID++;
+      streamDefTimestep(streamID, tsID);
+    }
+
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
+
+  int vlistID = streamptr->vlistID;
+  int gridID  = vlistInqVarGrid(vlistID, varID);
+  int zaxisID = vlistInqVarZaxis(vlistID, varID);
+  int param   = vlistInqVarParam(vlistID, varID);
+  int level   = (int) zaxisInqLevel(zaxisID, levelID);
+
+  streamptr->record->varID    = varID;
+  streamptr->record->levelID  = levelID;
+  streamptr->record->param    = param;
+  streamptr->record->level    = level;
+  streamptr->record->date     = streamptr->tsteps[tsID].taxis.vdate;
+  streamptr->record->time     = streamptr->tsteps[tsID].taxis.vtime;
+  streamptr->record->gridID   = gridID;
+  streamptr->record->prec     = vlistInqVarDatatype(vlistID, varID);
+
+  switch (streamptr->filetype)
+    {
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      grbDefRecord(streamptr);
+      break;
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      srvDefRecord(streamptr);
+      break;
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      extDefRecord(streamptr);
+      break;
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      iegDefRecord(streamptr);
+      break;
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+      cdfDefRecord(streamptr);
+      break;
+#endif
+    default:
+      Error("%s support not compiled in!", strfiletype(streamptr->filetype));
+      break;
+    }
+}
+
+
+void streamReadRecord(int streamID, double *data, int *nmiss)
+{
+  check_parg(data);
+  check_parg(nmiss);
 
-	    fprintf(grprsm, " Number of ICE fields used:           %9d\n", isec1[45]);
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
 
-	    for (jloop = 1; jloop < isec1[45]; jloop++)
-	      {
-		iyear = isec1[44+(jloop*2)];
-		if ( iyear > 100 )
-		  {
-		    if ( iyear < 19000000 ) iyear = iyear + 19000000;
-		    fprintf(grprsm, " Date of ICE field%3d                 %9d\n", jloop,
-			   iyear);
-		    fprintf(grprsm, " Satellite number (ICE field%3d)      %9d\n", jloop,
-			   isec1[45+(jloop*2)]);
-		  }
-		else
-		  fprintf(grprsm, "Date of sst/ice field used           Not given\n");
-	      } 
-	  }
-	}
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 3 . Print Washington ensemble product information.
-    -----------------------------------------------------------------
-  */
-  /*
-    Washington EPS products (but not reformatted Washington EPS
-    products.
-  */
-  if ( (isec1[1] == 7 && isec1[23] == 1) && (! (ISEC1_SubCenterID == 98)) )
+  *nmiss = 0;
+
+  switch (streamptr->filetype)
     {
-      /*   CALL KWPRS1 (iSEC0,iSEC1)*/
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      grbReadRecord(streamptr, data, nmiss);
+      break;
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      srvReadRecord(streamptr, data, nmiss);
+      break;
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      extReadRecord(streamptr, data, nmiss);
+      break;
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      iegReadRecord(streamptr, data, nmiss);
+      break;
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      cdfReadRecord(streamptr, data, nmiss);
+      break;
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(streamptr->filetype));
+	break;
+      }
     }
-  /*
-    -----------------------------------------------------------------
-    Section 4 . Print local MPIM information.
-    -----------------------------------------------------------------
-  */
-  if (isec1[ 1] == 252 && isec1[36] == 1)
+}
+
+static void
+stream_write_record(int streamID, int memtype, const void *data, int nmiss)
+{
+  check_parg(data);
+
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+
+  switch (streamptr->filetype)
     {
-      fprintf(grprsm, " MPIM local usage identifier.         %9d\n", isec1[36]);
-      fprintf(grprsm, " Type of ensemble forecast            %9d\n", isec1[37]);
-      fprintf(grprsm, " Individual ensemble member           %9d\n", isec1[38]);
-      fprintf(grprsm, " Number of forecasts in ensemble      %9d\n", isec1[39]);
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      grb_write_record(streamptr, memtype, data, nmiss);
+      break;
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteRecord not implemented for memtype float!");
+      srvWriteRecord(streamptr, (const double *)data);
+      break;
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      if ( memtype == MEMTYPE_FLOAT ) Error("extWriteRecord not implemented for memtype float!");
+      extWriteRecord(streamptr, (const double *)data);
+      break;
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteRecord not implemented for memtype float!");
+      iegWriteRecord(streamptr, (const double *)data);
+      break;
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+	cdf_write_record(streamptr, memtype, data, nmiss);
+	break;
+      }
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(streamptr->filetype));
+	break;
+      }
     }
 }
 
-void printQuasi(int *isec2)
+/*
+ at Function  streamWriteRecord
+ at Title     Write a horizontal slice of a variable
+
+ at Prototype void streamWriteRecord(int streamID, const double *data, int nmiss)
+ at Parameter
+    @Item  streamID  Stream ID, from a previous call to @fref{streamOpenWrite}.
+    @Item  data      Pointer to a block of double precision floating point data values to be written.
+    @Item  nmiss     Number of missing values.
+
+ at Description
+The function streamWriteRecord writes the values of a horizontal slice (record) of a variable to an open dataset.
+The values are converted to the external data type of the variable, if necessary.
+ at EndFunction
+*/
+void streamWriteRecord(int streamID, const double *data, int nmiss)
 {
-  /*
+  stream_write_record(streamID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
+}
 
-    Print the qusai-regular information in the Grid Description
-    Section (Section 2) of decoded GRIB data.
+void streamWriteRecordF(int streamID, const float *data, int nmiss)
+{
+  stream_write_record(streamID, MEMTYPE_FLOAT, (const void *) data, nmiss);
+}
 
-    Input Parameters:
 
-       isec2 - Array of decoded integers from Section 2.
+void streamCopyRecord(int streamID2, int streamID1)
+{
+  stream_t *streamptr1 = stream_to_pointer(streamID1);
+  stream_t *streamptr2 = stream_to_pointer(streamID2);
 
-    Comments:
+  stream_check_ptr(__func__, streamptr1);
+  stream_check_ptr(__func__, streamptr2);
 
-       Only data representation types catered for are Gaussian
-       grid, latitude/longitude grid, Spherical Harmonics,
-       Polar stereographic and Space view perspective.
+  int filetype1 = streamptr1->filetype;
+  int filetype2 = streamptr2->filetype;
+  int filetype  = FILETYPE_UNDEF;
 
-    Converted from EMOS routine PTQUASI.
+  if ( filetype1 == filetype2 ) filetype = filetype2;
+  else
+    {
+      switch (filetype1)
+        {
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+          switch (filetype2)
+            {
+            case FILETYPE_NC:
+            case FILETYPE_NC2:
+            case FILETYPE_NC4:
+            case FILETYPE_NC4C:
+              Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
+              filetype = filetype2;
+              break;
+            }
+          break;
+        }
+    }
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  if ( filetype == FILETYPE_UNDEF )
+    Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
 
-  */
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBGRIB)
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
+      grbCopyRecord(streamptr2, streamptr1);
+      break;
+#endif
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:
+      srvCopyRecord(streamptr2, streamptr1);
+      break;
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:
+      extCopyRecord(streamptr2, streamptr1);
+      break;
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:
+      iegCopyRecord(streamptr2, streamptr1);
+      break;
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      cdfCopyRecord(streamptr2, streamptr1);
+      break;
+#endif
+    default:
+      {
+	Error("%s support not compiled in!", strfiletype(filetype));
+	break;
+      }
+    }
+}
 
-  char yout[64];
-  int nextlat, latcnt;
-  int j;
-  int ntos;
 
-  /*
-    -----------------------------------------------------------------
-    Section 1. Print quasi-grid data.
-    -----------------------------------------------------------------
-  */
-  /*
-    See if scanning is north->south or south->north
-  */
-  fprintf(grprsm, "  Number of points along a parallel varies.\n");
+void cdi_create_records(stream_t *streamptr, int tsID)
+{
+  unsigned nrecords, maxrecords;
+  record_t *records;
 
-  ntos = ( fmod((double) isec2[10], 128.) < 64 );
+  tsteps_t* sourceTstep = streamptr->tsteps;
+  tsteps_t* destTstep = sourceTstep + tsID;
 
-  if ( ntos )
-    fprintf(grprsm, "  Number of points.   Parallel. (North to South)\n");
-  else
-    fprintf(grprsm, "  Number of points.   Parallel. (South to North)\n");
+  if ( destTstep->records ) return;
 
-  /*  Display number of points for each latitude */
-  latcnt  = isec2[2];
-  nextlat = 0;
-  memset(yout, ' ', (size_t) 11);
+  int vlistID = streamptr->vlistID;
 
-  for ( j = 0; j < latcnt; j++ )
+  if ( tsID == 0 )
     {
-      nextlat = nextlat + 1;
-      sprintf(yout, "%4d", nextlat);
+      maxrecords = 0;
+      int nvars = streamptr->nvars;
+      for ( int varID = 0; varID < nvars; varID++)
+	maxrecords += (unsigned)streamptr->vars[varID].nlevs;
+    }
+  else
+    {
+      maxrecords = (unsigned)sourceTstep->recordSize;
+    }
 
-      /*       Finished?  */
-      if ( nextlat > latcnt ) break;
-      if ( nextlat == latcnt )
+  if ( tsID == 0 )
+    {
+      nrecords = maxrecords;
+    }
+  else if ( tsID == 1 )
+    {
+      nrecords = 0;
+      maxrecords = (unsigned)sourceTstep->recordSize;
+      for ( unsigned recID = 0; recID < maxrecords; recID++ )
 	{
-	  fprintf(grprsm, " %5d                %-12s\n", isec2[nextlat+21], yout);
-	  break;
+	  int varID = sourceTstep->records[recID].varID;
+	  nrecords += (varID == CDI_UNDEFID /* varID = CDI_UNDEFID for write mode !!! */
+                       || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
+          //    printf("varID nrecords %d %d %d \n", varID, nrecords, vlistInqVarTsteptype(vlistID, varID));
 	}
-      /*
-	Look for neighbouring latitudes with same number of points
-      */
-      unsigned nrepeat = 0;
+    }
+  else
+    {
+      nrecords = (unsigned)streamptr->tsteps[1].nallrecs;
+    }
+  //  printf("tsID, nrecords %d %d\n", tsID, nrecords);
 
-    LABEL110:
-      /*
-	If neighbouring latitudes have same number of points
-	increase the repeat count.
-      */
-      if ( isec2[nextlat+21+1] == isec2[nextlat+21] )
+  if ( maxrecords > 0 )
+    records = (record_t *) malloc(maxrecords * sizeof(record_t));
+  else
+    records = NULL;
+
+  destTstep->records    = records;
+  destTstep->recordSize = (int)maxrecords;
+  destTstep->nallrecs   = (int)nrecords;
+
+  if ( tsID == 0 )
+    {
+      for ( unsigned recID = 0; recID < maxrecords; recID++ )
+        recordInitEntry(&destTstep->records[recID]);
+    }
+  else
+    {
+      memcpy(destTstep->records, sourceTstep->records, (size_t)maxrecords*sizeof(record_t));
+
+      for ( unsigned recID = 0; recID < maxrecords; recID++ )
 	{
-          nrepeat = nrepeat + 1;
-          nextlat = nextlat + 1;
-	  if ( nextlat < latcnt ) goto LABEL110;
+          record_t* curRecord = &sourceTstep->records[recID];
+          destTstep->records[recID].used = curRecord->used;
+          if ( curRecord->used != CDI_UNDEFID && curRecord->varID != -1 ) /* curRecord->varID = -1 for write mode !!! */
+            {
+              if ( vlistInqVarTsteptype(vlistID, curRecord->varID) != TSTEP_CONSTANT )
+                {
+                  destTstep->records[recID].position = CDI_UNDEFID;
+                  destTstep->records[recID].size     = 0;
+                  destTstep->records[recID].used     = FALSE;
+                }
+            }
 	}
-      /*
-	Display neighbouring latitudes with same number of points as
-	'nn to mm'.
-      */
-      if ( nrepeat >= 1 )
-	{
-	  strncpy(yout+4, " to", 3);
-	  sprintf(yout+7, "%5d", nextlat);
-        }
-      fprintf(grprsm, " %5d                %-12s\n", isec2[nextlat+21], yout);
-      memset(yout, ' ', (size_t) 11);
     }
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+#define SINGLE_PRECISION  4
+#define DOUBLE_PRECISION  8
+
+#if defined (HAVE_LIBSERVICE)
+
+
+typedef struct {
+  int param;
+  int level;
+} SRVCOMPVAR;
+
+
+int srvInqDatatype(int prec)
+{
+  int datatype;
+
+  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+  else                            datatype = DATATYPE_FLT32;
+
+  return (datatype);
+}
+
+
+int srvDefDatatype(int datatype)
+{
+  int prec;
+
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    Error("CDI/SERVICE library does not support complex numbers!");
+
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
+    datatype = DATATYPE_FLT32;
+
+  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
+  else                              prec = SINGLE_PRECISION;
+
+  return (prec);
+}
+
+/* not used
+int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
+{
+  int status;
+  int fileID;
+  int icode, ilevel;
+  int zaxisID = -1;
+  int header[8];
+  int vlistID;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+
+  *varID   = -1;
+  *levelID = -1;
+
+  status = srvRead(fileID, srvp);
+  if ( status != 0 ) return (0);
+
+  srvInqHeader(srvp, header);
+
+  icode  = header[0];
+  ilevel = header[1];
+
+  *varID = vlistInqVarID(vlistID, icode);
+
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
+
+  zaxisID = vlistInqVarZaxis(vlistID, *varID);
+
+  *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
+
+  return (1);
+}
+*/
+
+void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int status;
+  int recID, vrecID, tsID;
+  off_t recpos;
+  int header[8];
+  int varID, gridID;
+  int i, size;
+  double missval;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+  tsID    = streamptr->curTsID;
+  vrecID  = streamptr->tsteps[tsID].curRecID;
+  recID   = streamptr->tsteps[tsID].recIDs[vrecID];
+  recpos  = streamptr->tsteps[tsID].records[recID].position;
+  varID   = streamptr->tsteps[tsID].records[recID].varID;
+
+  fileSetPos(fileID, recpos, SEEK_SET);
+
+  status = srvRead(fileID, srvp);
+  if ( status != 0 )
+    Error("Failed to read record from SRV file");
+
+  srvInqHeader(srvp, header);
+  srvInqDataDP(srvp, data);
+
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
+
+  streamptr->numvals += size;
+
+  *nmiss = 0;
+  for ( i = 0; i < size; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
+}
+
+
+void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+{
+  streamFCopyRecord(streamptr2, streamptr1, "SRV");
+}
+
+
+void srvDefRecord(stream_t *streamptr)
+{
+  int gridID;
+  int header[8];
+  int xsize, ysize;
+  int datatype;
+  int pdis, pcat, pnum;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+
+  gridID = streamptr->record->gridID;
+
+  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
+  header[0] = pnum;
+  header[1] = streamptr->record->level;
+  header[2] = streamptr->record->date;
+  header[3] = streamptr->record->time;
+
+  xsize = gridInqXsize(gridID);
+  ysize = gridInqYsize(gridID);
+  if ( xsize == 0 || ysize == 0 )
+    {
+      xsize = gridInqSize(gridID);
+      ysize = 1;
+    }
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
+  if ( gridInqSize(gridID) != xsize*ysize )
+    Error("Internal problem with gridsize!");
+
+  header[4] = xsize;
+  header[5] = ysize;
+  header[6] = 0;
+  header[7] = 0;
+
+  datatype = streamptr->record->prec;
+
+  srvp->dprec = srvDefDatatype(datatype);
+
+  srvDefHeader(srvp, header);
+}
 
-void gribPrintSec2DP(int *isec0, int *isec2, double *fsec2)
+
+void srvWriteRecord(stream_t *streamptr, const double *data)
 {
-  /*
+  int fileID = streamptr->fileID;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 
-    Print the information in the Grid Description
-    Section (Section 2) of decoded GRIB data.
+  srvDefDataDP(srvp, data);
 
-    Input Parameters:
+  srvWrite(fileID, srvp);
+}
 
-       isec0  - Array of decoded integers from Section 0
+static
+void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
+                    size_t recsize, off_t position, int prec)
+{
+  int vlistID = streamptr->vlistID;
+  int tsID    = streamptr->curTsID;
+  int recID   = recordNewEntry(streamptr, tsID);
+  record_t *record = &streamptr->tsteps[tsID].records[recID];
 
-       isec2  - Array of decoded integers from Section 2
+  record->size     = recsize;
+  record->position = position;
+  record->param    = param;
+  record->ilevel   = level;
 
-       fsec2  - Array of decoded floats from Section 2
+  grid_t grid;
+  memset(&grid, 0, sizeof(grid_t));
+  grid.type  = GRID_GENERIC;
+  grid.size  = xsize*ysize;
+  grid.xsize = xsize;
+  grid.ysize = ysize;
+  grid.xvals = NULL;
+  grid.yvals = NULL;
+  int gridID = varDefGrid(vlistID, &grid, 0);
+  /*
+  if ( level == 0 ) leveltype = ZAXIS_SURFACE;
+  else              leveltype = ZAXIS_GENERIC;
+  */
+  int leveltype = ZAXIS_GENERIC;
 
-    Comments:
+  int datatype = srvInqDatatype(prec);
 
-       Only data representation types catered for are Gaussian
-       grid, latitude/longitude grid, Spherical Harmonics,
-       Polar stereographic and Space view perspective.
+  int levelID = 0;
+  int varID;
 
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
+	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
 
-    Converted from EMOS routine GRPRS2.
+  xassert(varID <= SHRT_MAX && levelID <= SHRT_MAX);
+  record->varID   = (short)varID;
+  record->levelID = (short)levelID;
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  streamptr->tsteps[tsID].nallrecs++;
+  streamptr->nrecs++;
 
-  */
+  if ( CDI_Debug )
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
+}
 
-  int i, ibit, iedit, ierr, iout, iresol;
+static
+void srvScanTimestep1(stream_t *streamptr)
+{
+  int header[8];
+  int prec = 0;
+  int status;
+  int fileID;
+  int rxsize = 0, rysize = 0;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  DateTime datetime, datetime0;
+  int tsID;
+  int varID;
+  off_t recpos;
+  int nrecords, nrecs, recID;
+  int taxisID = -1;
+  taxis_t *taxis;
+  int vlistID;
+  SRVCOMPVAR compVar, compVar0;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 
-  grsdef();
-  /*
-    -----------------------------------------------------------------
-    Section 1 . Print GRIB Edition number.
-    -----------------------------------------------------------------
-  */
-  iedit = isec0[1];
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " Section 2 - Grid Description Section.\n");
-  fprintf(grprsm, " -------------------------------------\n");
-  /*
-    -----------------------------------------------------------------
-    Section 2 . Print spherical harmonic data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] == 50 || isec2[0] == 60 || 
-       isec2[0] == 70 || isec2[0] == 80 )
-    {
-      fprintf(grprsm, " Data represent type = spectral     (Table 6) %9d\n", isec2[0]);
-      fprintf(grprsm, " J - Pentagonal resolution parameter.         %9d\n", isec2[1]);
-      fprintf(grprsm, " K - Pentagonal resolution parameter.         %9d\n", isec2[2]);
-      fprintf(grprsm, " M - Pentagonal resolution parameter.         %9d\n", isec2[3]);
-      fprintf(grprsm, " Representation type (Table 9)                %9d\n", isec2[4]);
-      fprintf(grprsm, " Representation mode (Table 10).              %9d\n", isec2[5]);
-      for (i = 7; i <= 11; i++)
-        fprintf(grprsm, " Not used.                                    %9d\n", isec2[i-1]);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      goto LABEL800;
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 3 . Print Gaussian grid data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] ==  4 || isec2[0] == 14 || 
-       isec2[0] == 24 || isec2[0] == 34 )
+  streamptr->curTsID = 0;
+
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
+
+  if ( tsID != 0 )
+    Error("Internal problem! tstepsNewEntry returns %d", tsID);
+
+  fileID = streamptr->fileID;
+
+  nrecs = 0;
+  while ( TRUE )
     {
-      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
-      fprintf(grprsm, " Data represent type = gaussian     (Table 6) %9d\n", isec2[0]);
-      /*
-	Quasi-regular grids introduced in Edition 1.
-      */
-      if ( isec2[16] == 0 || iedit < 1 )
-	fprintf(grprsm, " Number of points along a parallel.           %9d\n", isec2[1]);
-      else
-      	printQuasi(isec2);
+      recpos = fileGetPos(fileID);
+      status = srvRead(fileID, srvp);
+      if ( status != 0 )
+	{
+	  streamptr->ntsteps = 1;
+	  break;
+	}
+      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-      fprintf(grprsm, " Number of points along a meridian.           %9d\n", isec2[2]);
-      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
-      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
+      srvInqHeader(srvp, header);
 
-      ibit = 8;
-      iresol = isec2[5] + isec2[17] + isec2[18];
-      prtbin(iresol, ibit, &iout, &ierr);
+      prec   = srvp->dprec;
+      rcode  = header[0];
+      rlevel = header[1];
+      vdate  = header[2];
+      vtime  = header[3];
+      rxsize = header[4];
+      rysize = header[5];
 
-      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
-      fprintf(grprsm, " Latitude of last grid point.                 %9d\n", isec2[6]);
-      fprintf(grprsm, " Longitude of last grid point.                %9d\n", isec2[7]);
-      /*
-	Print increment if given.
-      */
-      if ( isec2[5] == 128 )
-	fprintf(grprsm, " i direction (East-West) increment.           %9d\n", isec2[8]);
+      param = cdiEncodeParam(rcode, 255, 255);
+
+      if ( nrecs == 0 )
+	{
+	  datetime0.date = vdate;
+	  datetime0.time = vtime;
+	}
       else
-	fprintf(grprsm, " i direction (East-West) increment            Not given\n");
+	{
+	  datetime.date = vdate;
+	  datetime.time = vtime;
+	  compVar.param = param;
+          compVar.level = rlevel;
+	  for ( recID = 0; recID < nrecs; recID++ )
+	    {
+	      compVar0.param = streamptr->tsteps[0].records[recID].param;
+	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
 
-      fprintf(grprsm, " Number of parallels between pole and equator.%9d\n", isec2[9]);
+	      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 ) break;
+	    }
+	  if ( recID < nrecs ) break;
+	  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) )
+	    Warning("Inconsistent verification time for code %d level %d", rcode, rlevel);
+	}
 
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
+      nrecs++;
 
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      goto LABEL800;
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
+
+      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
     }
-  /*
-    -----------------------------------------------------------------
-    Section 4 . Print Latitude / longitude grid data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] ==  0 || isec2[0] == 10 || 
-       isec2[0] == 20 || isec2[0] == 30 )
-    {
-      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
-      fprintf(grprsm, " Data represent type = lat/long     (Table 6) %9d\n", isec2[0]);
-      /*
-	Quasi-regular lat/long grids also possible.
-      */
-      if ( isec2[16] == 0 )
-	fprintf(grprsm, " Number of points along a parallel.           %9d\n", isec2[1]);
-      else
-        printQuasi(isec2);
 
-      fprintf(grprsm, " Number of points along a meridian.           %9d\n", isec2[2]);
-      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
-      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
+  streamptr->rtsteps = 1;
 
-      ibit = 8;
-      iresol = isec2[5] + isec2[17] + isec2[18];
-      prtbin(iresol, ibit, &iout, &ierr);
+  cdi_generate_vars(streamptr);
 
-      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
-      fprintf(grprsm, " Latitude of last grid point.                 %9d\n", isec2[6]);
-      fprintf(grprsm, " Longitude of last grid point.                %9d\n", isec2[7]);
-      /*
-	Print increment if given.
-      */
-      if ( isec2[8] < 0 )
-	fprintf(grprsm, " i direction (East-West) increment            Not given\n");
-      else
-	fprintf(grprsm, " i direction (East-West) increment.           %9d\n", isec2[8]);
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  taxis->type  = TAXIS_ABSOLUTE;
+  taxis->vdate = (int)datetime0.date;
+  taxis->vtime = (int)datetime0.time;
 
-      if ( isec2[9] < 0 )
-	fprintf(grprsm, " j direction (North-South) increment          Not given\n");
-      else
-	fprintf(grprsm, " j direction (North-South) increment.         %9d\n", isec2[9]);
-    
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
+  vlistID = streamptr->vlistID;
+  vlistDefTaxis(vlistID, taxisID);
 
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      goto LABEL800;
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 5 . Print polar stereographic data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] == 5 )
-    {
-      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
-      fprintf(grprsm, " Data represent type = polar stereo (Table 6) %9d\n", isec2[0]);
-      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
-      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
-      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
-      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
-      ibit = 8;
-      iresol = isec2[17] + isec2[18];
-      prtbin(iresol, ibit, &iout, &ierr);
-      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
-      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
-      fprintf(grprsm, " X direction increment.                       %9d\n", isec2[8]);
-      fprintf(grprsm, " Y direction increment.                       %9d\n", isec2[9]);
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      fprintf(grprsm, " Projection centre flag.                      %9d\n", isec2[12]);
-      goto LABEL800;
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 6 . Print Lambert conformal data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] == 3 )
-    {
-      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
-      fprintf(grprsm, " Data represent type = Lambert      (Table 6) %9d\n", isec2[0]);
-      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
-      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
-      fprintf(grprsm, " Latitude of first grid point.                %9d\n", isec2[3]);
-      fprintf(grprsm, " Longitude of first grid point.               %9d\n", isec2[4]);
-      ibit = 8;
-      iresol = isec2[17] + isec2[18] + isec2[5];
-      prtbin(iresol, ibit, &iout, &ierr);
-      fprintf(grprsm, " Resolution and components flag.               %8.8d\n", iout);
-      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
-      fprintf(grprsm, " X direction increment.                       %9d\n", isec2[8]);
-      fprintf(grprsm, " Y direction increment.                       %9d\n", isec2[9]);
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      fprintf(grprsm, " Projection centre flag.                      %9d\n", isec2[12]);
-      fprintf(grprsm, " Latitude intersection 1 - Latin 1 -.         %9d\n", isec2[13]);
-      fprintf(grprsm, " Latitude intersection 2 - Latin 2 -.         %9d\n", isec2[14]);
-      fprintf(grprsm, " Latitude of Southern Pole.                   %9d\n", isec2[19]);
-      fprintf(grprsm, " Longitude of Southern Pole.                  %9d\n", isec2[20]);
-      goto LABEL800;
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 7 . Print space view perspective or orthographic data.
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] == 90 )
+  vlist_check_contents(vlistID);
+
+  nrecords = streamptr->tsteps[0].nallrecs;
+  if ( nrecords < streamptr->tsteps[0].recordSize )
     {
-      fprintf(grprsm, " (Southern latitudes and Western longitudes are negative.)\n");
-      fprintf(grprsm, " Data represent type = space/ortho  (Table 6) %9d\n", isec2[0]);
-      fprintf(grprsm, " Number of points along X axis.               %9d\n", isec2[1]);
-      fprintf(grprsm, " Number of points along Y axis.               %9d\n", isec2[2]);
-      fprintf(grprsm, " Latitude of sub-satellite point.             %9d\n", isec2[3]);
-      fprintf(grprsm, " Longitude of sub-satellite point.            %9d\n", isec2[4]);
-      iresol = isec2[17] + isec2[18];
-      fprintf(grprsm, " Diameter of the earth in x direction.        %9d\n", isec2[6]);
-      fprintf(grprsm, " Y coordinate of sub-satellite point.         %9d\n", isec2[9]);
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      fprintf(grprsm, " Orientation of the grid.                     %9d\n", isec2[6]);
-      fprintf(grprsm, " Altitude of the camera.                      %9d\n", isec2[13]);
-      fprintf(grprsm, " Y coordinate of origin of sector image.      %9d\n", isec2[14]);
-      fprintf(grprsm, " X coordinate of origin of sector image.      %9d\n", isec2[15]);
-      goto LABEL800;
+      streamptr->tsteps[0].recordSize = nrecords;
+      streamptr->tsteps[0].records =
+	(record_t *)xrealloc(streamptr->tsteps[0].records,
+                             (size_t)nrecords * sizeof(record_t));
     }
-  /*
-    -----------------------------------------------------------------
-    Section 7.5 . Print ocean data
-    -----------------------------------------------------------------
-  */
-  /*
-  if ( isec2[0] == 192 && ISEC1_CenterID == 98 )
-    {
-      fprintf(grprsm, " Data represent type = ECMWF ocean  (Table 6) %9d\n", isec2[0]);
-      if ( isec2[1] ==  32767 )
-	fprintf(grprsm, " Number of points along the first axis.       Not used\n");
-      else
-	fprintf(grprsm, " Number of points along the first axis.       %9d\n", isec2[1]);
 
-      if ( isec2[2] ==  32767 )
-	fprintf(grprsm, " Number of points along the second axis.      Not used\n");
-      else
-	fprintf(grprsm, " Number of points along the second axis.      %9d\n", isec2[2]);
+  streamptr->tsteps[0].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
+  streamptr->tsteps[0].nrecs = nrecords;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[0].recIDs[recID] = recID;
 
-      ibit = 8;
-      prtbin(isec2[10], ibit, &iout, &ierr);
-      fprintf(grprsm, " Scanning mode flags (Code Table 8)            %8.8d\n", iout);
-      goto LABEL800;
-    }
-    */
-  /*
-    -----------------------------------------------------------------
-    Section 7.6 . Print triangular data
-    -----------------------------------------------------------------
-  */
-  if ( isec2[0] == 192 /* && ISEC1_CenterID == 78 */ )
+  if ( streamptr->ntsteps == -1 )
     {
-      fprintf(grprsm, " Data represent type = triangular   (Table 6) %9d\n", isec2[0]);
-      fprintf(grprsm, " Number of factor 2 in factorisation of Ni.   %9d\n", isec2[1]);
-      fprintf(grprsm, " Number of factor 3 in factorisation of Ni.   %9d\n", isec2[2]);
-      fprintf(grprsm, " Number of diamonds (Nd).                     %9d\n", isec2[3]);
-      fprintf(grprsm, " Number of triangular subdivisions of the\n");
-      fprintf(grprsm, "           icosahedron (Ni).                  %9d\n", isec2[4]);
-      fprintf(grprsm, " Flag for orientation of diamonds (Table A).  %9d\n", isec2[5]);
-      fprintf(grprsm, " Latitude of pole point.                      %9d\n", isec2[6]);
-      fprintf(grprsm, " Longitude of pole point.                     %9d\n", isec2[7]);
-      fprintf(grprsm, " Longitude of the first diamond.              %9d\n", isec2[8]);
-      fprintf(grprsm, " Flag for storage sequence (Table B).         %9d\n", isec2[9]);
-      fprintf(grprsm, " Number of vertical coordinate parameters.    %9d\n", isec2[11]);
-      goto LABEL800;
-    }
-  /*
-    -----------------------------------------------------------------
-    Drop through to here => representation type not catered for.
-    -----------------------------------------------------------------
-  */
-  fprintf(grprsm, "GRPRS2 :Data representation type not catered for -%d\n", isec2[0]);
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-  goto LABEL900;
-  /*
-    -----------------------------------------------------------------
-    Section 8 . Print vertical coordinate parameters,
-                rotated grid information,
-                stretched grid information, if any.
-    -----------------------------------------------------------------
-  */
- LABEL800:;
-  /*
-    Vertical coordinate parameters ...
-  */
-  if ( isec2[11] != 0 )
-    {
-      fprintf(grprsm, " \n");
-      fprintf(grprsm, " Vertical Coordinate Parameters.\n");
-      fprintf(grprsm, " -------------------------------\n");
-      for ( i = 10; i < isec2[11]+10; i++ )
-	fprintf(grprsm, "    %20.12f\n", fsec2[i]);
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
     }
-  /*
-    Rotated and stretched grids introduced in Edition 1.
-  */
-  if ( iedit < 1 ) goto LABEL900;
-  /*
-    Rotated grid information ...
-  */
-  if ( isec2[0] == 10 || isec2[0] == 30 || 
-       isec2[0] == 14 || isec2[0] == 34 || 
-       isec2[0] == 60 || isec2[0] == 80 || 
-       isec2[0] == 30 )
+
+  if ( streamptr->ntsteps == 1 )
     {
-      fprintf(grprsm, " \n");
-      fprintf(grprsm, " Latitude of southern pole of rotation.       %9d\n", isec2[12]);
-      fprintf(grprsm, " Longitude of southern pole of rotation.      %9d\n", isec2[13]);
-      fprintf(grprsm, " Angle of rotation.                     %20.10f\n", fsec2[0]);
+      if ( taxis->vdate == 0 && taxis->vtime == 0 )
+	{
+	  streamptr->ntsteps = 0;
+	  for ( varID = 0; varID < streamptr->nvars; varID++ )
+	    {
+	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	    }
+	}
     }
-  /*
-    Stretched grid information ...
-  */
-  if ( isec2[0] == 20 || isec2[0] == 30 || 
-       isec2[0] == 24 || isec2[0] == 34 || 
-       isec2[0] == 70 || isec2[0] == 80 )
+}
+
+static
+int srvScanTimestep2(stream_t *streamptr)
+{
+  int header[8];
+  int status;
+  int fileID;
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  int tsID;
+  int varID;
+  off_t recpos = 0;
+  int nrecords, nrecs, recID, rindex;
+  int nextstep;
+  taxis_t *taxis;
+  int vlistID;
+  SRVCOMPVAR compVar, compVar0;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+
+  streamptr->curTsID = 1;
+
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+
+  tsID = streamptr->rtsteps;
+  if ( tsID != 1 )
+    Error("Internal problem! unexpected timestep %d", tsID+1);
+
+  taxis = &streamptr->tsteps[tsID].taxis;
+
+  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+
+  cdi_create_records(streamptr, tsID);
+
+  nrecords = streamptr->tsteps[0].nallrecs;
+  streamptr->tsteps[1].recIDs = (int *)xmalloc((size_t)nrecords * sizeof (int));
+  streamptr->tsteps[1].nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    streamptr->tsteps[1].recIDs[recID] = -1;
+
+  for ( recID = 0; recID < nrecords; recID++ )
     {
-      fprintf(grprsm, " \n");
-      fprintf(grprsm, " Latitude of pole of stretching.              %9d\n", isec2[14]);
-      fprintf(grprsm, " Longitude of pole of stretching.             %9d\n", isec2[15]);
-      fprintf(grprsm, " Stretching factor.                     %20.10f\n", fsec2[1]);
+      varID = streamptr->tsteps[0].records[recID].varID;
+      streamptr->tsteps[tsID].records[recID].position =
+	streamptr->tsteps[0].records[recID].position;
+      streamptr->tsteps[tsID].records[recID].size     =
+	streamptr->tsteps[0].records[recID].size;
     }
 
- LABEL900:;
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
+    {
+      recpos = fileGetPos(fileID);
+      status = srvRead(fileID, srvp);
+      if ( status != 0 )
+	{
+	  streamptr->ntsteps = 2;
+	  break;
+	}
+      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-  return;
-}
+      srvInqHeader(srvp, header);
 
-void gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2sp)
-{
-  int inum;
-  int j;
-  double *fsec2;
+      rcode  = header[0];
+      rlevel = header[1];
+      vdate  = header[2];
+      vtime  = header[3];
 
-  inum = 10 + isec2[11];
+      param = cdiEncodeParam(rcode, 255, 255);
 
-  fsec2 = (double*) malloc(inum*sizeof(double));
-  if ( fsec2 == NULL ) SysError("No Memory!");
+      if ( rindex == 0 )
+	{
+	  taxis->type  = TAXIS_ABSOLUTE;
+	  taxis->vdate = vdate;
+	  taxis->vtime = vtime;
+	}
 
-  for ( j = 0; j < inum; j++ )
-     fsec2[j] = fsec2sp[j];
-  
-  gribPrintSec2DP(isec0, isec2, fsec2);
+      compVar.param = param;
+      compVar.level = rlevel;
+      nextstep = FALSE;
+      for ( recID = 0; recID < nrecords; recID++ )
+	{
+	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-  free(fsec2);
-}
+	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 )
+	    {
+	      if ( streamptr->tsteps[tsID].records[recID].used )
+		{
+		  nextstep = TRUE;
+		}
+	      else
+		{
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
+		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
+		}
+	      break;
+	    }
+	}
+      if ( recID == nrecords )
+	{
+	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
+	  return (CDI_EUFSTRUCT);
+	}
 
-void gribPrintSec3DP(int *isec0, int *isec3, double *fsec3)
-{
-  /*
+      if ( nextstep ) break;
 
-    Print the information in the Bit-Map Section
-    (Section 3) of decoded GRIB data.
+      if ( CDI_Debug )
+	Message("%4d%8d%4d%8d%8d%6d", rindex+1, (int)recpos, rcode, rlevel, vdate, vtime);
 
-    Input Parameters:
+      streamptr->tsteps[tsID].records[recID].size = recsize;
 
-       isec0  - Array of decoded integers from Section 0
+      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
+      compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-       isec3  - Array of decoded integers from Section 3
+      if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
+	{
+	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		  tsID, recID,
+		  streamptr->tsteps[tsID].records[recID].param, param,
+		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	  return (CDI_EUFSTRUCT);
+	}
 
-       fsec3  - Array of decoded floats from Section 3
+      streamptr->tsteps[1].records[recID].position = recpos;
+    }
 
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
+    {
+      if ( ! streamptr->tsteps[tsID].records[recID].used )
+	{
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
+          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	}
+      else
+	{
+	  nrecs++;
+	}
+    }
+  streamptr->tsteps[tsID].nrecs = nrecs;
 
-    Converted from EMOS routine GRPRS3.
+  streamptr->rtsteps = 2;
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  if ( streamptr->ntsteps == -1 )
+    {
+      tsID = tstepsNewEntry(streamptr);
+      if ( tsID != streamptr->rtsteps )
+	Error("Internal error. tsID = %d", tsID);
 
-  */
+      streamptr->tsteps[tsID-1].next   = TRUE;
+      streamptr->tsteps[tsID].position = recpos;
+    }
 
-  UNUSED(isec0);
+  return (0);
+}
 
-  grsdef();
 
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " Section 3 - Bit-map Section.\n");
-  fprintf(grprsm, " -------------------------------------\n");
+int srvInqContents(stream_t *streamptr)
+{
+  int fileID;
+  int status = 0;
 
-  if ( isec3[0] != 0 )
-    fprintf(grprsm, " Predetermined bit-map number.                %9d\n", isec3[0]);
-  else
-    fprintf(grprsm, " No predetermined bit-map.\n");
+  fileID = streamptr->fileID;
 
-  fprintf(grprsm, " Missing data value for integer data.    %14d\n", isec3[1]);
+  streamptr->curTsID = 0;
 
-  fprintf(grprsm, " Missing data value for real data. %20.6g\n", fsec3[1]);
-}
+  srvScanTimestep1(streamptr);
 
-void gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3sp)
-{
-  double fsec3[2];
+  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
 
-  fsec3[0] = fsec3sp[0];
-  fsec3[1] = fsec3sp[1];
-  
-  gribPrintSec3DP(isec0, isec3, fsec3);
+  fileSetPos(fileID, 0, SEEK_SET);
+
+  return (status);
 }
 
-void gribPrintSec4DP(int *isec0, int *isec4, double *fsec4)
+static
+long srvScanTimestep(stream_t *streamptr)
 {
+  int header[8];
+  int status;
+  int fileID;
+  /* int rxsize = 0, rysize = 0; */
+  int param = 0;
+  int rcode = 0, rlevel = 0, vdate = 0, vtime = 0;
+  off_t recpos = 0;
+  int recID;
+  int rindex, nrecs = 0;
+  SRVCOMPVAR compVar, compVar0;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
   /*
+  if ( CDI_Debug )
+    {
+      Message("streamID = %d", streamptr->self);
+      Message("cts = %d", streamptr->curTsID);
+      Message("rts = %d", streamptr->rtsteps);
+      Message("nts = %d", streamptr->ntsteps);
+    }
+  */
 
-    Print the information in the Binary Data Section
-    (Section 4) of decoded GRIB data.
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-    Input Parameters:
+  if ( streamptr->tsteps[tsID].recordSize == 0 )
+    {
+      cdi_create_records(streamptr, tsID);
 
-       isec0  - Array of decoded integers from Section 0
+      nrecs = streamptr->tsteps[1].nrecs;
 
-       isec4  - Array of decoded integers from Section 4
+      streamptr->tsteps[tsID].nrecs = nrecs;
+      streamptr->tsteps[tsID].recIDs = (int *)xmalloc((size_t)nrecs * sizeof (int));
+      for ( recID = 0; recID < nrecs; recID++ )
+	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-       fsec4  - Array of decoded floats from Section 4
+      fileID = streamptr->fileID;
 
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-    Converted from EMOS routine GRPRS4.
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
+	{
+	  recpos = fileGetPos(fileID);
+	  status = srvRead(fileID, srvp);
+	  if ( status != 0 )
+	    {
+	      streamptr->ntsteps = streamptr->rtsteps + 1;
+	      break;
+	    }
+	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+	  srvInqHeader(srvp, header);
 
-  */
-  int inum;
-  int j;
+	  rcode  = header[0];
+	  rlevel = header[1];
+	  vdate  = header[2];
+	  vtime  = header[3];
+          /* rxsize = header[4]; */
+          /* rysize = header[5]; */
 
-  UNUSED(isec0);
+	  param = cdiEncodeParam(rcode, 255, 255);
 
-  grsdef();
+	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
+	  if ( rindex == nrecs ) continue;
+	  recID = streamptr->tsteps[tsID].recIDs[rindex];
 
-  /*
-    -----------------------------------------------------------------
-    Section 1 . Print integer information from isec4.
-    -----------------------------------------------------------------
-  */
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " Section 4 - Binary Data  Section.\n");
-  fprintf(grprsm, " -------------------------------------\n");
+	  if ( rindex == 0 )
+	    {
+	      taxis->type  = TAXIS_ABSOLUTE;
+	      taxis->vdate = vdate;
+	      taxis->vtime = vtime;
+	    }
 
-  fprintf(grprsm, " Number of data values coded/decoded.         %9d\n", isec4[0]);
-  fprintf(grprsm, " Number of bits per data value.               %9d\n", isec4[1]);
-  fprintf(grprsm, " Type of data       (0=grid pt, 128=spectral).%9d\n", isec4[2]);
-  fprintf(grprsm, " Type of packing    (0=simple, 64=complex).   %9d\n", isec4[3]);
-  fprintf(grprsm, " Type of data       (0=float, 32=integer).    %9d\n", isec4[4]);
-  fprintf(grprsm, " Additional flags   (0=none, 16=present).     %9d\n", isec4[5]);
-  fprintf(grprsm, " Reserved.                                    %9d\n", isec4[6]);
-  fprintf(grprsm, " Number of values   (0=single, 64=matrix).    %9d\n", isec4[7]);
-  fprintf(grprsm, " Secondary bit-maps (0=none, 32=present).     %9d\n", isec4[8]);
-  fprintf(grprsm, " Values width       (0=constant, 16=variable).%9d\n", isec4[9]);
-  /*
-    If complex packing ..
-  */
-  if ( isec4[3] == 64 )
-    {
-      if ( isec4[2] == 128 )
-	{
-	  fprintf(grprsm, " Byte offset of start of packed data (N).     %9d\n", isec4[15]);
-	  fprintf(grprsm, " Power (P * 1000).                            %9d\n", isec4[16]);
-	  fprintf(grprsm, " Pentagonal resolution parameter J for subset.%9d\n", isec4[17]);
-	  fprintf(grprsm, " Pentagonal resolution parameter K for subset.%9d\n", isec4[18]);
-	  fprintf(grprsm, " Pentagonal resolution parameter M for subset.%9d\n", isec4[19]);
+	  compVar.param  = param;
+          compVar.level  = rlevel;
+	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
+	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
+
+	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) != 0 )
+	    {
+	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
+		      tsID, recID,
+		      streamptr->tsteps[tsID].records[recID].param, param,
+		      streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
+	      Error("Invalid, unsupported or inconsistent record structure!");
+	    }
+
+	  streamptr->tsteps[tsID].records[recID].position = recpos;
+	  streamptr->tsteps[tsID].records[recID].size = recsize;
+
+	  if ( CDI_Debug )
+	    Message("%4d%8d%4d%8d%8d%6d", rindex, (int)recpos, rcode, rlevel, vdate, vtime);
 	}
-      else
-	{
-	  fprintf(grprsm, " Bits number of 2nd order values    (none=>0).%9d\n", isec4[10]);
-	  fprintf(grprsm, " General extend. 2-order packing (0=no,8=yes).%9d\n", isec4[11]);
-	  fprintf(grprsm, " Boustrophedonic ordering        (0=no,4=yes).%9d\n", isec4[12]);
-	  fprintf(grprsm, " Spatial differencing order          (0=none).%9d\n", isec4[13]+isec4[14]);
-        }
-    }
-  /*
-    Number of non-missing values
-  */
-  if ( isec4[20] != 0 )
-    fprintf(grprsm, " Number of non-missing values                 %9d\n", isec4[20]);
-  /*
-    Information on matrix of values , if present.
-  */
-  if ( isec4[7] == 64 )
-    {
-      fprintf(grprsm, " First dimension (rows) of each matrix.       %9d\n", isec4[49]);
-      fprintf(grprsm, " Second dimension (columns) of each matrix.   %9d\n", isec4[50]);
-      fprintf(grprsm, " First dimension coordinate values definition.%9d\n", isec4[51]);
-      fprintf(grprsm, " (Code Table 12)\n");
-      fprintf(grprsm, " NC1 - Number of coefficients for 1st dimension.%7d\n", isec4[52]);
-      fprintf(grprsm, " Second dimension coordinate values definition.%8d\n", isec4[53]);
-      fprintf(grprsm, " (Code Table 12)\n");
-      fprintf(grprsm, " NC2 - Number of coefficients for 2nd dimension.%7d\n", isec4[54]);
-      fprintf(grprsm, " 1st dimension physical signifance (Table 13). %8d\n", isec4[55]);
-      fprintf(grprsm, " 2nd dimension physical signifance (Table 13).%8d\n", isec4[56]);
-    }
-  /*
-    -----------------------------------------------------------------
-    Section 2. Print values from fsec4.
-    -----------------------------------------------------------------
-  */
 
-  inum = isec4[0];
-  if ( inum <  0 ) inum = - inum;
-  if ( inum > 20 ) inum = 20;
-  /*
-    Print first inum values.
-  */
-  fprintf(grprsm, " \n");
-  fprintf(grprsm, " First %4d data values.\n", inum);
+      streamptr->rtsteps++;
 
-  if ( isec4[4] == 0 )
-    {
-      /*
-	Print real values ...
-      */
-      for ( j = 0; j < inum; j++ )
+      if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  if ( fabs(fsec4[j]) > 0 )
-	    {
-	      if ( fabs(fsec4[j]) >= 0.1 && fabs(fsec4[j]) <= 1.e8 )
-		fprintf(grprsm, " %#16.8G    \n", fsec4[j]);
-	      else
-		fprintf(grprsm, " %#20.8E\n", fsec4[j]);
-	    }
-	  else
-	    fprintf(grprsm, " %#16.0f    \n", fabs(fsec4[j]));
+	  tsID = tstepsNewEntry(streamptr);
+	  if ( tsID != streamptr->rtsteps )
+	    Error("Internal error. tsID = %d", tsID);
+
+	  streamptr->tsteps[tsID-1].next   = 1;
+	  streamptr->tsteps[tsID].position = recpos;
 	}
+
+      fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
+      streamptr->tsteps[tsID].position = recpos;
     }
-  else
+
+  if ( nrecs > 0 && nrecs < streamptr->tsteps[tsID].nrecs )
     {
-      /*
-	Print integer values ...
-      */
-      fprintf(grprsm, " Print of integer values not supported\n");
-      /*
-        CALL SETPAR(IBIT,IDUM,IDUM)
-        DO 212 J=1,INUM
-           INSPT = 0
-           CALL INXBIT(IVALUE,1,INSPT,FSEC4(J),1,IBIT,IBIT,'C',IRET)
-           WRITE (*,9033) IVALUE
- 9033 FORMAT(' ',I15)
-  212   CONTINUE
-      ENDIF
-      */
+      Warning("Incomplete timestep. Stop scanning at timestep %d.", tsID);
+      streamptr->ntsteps = tsID;
     }
-}
-
-void gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4sp)
-{
-  int inum;
-  int j;
-  double fsec4[20];
-
-  inum = isec4[0];
-  if ( inum <  0 ) inum = -inum;
-  if ( inum > 20 ) inum = 20;
 
-  for ( j = 0; j < inum; j++ ) fsec4[j] = fsec4sp[j];
-  
-  gribPrintSec4DP(isec0, isec4, fsec4);
+  return (streamptr->ntsteps);
 }
 
-void gribPrintSec4Wave(int *isec4)
+
+int srvInqTimestep(stream_t *streamptr, int tsID)
 {
-  /*
+  long ntsteps;
+  int nrecs;
 
-    Print the wave coordinate information in the Binary Data
-    Section (Section 4) of decoded GRIB data.
+  if ( tsID == 0 && streamptr->rtsteps == 0 )
+    Error("Call to cdiInqContents missing!");
 
-    Input Parameters:
+  if ( CDI_Debug )
+    Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-       isec4 - Array of decoded integers from Section 4
+  ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
+    ntsteps = srvScanTimestep(streamptr);
 
-    Comments:
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
+    {
+      streamptr->curTsID = tsID;
+      nrecs = streamptr->tsteps[tsID].nrecs;
+    }
 
-       Wave coordinate information held in isec4 are 32-bit floats,
-       hence the PTEMP and NTEMP used for printing are 4-byte variables.
+  return (nrecs);
+}
 
 
-    Converted from EMOS routine GRPRS4W.
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[8];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  */
-  int    jloop;
-  int    ntemp[100];
-  float *ptemp;
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-  grsdef();
+  currentfilepos = fileGetPos(fileID);
 
-  /*
-    -----------------------------------------------------------------
-    Section 1 . Print integer information from isec4.
-    -----------------------------------------------------------------
-  */
-  fprintf(grprsm, " Coefficients defining first dimension coordinates:\n");
-  for ( jloop = 0; jloop < isec4[52]; jloop++ )
-    {
-      ntemp[jloop] = isec4[59 + jloop];
-      ptemp = (float *) &ntemp[jloop];
-      fprintf(grprsm, "%20.10f\n", *ptemp);
-    }
-  fprintf(grprsm, " Coefficients defining second dimension coordinates:\n");
-  for ( jloop = 0; jloop < isec4[54]; jloop++ )
+  for (levID = 0; levID < nlevs; levID++)
     {
-      ntemp[jloop] = isec4[59 + isec4[52] + jloop];
-      ptemp = (float *) &ntemp[jloop];
-      fprintf(grprsm, "%20.10f\n", *ptemp);
+      recID = streamptr->vars[varID].level[levID];
+      recpos = streamptr->tsteps[tsid].records[recID].position;
+      fileSetPos(fileID, recpos, SEEK_SET);
+      if (srvRead(fileID, srvp) < 0)
+        abort();
+      srvInqHeader(srvp, header);
+      srvInqDataDP(srvp, &data[levID*gridsize]);
     }
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
+
+  *nmiss = 0;
+  for ( i = 0; i < nlevs*gridsize; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
 }
-#if defined (HAVE_CONFIG_H)
-#endif
 
-#include <string.h>
-#include <ctype.h>
 
+void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[8];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
+
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  nlevs    = streamptr->vars[varID].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
 
-int gribOpen(const char *filename, const char *mode)
-{
-  int fileID;
+  currentfilepos = fileGetPos(fileID);
 
-  fileID = fileOpen(filename, mode);
+  recID = streamptr->vars[varID].level[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
+  fileSetPos(fileID, recpos, SEEK_SET);
+  if (srvRead(fileID, srvp) < 0)
+    abort();
+  srvInqHeader(srvp, header);
+  srvInqDataDP(srvp, data);
 
-#if defined (__sun)
-  if ( fileID != FILE_UNDEFID && tolower(*mode) == 'r' )
-    {
-      fileSetBufferType(fileID, FILE_BUFTYPE_MMAP);
-    }
-#endif
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
 
-  return (fileID);  
+  *nmiss = 0;
+  for ( i = 0; i < gridsize; i++ )
+    if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
+      {
+	data[i] = missval;
+	(*nmiss)++;
+      }
 }
 
 
-void gribClose(int fileID)
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
-  fileClose(fileID);
-}
+  int fileID;
+  int levID, nlevs, gridID, gridsize;
+  int zaxisID;
+  double level;
+  int header[8];
+  int xsize, ysize;
+  int datatype;
+  int tsID;
+  int vlistID;
+  int pdis, pcat, pnum;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-off_t gribGetPos(int fileID)
-{
-  return (fileGetPos(fileID));
-}
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  nlevs    = zaxisInqSize(zaxisID);
 
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-int gribCheckFiletype(int fileID)
-{
-  int ierr;
-  int found = 0;
-  char buffer[4];
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-  if ( fileRead(fileID, buffer, 4) != 4 ) return(found);
+  header[0] = pnum;
+  header[2] = streamptr->tsteps[tsID].taxis.vdate;
+  header[3] = streamptr->tsteps[tsID].taxis.vtime;
 
-  if ( memcmp(buffer, "GRIB", 4) == 0 )
-    {
-      found = 1;
-      if ( CGRIBEX_Debug ) Message("found GRIB file = %s", fileInqName(fileID));
-    }
-  else
+  xsize = gridInqXsize(gridID);
+  ysize = gridInqYsize(gridID);
+  if ( xsize == 0 || ysize == 0 )
     {
-      long offset;
-
-      ierr = gribFileSeek(fileID, &offset);
-      fileRewind(fileID);
-      if ( !ierr )
-	{
-	  found = 1;
-	  if ( CGRIBEX_Debug ) Message("found seek GRIB file = %s", fileInqName(fileID));
-	}
+      xsize = gridInqSize(gridID);
+      ysize = 1;
     }
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
+  if ( gridInqSize(gridID) != xsize*ysize )
+    Error("Internal problem with gridsize!");
 
-  return (found);
-}
-
+  header[4] = xsize;
+  header[5] = ysize;
+  header[6] = 0;
+  header[7] = 0;
 
-int gribCheckSeek(int fileID, long *offset, int *version)
-{
-  int ierr;
-  char buffer[4];
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
-  ierr = gribFileSeek(fileID, offset);
+  srvp->dprec = srvDefDatatype(datatype);
 
-  *version = -1;
-  if ( !ierr )
+  for ( levID = 0; levID < nlevs; levID++ )
     {
-      if ( fileRead(fileID, buffer, 4) == 4 )
-	*version = buffer[3];
-    }
+      level = zaxisInqLevel(zaxisID, levID);
 
-  return (ierr);
+      header[1] = (int) level;
+      srvDefHeader(srvp, header);
+      srvDefDataDP(srvp, &data[levID*gridsize]);
+      srvWrite(fileID, srvp);
+    }
 }
 
 
-int gribFileSeekOld(int fileID, long *offset)
+void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
-  /* position file pointer after GRIB */
-  int ch;
-  int buffersize = 4096;
-  unsigned char buffer[4096];
-  int retry = 4096;
-  int i;
-  void *fileptr;
+  int fileID;
+  int gridID;
+  int zaxisID;
+  double level;
+  int header[8];
+  int xsize, ysize;
+  int datatype;
+  int tsID;
+  int vlistID;
+  int pdis, pcat, pnum;
+  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 
-  *offset = 0;
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  level    = zaxisInqLevel(zaxisID, levID);
 
-  fileptr = filePtr(fileID);
+  if ( CDI_Debug )
+    Message("gridID = %d zaxisID = %d", gridID, zaxisID);
 
-  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[0] = ch;
-  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[1] = ch;
-  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[2] = ch;
-  ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[3] = ch;
-  /*
-  fileRead(fileID, buffer, 4);
-  */
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-  while ( retry-- )
+  header[0] = pnum;
+  header[1] = (int) level;
+  header[2] = streamptr->tsteps[tsID].taxis.vdate;
+  header[3] = streamptr->tsteps[tsID].taxis.vtime;
+
+  xsize = gridInqXsize(gridID);
+  ysize = gridInqYsize(gridID);
+  if ( xsize == 0 || ysize == 0 )
     {
-      for ( i = 0; i < buffersize-4; ++i )
-	{
-	  if (buffer[i  ] == 'G' && 
-	      buffer[i+1] == 'R' &&
-	      buffer[i+2] == 'I' &&
-	      buffer[i+3] == 'B')
-	    {
-	      if ( CGRIBEX_Debug )
-		Message("record offset = %d", (int) *offset);
-	      return (0);
-	    }
-	  else
-	    {
-	      ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[i+4] = ch;
-	      (*offset)++;
-	    }
-	}
-      buffer[0] = buffer[i  ];
-      buffer[1] = buffer[i+1];
-      buffer[2] = buffer[i+2];
-      buffer[3] = buffer[i+3];
+      xsize = gridInqSize(gridID);
+      ysize = 1;
     }
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED ) ysize = 1;
+  if ( gridInqSize(gridID) != xsize*ysize )
+    Error("Internal problem with gridsize!");
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+  header[4] = xsize;
+  header[5] = ysize;
+  header[6] = 0;
+  header[7] = 0;
 
-  return (1);
-}
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
+  srvp->dprec = srvDefDatatype(datatype);
 
-int gribFileSeek(int fileID, long *offset)
-{
-  /* position file pointer after GRIB */
-  const long GRIB = 0x47524942;
-  long code = 0;
-  int ch;
-  int retry = 4096*4096;
-  void *fileptr;
+  srvDefHeader(srvp, header);
+  srvDefDataDP(srvp, data);
+  srvWrite(fileID, srvp);
+}
 
-  *offset = 0;
+#endif /* HAVE_LIBSERVICE */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  fileptr = filePtr(fileID);
+#include <string.h>
 
-  while ( retry-- )
-    {
-      ch = filePtrGetc(fileptr);
-      if ( ch == EOF ) return (-1);
-    
-      code = ( (code << 8) + ch ) & 0xFFFFFFFF;
 
-      if ( code == GRIB )
-	{
-	  if ( CGRIBEX_Debug )
-	    Message("record offset = %d", (int) *offset);
-	  return (0);
-	}
 
-      (*offset)++;
-    }
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+static
+void streamvar_init_entry(stream_t *streamptr, int varID)
+{
+  streamptr->vars[varID].ncvarid      = CDI_UNDEFID;
+  streamptr->vars[varID].defmiss      = 0;
+  streamptr->vars[varID].nlevs        = 0;
+  streamptr->vars[varID].level        = NULL;
+  streamptr->vars[varID].lindex       = NULL;
 
-  return (1);
+  streamptr->vars[varID].gridID       = CDI_UNDEFID;
+  streamptr->vars[varID].zaxisID      = CDI_UNDEFID;
+  streamptr->vars[varID].tsteptype    = CDI_UNDEFID;
 }
 
-
-int gribFileSeekTest(int fileID, long *offset)
+static
+int streamvar_new_entry(stream_t *streamptr)
 {
-  /* position file pointer after GRIB */
-  const long GRIB = 0x47524942;
-  long code = 0;
-  int ch;
-  int i = 0;
-  const int buffersize = 8;
-  unsigned char buffer[8];
-  int retry = 4096*4096;
-  void *fileptr;
-  int nread = 0;
+  int varID = 0;
+  int streamvarSize;
+  svarinfo_t *streamvar;
 
-  *offset = 0;
+  streamvarSize = streamptr->varsAllocated;
+  streamvar     = streamptr->vars;
+  /*
+    Look for a free slot in streamvar.
+    (Create the table the first time through).
+  */
+  if ( ! streamvarSize )
+    {
+      int i;
 
-  fileptr = filePtr(fileID);
+      streamvarSize = 2;
+      streamvar
+        = (svarinfo_t *)xmalloc((size_t)streamvarSize * sizeof(svarinfo_t));
+      if ( streamvar == NULL )
+	{
+          Message("streamvarSize = %d", streamvarSize);
+	  SysError("Allocation of svarinfo_t failed");
+	}
 
-  while ( retry-- )
+      for ( i = 0; i < streamvarSize; i++ )
+	streamvar[i].isUsed = FALSE;
+    }
+  else
     {
-      if ( i >= nread )
+      while ( varID < streamvarSize )
 	{
-	  nread = (int) filePtrRead(fileptr, buffer, buffersize);
-	  if ( nread == 0 ) return (-1);
-	  i = 0;
+	  if ( ! streamvar[varID].isUsed ) break;
+	  varID++;
 	}
+    }
+  /*
+    If the table overflows, double its size.
+  */
+  if ( varID == streamvarSize )
+    {
+      int i;
 
-      ch = buffer[i++];
-      code = ( (code << 8) + ch ) & 0xFFFFFFFF;
-
-      if ( code == GRIB )
+      streamvarSize = 2*streamvarSize;
+      streamvar
+        = (svarinfo_t *)xrealloc(streamvar,
+                                 (size_t)streamvarSize * sizeof (svarinfo_t));
+      if ( streamvar == NULL )
 	{
-	  /* printf("end: %d %d\n", nread, i); */
-	  if ( CGRIBEX_Debug )
-	    Message("record offset = %d", (int) *offset);
-
-	  if ( i != nread ) fileSetPos(fileID, (off_t) i-nread, SEEK_CUR);
-
-	  return (0);
+          Message("streamvarSize = %d", streamvarSize);
+	  SysError("Reallocation of svarinfo_t failed");
 	}
+      varID = streamvarSize/2;
 
-      (*offset)++;
+      for ( i = varID; i < streamvarSize; i++ )
+	streamvar[i].isUsed = FALSE;
     }
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+  streamptr->varsAllocated = streamvarSize;
+  streamptr->vars          = streamvar;
 
-  return (1);
+  streamvar_init_entry(streamptr, varID);
+
+  streamptr->vars[varID].isUsed = TRUE;
+
+  return (varID);
 }
 
 
-int gribReadSize(int fileID)
+int stream_new_var(stream_t *streamptr, int gridID, int zaxisID)
 {
-  int gribversion, gribsize;
-  int b1, b2, b3;
-  off_t pos;
-  void *fileptr;
-  /*
-  const int buffersize = 4;
-  unsigned char buffer[4];
-  */
-  fileptr = filePtr(fileID);
+  int varID;
+  int *level;
+  int *lindex;
+  int nlevs;
+  int levID;
 
-  pos = fileGetPos(fileID); 
-  /* bug: order of functions calls!
-     gribsize = (filePtrGetc(fileptr) << 16) + (filePtrGetc(fileptr) << 8) + filePtrGetc(fileptr);
-  */
-  b1 = filePtrGetc(fileptr);
-  b2 = filePtrGetc(fileptr);
-  b3 = filePtrGetc(fileptr);
-  // gribsize = (b1 << 16) + (b2 << 8) + b3;
-  gribsize = gribrec_len(b1, b2, b3);
+  if ( CDI_Debug )
+    Message("gridID = %d  zaxisID = %d", gridID, zaxisID);
 
-  gribversion = filePtrGetc(fileptr);
-  /*
-  filePtrRead(fileptr, buffer, buffersize);
+  varID = streamvar_new_entry(streamptr);
 
-  gribsize = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2];
+  streamptr->nvars++;
 
-  gribversion = buffer[3];
-  */
-  if ( gribsize == 24 )
-    {
-      if ( gribversion != 1 && gribversion != 2 ) gribversion = 0;
-    }
+  streamptr->vars[varID].gridID  = gridID;
+  streamptr->vars[varID].zaxisID = zaxisID;
 
-  if ( CGRIBEX_Debug )
-    Message("gribversion = %d", gribversion);
+  nlevs = zaxisInqSize(zaxisID);
 
-  if ( gribversion == 0 )
-    {
-      int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
-      int issize = 4, essize = 4;
-      int flag;
+  level  = (int *)xmalloc((size_t)nlevs * sizeof (int));
+  lindex = (int *)xmalloc((size_t)nlevs * sizeof (int));
 
-      pdssize = gribsize;
-      fileSetPos(fileID, (off_t) 3, SEEK_CUR);
-      if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
-      flag = filePtrGetc(fileptr);
-      if ( CGRIBEX_Debug ) Message("flag        = %d", flag);
-  
-      fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
+  for ( levID = 0; levID < nlevs; levID++ )
+    level[levID] = CDI_UNDEFID;
 
-      if ( flag & 128 )
-	{
-	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	  gdssize = (b1 << 16) + (b2 << 8) + b3;
-	  fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
-	  if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
-	}
+  for ( levID = 0; levID < nlevs; levID++ )
+    lindex[levID] = levID;
 
-      if ( flag & 64 )
-	{
-	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	  bmssize = (b1 << 16) + (b2 << 8) + b3;
-	  fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
-	  if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
-	}
+  streamptr->vars[varID].nlevs  = nlevs;
+  streamptr->vars[varID].level  = level;
+  streamptr->vars[varID].lindex = lindex;
 
-      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-      bdssize = (b1 << 16) + (b2 << 8) + b3;
-      if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
+  return (varID);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-      gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
-    }
-  else if ( gribversion == 1 )
-    {
-      if ( gribsize > JP23SET ) /* Large GRIB record */
-	{
-	  int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
-	  int issize = 4, essize = 4;
-	  int flag;
+#include <inttypes.h>
+#include <stdio.h>
 
-	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	  pdssize = (b1 << 16) + (b2 << 8) + b3;
-	  if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
 
-	  for ( int i = 0; i < 5; ++i ) flag = filePtrGetc(fileptr);
-	  if ( CGRIBEX_Debug ) Message("flag        = %d", flag);
-  
-	  fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
+void swap4byte(void *ptr, size_t size)
+{
+  int32_t *ptrtmp = ptr;
 
-	  if ( flag & 128 )
-	    {
-	      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	      gdssize = (b1 << 16) + (b2 << 8) + b3;
-	      fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
-	      if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
-	    }
-	  
-	  if ( flag & 64 )
-	    {
-	      b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	      bmssize = (b1 << 16) + (b2 << 8) + b3;
-	      fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
-	      if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
-	    }
+  if (sizeof (int32_t) == 4)
+    for (size_t i = 0; i < size; ++i)
+      ptrtmp[i] = (((ptrtmp[i] >> 24) & 0x00ff) | ((ptrtmp[i] & 0x00ff) << 24) |
+                   ((ptrtmp[i] >>  8) & 0xff00) | ((ptrtmp[i] & 0xff00) <<  8));
+  else
+    Error("not implemented for %d byte data", sizeof(int32_t));
+}
 
-	  b1 = filePtrGetc(fileptr); b2 = filePtrGetc(fileptr); b3 = filePtrGetc(fileptr);
-	  bdssize = (b1 << 16) + (b2 << 8) + b3;
-	  bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
-	  if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
+void swap8byte(void *ptr, size_t size)
+{
+  int64_t *ptrtmp = ptr;
 
-	  gribsize = issize+pdssize+gdssize+bmssize+bdssize+essize;
-	}
-    }
-  else if ( gribversion == 2 )
-    {
-      int i;
-      /* we set gribsize the following way because it doesn't matter then
-	 whether int is 4 or 8 bytes long - we don't have to care if the size
-	 really fits: if it does not, the record can not be read at all */
-      gribsize = 0;
-      for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | filePtrGetc(fileptr);
-    }
+  if (sizeof (int64_t) == 8)
+    for (size_t i = 0; i < size; ++i)
+      ptrtmp[i] = (((ptrtmp[i] >> 56) & 0x000000ff) | ((ptrtmp[i] & 0x000000ff) << 56) |
+                   ((ptrtmp[i] >> 40) & 0x0000ff00) | ((ptrtmp[i] & 0x0000ff00) << 40) |
+                   ((ptrtmp[i] >> 24) & 0x00ff0000) | ((ptrtmp[i] & 0x00ff0000) << 24) |
+                   ((ptrtmp[i] >>  8) & 0xff000000) | ((ptrtmp[i] & 0xff000000) <<  8));
   else
-    {
-      gribsize = 0;
-      Warning("GRIB version %d unsupported!", gribversion);
-    }
+    Error("not implemented for %d byte data", sizeof(int64_t));
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _TABLEPAR_H
+#define _TABLEPAR_H
 
-  if ( filePtrEOF(fileptr) ) gribsize = 0;
+enum {
+  TABLE_DUP_NAME = 1 << 0,
+  TABLE_DUP_LONGNAME = 1 << 1,
+  TABLE_DUP_UNITS = 1 << 2,
+};
+
+typedef struct
+{
+  int   id;	     /* Parameter number (GRIB) */
+  int dupflags;      /* keep track of which attributes got strdup'ed */
+  const char *name;	     /* Parameter name */
+  const char *longname;    /* Parameter long name */
+  const char *units;	     /* Parameter units */
+}
+PAR;
+
+
+static void tableLink(int tableID, const PAR *pars, int npars);
+int tableDef(int modelID, int tablegribID, const char *tablename);
+
+#endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _TABLE_H
+#define _TABLE_H
+
+static const PAR echam4[] = {
+  {   4, 0, "precip",      "total precipitation",                      "m/s"      },
+  {  34, 0, "low_cld",     "low cloud",                                 NULL      },
+  {  35, 0, "mid_cld",     "mid cloud",                                 NULL      },
+  {  36, 0, "hih_cld",     "high cloud",                                NULL      },
+  { 129, 0, "geosp",       "surface geopotential (orography)",         "m^2/s^2"  },
+  { 130, 0, "t",           "temperature",                              "K"        },
+  { 131, 0, "u",           "u-velocity",                               "m/s"      },
+  { 132, 0, "v",           "v-velocity",                               "m/s"      },
+  { 133, 0, "sq",          "specific humidity",                        "kg/kg"    },
+  { 134, 0, "aps",         "Surface pressure",                         "Pa"       },
+  { 135, 0, "omega",       "vertical velocity",                        "Pa/s"     },
+  { 138, 0, "svo",         "vorticity",                                "1/s"      },
+  { 139, 0, "ts",          "surface temperature",                      "K"        },
+  { 140, 0, "ws",          "soil wetness",                             "m"        },
+  { 141, 0, "sn",          "snow depth",                               "m"        },
+  { 142, 0, "aprl",        "large scale precipitation",                "m/s"      },
+  { 143, 0, "aprc",        "convective  precipitation",                "m/s"      },
+  { 144, 0, "aprs",        "snow fall",                                "m/s"      },
+  { 145, 0, "vdis",        "boundary layer dissipation",               "W/m^2"    },
+  { 146, 0, "ahfs",        "surface sensible heat flux",               "W/m^2"    },
+  { 147, 0, "ahfl",        "surface latent heat flux",                 "W/m^2"    },
+  { 148, 0, "stream",      "streamfunction",                           "m^2/s"    },
+  { 149, 0, "velopot",     "velocity potential",                       "m^2/s"    },
+  { 151, 0, "slp",         "mean sea level pressure",                  "Pa"       },
+  { 152, 0, "lsp",         "log surface pressure",                      NULL      },
+  { 153, 0, "sx",          "liquid water content",                     "kg/kg"    },
+  { 155, 0, "sd",          "divergence",                               "1/s"      },
+  { 156, 0, "geopoth",     "geopotential height",                      "m"        },
+  { 157, 0, "rhumidity",   "relative humidity",                        "fraction" },
+  { 158, 0, "var158",      "tendency of surface pressure",             "Pa/s"     },
+  { 159, 0, "ustar3",      "ustar3",                                   "m^3/s^3"  },
+  { 160, 0, "runoff",      "surface runoff",                           "m/s"      },
+  { 161, 0, "alwc",        "liquid water content",                     "kg/kg"    },
+  { 162, 0, "aclc",        "cloud cover",                              "fraction" },
+  { 163, 0, "aclcv",       "total cloud cover",                        "fraction" },
+  { 164, 0, "aclcov",      "total cloud cover",                        "fraction" },
+  { 165, 0, "u10",         "10m u-velocity",                           "m/s"      },
+  { 166, 0, "v10",         "10m v-velocity",                           "m/s"      },
+  { 167, 0, "temp2",       "2m temperature",                           "K"        },
+  { 168, 0, "dew2",        "2m dew point temperature",                 "K"        },
+  { 169, 0, "tsurf",       "surface temperature",                      "K"        },
+  { 170, 0, "td",          "deep soil temperature",                    "K"        },
+  { 171, 0, "wind10",      "10m windspeed",                            "m/s"      },
+  { 172, 0, "slm",         "land sea mask",                            "fraction" },
+  { 173, 0, "az0",         "surface roughness length",                 "m"        },
+  { 174, 0, "alb",         "surface background albedo",                "fraction" },
+  { 175, 0, "albedo",      "surface albedo",                           "fraction" },
+  { 176, 0, "srads",       "net surface solar radiation",              "W/m^2"    },
+  { 177, 0, "trads",       "net surface thermal radiation",            "W/m^2"    },
+  { 178, 0, "srad0",       "net top solar radiation",                  "W/m^2"    },
+  { 179, 0, "trad0",       "top thermal radiation (OLR)",              "W/m^2"    },
+  { 180, 0, "ustr",        "surface u-stress",                         "Pa"       },
+  { 181, 0, "vstr",        "surface v-stress",                         "Pa"       },
+  { 182, 0, "evap",        "surface evaporation",                      "m/s"      },
+  { 183, 0, "tdcl",        "soil temperature",                         "K"        },
+  { 185, 0, "srafs",       "net surf. solar radiation   (clear sky)",  "W/m^2"    },
+  { 186, 0, "trafs",       "net surf. thermal radiation (clear sky)",  "W/m^2"    },
+  { 187, 0, "sraf0",       "net top solar radiation     (clear sky)",  "W/m^2"    },
+  { 188, 0, "traf0",       "net top thermal radiation   (clear sky)",  "W/m^2"    },
+  { 189, 0, "sclfs",       "surface solar cloud forcing",              "W/m^2"    },
+  { 190, 0, "tclfs",       "surface thermal cloud forcing",            "W/m^2"    },
+  { 191, 0, "sclf0",       "top solar cloud forcing",                  "W/m^2"    },
+  { 192, 0, "tclf0",       "top thermal cloud forcing",                "W/m^2"    },
+  { 193, 0, "wl",          "skin reservoir content",                   "m"        },
+  { 194, 0, "wlm1",        "skin reservoir content of plants",         "m"        },
+  { 195, 0, "ustrgw",      "u-gravity wave stress",                    "Pa"       },
+  { 196, 0, "vstrgw",      "v-gravity wave stress",                    "Pa"       },
+  { 197, 0, "vdisgw",      "gravity wave dissipation",                 "W/m^2"    },
+  { 198, 0, "vgrat",       "vegetation ratio",                         "fraction" },
+  { 199, 0, "varor",       "orographic variance",                      "m^2"      },
+  { 200, 0, "vlt",         "leaf area index",                           NULL      },
+  { 201, 0, "t2max",       "maximum 2m-temperature",                   "K"        },
+  { 202, 0, "t2min",       "minimum 2m-temperature",                   "K"        },
+  { 203, 0, "srad0u",      "top solar radiation upward",               "W/m^2"    },
+  { 204, 0, "sradsu",      "surface solar radiation upward",           "W/m^2"    },
+  { 205, 0, "tradsu",      "surface thermal radiation upward",         "W/m^2"    },
+  { 206, 0, "tsn",         "snow temperature",                         "K"        },
+  { 207, 0, "td3",         "soil temperature 3",                       "K"        },
+  { 208, 0, "td4",         "soil temperature 4",                       "K"        },
+  { 209, 0, "td5",         "soil temperature 5",                       "K"        },
+  { 210, 0, "seaice",      "sea ice cover",                            "fraction" },
+  { 211, 0, "siced",       "sea ice depth",                            "m"        },
+  { 212, 0, "forest",      "vegetation type",                          "fraction" },
+  { 213, 0, "teff",        "(effective) sea-ice skin temperature",     "K"        },
+  { 214, 0, "tsmax",       "maximum surface temperature",              "K"        },
+  { 215, 0, "tsmin",       "minimum surface temperature",              "K"        },
+  { 216, 0, "wimax",       "maximum 10m-wind speed",                   "m/s"      },
+  { 217, 0, "topmax",      "maximum height of convective cloud tops",  "Pa"       },
+  { 218, 0, "snmel",       "snow melt",                                "m/s"      },
+  { 219, 0, "runtoc",      "surface runoff into ocean",                 NULL      },
+  { 220, 0, "tslin",       "land: residual surface heat budget",       "W/m^2"    },
+  { 221, 0, "dsnac",       "snow depth change",                        "m/s"      },
+  { 222, 0, "alwcac",      "liquid water content",                     "kg/kg"    },
+  { 223, 0, "aclcac",      "cloud cover",                              "fraction" },
+  { 224, 0, "tke",         "turbulent kinetic energy",                  NULL      },
+  { 225, 0, "tkem1",       "turbulent kinetic energy (t-1)",            NULL      },
+  { 226, 0, "fao",         "FAO data set (soil data flags)",            NULL      },
+  { 227, 0, "rgcgn",       "heat capacity of soil",                     NULL      },
+  { 228, 0, "sodif",       "soil diffusivity",                          NULL      },
+  { 229, 0, "wsmx",        "field capacity of soil",                   "m"        },
+  { 230, 0, "qvi",         "vertically integrated specific humidity",  "kg/m^2"   },
+  { 231, 0, "alwcvi",      "vertically integrated liquid water cont.", "kg/m^2"   },
+  { 232, 0, "glac",        "glacier mask",                             "fraction" },
+  { 233, 0, "runlnd",      "surface runoff not running into ocean",     NULL      },
+  { 259, 0, "windspeed",   "windspeed (sqrt(u^2+v^2))",                 NULL      },
+  { 260, 0, "precip",      "total precipitation",                      "m/s"      },
+  { 261, 0, "net_top",     "total top radiation",                       NULL      },
+  { 262, 0, "net_bot",     "total surface radiation",                   NULL      },
+  { 263, 0, "net_heat",    "net surface heat flux",                     NULL      },
+  { 264, 0, "net_water",   "total surface water",                       NULL      },
+  { 268, 0, "sw_atm",       NULL,                                       NULL      },
+  { 269, 0, "lw_atm",       NULL,                                       NULL      },
+  { 270, 0, "net_atm",      NULL,                                       NULL      },
+  { 271, 0, "surf_runoff", "surface runoff",                            NULL      },
+  { 275, 0, "fresh_water",  NULL,                                       NULL      },
+};
 
-  if ( CGRIBEX_Debug )
-    Message("gribsize    = %d", gribsize);
+static const PAR echam5[] = {
+  {   4, 0, "precip",     "total precipitation",                       "kg/m^2s" },
+  {  79, 0, "swnirac",    "net surface NIR flux acc.",                 "W/m^2"   },
+  {  80, 0, "swdifnirac", "fraction of diffuse NIR acc.",              "W/m^2"   },
+  {  81, 0, "swvisac",    "net surface visible flux acc.",             "W/m^2"   },
+  {  82, 0, "swdifvisac", "fraction of diffuse visible acc.",          "W/m^2"   },
+  {  83, 0, "ocu",        "ocean eastw. velocity (coupled mode)",      "m/s"     },
+  {  84, 0, "ocv",        "ocean northw. velocity (coupled mode)",     "m/s"     },
+  {  85, 0, "tradl",      "net LW radiation 200mb",                    "W/m^2"   },
+  {  86, 0, "sradl",      "net SW radiation 200mb",                    "W/m^2"   },
+  {  87, 0, "trafl",      "net LW radiation 200mb (clear sky)",        "W/m^2"   },
+  {  88, 0, "srafl",      "net SW radiation 200mb (clear sky)",        "W/m^2"   },
+  {  89, 0, "amlcorac",   "mixed layer flux correction",               "W/m^2"   },
+  {  90, 0, "amlheatac",  "mixed layer heat content",                  "J/m^2"   },
+  {  91, 0, "trfliac",    "net LW radiation over ice",                 "W/m^2"   },
+  {  92, 0, "trflwac",    "net LW radiation over water",               "W/m^2"   },
+  {  93, 0, "trfllac",    "net LW radiation over land",                "W/m^2"   },
+  {  94, 0, "sofliac",    "net SW radiation over ice",                 "W/m^2"   },
+  {  95, 0, "soflwac",    "net SW radiation over water",               "W/m^2"   },
+  {  96, 0, "sofllac",    "net SW radiation over land",                "W/m^2"   },
+  {  97, 0, "friac",      "ice cover (fraction of grid box)",           NULL     },
+  { 102, 0, "tsi",        "surface temperature of ice",                "K"       },
+  { 103, 0, "tsw",        "surface temperature of water",              "K"       },
+  { 104, 0, "ustri",      "zonal      wind stress over ice",           "Pa"      },
+  { 105, 0, "vstri",      "meridional wind stress over ice",           "Pa"      },
+  { 106, 0, "ustrw",      "zonal      wind stress over water",         "Pa"      },
+  { 107, 0, "vstrw",      "meridional wind stress over water",         "Pa"      },
+  { 108, 0, "ustrl",      "zonal      wind stress over land",          "Pa"      },
+  { 109, 0, "vstrl",      "meridional wind stress over land",          "Pa"      },
+  { 110, 0, "ahfliac",    "latent heat flux over ice",                 "W/m^2"   },
+  { 111, 0, "ahflwac",    "latent heat flux over water",               "W/m^2"   },
+  { 112, 0, "ahfllac",    "latent heat flux over land",                "W/m^2"   },
+  { 113, 0, "evapiac",    "evaporation over ice",                      "kg/m^2s" },
+  { 114, 0, "evapwac",    "evaporation over water",                    "kg/m^2s" },
+  { 115, 0, "evaplac",    "evaporation over land",                     "kg/m^2s" },
+  { 116, 0, "az0i",       "roughness length over ice",                 "m"       },
+  { 117, 0, "az0w",       "roughness length over water",               "m"       },
+  { 118, 0, "az0l",       "roughness length over land",                "m"       },
+  { 119, 0, "ahfsiac",    "sensible heat flux over ice",               "W/m^2"   },
+  { 120, 0, "ahfswac",    "sensible heat flux over water",             "W/m^2"   },
+  { 121, 0, "ahfslac",    "sensible heat flux over land",              "W/m^2"   },
+  { 122, 0, "alsoi",      "albedo of ice",                              NULL     },
+  { 123, 0, "alsow",      "albedo of water",                            NULL     },
+  { 124, 0, "alsol",      "albedo of land",                             NULL     },
+  { 125, 0, "ahfice",     "conductive heat flux through ice",          "W/m^2"   },
+  { 126, 0, "qres",       "residual heat flux for melting sea ice",    "W/m^2"   },
+  { 127, 0, "alake",      "lake fraction",                              NULL     },
+  { 128, 0, "rintop",     "low level inversion",                        NULL     },
+  { 129, 0, "geosp",      "surface geopotential (orography)",          "m^2/s^2" },
+  { 130, 0, "t",          "temperature",                               "K"       },
+  { 131, 0, "u",          "u-velocity",                                "m/s"     },
+  { 132, 0, "v",          "v-velocity",                                "m/s"     },
+  { 133, 0, "q",          "specific humidity",                         "kg/kg"   },
+  { 134, 0, "aps",        "surface pressure",                          "Pa"      },
+  { 135, 0, "omega",      "vertical velocity",                         "Pa/s"    },
+  { 136, 0, "acdnc",      "cloud droplet number concentration",        "1/m^3"   },
+  { 137, 0, "apmeb",      "(P-E) error",                               "kg/m^2s" },
+  { 138, 0, "svo",        "vorticity",                                 "1/s"     },
+  { 139, 0, "tslm1",      "surface temperature of land",               "K"       },
+  { 140, 0, "ws",         "soil wetness",                              "m"       },
+  { 141, 0, "sn",         "water equivalent snow depth",               "m"       },
+  { 142, 0, "aprl",       "large scale precipitation",                 "kg/m^2s" },
+  { 143, 0, "aprc",       "convective  precipitation",                 "kg/m^2s" },
+  { 144, 0, "aprs",       "snow fall",                                 "kg/m^2s" },
+  { 145, 0, "vdis",       "boundary layer dissipation",                "W/m^2"   },
+  { 146, 0, "ahfs",       "sensible heat flux",                        "W/m^2"   },
+  { 147, 0, "ahfl",       "latent heat flux",                          "W/m^2"   },
+  { 148, 0, "stream",     "streamfunction",                            "m^2/s"   },
+  { 149, 0, "velopot",    "velocity potential",                        "m^2/s"   },
+  { 150, 0, "xivi",       "vertically integrated cloud ice",           "kg/m^2"  },
+  { 151, 0, "slp",        "mean sea level pressure",                   "Pa"      },
+  { 152, 0, "lsp",        "log surface pressure",                       NULL     },
+  { 153, 0, "xl",         "cloud water",                               "kg/kg"   },
+  { 154, 0, "xi",         "cloud ice",                                 "kg/kg"   },
+  { 155, 0, "sd",         "divergence",                                "1/s"     },
+  { 156, 0, "geopoth",    "geopotential height",                       "m"       },
+  { 157, 0, "rhumidity",  "relative humidity",                          NULL     },
+  { 159, 0, "wind10w",    "10m windspeed over water",                  "m/s"     },
+  { 160, 0, "runoff",     "surface runoff and drainage",               "kg/m^2s" },
+  { 161, 0, "drain",      "drainage",                                  "kg/m^2s" },
+  { 162, 0, "aclc",       "cloud cover",                                NULL     },
+  { 164, 0, "aclcov",     "total cloud cover",                          NULL     },
+  { 165, 0, "u10",        "10m u-velocity",                            "m/s"     },
+  { 166, 0, "v10",        "10m v-velocity",                            "m/s"     },
+  { 167, 0, "temp2",      "2m temperature",                            "K"       },
+  { 168, 0, "dew2",       "2m dew point temperature",                  "K"       },
+  { 169, 0, "tsurf",      "surface temperature",                       "K"       },
+  { 170, 0, "xvar",       "variance of total water amount",            "kg/kg"   },
+  { 171, 0, "wind10",     "10m windspeed",                             "m/s"     },
+  { 172, 0, "slm",        "land sea mask (1. = land, 0. = sea/lakes)",  NULL     },
+  { 173, 0, "az0",        "roughness length",                          "m"       },
+  { 174, 0, "alb",        "surface background albedo",                  NULL     },
+  { 175, 0, "albedo",     "surface albedo",                             NULL     },
+  { 176, 0, "srads",      "net surface SW radiation",                  "W/m^2"   },
+  { 177, 0, "trads",      "net surface LW radiation",                  "W/m^2"   },
+  { 178, 0, "srad0",      "net top SW radiation",                      "W/m^2"   },
+  { 179, 0, "trad0",      "net top LW radiation (-OLR)",               "W/m^2"   },
+  { 180, 0, "ustr",       "u-stress",                                  "Pa"      },
+  { 181, 0, "vstr",       "v-stress",                                  "Pa"      },
+  { 182, 0, "evap",       "evaporation",                               "kg/m^2s" },
+  { 183, 0, "xskew",      "skewness of total water amount qv+qi+ql",    NULL     },
+  { 184, 0, "srad0d",     "top incoming SW radiation",                 "W/m^2"   },
+  { 185, 0, "srafs",      "net surface SW radiation (clear sky)",      "W/m^2"   },
+  { 186, 0, "trafs",      "net surface LW radiation (clear sky)",      "W/m^2"   },
+  { 187, 0, "sraf0",      "net top SW radiation   (clear sky)",        "W/m^2"   },
+  { 188, 0, "traf0",      "net top LW radiation   (clear sky)",        "W/m^2"   },
+  { 189, 0, "sclfs",      "net surface SW cloud forcing (176-185)",    "W/m^2"   },
+  { 190, 0, "tclfs",      "net surface LW cloud forcing (177-186)",    "W/m^2"   },
+  { 191, 0, "sclf0",      "net SW top cloud forcing (178-187)",        "W/m^2"   },
+  { 192, 0, "tclf0",      "net LW top cloud forcing (179-188)",        "W/m^2"   },
+  { 193, 0, "wl",         "skin reservoir content",                    "m"       },
+  { 194, 0, "slf",        "fractional land cover",                      NULL     },
+  { 195, 0, "ustrgw",     "u-gravity wave stress",                     "Pa"      },
+  { 196, 0, "vstrgw",     "v-gravity wave stress",                     "Pa"      },
+  { 197, 0, "vdisgw",     "gravity wave dissipation",                  "W/m^2"   },
+  { 198, 0, "vgrat",      "vegetation ratio",                           NULL     },
+  { 199, 0, "orostd",     "orographic standard deviation",             "m"       },
+  { 200, 0, "vlt",        "leaf area index",                            NULL     },
+  { 201, 0, "t2max",      "maximum 2m-temperature",                    "K"       },
+  { 202, 0, "t2min",      "minimum 2m-temperature",                    "K"       },
+  { 203, 0, "srad0u",     "top SW radiation upward",                   "W/m^2"   },
+  { 204, 0, "sradsu",     "surface SW radiation upward",               "W/m^2"   },
+  { 205, 0, "tradsu",     "surface LW radiation upward",               "W/m^2"   },
+  { 206, 0, "grndflux",   "surface ground heat flux",                   NULL     },
+  { 207, 0, "tsoil",      "deep soil temperatures (5 layers)",         "K"       },
+  { 208, 0, "ahfcon",     "conductive heat flux through ice",          "W/m^2"   },
+  { 209, 0, "ahfres",     "res. heat flux for melting ice",            "W/m^2"   },
+  { 210, 0, "seaice",     "ice cover (fraction of ice+water)",          NULL     },
+  { 211, 0, "siced",      "ice thickness",                             "m"       },
+  { 212, 0, "forest",     "forest fraction",                            NULL     },
+  { 213, 0, "gld",        "glacier thickness",                         "m"       },
+  { 214, 0, "sni",        "water equivalent of snow on ice",           "m"       },
+  { 215, 0, "rogl",       "glacier runoff",                            "kg/m^2s" },
+  { 216, 0, "wimax",      "maximum 10m-wind speed",                    "m/s"     },
+  { 217, 0, "topmax",     "maximum height of convective cloud tops",   "Pa"      },
+  { 218, 0, "snmel",      "snow melt",                                 "kg/m^2s" },
+  { 219, 0, "runtoc",     "surface runoff into ocean",                 "kg/m^2s" },
+  { 220, 0, "runlnd",     "surface runoff not running into ocean",     "kg/m^2s" },
+  { 221, 0, "apmegl",     "P-E over land ice",                         "kg/m^2s" },
+  { 222, 0, "snacl",      "snow accumulation over land",               "kg/m^2s" },
+  { 223, 0, "aclcac",     "cloud cover",                                NULL     },
+  { 224, 0, "tke",        "turbulent kinetic energy",                  "m^2/s^2" },
+  { 225, 0, "tkem1",      "turbulent kinetic energy (t-1)",            "m^2/s^2" },
+  { 226, 0, "fao",        "FAO data set (soil data flags) 0...5",       NULL     },
+  { 227, 0, "rgcgn",      "heat capacity of soil",                      NULL     },
+  { 228, 0, "sodif",      "soil diffusivity",                          "m^2/s"   },
+  { 229, 0, "wsmx",       "field capacity of soil",                    "m"       },
+  { 230, 0, "qvi",        "vertically integrated water vapor",         "kg/m^2"  },
+  { 231, 0, "xlvi",       "vertically integrated cloud water",         "kg/m^2"  },
+  { 232, 0, "glac",       "fraction of land covered by glaciers",       NULL     },
+  { 233, 0, "snc",        "snow depth at the canopy",                  "m"       },
+  { 234, 0, "rtype",      "type of convection",                        "0...3"   },
+  { 235, 0, "abso4",      "anthropogenic sulfur burden",               "kg/m^2"  },
+  { 236, 0, "ao3",        "ipcc ozone",                                "kg/m^2"  },
+  { 237, 0, "tropo",      "WMO defined tropopause height",             "Pa"      },
+  { 259, 0, "windspeed",  "windspeed (sqrt(u^2+v^2))",                 "m/s"     },
+  { 260, 0, "precip",     "total precipitation  (142+143)",            "kg/m^2s" },
+  { 261, 0, "net_top",    "total top radiation  (178+179)",            "W/m^2"   },
+  { 262, 0, "net_bot",    "total surface radiation (176+177)",         "W/m^2"   },
+  { 272, 0, "mastrfu",    "mass stream function",                      "kg/s"    },
+};
 
-  fileSetPos(fileID, pos, SEEK_SET);
+static const PAR echam6[] = {
+  {   4, 0, "precip",         "total precipitation",                       "kg m-2 s-1" },
+  {  34, 0, "low_cld",        "low cloud",                                  NULL        },
+  {  35, 0, "mid_cld",        "mid cloud",                                  NULL        },
+  {  36, 0, "hih_cld",        "high cloud",                                 NULL        },
+  {  68, 0, "fage",           "aging factor of snow on ice",                NULL        },
+  {  69, 0, "snifrac",        "fraction of ice covered with snow",          NULL        },
+  {  70, 0, "barefrac",       "bare ice fraction",                          NULL        },
+  {  71, 0, "alsom",          "albedo of melt ponds",                       NULL        },
+  {  72, 0, "alsobs",         "albedo of bare ice and snow",                NULL        },
+  {  73, 0, "sicepdw",        "melt pond depth on sea-ice",                "m"          },
+  {  74, 0, "sicepdi",        "ice thickness on melt pond",                "m"          },
+  {  75, 0, "tsicepdi",       "ice temperature on frozen melt pond",       "K"          },
+  {  76, 0, "sicepres",       "residual heat flux",                        "W m-2"      },
+  {  77, 0, "ameltdepth",     "total melt pond depth",                     "m"          },
+  {  78, 0, "ameltfrac",      "fractional area of melt ponds on sea-ice",   NULL        },
+  {  79, 0, "albedo_vis_dir", "surface albedo visible range direct",        NULL        },
+  {  80, 0, "albedo_nir_dir", "surface albedo NIR range direct",            NULL        },
+  {  81, 0, "albedo_vis_dif", "surface albedo visible range diffuse",       NULL        },
+  {  82, 0, "albedo_nir_dif", "surface albedo NIR range diffuse",           NULL        },
+  {  83, 0, "ocu",            "ocean eastw. velocity (coupled mode)",      "m/s"        },
+  {  84, 0, "ocv",            "ocean northw. velocity (coupled mode)",     "m/s"        },
+  {  85, 0, "tradl",          "thermal radiation 200mb",                   "W m-2"      },
+  {  86, 0, "sradl",          "solar radiation 200mb",                     "W m-2"      },
+  {  87, 0, "trafl",          "thermal radiation 200mb (clear sky)",       "W m-2"      },
+  {  88, 0, "srafl",          "solar radiation 200mb (clear sky)",         "W m-2"      },
+  {  89, 0, "amlcorac",       "mixed layer flux correction",               "W m-2"      },
+  {  90, 0, "amlheatac",      "mixed layer heat content",                  "J m-2"      },
+  {  91, 0, "trfliac",        "LW flux over ice",                          "W m-2"      },
+  {  92, 0, "trflwac",        "LW flux over water",                        "W m-2"      },
+  {  93, 0, "trfllac",        "LW flux over land",                         "W m-2"      },
+  {  94, 0, "sofliac",        "SW flux over ice",                          "W m-2"      },
+  {  95, 0, "soflwac",        "SW flux over water",                        "W m-2"      },
+  {  96, 0, "sofllac",        "SW flux over land",                         "W m-2"      },
+  {  97, 0, "friac",          "ice cover (fraction of grid box)",           NULL        },
+  { 102, 0, "tsi",            "surface temperature of ice",                "K"          },
+  { 103, 0, "tsw",            "surface temperature of water",              "K"          },
+  { 104, 0, "ustri",          "zonal      wind stress over ice",           "Pa"         },
+  { 105, 0, "vstri",          "meridional wind stress over ice",           "Pa"         },
+  { 106, 0, "ustrw",          "zonal      wind stress over water",         "Pa"         },
+  { 107, 0, "vstrw",          "meridional wind stress over water",         "Pa"         },
+  { 108, 0, "ustrl",          "zonal      wind stress over land",          "Pa"         },
+  { 109, 0, "vstrl",          "meridional wind stress over land",          "Pa"         },
+  { 110, 0, "ahfliac",        "latent heat flux over ice",                 "W m-2"      },
+  { 111, 0, "ahflwac",        "latent heat flux over water",               "W m-2"      },
+  { 112, 0, "ahfllac",        "latent heat flux over land",                "W m-2"      },
+  { 113, 0, "evapiac",        "evaporation over ice",                      "kg m-2 s-1" },
+  { 114, 0, "evapwac",        "evaporation over water",                    "kg m-2 s-1" },
+  { 115, 0, "evaplac",        "evaporation over land",                     "kg m-2 s-1" },
+  { 116, 0, "az0i",           "roughness length over ice",                 "m"          },
+  { 117, 0, "az0w",           "roughness length over water",               "m"          },
+  { 118, 0, "az0l",           "roughness length over land",                "m"          },
+  { 119, 0, "ahfsiac",        "sensible heat flux over ice",               "W m-2"      },
+  { 120, 0, "ahfswac",        "sensible heat flux over water",             "W m-2"      },
+  { 121, 0, "ahfslac",        "sensible heat flux over land",              "W m-2"      },
+  { 122, 0, "alsoi",          "albedo of ice",                              NULL        },
+  { 123, 0, "alsow",          "albedo of water",                            NULL        },
+  { 124, 0, "alsol",          "albedo of land",                             NULL        },
+  { 125, 0, "ahfice",         "conductive heat flux",                      "W m-2"      },
+  { 126, 0, "qres",           "residual heat flux for melting sea ice",    "W m-2"      },
+  { 127, 0, "alake",          "lake fraction of grid box",                 "fraction"   },
+  { 128, 0, "rintop",         "low level inversion",                        NULL        },
+  { 129, 0, "geosp",          "surface geopotential (orography)",          "m^2/s^2"    },
+  { 130, 0, "t",              "temperature",                               "K"          },
+  { 131, 0, "u",              "u-velocity",                                "m/s"        },
+  { 132, 0, "v",              "v-velocity",                                "m/s"        },
+  { 133, 0, "q",              "specific humidity",                         "kg/kg"      },
+  { 134, 0, "aps",            "surface pressure",                          "Pa"         },
+  { 135, 0, "omega",          "vertical velocity",                         "Pa/s"       },
+  { 136, 0, "acdnc",          "cloud droplet number concentration",        "1 m-3"      },
+  { 137, 0, "apmeb",          "vert. integr. tendencies of water",         "kg m-2 s-1" },
+  { 138, 0, "svo",            "vorticity",                                 "1/s"        },
+  { 139, 0, "tslm1",          "surface temperature of land",               "K"          },
+  { 140, 0, "ws",             "soil wetness",                              "m"          },
+  { 141, 0, "sn",             "snow depth",                                "m"          },
+  { 142, 0, "aprl",           "large scale precipitation",                 "kg m-2 s-1" },
+  { 143, 0, "aprc",           "convective  precipitation",                 "kg m-2 s-1" },
+  { 144, 0, "aprs",           "snow fall",                                 "kg m-2 s-1" },
+  { 145, 0, "vdis",           "boundary layer dissipation",                "W m-2"      },
+  { 146, 0, "ahfs",           "sensible heat flux",                        "W m-2"      },
+  { 147, 0, "ahfl",           "latent heat flux",                          "W m-2"      },
+  { 148, 0, "stream",         "streamfunction",                            "m^2/s"      },
+  { 149, 0, "velopot",        "velocity potential",                        "m^2/s"      },
+  { 150, 0, "xivi",           "vertically integrated cloud ice",           "kg m-2"     },
+  { 151, 0, "slp",            "mean sea level pressure",                   "Pa"         },
+  { 152, 0, "lsp",            "log surface pressure",                       NULL        },
+  { 153, 0, "xl",             "cloud water",                               "kg/kg"      },
+  { 154, 0, "xi",             "cloud ice",                                 "kg/kg"      },
+  { 155, 0, "sd",             "divergence",                                "1/s"        },
+  { 156, 0, "geopoth",        "geopotential height",                       "m"          },
+  { 157, 0, "rhumidity",      "relative humidity",                         "fraction"   },
+  { 158, 0, "var158",         "tendency of surface pressure",              "Pa/s"       },
+  { 159, 0, "wind10w",        "10m windspeed over water",                  "m/s"        },
+  { 160, 0, "runoff",         "surface runoff and drainage",               "kg m-2 s-1" },
+  { 161, 0, "drain",          "drainage",                                  "kg m-2 s-1" },
+  { 162, 0, "aclc",           "cloud cover",                                NULL        },
+  { 163, 0, "aclcv",          "total cloud cover",                          NULL        },
+  { 164, 0, "aclcov",         "total cloud cover (mean)",                   NULL        },
+  { 165, 0, "u10",            "10m u-velocity",                            "m/s"        },
+  { 166, 0, "v10",            "10m v-velocity",                            "m/s"        },
+  { 167, 0, "temp2",          "2m temperature",                            "K"          },
+  { 168, 0, "dew2",           "2m dew point temperature",                  "K"          },
+  { 169, 0, "tsurf",          "surface temperature",                       "K"          },
+  { 170, 0, "xvar",           "variance of total water amount qv+qi+ql",   "kg/kg"      },
+  { 171, 0, "wind10",         "10m windspeed",                             "m/s"        },
+  { 172, 0, "slm",            "land sea mask (1. = land, 0. = sea/lakes)",  NULL        },
+  { 173, 0, "az0",            "roughness length",                          "m"          },
+  { 174, 0, "alb",            "surface background albedo",                  NULL        },
+  { 175, 0, "albedo",         "surface albedo",                             NULL        },
+  { 176, 0, "srads",          "net surface solar radiation",               "W m-2"      },
+  { 177, 0, "trads",          "net surface thermal radiation",             "W m-2"      },
+  { 178, 0, "srad0",          "net top solar radiation",                   "W m-2"      },
+  { 179, 0, "trad0",          "top thermal radiation (OLR)",               "W m-2"      },
+  { 180, 0, "ustr",           "u-stress",                                  "Pa"         },
+  { 181, 0, "vstr",           "v-stress",                                  "Pa"         },
+  { 182, 0, "evap",           "evaporation",                               "kg m-2 s-1" },
+  { 183, 0, "xskew",          "skewness of total water amount qv+qi+ql",    NULL        },
+  { 184, 0, "srad0d",         "top incoming solar radiation",              "W m-2"      },
+  { 185, 0, "srafs",          "net surf. solar radiation   (clear sky)",   "W m-2"      },
+  { 186, 0, "trafs",          "net surf. thermal radiation (clear sky)",   "W m-2"      },
+  { 187, 0, "sraf0",          "net top solar radiation     (clear sky)",   "W m-2"      },
+  { 188, 0, "traf0",          "net top thermal radiation   (clear sky)",   "W m-2"      },
+  { 189, 0, "sclfs",          "surface solar cloud forcing",               "W m-2"      },
+  { 190, 0, "tclfs",          "surface thermal cloud forcing",             "W m-2"      },
+  { 191, 0, "sclf0",          "SW top cloud forcing (178-187)",            "W m-2"      },
+  { 192, 0, "tclf0",          "LW top cloud forcing (179-188)",            "W m-2"      },
+  { 193, 0, "wl",             "skin reservoir content",                    "m"          },
+  { 194, 0, "slf",            "sea land fraction",                          NULL        },
+  { 195, 0, "ustrgw",         "u-gravity wave stress",                     "Pa"         },
+  { 196, 0, "vstrgw",         "v-gravity wave stress",                     "Pa"         },
+  { 197, 0, "vdisgw",         "gravity wave dissipation",                  "W m-2"      },
+  { 198, 0, "vgrat",          "vegetation ratio",                           NULL        },
+  { 199, 0, "orostd",         "orographic standard deviation",             "m"          },
+  { 200, 0, "vlt",            "leaf area index",                            NULL        },
+  { 201, 0, "t2max",          "maximum 2m-temperature",                    "K"          },
+  { 202, 0, "t2min",          "minimum 2m-temperature",                    "K"          },
+  { 203, 0, "srad0u",         "top solar radiation upward",                "W m-2"      },
+  { 204, 0, "sradsu",         "surface solar radiation upward",            "W m-2"      },
+  { 205, 0, "tradsu",         "surface thermal radiation upward",          "W m-2"      },
+  { 206, 0, "grndflux",       "surface ground heat flux",                   NULL        },
+  { 207, 0, "tsoil",          "deep soil temperatures (5 layers)",         "K"          },
+  { 208, 0, "ahfcon",         "conductive heat flux through ice",          "W m-2"      },
+  { 209, 0, "ahfres",         "melting of ice",                            "W m-2"      },
+  { 210, 0, "seaice",         "ice cover (fraction of 1-SLM)",              NULL        },
+  { 211, 0, "siced",          "ice depth",                                 "m"          },
+  { 212, 0, "forest",         "forest fraction",                            NULL        },
+  { 213, 0, "gld",            "glacier depth",                             "m"          },
+  { 214, 0, "sni",            "water equivalent of snow on ice",           "m"          },
+  { 215, 0, "rogl",           "glacier runoff",                            "kg m-2 s-1" },
+  { 216, 0, "wimax",          "maximum 10m-wind speed",                    "m/s"        },
+  { 217, 0, "topmax",         "maximum height of convective cloud tops",   "Pa"         },
+  { 218, 0, "snmel",          "snow melt",                                 "kg m-2 s-1" },
+  { 219, 0, "runtoc",         "surface runoff into ocean",                 "kg m-2 s-1" },
+  { 220, 0, "runlnd",         "surface runoff not running into ocean",     "kg m-2 s-1" },
+  { 221, 0, "apmegl",         "P-E over land ice",                         "kg m-2 s-1" },
+  { 222, 0, "snacl",          "snow accumulation over land",               "kg m-2 s-1" },
+  { 223, 0, "aclcac",         "cloud cover",                                NULL        },
+  { 224, 0, "tke",            "turbulent kinetic energy",                  "m^2/s^2"    },
+  { 225, 0, "tkem1",          "turbulent kinetic energy (t-1)",            "m^2/s^2"    },
+  { 226, 0, "fao",            "FAO data set (soil data flags)",            "0...5"      },
+  { 227, 0, "rgcgn",          "heat capacity of soil",                      NULL        },
+  { 228, 0, "sodif",          "diffusivity of soil and land ice",          "m^2/s"      },
+  { 229, 0, "wsmx",           "field capacity of soil",                    "m"          },
+  { 230, 0, "qvi",            "vertically integrated water vapor",         "kg m-2"     },
+  { 231, 0, "xlvi",           "vertically integrated cloud water",         "kg m-2"     },
+  { 232, 0, "glac",           "fraction of land covered by glaciers",       NULL        },
+  { 233, 0, "snc",            "snow depth at the canopy",                  "m"          },
+  { 234, 0, "rtype",          "type of convection",                        "0...3"      },
+  { 235, 0, "abso4",          "antropogenic sulfur burden",                "kg m-2"     },
+  { 236, 0, "ao3",            "ipcc ozone",                                "kg m-2"     },
+  { 237, 0, "tropo",          "WMO defined tropopause height",             "Pa"         },
+  { 259, 0, "windspeed",      "windspeed (sqrt(u^2+v^2))",                 "m/s"        },
+  { 260, 0, "precip",         "total precipitation  (142+143)",            "kg m-2 s-1" },
+  { 261, 0, "net_top",        "total top radiation  (178+179)",            "W m-2"      },
+  { 262, 0, "net_bot",        "total surface radiation (176+177)",         "W m-2"      },
+  { 272, 0, "mastfru",        "mass stream function",                      "kg/s"       },
+};
 
-  return (gribsize);
-}
+static const PAR mpiom1[] = {
+  {   2, 0, "THO",      "temperature",                     "C"        },
+  {   5, 0, "SAO",      "salinity",                        "psu"      },
+  {   3, 0, "UKO",      "zon. velocity",                   "m/s"      },
+  {   4, 0, "VKE",      "mer. velocity",                   "m/s"      },
+  { 303, 0, "UKOMFL",   "zon. velocity (divergence free)", "m/s"      },
+  { 304, 0, "VKEMFL",   "mer. velocity (divergence free)", "m/s"      },
+  {   7, 0, "WO",       "ver. velocity",                   "m/s"      },
+  {   8, 0, "RHO",      "insitu density",                  "kg/m**3"  },
+  {   6, 0, "PO",       "pressure",                        "Pa"       },
+  {  67, 0, "EMINPO",   "freshwaterflux by restoring",     "m/s"      },
+  {  70, 0, "FLUM",     "total heatflux",                  "W/m**2"   },
+  {  79, 0, "PEM",      "total freshwaterflux",            "m/s"      },
+  {  13, 0, "SICTHO",   "ice thickness",                   "m"        },
+  {  15, 0, "SICOMO",   "ice compactness",                 "frac."    },
+  {  35, 0, "SICUO",    "zon. ice velocity",               "m/s"      },
+  {  36, 0, "SICVE",    "mer. ice velocity",               "m/s"      },
+  {  92, 0, "TAFO",     "surface air temperature",         "C"        },
+  { 164, 0, "FCLOU",    "cloud cover",                      NULL      },
+  {  52, 0, "TXO",      "surface u-stress",                "Pa/1025." },
+  {  53, 0, "TYE",      "surface v-stress",                "Pa/1025." },
+  { 260, 0, "FPREC",    "prescr. precipitation",           "m/s"      },
+  {  80, 0, "FSWR",     "downward shortwave rad.",         "W/m**2"   },
+  {  81, 0, "FTDEW",    "dewpoint temperature",            "K"        },
+  { 171, 0, "FU10",     "10m windspeed",                   "m/s"      },
+  { 141, 0, "SICSNO",   "snow thickness",                  "m"        },
+  { 176, 0, "QSWO",     "heat flux shortwave",             "W/m**2"   },
+  { 177, 0, "QLWO",     "heat flux longwave",              "W/m**2"   },
+  { 147, 0, "QLAO",     "heat flux latent",                "W/m**2"   },
+  { 146, 0, "QSEO",     "heat flux sensible",              "W/m**2"   },
+  {  65, 0, "PRECO",    "net freshwater flux + runoff",    "m/s"      },
+  {   1, 0, "ZO",       "sealevel",                        "m"        },
+  {  82, 0, "Z1O",      "sealevel change",                 "m"        },
+  {  69, 0, "KCONDEP",  "depth of convection",             "level"    },
+  {  27, 0, "PSIUWE",   "hor. bar. streamfunction",        "Sv"       },
+  {  83, 0, "AMLD",     "mixed layer depth",               "m"        },
+  { 172, 0, "WETO",     "landseamask (pressure points)",    NULL      },
+  { 507, 0, "AMSUE",    "landseamask (vector points v)",    NULL      },
+  { 508, 0, "AMSUO",    "landseamask (vector points u)",    NULL      },
+  {  84, 0, "DEPTO",    "depth at pressure points",        "m"        },
+  { 484, 0, "DEUTO",    "depth at vector points (u)",      "m"        },
+  { 584, 0, "DEUTE",    "depth at vector points (v)",      "m"        },
+  { 184, 0, "DDUO",     "level thickness (vector u )",     "m"        },
+  { 284, 0, "DDUE",     "level thickness (vector v )",     "m"        },
+  { 384, 0, "DDPO",     "level thickness (pressure )",     "m"        },
+  {  85, 0, "DLXP",     "grid distance x",                 "m"        },
+  {  86, 0, "DLYP",     "grid distance y",                 "m"        },
+  { 185, 0, "DLXU",     "grid distance x  (vector u)",     "m"        },
+  { 186, 0, "DLYU",     "grid distance y  (vector u)",     "m"        },
+  { 285, 0, "DLXV",     "grid distance x  (vector v)",     "m"        },
+  { 286, 0, "DLYV",     "grid distance y  (vector v)",     "m"        },
+  {  54, 0, "GILA",     "latitude in radiants",            "rad"      },
+  {  55, 0, "GIPH",     "longitude in radiants",           "rad"      },
+  { 354, 0, "ALAT",     "latitude in degrees (pressure)",  "deg"      },
+  { 355, 0, "ALON",     "longitude in degrees (pressure)", "deg"      },
+  { 154, 0, "ALATU",    "latitude in degrees (vector u)",  "deg"      },
+  { 155, 0, "ALONU",    "longitude in degrees (vector u)", "deg"      },
+  { 254, 0, "ALATV",    "latitude in degrees (vector v)",  "deg"      },
+  { 255, 0, "ALONV",    "longitude in degrees (vector v)", "deg"      },
+  { 110, 0, "AVO",      "vertical impuls diffusion",       "m**2/s"   },
+  { 111, 0, "DVO",      "vertical T,S diffusion",          "m**2/s"   },
+  { 142, 0, "SICTRU",   "seaice transport x",              "m**2/s"   },
+  { 143, 0, "SICTRV",   "seaice transport y",              "m**2/s"   },
+  { 612, 0, "WTMIX",    "wind mixing",                     "m**2/s"   },
+  { 183, 0, "zmld",     "mixed layer depth (SJ)",          "m"        },
+  { 207, 0, "WGO",      "GM vertical velocity",            "m/s"      },
+  { 305, 0, "rivrun",   "RiverRunoff",                     "m/s"      },
+  { 158, 0, "TMCDO",    "mon. mean depth of convection",   "level"    },
+  { 247, 0, "DQSWO",    "heatflux sw over water",          "W/m**2"   },
+  { 248, 0, "DQLWO",    "heatflux lw over water",          "W/m**2"   },
+  { 249, 0, "DQSEO",    "heatflux se over water",          "W/m**2"   },
+  { 250, 0, "DQLAO",    "heatflux la over water",          "W/m**2"   },
+  { 251, 0, "DQTHO",    "heatflux net over water",         "W/m**2"   },
+  { 252, 0, "DQSWI",    "heatflux sw over seaice",         "W/m**2"   },
+  { 253, 0, "DQLWI",    "heatflux lw over seaice",         "W/m**2"   },
+  { 254, 0, "DQSEI",    "heatflux se over seaice",         "W/m**2"   },
+  { 255, 0, "DQLAI",    "heatflux la over seaice",         "W/m**2"   },
+  { 256, 0, "DQTHI",    "heatflux net over seaice",        "W/m**2"   },
+  { 257, 0, "DTICEO",   "Equi. temp over seaice",          "K"        },
+  { 270, 0, "AOFLNHWO", "oasis net heat flux water",       "W/m**2"   },
+  { 271, 0, "AOFLSHWO", "oasis downward short wave",       "W/m**2"   },
+  { 272, 0, "AOFLRHIO", "oasis residual heat flux ice",    "W/m**2"   },
+  { 273, 0, "AOFLCHIO", "oasis conduct. heat flux ice",    "W/m**2"   },
+  { 274, 0, "AOFLFRWO", "oasis fluid fresh water flux",    "m/s"      },
+  { 275, 0, "AOFLFRIO", "oasis solid fresh water flux",    "m/s"      },
+  { 276, 0, "AOFLTXWO", "oasis wind stress water x",       "Pa/102"   },
+  { 277, 0, "AOFLTYWO", "oasis wind stress water y",       "Pa/102"   },
+  { 278, 0, "AOFLTXIO", "oasis wind stress ice x",         "Pa/102"   },
+  { 279, 0, "AOFLTYIO", "oasis wind stress ice x",         "Pa/102"   },
+  { 280, 0, "AOFLWSVO", "oasis wind speed",                "m/s"      },
+};
 
+static const PAR ecmwf[] = {
+  {   1, 0, "STRF",   "Stream function",                                            "m**2 s**-1"            },
+  {   2, 0, "VPOT",   "Velocity potential",                                         "m**2 s**-1"            },
+  {   3, 0, "PT",     "Potential temperature",                                      "K"                     },
+  {   4, 0, "EQPT",   "Equivalent potential temperature",                           "K"                     },
+  {   5, 0, "SEPT",   "Saturated equivalent potential temperature",                 "K"                     },
+  {  11, 0, "UDVW",   "U component of divergent wind",                              "m s**-1"               },
+  {  12, 0, "VDVW",   "V component of divergent wind",                              "m s**-1"               },
+  {  13, 0, "URTW",   "U component of rotational wind",                             "m s**-1"               },
+  {  14, 0, "VRTW",   "V component of rotational wind",                             "m s**-1"               },
+  {  21, 0, "UCTP",   "Unbalanced component of temperature",                        "K"                     },
+  {  22, 0, "UCLN",   "Unbalanced component of logarithm of surface pressure",       NULL                   },
+  {  23, 0, "UCDV",   "Unbalanced component of divergence",                         "s**-1"                 },
+  {  26, 0, "CL",     "Lake cover",                                                  NULL                   },
+  {  27, 0, "CVL",    "Low vegetation cover",                                        NULL                   },
+  {  28, 0, "CVH",    "High vegetation cover",                                       NULL                   },
+  {  29, 0, "TVL",    "Type of low vegetation",                                      NULL                   },
+  {  30, 0, "TVH",    "Type of high vegetation",                                     NULL                   },
+  {  31, 0, "CI",     "Sea-ice cover",                                               NULL                   },
+  {  32, 0, "ASN",    "Snow albedo",                                                 NULL                   },
+  {  33, 0, "RSN",    "Snow density kg",                                            "m**-3"                 },
+  {  34, 0, "SSTK",   "Sea surface temperature",                                    "K"                     },
+  {  35, 0, "ISTL1",  "Ice surface temperature layer 1",                            "K"                     },
+  {  36, 0, "ISTL2",  "Ice surface temperature layer 2",                            "K"                     },
+  {  37, 0, "ISTL3",  "Ice surface temperature layer 3",                            "K"                     },
+  {  38, 0, "ISTL4",  "Ice surface temperature layer 4",                            "K"                     },
+  {  39, 0, "SWVL1",  "Volumetric soil water layer 1",                              "m**3 m**-3"            },
+  {  40, 0, "SWVL2",  "Volumetric soil water layer 2",                              "m**3 m**-3"            },
+  {  41, 0, "SWVL3",  "Volumetric soil water layer 3",                              "m**3 m**-3"            },
+  {  42, 0, "SWVL4",  "Volumetric soil water layer 4",                              "m**3 m**-3"            },
+  {  43, 0, "SLT",    "Soil type",                                                   NULL                   },
+  {  44, 0, "ES",     "Snow evaporation m of water",                                 NULL                   },
+  {  45, 0, "SMLT",   "Snowmelt m of water",                                         NULL                   },
+  {  46, 0, "SDUR",   "Solar duration",                                             "s"                     },
+  {  47, 0, "DSRP",   "Direct solar radiation",                                     "w m**-2"               },
+  {  48, 0, "MAGSS",  "Magnitude of surface stress",                                "N m**-2 s"             },
+  {  49, 0, "WG10",   "Wind gust at 10 metres",                                     "m s**-1"               },
+  {  50, 0, "LSPF",   "Large-scale precipitation fraction",                         "s"                     },
+  {  51, 0, "MX2T24", "Maximum 2 metre temperature",                                "K"                     },
+  {  52, 0, "MN2T24", "Minimum 2 metre temperature",                                "K"                     },
+  {  53, 0, "MONT",   "Montgomery potential",                                       "m**2 s**-2"            },
+  {  54, 0, "PRES",   "Pressure",                                                   "Pa"                    },
+  {  55, 0, "MN2T24", "Mean 2 metre temperature past 24 hours",                     "K"                     },
+  {  56, 0, "MN2D24", "Mean 2 metre dewpoint temperature past 24 hours",            "K"                     },
+  {  60, 0, "PV",     "Potential vorticity",                                        "K m**2 kg**-1 s**-1"   },
+  { 127, 0, "AT",     "Atmospheric tide",                                            NULL                   },
+  { 128, 0, "BV",     "Budget values",                                               NULL                   },
+  { 129, 0, "Z",      "Geopotential",                                               "m**2 s**-2"            },
+  { 130, 0, "T",      "Temperature",                                                "K"                     },
+  { 131, 0, "U",      "U velocity",                                                 "m s**-1"               },
+  { 132, 0, "V",      "V velocity",                                                 "m s**-1"               },
+  { 133, 0, "Q",      "Specific humidity",                                          "kg kg**-1"             },
+  { 134, 0, "SP",     "Surface pressure",                                           "Pa"                    },
+  { 135, 0, "W",      "Vertical velocity",                                          "Pa s**-1"              },
+  { 136, 0, "TCW",    "Total column water",                                         "kg m**-2"              },
+  { 137, 0, "TCWV",   "Total column water vapour",                                  "kg m**-2"              },
+  { 138, 0, "VO",     "Vorticity (relative)",                                       "s**-1"                 },
+  { 139, 0, "STL1",   "Soil temperature level 1",                                   "K"                     },
+  { 140, 0, "SWL1",   "Soil wetness level 1 m of water",                             NULL                   },
+  { 141, 0, "SD",     "Snow depth         1 m of water equivalent",                  NULL                   },
+  { 142, 0, "LSP",    "Stratiform precipitation (Large scale precipitation)",       "m"                     },
+  { 143, 0, "CP",     "Convective precipitation",                                   "m"                     },
+  { 144, 0, "SF",     "Snowfall (convective + stratiform)",                         "m"                     },
+  { 145, 0, "BLD",    "Boundary layer dissipation",                                 "W m**-2 s"             },
+  { 146, 0, "SSHF",   "Surface sensible heat flux",                                 "W m**-2 s"             },
+  { 147, 0, "SLHF",   "Surface latent heat flux",                                   "W m**-2 s"             },
+  { 148, 0, "CHNK",   "Charnock",                                                    NULL                   },
+  { 149, 0, "SNR",    "Surface net radiation",                                      "W m**-2 s"             },
+  { 150, 0, "TNR",    "Top net radiation",                                           NULL                   },
+  { 151, 0, "MSL",    "Mean sea-level pressure",                                    "Pa"                    },
+  { 152, 0, "LNSP",   "Logarithm of surface pressure",                               NULL                   },
+  { 153, 0, "SWHR",   "Short-wave heating rate",                                    "K"                     },
+  { 154, 0, "LWHR",   "Long-wave heating rate",                                     "K"                     },
+  { 155, 0, "D",      "Divergence",                                                 "s**-1"                 },
+  { 156, 0, "GH",     "Height m Geopotential height",                                NULL                   },
+  { 157, 0, "R",      "Relative humidity",                                          "%"                     },
+  { 158, 0, "TSP",    "Tendency of surface pressure",                               "Pa s**-1"              },
+  { 159, 0, "BLH",    "Boundary layer height",                                      "m"                     },
+  { 160, 0, "SDOR",   "Standard deviation of orography",                             NULL                   },
+  { 161, 0, "ISOR",   "Anisotropy of sub-gridscale orography",                       NULL                   },
+  { 162, 0, "ANOR",   "Angle of sub-gridscale orography",                           "rad"                   },
+  { 163, 0, "SLOR",   "Slope of sub-gridscale orography",                            NULL                   },
+  { 164, 0, "TCC",    "Total cloud cover",                                           NULL                   },
+  { 165, 0, "U10M",   "10 metre U wind component",                                  "m s**-1"               },
+  { 166, 0, "V10M",   "10 metre V wind component",                                  "m s**-1"               },
+  { 167, 0, "T2M",    "2 metre temperature",                                        "K"                     },
+  { 168, 0, "D2M",    "2 metre dewpoint temperature",                               "K"                     },
+  { 169, 0, "SSRD",   "Surface solar radiation downwards",                          "W m**-2 s"             },
+  { 170, 0, "STL2",   "Soil temperature level 2",                                   "K"                     },
+  { 171, 0, "SWL2",   "Soil wetness level 2",                                       "m of water"            },
+  { 172, 0, "LSM",    "Land/sea mask",                                               NULL                   },
+  { 173, 0, "SR",     "Surface roughness",                                          "m"                     },
+  { 174, 0, "AL",     "Albedo",                                                      NULL                   },
+  { 175, 0, "STRD",   "Surface thermal radiation downwards",                        "W m**-2 s"             },
+  { 176, 0, "SSR",    "Surface solar radiation",                                    "W m**-2 s"             },
+  { 177, 0, "STR",    "Surface thermal radiation",                                  "W m**-2 s"             },
+  { 178, 0, "TSR",    "Top solar radiation",                                        "W m**-2 s"             },
+  { 179, 0, "TTR",    "Top thermal radiation",                                      "W m**-2 s"             },
+  { 180, 0, "EWSS",   "East/West surface stress",                                   "N m**-2 s"             },
+  { 181, 0, "NSSS",   "North/South surface stress",                                 "N m**-2 s"             },
+  { 182, 0, "E",      "Evaporation",                                                "m of water"            },
+  { 183, 0, "STL3",   "Soil temperature level 3",                                   "K"                     },
+  { 184, 0, "SWL3",   "Soil wetness level 3",                                       "m of water"            },
+  { 185, 0, "CCC",    "Convective cloud cover",                                      NULL                   },
+  { 186, 0, "LCC",    "Low cloud cover",                                             NULL                   },
+  { 187, 0, "MCC",    "Medium cloud cover",                                          NULL                   },
+  { 188, 0, "HCC",    "High cloud cover",                                            NULL                   },
+  { 189, 0, "SUND",   "Sunshine duration",                                          "s"                     },
+  { 190, 0, "EWOV",   "EW component of subgrid orographic variance",                "m**2"                  },
+  { 191, 0, "NSOV",   "NS component of subgrid orographic variance",                "m**2"                  },
+  { 192, 0, "NWOV",   "NWSE component of subgrid orographic variance",              "m**2"                  },
+  { 193, 0, "NEOV",   "NESW component of subgrid orographic variance",              "m**2"                  },
+  { 194, 0, "BTMP",   "Brightness temperature",                                     "K"                     },
+  { 195, 0, "LGWS",   "Lat. component of gravity wave stress",                      "N m**-2 s"             },
+  { 196, 0, "MGWS",   "Meridional component of gravity wave stress",                "N m**-2 s"             },
+  { 197, 0, "GWD",    "Gravity wave dissipation",                                   "W m**-2 s"             },
+  { 198, 0, "SRC",    "Skin reservoir content",                                     "m of water"            },
+  { 199, 0, "VEG",    "Vegetation fraction",                                         NULL                   },
+  { 200, 0, "VSO",    "Variance of sub-gridscale orography",                        "m**2"                  },
+  { 201, 0, "MX2T",   "Maximum 2 metre temperature since previous post-processing", "K"                     },
+  { 202, 0, "MN2T",   "Minimum 2 metre temperature since previous post-processing", "K"                     },
+  { 203, 0, "O3",     "Ozone mass mixing ratio",                                    "kg kg**-1"             },
+  { 204, 0, "PAW",    "Precipiation analysis weights",                               NULL                   },
+  { 205, 0, "RO",     "Runoff",                                                     "m"                     },
+  { 206, 0, "TCO3",   "Total column ozone",                                         "kg m**-2"              },
+  { 207, 0, "WS10",   "10 meter windspeed",                                         "m s**-1"               },
+  { 208, 0, "TSRC",   "Top net solar radiation, clear sky",                         "W m**-2"               },
+  { 209, 0, "TTRC",   "Top net thermal radiation, clear sky",                       "W m**-2"               },
+  { 210, 0, "SSRC",   "Surface net solar radiation, clear sky",                     "W m**-2"               },
+  { 211, 0, "STRC",   "Surface net thermal radiation, clear sky",                   "W m**-2"               },
+  { 212, 0, "SI",     "Solar insolation",                                           "W m**-2"               },
+  { 214, 0, "DHR",    "Diabatic heating by radiation",                              "K"                     },
+  { 215, 0, "DHVD",   "Diabatic heating by vertical diffusion",                     "K"                     },
+  { 216, 0, "DHCC",   "Diabatic heating by cumulus convection",                     "K"                     },
+  { 217, 0, "DHLC",   "Diabatic heating large-scale condensation",                  "K"                     },
+  { 218, 0, "VDZW",   "Vertical diffusion of zonal wind",                           "m s**-1"               },
+  { 219, 0, "VDMW",   "Vertical diffusion of meridional wind",                      "m s**-1"               },
+  { 220, 0, "EWGD",   "EW gravity wave drag tendency",                              "m s**-1"               },
+  { 221, 0, "NSGD",   "NS gravity wave drag tendency",                              "m s**-1"               },
+  { 222, 0, "CTZW",   "Convective tendency of zonal wind",                          "m s**-1"               },
+  { 223, 0, "CTMW",   "Convective tendency of meridional wind",                     "m s**-1"               },
+  { 224, 0, "VDH",    "Vertical diffusion of humidity",                             "kg kg**-1"             },
+  { 225, 0, "HTCC",   "Humidity tendency by cumulus convection",                    "kg kg**-1"             },
+  { 226, 0, "HTLC",   "Humidity tendency large-scale condensation",                 "kg kg**-1"             },
+  { 227, 0, "CRNH",   "Change from removing negative humidity",                     "kg kg**-1"             },
+  { 228, 0, "TP",     "Total precipitation",                                        "m"                     },
+  { 229, 0, "IEWS",   "Instantaneous X surface stress",                             "N m**-2"               },
+  { 230, 0, "INSS",   "Instantaneous Y surface stress",                             "N m**-2"               },
+  { 231, 0, "ISHF",   "Instantaneous surface heat flux",                            "W m**-2"               },
+  { 232, 0, "IE",     "Instantaneous moisture flux",                                "kg m**-2 s"            },
+  { 233, 0, "ASQ",    "Apparent surface humidity",                                  "kg kg**-1"             },
+  { 234, 0, "LSRH",   "Logarithm of surface roughness length for heat",              NULL                   },
+  { 235, 0, "SKT",    "Skin temperature",                                           "K"                     },
+  { 236, 0, "STL4",   "Soil temperature level 4",                                   "K"                     },
+  { 237, 0, "SWL4",   "Soil wetness level 4",                                       "m"                     },
+  { 238, 0, "TSN",    "Temperature of snow layer",                                  "K"                     },
+  { 239, 0, "CSF",    "Convective snowfall",                                        "m of water equivalent" },
+  { 240, 0, "LSF",    "Large-scale snowfall",                                       "m of water equivalent" },
+  { 241, 0, "ACF",    "Accumulated cloud fraction tendency",                         NULL                   },
+  { 242, 0, "ALW",    "Accumulated liquid water tendency",                           NULL                   },
+  { 243, 0, "FAL",    "Forecast albedo",                                             NULL                   },
+  { 244, 0, "FSR",    "Forecast surface roughness",                                 "m"                     },
+  { 245, 0, "FLSR",   "Forecast log of surface roughness for heat",                  NULL                   },
+  { 246, 0, "CLWC",   "Cloud liquid water content",                                 "kg kg**-1"             },
+  { 247, 0, "CIWC",   "Cloud ice water content",                                    "kg kg**-1"             },
+  { 248, 0, "CC",     "Cloud cover",                                                 NULL                   },
+  { 249, 0, "AIW",    "Accumulated ice water tendency",                              NULL                   },
+  { 250, 0, "ICE",    "Ice age",                                                     NULL                   },
+  { 251, 0, "ATTE",   "Adiabatic tendency of temperature",                          "K"                     },
+  { 252, 0, "ATHE",   "Adiabatic tendency of humidity",                             "kg kg**-1"             },
+  { 253, 0, "ATZE",   "Adiabatic tendency of zonal wind",                           "m s**-1"               },
+  { 254, 0, "ATMW",   "Adiabatic tendency of meridional wind",                      "m s**-1"               },
+};
 
-int gribGetSize(int fileID)
-{
-  int recsize;
-  long offset;
-  int ierr;
+static const PAR remo[] = {
+  {  14, 0, "FTKVM",     "turbulent transfer coefficient of momentum in the atmosphere",   NULL           },
+  {  15, 0, "FTKVH",     "turbulent transfer coefficient of heat in the atmosphere",       NULL           },
+  {  38, 0, "U10ER",     "10m u-velocity",                                                "m/s"           },
+  {  39, 0, "V10ER",     "10m v-velocity",                                                "m/s"           },
+  {  40, 0, "CAPE",      "convetive available potential energy",                           NULL           },
+  {  41, 0, "GHPBL",     "height of the planetary boudary layer",                         "gpm"           },
+  {  42, 0, "BETA",      "BETA",                                                           NULL           },
+  {  43, 0, "WMINLOK",   "WMINLOK",                                                        NULL           },
+  {  44, 0, "WMAXLOK",   "WMAXLOK",                                                        NULL           },
+  {  45, 0, "VBM10M",    "maximum of the expected gust velocity near the surface",        "m/s"           },
+  {  46, 0, "BFLHS",     "surface sensible heat flux",                                    "W/m**2"        },
+  {  47, 0, "BFLQDS",    "surface latent heat flux",                                      "W/m**2"        },
+  {  48, 0, "TMCM",      "turbulent transfer coefficient of momentum at the surface",      NULL           },
+  {  49, 0, "TRSOL",     "TRSOL",                                                          NULL           },
+  {  50, 0, "TMCH",      "turbulent transfer coefficient of heat at the surface",          NULL           },
+  {  51, 0, "EMTEF",     "EMTEF",                                                          NULL           },
+  {  52, 0, "TRSOF",     "TRSOF",                                                          NULL           },
+  {  53, 0, "DRAIN",     "drainage",                                                      "mm"            },
+  {  54, 0, "TSL",       "surface temperature (land)",                                    "K"             },
+  {  55, 0, "TSW",       "surface temperature (water)",                                   "K"             },
+  {  56, 0, "TSI",       "surface temperature (ice)",                                     "K"             },
+  {  57, 0, "USTRL",     "surface u-stress (land)",                                       "Pa"            },
+  {  58, 0, "USTRW",     "surface u-stress (water)",                                      "Pa"            },
+  {  59, 0, "USTRI",     "surface u-stress (ice)",                                        "Pa"            },
+  {  60, 0, "VSTRL",     "surface v-stress (land)",                                       "Pa"            },
+  {  61, 0, "VSTRW",     "surface v-stress (water)",                                      "Pa"            },
+  {  62, 0, "VSTRI",     "surface v-stress (ice)",                                        "Pa"            },
+  {  63, 0, "EVAPL",     "surface evaporation (land)",                                    "mm"            },
+  {  64, 0, "EVAPW",     "surface evaporation (water)",                                   "mm"            },
+  {  65, 0, "EVAPI",     "surface evaporation (ice)",                                     "mm"            },
+  {  66, 0, "AHFLL",     "surface latent heat flux (land)",                               "W/m**2"        },
+  {  67, 0, "AHFLW",     "surface latent heat flux (water)",                              "W/m**2"        },
+  {  68, 0, "AHFLI",     "surface latent heat flux (ice)",                                "W/m**2"        },
+  {  69, 0, "AHFSL",     "surface sensible heat flux (land)",                             "W/m**2"        },
+  {  70, 0, "AHFSW",     "surface sensible heat flux (water)",                            "W/m**2"        },
+  {  71, 0, "AHFSI",     "surface sensible heat flux (ice)",                              "W/m**2"        },
+  {  72, 0, "AZ0L",      "surface roughness length (land)",                               "m"             },
+  {  73, 0, "AZ0W",      "surface roughness length (water)",                              "m"             },
+  {  74, 0, "AZ0I",      "surface roughness length (ice)",                                "m"             },
+  {  75, 0, "ALSOL",     "surface albedo (land)",                                         "fract."        },
+  {  76, 0, "ALSOW",     "surface albedo (water)",                                        "fract."        },
+  {  77, 0, "ALSOI",     "surface albedo (ice)",                                          "fract."        },
+  {  81, 0, "TMCHL",     "turbulent transfer coefficient of heat at the surface (land)",   NULL           },
+  {  82, 0, "TMCHW",     "turbulent transfer coefficient of heat at the surface (water)",  NULL           },
+  {  83, 0, "TMCHI",     "turbulent transfer coefficient of heat at the surface (ice)",    NULL           },
+  {  84, 0, "QDBL",      "specific humidity surface (land)",                              "kg/kg"         },
+  {  85, 0, "QDBW",      "specific humidity surface (water)",                             "kg/kg"         },
+  {  86, 0, "QDBI",      "specific humidity surface (ice)",                               "kg/kg"         },
+  {  87, 0, "BFLHSL",    "surface sensible heat flux (land)",                             "W/m**2"        },
+  {  88, 0, "BFLHSW",    "surface sensible heat flux (water)",                            "W/m**2"        },
+  {  89, 0, "BFLHSI",    "surface sensible heat flux (ice)",                              "W/m**2"        },
+  {  90, 0, "BFLQDSL",   "surface latent heat flux (land)",                               "W/m**2"        },
+  {  91, 0, "BFLQDSW",   "surface latent heat flux (water)",                              "W/m**2"        },
+  {  92, 0, "BFLQDSI",   "surface latent heat flux (ice)",                                "W/m**2"        },
+  {  93, 0, "AHFICE",    "sea-ice: conductive heat",                                      "W/m"           },
+  {  94, 0, "QRES",      "residual heat flux for melting sea ice",                        "W/m**2"        },
+  {  95, 0, "SRFL",      "SRFL",                                                           NULL           },
+  {  96, 0, "QDBOXS",    "horizontal transport of water vapour",                          "kg/m**2"       },
+  {  97, 0, "QWBOXS",    "horizontal transport of cloud water",                           "kg/m**2"       },
+  {  98, 0, "EKBOXS",    "horizontal transport of kinetic energy",                        "(3600*J)/m**2" },
+  {  99, 0, "FHBOXS",    "horizontal transport of sensible heat",                         "(3600*J)/m**2" },
+  { 100, 0, "FIBOXS",    "horizontal transport of potential energy",                      "(3600*J)/m**2" },
+  { 101, 0, "TLAMBDA",   "heat conductivity of dry soil",                                 "W/(K*m)"       },
+  { 103, 0, "DLAMBDA",   "parameter for increasing the heat conductivity of the soil",     NULL           },
+  { 104, 0, "PORVOL",    "pore volume",                                                    NULL           },
+  { 105, 0, "FCAP",      "field capacity of soil",                                         NULL           },
+  { 106, 0, "WI3",       "fraction of frozen soil",                                        NULL           },
+  { 107, 0, "WI4",       "fraction of frozen soil",                                        NULL           },
+  { 108, 0, "WI5",       "fraction of frozen soil",                                        NULL           },
+  { 109, 0, "WI",        "fraction of frozen soil",                                        NULL           },
+  { 110, 0, "WICL",      "fraction of frozen soil",                                        NULL           },
+  { 112, 0, "QDB",       "specific humidity surface",                                     "kg/kg"         },
+  { 129, 0, "FIB",       "surface geopotential (orography)",                              "m"             },
+  { 130, 0, "T",         "temperature",                                                   "K"             },
+  { 131, 0, "U",         "u-velocity",                                                    "m/s"           },
+  { 132, 0, "V",         "v-velocity",                                                    "m/s"           },
+  { 133, 0, "QD",        "specific humidity",                                             "kg/kg"         },
+  { 134, 0, "PS",        "Surface pressure",                                              "Pa"            },
+  { 135, 0, "VERVEL",    "Vertical velocity",                                             "Pa/s"          },
+  { 138, 0, "SVO",       "vorticity",                                                     "1/s"           },
+  { 139, 0, "TS",        "surface temperature",                                           "K"             },
+  { 140, 0, "WS",        "soil wetness",                                                  "m"             },
+  { 141, 0, "SN",        "snow depth",                                                    "m"             },
+  { 142, 0, "APRL",      "large scale precipitation",                                     "mm"            },
+  { 143, 0, "APRC",      "convective  precipitation",                                     "mm"            },
+  { 144, 0, "APRS",      "snow fall",                                                     "mm"            },
+  { 145, 0, "VDIS",      "boundary layer dissipation",                                    "W/m**2"        },
+  { 146, 0, "AHFS",      "surface sensible heat flux",                                    "W/m**2"        },
+  { 147, 0, "AHFL",      "surface latent heat flux",                                      "W/m**2"        },
+  { 148, 0, "STREAM",    "streamfunction",                                                "m**2/s"        },
+  { 149, 0, "VELOPOT",   "velocity potential",                                            "m**2/s"        },
+  { 151, 0, "PSRED",     "mean sea level pressure",                                       "Pa"            },
+  { 152, 0, "LSP",       "log surface pressure",                                           NULL           },
+  { 153, 0, "QW",        "liquid water content",                                          "kg/kg"         },
+  { 155, 0, "SD",        "divergence",                                                    "1/s"           },
+  { 156, 0, "FI",        "geopotential height",                                           "gpm"           },
+  { 159, 0, "USTAR3",    "ustar**3",                                                      "m**3/s**3"     },
+  { 160, 0, "RUNOFF",    "surface runoff",                                                "mm"            },
+  { 162, 0, "ACLC",      "cloud cover",                                                   "fract."        },
+  { 163, 0, "ACLCV",     "total cloud cover",                                             "fract."        },
+  { 164, 0, "ACLCOV",    "total cloud cover",                                             "fract."        },
+  { 165, 0, "U10",       "10m u-velocity",                                                "m/s"           },
+  { 166, 0, "V10",       "10m v-velocity",                                                "m/s"           },
+  { 167, 0, "TEMP2",     "2m temperature",                                                "K"             },
+  { 168, 0, "DEW2",      "2m dew point temperature",                                      "K"             },
+  { 169, 0, "TSURF",     "surface temperature (land)",                                    "K"             },
+  { 170, 0, "TD",        "deep soil temperature",                                         "K"             },
+  { 171, 0, "WIND10",    "10m windspeed",                                                 "m/s"           },
+  { 172, 0, "BLA",       "land sea mask",                                                 "fract."        },
+  { 173, 0, "AZ0",       "surface roughness length",                                      "m"             },
+  { 174, 0, "ALB",       "surface background albedo",                                     "fract."        },
+  { 175, 0, "ALBEDO",    "surface albedo",                                                "fract."        },
+  { 176, 0, "SRADS",     "net surface solar radiation",                                   "W/m**2"        },
+  { 177, 0, "TRADS",     "net surface thermal radiation",                                 "W/m**2"        },
+  { 178, 0, "SRAD0",     "net top solar radiation",                                       "W/m**2"        },
+  { 179, 0, "TRAD0",     "top thermal radiation (OLR)",                                   "W/m**2"        },
+  { 180, 0, "USTR",      "surface u-stress",                                              "Pa"            },
+  { 181, 0, "VSTR",      "surface v-stress",                                              "Pa"            },
+  { 182, 0, "EVAP",      "surface evaporation",                                           "mm"            },
+  { 183, 0, "TDCL",      "soil temperature",                                              "K"             },
+  { 185, 0, "SRAFS",     "net surf. solar radiation   (clear sky)",                       "W/m**2"        },
+  { 186, 0, "TRAFS",     "net surf. thermal radiation (clear sky)",                       "W/m**2"        },
+  { 187, 0, "SRAF0",     "net top solar radiation     (clear sky)",                       "W/m**2"        },
+  { 188, 0, "TRAF0",     "net top thermal radiation   (clear sky)",                       "W/m**2"        },
+  { 189, 0, "SCLFS",     "surface solar cloud forcing",                                   "W/m**2"        },
+  { 190, 0, "TCLFS",     "surface thermal cloud forcing",                                 "W/m**2"        },
+  { 191, 0, "SCLF0",     "top solar cloud forcing",                                       "W/m**2"        },
+  { 192, 0, "TCLF0",     "top thermal cloud forcing",                                     "W/m**2"        },
+  { 194, 0, "WL",        "skin reservoir content",                                        "m"             },
+  { 195, 0, "USTRGW",    "u-gravity wave stress",                                         "Pa"            },
+  { 196, 0, "VSTRGW",    "v-gravity wave stress",                                         "Pa"            },
+  { 197, 0, "VDISGW",    "gravity wave dissipation",                                      "W/m**2"        },
+  { 198, 0, "VGRAT",     "vegetation ratio",                                               NULL           },
+  { 199, 0, "VAROR",     "orographic variance (for surface runoff)",                       NULL           },
+  { 200, 0, "VLT",       "leaf area index",                                                NULL           },
+  { 201, 0, "T2MAX",     "maximum 2m-temperature",                                        "K"             },
+  { 202, 0, "T2MIN",     "minimum 2m-temperature",                                        "K"             },
+  { 203, 0, "SRAD0U",    "top solar radiation upward",                                    "W/m**2"        },
+  { 204, 0, "SRADSU",    "surface solar radiation upward",                                "W/m**2"        },
+  { 205, 0, "TRADSU",    "surface thermal radiation upward",                              "W/m**2"        },
+  { 206, 0, "TSN",       "snow temperature",                                              "K"             },
+  { 207, 0, "TD3",       "soil temperature",                                              "K"             },
+  { 208, 0, "TD4",       "soil temperature",                                              "K"             },
+  { 209, 0, "TD5",       "soil temperature",                                              "K"             },
+  { 210, 0, "SEAICE",    "sea ice cover",                                                 "fract."        },
+  { 211, 0, "SICED",     "sea ice depth",                                                 "m"             },
+  { 212, 0, "FOREST",    "vegetation type",                                                NULL           },
+  { 213, 0, "TEFF",      "(effective) sea-ice skin temperature",                          "K"             },
+  { 214, 0, "TSMAX",     "maximum surface temperature",                                   "K"             },
+  { 215, 0, "TSMIN",     "minimum surface temperature",                                   "K"             },
+  { 216, 0, "WIMAX",     "maximum 10m-wind speed",                                        "m/s"           },
+  { 217, 0, "TOPMAX",    "maximum height of convective cloud tops",                       "Pa"            },
+  { 218, 0, "SNMEL",     "snow melt",                                                     "mm"            },
+  { 220, 0, "TSLIN",     "land: residual surface heat budget",                            "W/m**2"        },
+  { 221, 0, "DSNAC",     "snow depth change",                                             "mm"            },
+  { 222, 0, "EMTER",     "EMTER",                                                          NULL           },
+  { 223, 0, "ACLCAC",    "cloud cover",                                                   "fract."        },
+  { 224, 0, "TKE",       "turbulent kinetic energy",                                       NULL           },
+  { 226, 0, "FAO",       "FAO data set (soil data flags)",                                 NULL           },
+  { 227, 0, "RGCGN",     "heat capacity of soil",                                          NULL           },
+  { 229, 0, "WSMX",      "field capacity of soil",                                         NULL           },
+  { 230, 0, "QVI",       "vertically integrated specific humidity",                       "kg/m**2"       },
+  { 231, 0, "ALWCVI",    "vertically integrated liquid water cont.",                      "kg/m**2"       },
+  { 232, 0, "GLAC",      "glacier mask",                                                   NULL           },
+  { 253, 0, "PHI",       "latitude in real coordinates",                                  "degrees_north" },
+  { 254, 0, "RLA",       "longitude in real coordinates",                                 "degrees_east"  },
+  { 259, 0, "WINDSPEED", "windspeed (sqrt(u**2+v**2))",                                    NULL           },
+  { 260, 0, "PRECIP",    "total precipitation",                                            NULL           },
+};
 
-  ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
-  if ( ierr > 0 )
-    {
-      Warning("GRIB record not found!");
-      return (0);
-    }
+static const PAR cosmo002[] = {
+  {   1, 0, "P",         "pressure",                                          "Pa"         },
+  {   2, 0, "PMSL",      "mean sea level pressure",                           "Pa"         },
+  {   3, 0, "DPSDT",     "surface pressure change",                           "Pa s-1"     },
+  {   6, 0, "FI",        "geopotential",                                      "m2 s-2"     },
+  {   8, 0, "HH",        "height",                                            "m"          },
+  {  10, 0, "TO3",       "vertical integrated ozone content",                 "Dobson"     },
+  {  11, 0, "T",         "temperature",                                       "K"          },
+  {  15, 0, "TMAX",      "2m maximum temperature",                            "K"          },
+  {  16, 0, "TMIN",      "2m minimum temperature",                            "K"          },
+  {  17, 0, "TD",        "2m dew point temperature",                          "K"          },
+  {  31, 0, "DD",        "undefined",                                         "undefined"  },
+  {  32, 0, "FF",        "undefined",                                         "undefined"  },
+  {  33, 0, "U",         "U-component of wind",                               "m s-1"      },
+  {  34, 0, "V",         "V-component of wind",                               "m s-1"      },
+  {  39, 0, "OMEGA",     "omega",                                             "Pa s-1"     },
+  {  40, 0, "W",         "vertical wind velocity",                            "m s-1"      },
+  {  51, 0, "QV",        "specific humidity",                                 "kg kg-1"    },
+  {  52, 0, "RELHUM",    "relative humidity",                                 "%"          },
+  {  54, 0, "TQV",       "precipitable water",                                "kg m-2"     },
+  {  57, 0, "AEVAP",     "surface evaporation",                               "kg m-2"     },
+  {  58, 0, "TQI",       "vertical integrated cloud ice",                     "kg m-2"     },
+  {  59, 0, "TOT_PR",    "total precipitation rate",                          "kg m-2 s-1" },
+  {  61, 0, "TOT_PREC",  "total precipitation amount",                        "kg m-2"     },
+  {  65, 0, "W_SNOW",    "surface snow amount",                               "m"          },
+  {  66, 0, "H_SNOW",    "thickness of snow",                                 "m"          },
+  {  71, 0, "CLCT",      "total cloud cover",                                 "1"          },
+  {  72, 0, "CLC_CON",   "convective cloud area fraction",                    "1"          },
+  {  73, 0, "CLCL",      "low cloud cover",                                   "1"          },
+  {  74, 0, "CLCM",      "medium cloud cover",                                "1"          },
+  {  75, 0, "CLCH",      "high cloud cover",                                  "1"          },
+  {  76, 0, "TQC",       "vertical integrated cloud water",                   "kg m-2"     },
+  {  78, 0, "SNOW_CON",  "convective snowfall",                               "kg m-2"     },
+  {  79, 0, "SNOW_GSP",  "large scale snowfall",                              "kg m-2"     },
+  {  81, 0, "FR_LAND",   "land-sea fraction",                                 "1"          },
+  {  83, 0, "Z0",        "surface roughness length",                          "m"          },
+  {  84, 0, "ALB_RAD",   "surface albedo",                                    "1"          },
+  {  85, 0, "TSOIL",     "soil surface temperature",                          "K"          },
+  {  86, 0, "WSOIL",     "water content of 1. soil layer",                    "m"          },
+  {  87, 0, "PLCOV",     "vegetation area fraction",                          "1"          },
+  {  90, 0, "RUNOFF",    "subsurface runoff",                                 "kg m-2"     },
+  {  91, 0, "FR_ICE",    "sea ice area fraction",                             "1"          },
+  {  92, 0, "H_ICE",     "sea ice thickness",                                 "m"          },
+  { 111, 0, "ASOB",      "averaged surface net downward shortwave radiation", "W m-2"      },
+  { 112, 0, "ATHB",      "averaged surface net downward longwave radiation",  "W m-2"      },
+  { 113, 0, "ASOB",      "averaged TOA net downward shortwave radiation",     "W m-2"      },
+  { 114, 0, "ATHB",      "averaged TOA outgoing longwave radiation",          "W m-2"      },
+  { 115, 0, "ASWDIR",    "direct downward sw radiation at the surface",       "W m-2"      },
+  { 116, 0, "ASWDIFD",   "diffuse downward sw radiation at the surface",      "W m-2"      },
+  { 117, 0, "ASWDIFU",   "diffuse upwnward sw radiation at the surface",      "W m-2"      },
+  { 118, 0, "ALWD",      "downward lw radiation at the surface",              "W m-2"      },
+  { 119, 0, "ALWU",      "upward lw radiation at the surface",                "W m-2"      },
+  { 121, 0, "ALHFL",     "averaged surface latent heat flux",                 "W m-2"      },
+  { 122, 0, "ASHFL",     "averaged surface sensible heat flux",               "W m-2"      },
+  { 124, 0, "AUMFL",     "averaged eastward stress",                          "Pa"         },
+  { 125, 0, "AVMFL",     "averaged northward stress",                         "Pa"         },
+  { 128, 0, "SUNSH",     "undefined",                                         "undefined"  },
+  { 129, 0, "SUNSH2",    "undefined",                                         "undefined"  },
+  { 130, 0, "SUN_SUM",   "undefined",                                         "undefined"  },
+  { 131, 0, "SUN_SUM2",  "undefined",                                         "undefined"  },
+  { 133, 0, "FCOR",      "undefined",                                         "undefined"  },
+  { 134, 0, "SKYVIEW",   "sky-view factor",                                   "1"          },
+  { 137, 0, "SWDIR_COR", "topo correction of direct solar radiarion",         "1"          },
+};
 
-  if ( ierr == -1 )
-    return (0);
-  else if ( ierr == 1 )
-    return (0);
+static const PAR cosmo201[] = {
+  {   5, 0, "APAB",      "&",                                                         "W m-2"      },
+  {  13, 0, "SOHR_RAD",  "&",                                                         "K s-1"      },
+  {  14, 0, "THHR_RAD",  "&",                                                         "K s-1"      },
+  {  20, 0, "DURSUN",    "duration of sunshine",                                      "s"          },
+  {  29, 0, "CLC",       "cloud area fraction",                                       "1"          },
+  {  30, 0, "CLC_SGS",   "grid scale cloud area fraction",                            "1"          },
+  {  31, 0, "QC",        "specific cloud liquid water content",                       "kg kg-1"    },
+  {  33, 0, "QI",        "specific cloud ice content",                                "kg kg-1"    },
+  {  35, 0, "QR",        "specific rain content",                                     "kg kg-1"    },
+  {  36, 0, "QS",        "specific snow content",                                     "kg kg-1"    },
+  {  37, 0, "TQR",       "total rain water content vertically integrated",            "kg m-2"     },
+  {  38, 0, "TQS",       "total snow content vertically integrated",                  "kg m-2"     },
+  {  39, 0, "QG",        "specific graupel content",                                  "kg kg-1"    },
+  {  40, 0, "TQG",       "total graupel content vertically integrated",               "kg m-2"     },
+  {  41, 0, "TWATER",    "cloud condensed water content",                             "kg m-2"     },
+  {  42, 0, "TDIV_HUM",  "atmosphere water divergence",                               "kg m-2"     },
+  {  43, 0, "QC_RAD",    "sub scale specific cloud liquid water content",             "kg kg-1"    },
+  {  44, 0, "QI_RAD",    "sub scale specific cloud ice content",                      "kg kg-1"    },
+  {  61, 0, "CLW_CON",   "convective cloud liquid water",                             "1"          },
+  {  68, 0, "HBAS_CON",  "height of convective cloud base",                           "m"          },
+  {  69, 0, "HTOP_CON",  "height of convective cloud top",                            "m"          },
+  {  70, 0, "HBAS_CONI", "height of convective cloud base",                           "m"          },
+  {  71, 0, "HTOP_CONI", "height of convective cloud top",                            "m"          },
+  {  72, 0, "BAS_CON",   "index of convective cloud base",                            "1"          },
+  {  73, 0, "TOP_CON",   "index of convective cloud top",                             "1"          },
+  {  74, 0, "DT_CON",    "convective tendency of temperature",                        "K s-1"      },
+  {  75, 0, "DQV_CON",   "convective tendency of specific humidity",                  "s-1"        },
+  {  78, 0, "DU_CON",    "convective tendency of u-wind component",                   "m s-2"      },
+  {  79, 0, "DV_CON",    "convective tendency of v-wind component",                   "m s-2"      },
+  {  82, 0, "HTOP_DC",   "height of dry convection top",                              "m"          },
+  {  84, 0, "HZEROCL",   "height of freezing level",                                  "m"          },
+  {  85, 0, "SNOWLMT",   "height of the snow fall limit in m above sea level",        "m"          },
+  {  86, 0, "HCBAS",     "height of cloud base",                                      "m"          },
+  {  87, 0, "HCTOP",     "height of cloud top",                                       "m"          },
+  {  91, 0, "C_T_LK",    "&",                                                         "1"          },
+  {  92, 0, "GAMSO_LK",  "&",                                                         "m-1"        },
+  {  93, 0, "DP_BS_LK",  "&",                                                         "m"          },
+  {  94, 0, "H_B1_LK",   "&",                                                         "m"          },
+  {  95, 0, "H_ML_LK",   "&",                                                         "m"          },
+  {  96, 0, "DEPTH_LK",  "lake depth",                                                "m"          },
+  {  97, 0, "FETCH_LK",  "wind fetch over lake",                                      "m"          },
+  {  99, 0, "QRS",       "precipitation water (water loading)",                       "1"          },
+  { 100, 0, "PRR_GSP",   "mass flux density of large scale rainfall",                 "kg m-2 s-1" },
+  { 101, 0, "PRS_GSP",   "mass flux density of large scale snowfall",                 "kg m-2 s-1" },
+  { 102, 0, "RAIN_GSP",  "large scale rainfall",                                      "kg m-2"     },
+  { 111, 0, "PRR_CON",   "mass flux density of convective rainfall",                  "kg m-2 s-1" },
+  { 112, 0, "PRS_CON",   "mass flux density of convective snowfall",                  "kg m-2 s-1" },
+  { 113, 0, "RAIN_CON",  "convective rainfall",                                       "kg m-2"     },
+  { 129, 0, "FRESHSNW",  "freshness of snow",                                         "undefined"  },
+  { 131, 0, "PRG_GSP",   "mass flux density of large scale graupel",                  "kg m-2 s-1" },
+  { 132, 0, "GRAU_GSP",  "large scale graupel",                                       "kg m-2"     },
+  { 133, 0, "RHO_SNOW",  "density of snow",                                           "kg m-3"     },
+  { 139, 0, "PP",        "deviation from reference pressure",                         "Pa"         },
+  { 140, 0, "RCLD",      "standard deviation of saturation deficit",                  "undefined"  },
+  { 143, 0, "CAPE_MU",   "cape of most unstable parcel",                              "J kg-1"     },
+  { 144, 0, "CIN_MU",    "convective inhibition of most unstable parcel",             "J kg-1"     },
+  { 145, 0, "CAPE_ML",   "cape of mean surface layer parcel",                         "J kg-1"     },
+  { 146, 0, "CIN_ML",    "convective inhibition of mean surface layer parcel",        "J kg-1"     },
+  { 147, 0, "TKE_CON",   "convective turbulent kinetic energy",                       "undefined"  },
+  { 148, 0, "TKETENS",   "tendency of turbulent kinetic energy",                      "undefined"  },
+  { 152, 0, "TKE",       "turbulent kinetic energy",                                  "m2 s-2"     },
+  { 153, 0, "TKVM",      "diffusion coefficient of momentum",                         "m2 s-1"     },
+  { 154, 0, "TKVH",      "diffusion coefficient of heat",                             "m2 s-1"     },
+  { 170, 0, "TCM",       "drag coefficient of momentum",                              "1"          },
+  { 171, 0, "TCH",       "drag coefficient of heat",                                  "1"          },
+  { 187, 0, "VMAX",      "maximum turbulent wind gust in 10m",                        "m s-1"      },
+  { 190, 0, "TSOIL",     "&",                                                         "K"          },
+  { 191, 0, "TSOIL",     "&",                                                         "K"          },
+  { 192, 0, "TSOIL",     "&",                                                         "K"          },
+  { 193, 0, "TSOIL",     "mixed layer temperature",                                   "K"          },
+  { 194, 0, "TSOIL",     "mean temperature of water column",                          "K"          },
+  { 197, 0, "TSOIL",     "soil temperature",                                          "K"          },
+  { 198, 0, "W_SO",      "soil water content",                                        "m"          },
+  { 199, 0, "W_SO_ICE",  "soil frozen water content",                                 "m"          },
+  { 200, 0, "W_I",       "canopy water amount",                                       "m"          },
+  { 203, 0, "TSOIL",     "snow surface temperature",                                  "K"          },
+  { 215, 0, "TSOIL",     "temperature of ice upper surface",                          "K"          },
+  { 230, 0, "dBZ",       "unattenuated radar reflectivity in Rayleigh approximation", "1"          },
+  { 240, 0, "MFLX_CON",  "convective mass flux density",                              "kg m-2 s-1" },
+  { 241, 0, "CAPE_CON",  "&",                                                         "J kg-1"     },
+  { 243, 0, "QCVG_CON",  "&",                                                         "s-1"        },
+};
 
-  recsize = gribReadSize(fileID);
+static const PAR cosmo202[] = {
+  {  46, 0, "SSO_STDH",  "standard deviation of subgrid scale height",                "m"         },
+  {  47, 0, "SSO_GAMMA", "anisotropy of topography",                                  "-"         },
+  {  48, 0, "SSO_THETA", "angle between principal axis of orography and global east", "-"         },
+  {  49, 0, "SSO_SIGMA", "mean slope of subgrid scale orography",                     "-"         },
+  {  55, 0, "FR_LAKE",   "fraction of inland lake water",                             "1"         },
+  {  57, 0, "SOILTYP",   "soil type",                                                 "1"         },
+  {  61, 0, "LAI",       "leaf area index",                                           "1"         },
+  {  62, 0, "ROOTDP",    "root depth",                                                "m"         },
+  {  64, 0, "HMO3",      "air pressure at ozone maximum",                             "Pa"        },
+  {  65, 0, "VIO3",      "vertical integrated ozone amount",                          "Pa"        },
+  {  67, 0, "PLCOV_MX",  "vegetation area fraction maximum",                          "1"         },
+  {  68, 0, "PLCOV_MN",  "vegetation area fraction minimum",                          "1"         },
+  {  69, 0, "LAI_MX",    "leaf area index maximum",                                   "1"         },
+  {  70, 0, "LAI_MN",    "leaf area index minimum",                                   "1"         },
+  {  75, 0, "FOR_E",     "ground fraction covered by evergreen forest",               "-"         },
+  {  76, 0, "FOR_D",     "ground fraction covered by deciduous forest",               "-"         },
+  { 104, 0, "DQVDT",     "tendency of water vapor",                                   "s-1"       },
+  { 105, 0, "QVSFLX",    "surface flux of water vapour",                              "s-1m-2"    },
+  { 113, 0, "FC",        "coriolis parameter",                                        "s-1"       },
+  { 114, 0, "RLAT",      "latitude",                                                  "radian"    },
+  { 115, 0, "RLON",      "longitude",                                                 "radian"    },
+  { 121, 0, "ZTD",       "integrated total atmospheric refractivity",                 "undefined" },
+  { 122, 0, "ZWD",       "integrated wet atmospheric refractivity",                   "undefined" },
+  { 123, 0, "ZHD",       "integrated dry atmospheric refractivity",                   "undefined" },
+  { 180, 0, "O3",        "ozone mass mixing ratio",                                   "kg kg-1"   },
+  { 200, 0, "I131a",     "undefined",                                                 "undefined" },
+  { 201, 0, "I131a_DD",  "undefined",                                                 "undefined" },
+  { 202, 0, "I131a_WD",  "undefined",                                                 "undefined" },
+  { 203, 0, "Cs137",     "undefined",                                                 "undefined" },
+  { 204, 0, "Cs137_DD",  "undefined",                                                 "undefined" },
+  { 205, 0, "Cs137_WD",  "undefined",                                                 "undefined" },
+  { 206, 0, "Te132",     "undefined",                                                 "undefined" },
+  { 207, 0, "Te132_DD",  "undefined",                                                 "undefined" },
+  { 208, 0, "Te132_WD",  "undefined",                                                 "undefined" },
+  { 209, 0, "Zr95",      "undefined",                                                 "undefined" },
+  { 210, 0, "Zr95_DD",   "undefined",                                                 "undefined" },
+  { 211, 0, "Zr95_WD",   "undefined",                                                 "undefined" },
+  { 212, 0, "Kr85",      "undefined",                                                 "undefined" },
+  { 213, 0, "Kr85_DD",   "undefined",                                                 "undefined" },
+  { 214, 0, "Kr85_WD",   "undefined",                                                 "undefined" },
+  { 215, 0, "TRACER",    "undefined",                                                 "undefined" },
+  { 216, 0, "TRACER_DD", "undefined",                                                 "undefined" },
+  { 217, 0, "TRACER_WD", "undefined",                                                 "undefined" },
+  { 218, 0, "Xe133",     "undefined",                                                 "undefined" },
+  { 219, 0, "Xe133_DD",  "undefined",                                                 "undefined" },
+  { 220, 0, "Xe133_WD",  "undefined",                                                 "undefined" },
+  { 221, 0, "I131g",     "undefined",                                                 "undefined" },
+  { 222, 0, "I131g_DD",  "undefined",                                                 "undefined" },
+  { 223, 0, "I131g_WD",  "undefined",                                                 "undefined" },
+  { 224, 0, "I131o",     "undefined",                                                 "undefined" },
+  { 225, 0, "I131o_DD",  "undefined",                                                 "undefined" },
+  { 226, 0, "I131o_WD",  "undefined",                                                 "undefined" },
+  { 227, 0, "Ba140",     "undefined",                                                 "undefined" },
+  { 228, 0, "Ba140_DD",  "undefined",                                                 "undefined" },
+  { 229, 0, "Ba140_WD",  "undefined",                                                 "undefined" },
+  { 230, 0, "Sr90",      "undefined",                                                 "undefined" },
+  { 231, 0, "Sr90_DD",   "undefined",                                                 "undefined" },
+  { 232, 0, "Sr90_WD",   "undefined",                                                 "undefined" },
+  { 233, 0, "Ru103",     "undefined",                                                 "undefined" },
+  { 234, 0, "Ru103_DD",  "undefined",                                                 "undefined" },
+  { 235, 0, "Ru103_WD",  "undefined",                                                 "undefined" },
+};
 
-  if ( CGRIBEX_Debug ) Message("recsize = %d", recsize);
+static const PAR cosmo203[] = {
+  { 135, 0, "LCL_ML",   "undefined",                  "undefined" },
+  { 136, 0, "LFC_ML",   "undefined",                  "undefined" },
+  { 137, 0, "CAPE_3KM", "undefined",                  "undefined" },
+  { 138, 0, "SWISS00",  "swiss00 index",              "1"         },
+  { 139, 0, "SWISS12",  "swiss12 index",              "1"         },
+  { 147, 0, "SLI",      "surface lifted index",       "K"         },
+  { 149, 0, "SI",       "showalter index",            "K"         },
+  { 155, 0, "BRN",      "undefined",                  "undefined" },
+  { 156, 0, "HPBL",     "undefined",                  "undefined" },
+  { 203, 0, "CLDEPTH",  "normalized cloud depth",     "1"         },
+  { 204, 0, "CLCT_MOD", "modified_total_cloud_cover", "1"         },
+};
 
-  fileSetPos(fileID, (off_t) -4, SEEK_CUR);
+static const PAR cosmo205[] = {
+  {   1, 0, "SYNME5", "synthetic satellite images Meteosat5", "-" },
+  {   2, 0, "SYNME6", "synthetic satellite images Meteosat6", "-" },
+  {   3, 0, "SYNME7", "synthetic satellite images Meteosat7", "-" },
+  {   4, 0, "SYNMSG", "synthetic satellite images MSG",       "-" },
+};
 
-  return (recsize);
-}
+static const PAR cosmo250[] = {
+  {   1, 0, "QNH",       "sea level air pressure",                                         "hPa"                                },
+  {  11, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
+  {  12, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
+  {  13, 0, "D_T_2M_K",  "kalman correction to 2m temperature",                            "K"                                  },
+  {  14, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
+  {  15, 0, "TSOIL",     "2m temperature",                                                 "K"                                  },
+  {  16, 0, "RH_ICE",    "relative humidity over ice",                                     "%"                                  },
+  {  17, 0, "TD",        "dew point temperature",                                          "K"                                  },
+  {  18, 0, "D_TD",      "dew point depression",                                           "K"                                  },
+  {  19, 0, "THETAE",    "equivalent potential temperature",                               "K"                                  },
+  {  20, 0, "TD_2M_K",   "2m dew point temperature",                                       "K"                                  },
+  {  21, 0, "D_TD_2M_K", "kalman correction to 2m dew point temperature",                  "K"                                  },
+  {  22, 0, "TD_2M_OLD", "2m dew point temperature",                                       "K"                                  },
+  {  23, 0, "TD_2M_BUZ", "2m dew point temperature",                                       "K"                                  },
+  {  24, 0, "HI",        "heat index",                                                     "Fahrenheit"                         },
+  {  25, 0, "DURSUN_M",  "maximum duration of sunshine",                                   "s"                                  },
+  {  26, 0, "DURSUN_R",  "relative duration of sunshine",                                  "%"                                  },
+  {  52, 0, "RH_2M_K",   "2m relative humidity",                                           "%"                                  },
+  {  53, 0, "D_RH_2M_K", "kalman correction to 2m relative humidity",                      "%"                                  },
+  {  58, 0, "CLI_RATIO", "cloud ice ratio (Qi/Qc+Qi)",                                     "%"                                  },
+  {  61, 0, "TOT_SNOW",  "total precipitation in snow",                                    "kg/m**2"                            },
+  {  62, 0, "TOT_RAIN",  "total precipitation in rain",                                    "kg/m**2"                            },
+  {  63, 0, "TOT_CON",   "total convective precipitation",                                 "kg/m**2"                            },
+  {  64, 0, "TOT_GSP",   "total large scale precipitation",                                "kg/m**2"                            },
+  {  65, 0, "SNOW_%",    "percentage of precipitation in snow",                            "%"                                  },
+  {  66, 0, "CONV_%",    "percentage of convective precipitation",                         "%"                                  },
+  {  67, 0, "VORTP_ABS", "absolute",                                                       "VORTP_ABS 67 -1 absolute vorticity" },
+  {  68, 0, "VORTP_REL", "relative",                                                       "VORTP_REL 68 -1 relative vorticity" },
+  {  70, 0, "PDIFF_CON", "pressure difference between cloud base and cloud top",           "Pa"                                 },
+  {  71, 0, "TTOP_CON",  "temperature at cloud top",                                       "K"                                  },
+  {  80, 0, "GEM",       "emissivity of the ground",                                       "%"                                  },
+  {  82, 0, "Z0LOC",     "local surface roughness length",                                 "m"                                  },
+  { 110, 0, "LUM",       "luminosity",                                                     "klux"                               },
+  { 111, 0, "GLOB",      "global shortwave radiation at surface",                          "W/m**2"                             },
+  { 112, 0, "LW_IN_TG",  "incoming longwave radiation at surface",                         "W/m**2"                             },
+  { 113, 0, "LW_IN_TS",  "incoming longwave radiation at surface",                         "W/m**2"                             },
+  { 114, 0, "LW_IN_T2M", "incoming longwave radiation at surface",                         "W/m**2"                             },
+  { 115, 0, "SWISS_WE",  "Swiss",                                                          "SWISS_WE 115 1 Swiss coordinates"   },
+  { 116, 0, "SWISS_SN",  "Swiss",                                                          "SWISS_SN 116 1 Swiss coordinates"   },
+  { 150, 0, "KOINDEX",   "KO index",                                                       "K"                                  },
+  { 151, 0, "TTINDEX",   "total-totals index",                                             "K"                                  },
+  { 152, 0, "DCI",       "deep convection index",                                          "K"                                  },
+  { 153, 0, "SWEAT",     "severe weather thread index",                                    "undefined"                          },
+  { 154, 0, "ADEDO2",    "adedokun 2 index",                                               "K"                                  },
+  { 160, 0, "C_TSTORM",  "thunderstorm index using AdaBoost classifier",                   "undefined"                          },
+  { 161, 0, "CN_TSTORM", "thunderstorm probabilty using AdaBoost classifier",              "%"                                  },
+  { 200, 0, "WSHEARL",   "wind shear between surface and 3 km asl",                        "1/s"                                },
+  { 201, 0, "WSHEARM",   "wind shear between surface and 6 km asl",                        "1/s"                                },
+  { 202, 0, "WSHEARU",   "wind shear between 3 km (or surface) and 6 km asl",              "1/s"                                },
+  { 211, 0, "VWIN",      "maximum OLD turbulent wind gust in 10m",                         "m s-1"                              },
+  { 212, 0, "VW10M_20",  "maximum 10m wind speed",                                         "m s-1"                              },
+  { 213, 0, "VW10M_25",  "duration of VWIN_10M above 25 knots",                            "s"                                  },
+  { 214, 0, "VW10M_30",  "duration of VWIN_10M above 30 knots",                            "s"                                  },
+  { 215, 0, "VW10M_35",  "duration of VWIN_10M above 35 knots",                            "s"                                  },
+  { 216, 0, "VW10M_40",  "duration of VWIN_10M above 40 knots",                            "s"                                  },
+  { 217, 0, "VW10M_45",  "duration of VWIN_10M above 45 knots",                            "s"                                  },
+  { 218, 0, "VW10M_50",  "duration of VWIN_10M above 50 knots",                            "s"                                  },
+  { 219, 0, "VOLD",      "maximum turbulent wind gust in 10m",                             "m s-1"                              },
+  { 220, 0, "VJPS",      "maximum turbulent wind gust in 10m",                             "m s-1"                              },
+  { 221, 0, "VBRA",      "maximum Brasseur turbulent wind gust in 10m",                    "m s-1"                              },
+  { 222, 0, "VB10M_20",  "duration of VBRA_10M above 20 knots",                            "s"                                  },
+  { 223, 0, "VB10M_25",  "duration of VBRA_10M above 25 knots",                            "s"                                  },
+  { 224, 0, "VB10M_30",  "duration of VBRA_10M above 30 knots",                            "s"                                  },
+  { 225, 0, "VB10M_35",  "duration of VBRA_10M above 35 knots",                            "s"                                  },
+  { 226, 0, "VB10M_40",  "duration of VBRA_10M above 40 knots",                            "s"                                  },
+  { 227, 0, "VB10M_45",  "duration of VBRA_10M above 45 knots",                            "s"                                  },
+  { 228, 0, "VB10M_50",  "duration of VBRA_10M above 50 knots",                            "s"                                  },
+  { 231, 0, "VCON",      "maximum convective wind gust in 10m",                            "m s-1"                              },
+  { 232, 0, "VC10M_20",  "duration of VCON_10M above 20 knots",                            "s"                                  },
+  { 233, 0, "VC10M_25",  "duration of VCON_10M above 25 knots",                            "s"                                  },
+  { 234, 0, "VC10M_30",  "duration of VCON_10M above 30 knots",                            "s"                                  },
+  { 235, 0, "VC10M_35",  "duration of VCON_10M above 35 knots",                            "s"                                  },
+  { 236, 0, "VC10M_40",  "duration of VCON_10M above 40 knots",                            "s"                                  },
+  { 237, 0, "VC10M_45",  "duration of VCON_10M above 45 knots",                            "s"                                  },
+  { 238, 0, "VC10M_50",  "duration of VCON_10M above 50 knots",                            "s"                                  },
+  { 241, 0, "FMAX",      "maximum wind speed at k=ke",                                     "m s-1"                              },
+  { 242, 0, "USTARMAX",  "maximal u*=SQRT(Drag_coef)*fmax_10m",                            "m s-1"                              },
+  { 243, 0, "GLOB_DIF",  "global diffuse shortwave radiation at the surface",              "W/m**2"                             },
+  { 244, 0, "GLOB_DIR",  "global direct (beam) shortwave radiation at the surface",        "W/m**2"                             },
+  { 245, 0, "GLOB_vE",   "global shortwave radiation on a vertical surface facing east",   "W/m**2"                             },
+  { 246, 0, "GLOB_vS",   "global shortwave radiation on a vertical surface facing south",  "W/m**2"                             },
+  { 247, 0, "GLOB_vW",   "global shortwave radiation on a vertical surface facing west",   "W/m**2"                             },
+  { 248, 0, "GLOB_vN",   "global shortwave radiation on a vertical surface facing north",  "W/m**2"                             },
+  { 249, 0, "LW_TG_vS",  "incoming longwave radiation on a vertical surface facing south", "W/m**2"                             },
+  { 250, 0, "ENTH",      "enthalpy",                                                       "kJ/kg"                              },
+  { 251, 0, "ENTH",      "enthalpy",                                                       "kJ/kg"                              },
+  { 252, 0, "MIXRAT",    "mixing ratio",                                                   "g/kg"                               },
+  { 253, 0, "MIXRAT",    "mixing ratio",                                                   "g/kg"                               },
+  { 254, 0, "TW",        "wet bulb temperature",                                           "degC"                               },
+  { 255, 0, "TW",        "wet bulb temperature",                                           "degC"                               },
+};
 
 
-int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
+static void
+tableDefault(void)
 {
-  long offset;
-  int ierr = 0;
-  size_t nread, recsize, recsize0;
+  int tableID, instID, modelID;
 
-  ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
-  if ( ierr > 0 )
-    {
-      Warning("GRIB record not found!");
-      return (-2);
-    }
 
-  if ( ierr == -1 )
-    {
-      *buffersize = 0;
-      return (-1);
-    }
-  else if ( ierr == 1 )
-    {
-      *buffersize = 0;
-      return (-2);
-    }
+  /*
+   *  define table : echam4
+   */
 
-  recsize = gribReadSize(fileID);
+  instID  = institutInq(98, 255, "MPIMET", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(98, 255, "MPIMET", NULL);
 
-  buffer[0] = 'G';
-  buffer[1] = 'R';
-  buffer[2] = 'I';
-  buffer[3] = 'B';
+  modelID = modelInq(instID, 0, "ECHAM4");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "ECHAM4");
 
-  recsize0 = recsize;
+  tableID = tableDef(modelID, 128, "echam4");
 
-  if ( recsize > *buffersize )
-    {
-      recsize = *buffersize;
-      ierr = -3;
-    }
+  tableLink(tableID, echam4, sizeof(echam4) / sizeof(PAR));
 
-  *buffersize = recsize0;
+  /*
+   *  define table : echam5
+   */
 
-  nread = fileRead(fileID, &buffer[4], recsize-4);
+  instID  = institutInq(0, 0, "MPIMET", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MPIMET", NULL);
 
-  if ( nread != recsize-4 ) ierr = 1;
+  modelID = modelInq(instID, 0, "ECHAM5");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "ECHAM5");
 
-  return (ierr);
-}
+  tableID = tableDef(modelID, 128, "echam5");
 
+  tableLink(tableID, echam5, sizeof(echam5) / sizeof(PAR));
 
-int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
-{
-  int  nwrite = 0;
+  /*
+   *  define table : echam6
+   */
 
-  if( (nwrite = fileWrite(fileID, buffer, buffersize)) != (int) buffersize )
-    {
-      perror(__func__);
-      nwrite = -1;
-    }
+  instID  = institutInq(0, 0, "MPIMET", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MPIMET", NULL);
 
-  return ((int) nwrite);
-}
+  modelID = modelInq(instID, 0, "ECHAM6");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "ECHAM6");
 
+  tableID = tableDef(modelID, 128, "echam6");
 
-int gribrec_len(int b1, int b2, int b3)
-{
-  int gribsize;
+  tableLink(tableID, echam6, sizeof(echam6) / sizeof(PAR));
 
-  gribsize = (1-(int) ((unsigned) (b1&128) >> 6)) * (int) (((b1&127) << 16)+(b2<<8) + b3);
   /*
-    If count is negative, have to rescale by factor of -120.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( gribsize < 0 ) gribsize *= (-120);
+   *  define table : mpiom1
+   */
 
-  return (gribsize);
-}
+  instID  = institutInq(0, 0, "MPIMET", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MPIMET", NULL);
 
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
+  modelID = modelInq(instID, 0, "MPIOM1");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "MPIOM1");
 
+  tableID = tableDef(modelID, 128, "mpiom1");
 
-FILE *grprsm = NULL;
-double fref;
-double fmaxval;
-int nfref;
-int nfmaxval;
-int nrnd;
-int ndbg;
-int nvck;
-int nonoff;
-int noabort;
-int num2ok;
-int next2o;
-int nloc2o;
-int nsubce;
-int grib_calendar = -1;
+  tableLink(tableID, mpiom1, sizeof(mpiom1) / sizeof(PAR));
 
+  /*
+   *  define table : ecmwf
+   */
 
-void gribSetCalendar(int calendar)
-{
-  grib_calendar = calendar;
-}
+  instID  = institutInq(0, 0, "ECMWF", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "ECMWF", NULL);
 
+  modelID = modelInq(instID, 0, "");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "");
 
-void grsdef(void)
-{
-  /*
-C---->
-C**** GRSDEF - Initial (default) setting of common area variables
-C              for GRIBEX package.
-C
-C     Purpose.
-C     --------
-C
-C     Sets initial values for common area variables for all
-C     routines of GRIBEX package, if not already done.
-C
-C**   Interface.
-C     ----------
-C
-C     CALL GRSDEF
-C
-C     Input Parameters.
-C     -----------------
-C
-C     None.
-C
-C     Output Parameters.
-C     ------------------
-C
-C     None.
-C
-C     Method.
-C     -------
-C
-C     Self-explanatory.
-C
-C     Externals.
-C     ----------
-C
-C     None.
-C
-C     Reference.
-C     ----------
-C
-C     See subroutine GRIBEX.
-C
-C     Comments.
-C     ---------
-C
-C     None
-C
-C     Author.
-C     -------
-C
-C     J. Clochard, Meteo France, for ECMWF - March 1998.
-C
-C     Modifications.
-C     --------------
-C
-C     J. Clochard, Meteo France, for ECMWF - June 1999.
-C     Add variable NSUBCE.
-C     Use a static variable to determine if initialisation has already
-C     been done. NUSER removed .
-C     Reverse defaults for NEXT2O and NLOC2O, for consistency with
-C     version 13.023 of software .
-C
-  */
-  /*
-C     ----------------------------------------------------------------
-C*    Section 0 . Definition of variables.
-C     ----------------------------------------------------------------
-  */
-  char *envString;
-  char *env_stream;
-  static int lfirst = TRUE;
-  extern int CGRIBEX_Const;
+  tableID = tableDef(modelID, 128, "ecmwf");
 
-  if ( ! lfirst ) return;
+  tableLink(tableID, ecmwf, sizeof(ecmwf) / sizeof(PAR));
 
   /*
-    ----------------------------------------------------------------
-    Section 1 . Set values, conditionally.
-    ----------------------------------------------------------------
-  */
-  /*
-    Common area variables have not been set. Set them.
-    
-    User supplied reference value.
-  */
-  fref   = 0.0;
-  /*
-    Reference value supplied by user flag. Set to off.
-  */
-  nfref  = 0;
-  /*
-    User supplied maximum value.
-  */
-  fmaxval   = 0.0;
-  /*
-    Maximum value supplied by user flag. Set to off.
-  */
-  nfmaxval  = 0;
-  /*
-    Set rounding to 120 bytes on.
-  */
-  nrnd   = 1;
-  /*
-    Set GRIB calendar.
-  */
-  if ( grib_calendar == -1 )
-    {
-      grib_calendar = CALENDAR_PROLEPTIC;
-  
-      envString = getenv("GRIB_CALENDAR");
-      if ( envString )
-	{
-	  if      ( strncmp(envString, "standard", 8) == 0 )
-	    grib_calendar = CALENDAR_STANDARD;
-	  else if ( strncmp(envString, "proleptic", 9) == 0 )
-	    grib_calendar = CALENDAR_PROLEPTIC;
-	  else if ( strncmp(envString, "360days", 7) == 0 )
-	    grib_calendar = CALENDAR_360DAYS;
-	  else if ( strncmp(envString, "365days", 7) == 0 )
-	    grib_calendar = CALENDAR_365DAYS;
-	  else if ( strncmp(envString, "366days", 7) == 0 )
-	    grib_calendar = CALENDAR_366DAYS;
-	  else if ( strncmp(envString, "none", 4) == 0 )
-	    grib_calendar = CALENDAR_NONE;
-	}
-    }
-  /*
-    Set debug print off.
-  */
-  ndbg   = 0;
-  
-  envString = getenv("GRIBEX_DEBUG");
-  if ( envString != NULL )
-    {
-      if ( !strncmp(envString, "ON", 2) )
-        ndbg = 1;
-      else if( *envString == '1')
-        ndbg = 1;
-      else if( *envString == '2')
-        ndbg = 2;
-      else
-        ndbg = 0;
-    }
-  /*
-    Set GRIBEX compatibility mode.
-  */
-  envString = getenv("GRIB_GRIBEX_MODE_ON");
-  if ( envString != NULL )
-    {
-      if ( atoi(envString) == 1 ) CGRIBEX_Const = 0;
-    }
+   *  define table : remo
+   */
+
+  instID  = institutInq(0, 0, "MPIMET", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MPIMET", NULL);
+
+  modelID = modelInq(instID, 0, "REMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "REMO");
+
+  tableID = tableDef(modelID, 128, "remo");
+
+  tableLink(tableID, remo, sizeof(remo) / sizeof(PAR));
 
   /*
-    Set GRIB value checking on.
-  */
-  nvck   = 1;
-  
-  envString = getenv("GRIBEX_CHECK");
-  if ( envString )
-    {
-      if ( !strncmp(envString, "OFF", 3) )
-        nvck = 0;
-      else
-        nvck = 1;
-    }
-  /*
-    See if output stream needs changing
-  */
-  grprsm = stdout;
-  env_stream = getenv("GRPRS_STREAM");
-  if ( env_stream )
-    {
-      if ( isdigit((int) env_stream[0]) )
-	{
-	  int unit;
-	  unit = atoi(env_stream);
-	  if ( unit < 1 || unit > 99 )
-	    Warning("Invalid number for GRPRS_STREAM: %d", unit);
-	  else if ( unit == 2 )
-	    grprsm = stderr;
-	  else if ( unit == 6 )
-	    grprsm = stdout;
-	  else
-	    {
-	      char filename[] = "unit.00";
-	      sprintf(filename, "%2.2d", unit);
-	      grprsm = fopen(filename, "w");
-	      if ( ! grprsm )
-		SysError("GRPRS_STREAM = %d", unit);
-	    }
-	}
-      else
-	{
-	  if ( env_stream[0] )
-	    {
-	      grprsm = fopen(env_stream, "w");
-	      if ( ! grprsm )
-		SysError("GRPRS_STREAM = %s", env_stream);
-	    }
-	}
-    }
-  /*
-    Set P factor switch to default, user supplies the P factor.
-  */
-  nonoff = 0;
-  /*
-    Set abort flag to NO abort
-  */
-  noabort = 1;
+   *  define table : cosmo002
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 002, "cosmo002");
+
+  tableLink(tableID, cosmo002, sizeof(cosmo002) / sizeof(PAR));
+
   /*
-    Mark common area values set by user.
-  */
-  lfirst = FALSE;
+   *  define table : cosmo201
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 201, "cosmo201");
+
+  tableLink(tableID, cosmo201, sizeof(cosmo201) / sizeof(PAR));
+
   /*
-    Exhaustive use of all possible second-order packing methods
-    for HOPER='K'. Set to off.
-  */
-  num2ok  = 0;
+   *  define table : cosmo202
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 202, "cosmo202");
+
+  tableLink(tableID, cosmo202, sizeof(cosmo202) / sizeof(PAR));
+
   /*
-    Use of extended second-order packing methods for grid-point
-    encoding (HOPER='C' and 'K'). Set to on.
-  */
-  next2o  = 1;
+   *  define table : cosmo203
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 203, "cosmo203");
+
+  tableLink(tableID, cosmo203, sizeof(cosmo203) / sizeof(PAR));
+
   /*
-    Use of non-local second-order packing methods for grid-point
-    encoding (HOPER='C' and 'K'). Set to on.
-  */
-  nloc2o  = 1;
+   *  define table : cosmo205
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 205, "cosmo205");
+
+  tableLink(tableID, cosmo205, sizeof(cosmo205) / sizeof(PAR));
+
   /*
-    Use of (all valid) sub-centre values for ECMWF fields encoding .
-    encoding. Set to off.
-  */
-  nsubce  = 0;
+   *  define table : cosmo250
+   */
+
+  instID  = institutInq(0, 0, "MCH", NULL);
+  if ( instID == -1 )
+    instID  = institutDef(0, 0, "MCH", NULL);
+
+  modelID = modelInq(instID, 0, "COSMO");
+  if ( modelID == -1 )
+    modelID = modelDef(instID, 0, "COSMO");
+
+  tableID = tableDef(modelID, 250, "cosmo250");
+
+  tableLink(tableID, cosmo250, sizeof(cosmo250) / sizeof(PAR));
 }
 
-/* pack 8-bit bytes from 64-bit words to a packed buffer */
-/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (unsigned char) up[i]; */
+#endif  /* _TABLE_H */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-long packInt64(unsigned INT64 *up, unsigned char *cp, long bc, long tc)
-{
-#if defined (CRAY)
-  (void) _pack(up, cp, bc, tc);
-#else
-  U_BYTEORDER;
-  unsigned char *cp0;
-  unsigned INT64 upi, *up0, *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
-  long head, trail, inner, i, j;
-  long ipack = sizeof(INT64);
-  
-  /* Bytes until first word boundary in destination buffer */
+#include <ctype.h>
+#include <stddef.h>
+#include <string.h>
 
-  head = ( (long) cp ) & (ipack-1);
-  if ( head != 0 ) head = ipack - head;
 
-  inner = bc - head;
+#undef  UNDEFID
+#define UNDEFID -1
 
-  /* Trailing bytes which do not make a full word */
+/*int TableDefine = 0; */ /* Define new table also if the entry already exist */
+                          /* This is needed for createtable */
 
-  trail = inner & (ipack-1);
 
-  /* Number of bytes/words to be processed in fast loop */
+#define MAX_TABLE  256
+#define MAX_PARS   1024
 
-  inner -= trail;
-  inner /= ipack;
+typedef struct
+{
+  int    used;
+  PAR   *pars;
+  int    npars;
+  int    modelID;
+  int    number;
+  char  *name;
+}
+PARTAB;
 
-  ip0 = up + head;
-  ip1 = ip0 + 1;
-  ip2 = ip0 + 2;
-  ip3 = ip0 + 3;
-  ip4 = ip0 + 4;
-  ip5 = ip0 + 5;
-  ip6 = ip0 + 6;
-  ip7 = ip0 + 7;
+static PARTAB parTable[MAX_TABLE];
+static int  parTableSize = MAX_TABLE;
+static int  parTableNum  = 0;
+static int  ParTableInit = 0;
 
-  up0 = (unsigned INT64 *) (cp + head);
+static char *tablePath = NULL;
 
-  /* Here we should process any bytes until the first word boundary 
-   * of our destination buffer 
-   * That code is missing so far  because our output buffer is 
-   * word aligned by FORTRAN 
-   */
+static void tableDefModelID(int tableID, int modelID);
+static void tableDefNum(int tableID, int tablenum);
 
-  j = 0;
 
-  if ( IS_BIGENDIAN() )
+void tableDefEntry(int tableID, int id, const char *name,
+		   const char *longname, const char *units)
+{
+  int item;
+
+  if ( tableID >= 0 && tableID < MAX_TABLE && parTable[tableID].used) { } else
+    Error("Invalid table ID %d", tableID);
+  item = parTable[tableID].npars++;
+  parTable[tableID].pars[item].id       = id;
+  parTable[tableID].pars[item].dupflags = 0;
+  parTable[tableID].pars[item].name     = NULL;
+  parTable[tableID].pars[item].longname = NULL;
+  parTable[tableID].pars[item].units    = NULL;
+
+  if ( name && strlen(name) > 0 )
     {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-      for ( i = 0 ; i < inner ; i++ )
-	{
-	  upi =             (   ip0[j]          << 56 ) 
-	                 |  ( ( ip1[j] & 0xFF ) << 48 )
-	                 |  ( ( ip2[j] & 0xFF ) << 40 )
-	                 |  ( ( ip3[j] & 0xFF ) << 32 )
-	                 |  ( ( ip4[j] & 0xFF ) << 24 ) ;
-	  up0[i] = upi   |  ( ( ip5[j] & 0xFF ) << 16 )
-	                 |  ( ( ip6[j] & 0xFF ) <<  8 )
-	                 |    ( ip7[j] & 0xFF ) ;
-	  j += ipack;
-	}
+      parTable[tableID].pars[item].name     = strdupx(name);
+      parTable[tableID].pars[item].dupflags |= TABLE_DUP_NAME;
     }
-  else
+  if ( longname && strlen(longname) > 0 )
     {
-      for ( i = 0 ; i < inner ; i++ )
-	{
-	  upi =             (   ip7[j]          << 56 ) 
-	                 |  ( ( ip6[j] & 0xFF ) << 48 )
-                         |  ( ( ip5[j] & 0xFF ) << 40 )
-                         |  ( ( ip4[j] & 0xFF ) << 32 )
-                         |  ( ( ip3[j] & 0xFF ) << 24 ) ;
-	  up0[i] = upi   |  ( ( ip2[j] & 0xFF ) << 16 )
-                         |  ( ( ip1[j] & 0xFF ) <<  8 )
-                         |    ( ip0[j] & 0xFF ) ;
-	  j += ipack;
-	}
+      parTable[tableID].pars[item].longname = strdupx(longname);
+      parTable[tableID].pars[item].dupflags |= TABLE_DUP_LONGNAME;
     }
-
-  cp0 = (unsigned char *) ( up0 + inner );
-  if ( trail > 0 )
+  if ( units && strlen(units) > 0 )
     {
-      up0[inner] = 0;
-      for ( i = 0 ; i < trail ; i ++ )
-	{
-	  *cp0 = (unsigned char) ip0[ipack*inner+i];
-	  cp0++;
-	}
+      parTable[tableID].pars[item].units    = strdupx(units);
+      parTable[tableID].pars[item].dupflags |= TABLE_DUP_UNITS;
     }
+}
 
-  if ( tc != -1 )
+static void tableLink(int tableID, const PAR *pars, int npars)
+{
+  int item;
+
+  for ( item = 0; item < npars; item++ )
     {
-      bc++;
-      *cp0 = (unsigned char) tc;
+      parTable[tableID].pars[item].id       = pars[item].id;
+      parTable[tableID].pars[item].dupflags = 0;
+      parTable[tableID].pars[item].name     = pars[item].name;
+      parTable[tableID].pars[item].longname = pars[item].longname;
+      parTable[tableID].pars[item].units    = pars[item].units;
     }
-#endif
-  return (bc);
+
+  parTable[tableID].npars = npars;
 }
 
-/* unpack 8-bit bytes from a packed buffer with 64-bit words */
-/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT64) cp[i]; */
+static void parTableInitEntry(int tableID)
+{
+  parTable[tableID].used    = 0;
+  parTable[tableID].pars    = NULL;
+  parTable[tableID].npars   = 0;
+  parTable[tableID].modelID = UNDEFID;
+  parTable[tableID].number  = UNDEFID;
+  parTable[tableID].name    = NULL;
+}
 
-long unpackInt64(const unsigned char *cp, unsigned INT64 *up, long bc, long tc)
+static void tableGetPath(void)
 {
-  U_BYTEORDER;
-  const unsigned char *cp0;
-  unsigned INT64 *up0;
-  unsigned INT64 *ip0, *ip1, *ip2, *ip3, *ip4, *ip5, *ip6, *ip7;
-  long head, trail, inner, i, j;
-  long offset;
-  long ipack = sizeof(INT64);
+  char *path;
 
-  UNUSED(tc);
+  path = getenv("TABLEPATH");
 
-  /* Bytes until first word boundary in source buffer */
+  if ( path ) tablePath = strdupx(path);
+  /*
+  printf("tablePath = %s\n", tablePath);
+  */
+}
 
-  head = ( (long) cp ) & (ipack-1);
-  if ( head != 0 ) head = ipack - head;
-  if ( head > bc ) head = bc;
+static void parTableFinalize(void)
+{
+  for (int tableID = 0; tableID < MAX_TABLE; ++tableID)
+    if (parTable[tableID].used)
+      {
+        int npars = parTable[tableID].npars;
+        for (int item = 0; item < npars; ++item)
+          {
+            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_NAME)
+              free((void *)parTable[tableID].pars[item].name);
+            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_LONGNAME)
+              free((void *)parTable[tableID].pars[item].longname);
+            if (parTable[tableID].pars[item].dupflags & TABLE_DUP_UNITS)
+              free((void *)parTable[tableID].pars[item].units);
+          }
+        free(parTable[tableID].pars);
+        free(parTable[tableID].name);
+      }
+}
 
-  inner = bc - head;
+static void parTableInit(void)
+{
+  ParTableInit = 1;
 
-  /* Trailing bytes which do not make a full word */
- 
-  trail = inner & (ipack-1);
- 
-  /* Number of bytes/words to be processed in fast loop */
+  atexit(parTableFinalize);
+  if ( cdiPartabIntern )
+    tableDefault();
 
-  inner -= trail;
-  inner /= ipack;
+  tableGetPath();
+}
 
-  ip0 = up + head;
-  ip1 = ip0 + 1;
-  ip2 = ip0 + 2;
-  ip3 = ip0 + 3;
-  ip4 = ip0 + 4;
-  ip5 = ip0 + 5;
-  ip6 = ip0 + 6;
-  ip7 = ip0 + 7;
+static int tableNewEntry()
+{
+  int tableID = 0;
+  static int init = 0;
 
-  up0 = (unsigned INT64 *) (cp + head);
+  if ( ! init )
+    {
+      for ( tableID = 0; tableID < parTableSize; tableID++ )
+	parTableInitEntry(tableID);
+      init = 1;
+    }
 
-  /* Process any bytes until the first word boundary 
-   * of our source buffer 
-   */
-  for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT64) cp[i];
+  /*
+    Look for a free slot in parTable.
+  */
+  for ( tableID = 0; tableID < parTableSize; tableID++ )
+    {
+      if ( ! parTable[tableID].used ) break;
+    }
 
-  j = 0;
+  if ( tableID == parTableSize )
+    Error("no more entries!");
 
-  if ( IS_BIGENDIAN() )
-    {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-      for ( i = 0 ; i < inner ; i++ )
-	{
-	  ip0[j] = (up0[i] >> 56) & 0xFF;
-	  ip1[j] = (up0[i] >> 48) & 0xFF;
-	  ip2[j] = (up0[i] >> 40) & 0xFF;
-	  ip3[j] = (up0[i] >> 32) & 0xFF;
-	  ip4[j] = (up0[i] >> 24) & 0xFF;
-	  ip5[j] = (up0[i] >> 16) & 0xFF;
-	  ip6[j] = (up0[i] >>  8) & 0xFF;
-	  ip7[j] = (up0[i])       & 0xFF;
+  parTable[tableID].used = 1;
+  parTableNum++;
 
-	  j += ipack;
-	}
+  return (tableID);
+}
+
+static int
+decodeForm1(char *pline, char *name, char *longname, char *units)
+{
+  char *pstart, *pend;
+
+  /* FIXME: parse success isn't verified */
+  /* long level =  */strtol(pline, &pline, 10);
+  while ( isspace((int) *pline) ) pline++;
+
+  pstart = pline;
+  while ( ! (isspace((int) *pline) || *pline == 0) ) pline++;
+  size_t len = (size_t)(pline - pstart);
+  if ( len > 0 )
+    {
+      memcpy(name, pstart, len);
+      name[len] = 0;
     }
   else
+    return (0);
+
+  len = strlen(pline);
+  if ( len == 0 ) return (0);
+
+  /* Format 1 : code name add mult longname [units] */
+  /* FIXME: successful parse isn't verified */
+  /* double add  =  */strtod(pline, &pline);
+  /* FIXME: successful parse isn't verified */
+  /* double mult =  */strtod(pline, &pline);
+
+  while ( isspace((int) *pline) ) pline++;
+
+  len = strlen(pline);
+  if ( len > 0 )
     {
-      for ( i = 0 ; i < inner ; i++ )
+      pstart = pline;
+      pend = strrchr(pline, '[');
+      if ( pend == pstart )
+        len = 0;
+      else
+        {
+          if ( pend )
+            pend--;
+          else
+            pend = pstart + len;
+          while ( isspace((int) *pend) ) pend--;
+          len = (size_t)(pend - pstart + 1);
+        }
+      if ( len > 0 )
 	{
-	  ip7[j] = (up0[i] >> 56) & 0xFF;
-	  ip6[j] = (up0[i] >> 48) & 0xFF;
-	  ip5[j] = (up0[i] >> 40) & 0xFF;
-	  ip4[j] = (up0[i] >> 32) & 0xFF;
-	  ip3[j] = (up0[i] >> 24) & 0xFF;
-	  ip2[j] = (up0[i] >> 16) & 0xFF;
-	  ip1[j] = (up0[i] >>  8) & 0xFF;
-	  ip0[j] = (up0[i])       & 0xFF;
+	  memcpy(longname, pstart, len);
+	  longname[len] = 0;
+	}
+      pstart = strrchr(pline, '[');
+      if ( pstart )
+	{
+	  pstart++;
+	  while ( isspace((int) *pstart) ) pstart++;
+	  pend = strchr(pstart, ']');
+	  if ( ! pend ) return (0);
+	  pend--;
+	  while ( isspace((int) *pend) ) pend--;
+	  len = (size_t)(pend - pstart + 1);
+	  if ( len > 0 )
+	    {
+	      memcpy(units, pstart, len);
+	      units[len] = 0;
+	    }
+	}
+    }
+
+  return (0);
+}
+
+static int
+decodeForm2(char *pline, char *name, char *longname, char *units)
+{
+  /* Format 2 : code | name | longname | units */
+  char *pend;
+  size_t len;
+
+  pline = strchr(pline, '|');
+  pline++;
+
+  while ( isspace((int) *pline) ) pline++;
+  if (*pline != '|')
+    {
+      pend = strchr(pline, '|');
+      if ( ! pend )
+        {
+          pend = pline;
+          while ( ! isspace((int) *pend) ) pend++;
+          len = (size_t)(pend - pline);
+          if ( len > 0 )
+            {
+              memcpy(name, pline, len);
+              name[len] = 0;
+            }
+          return (0);
+        }
+      else
+        {
+          pend--;
+          while ( isspace((int) *pend) ) pend--;
+          len = (size_t)(pend - pline + 1);
+          if ( len > 0 )
+            {
+              memcpy(name, pline, len);
+              name[len] = 0;
+            }
+        }
+    }
+  else
+    name[0] = '\0';
 
-	  j += ipack;
-	}
+  pline = strchr(pline, '|');
+  pline++;
+  while ( isspace((int) *pline) ) pline++;
+  pend = strchr(pline, '|');
+  if ( !pend ) pend = strchr(pline, 0);
+  pend--;
+  while ( isspace((int) *pend) ) pend--;
+  len = (size_t)(pend - pline + 1);
+  if ( len > 0 )
+    {
+      memcpy(longname, pline, len);
+      longname[len] = 0;
     }
 
-  if ( trail > 0 )
+  pline = strchr(pline, '|');
+  if ( pline )
     {
-      offset = head + ipack*inner;
-      cp0 = cp + offset;
-      for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT64) cp0[i];
+      pline++;
+      while ( isspace((int) *pline) ) pline++;
+      pend = strchr(pline, '|');
+      if ( !pend ) pend = strchr(pline, 0);
+      pend--;
+      while ( isspace((int) *pend) ) pend--;
+      ptrdiff_t len = pend - pline + 1;
+      if ( len < 0 ) len = 0;
+      memcpy(units, pline, (size_t)len);
+      units[len] = 0;
     }
-  /*
-  if ( tc != -1 ) {
-    bc++;
-    *cp0 = (unsigned char) tc;
-  }
-  */
-  return (bc);
-}
 
-/* pack 8-bit bytes from 32-bit words to a packed buffer */
-/* same as : for ( int i = 0; i < bc; ++i ) cp[i] = (char) up[i]; */
+  return (0);
+}
 
-#if  defined  (INT32)
-long packInt32(unsigned INT32 *up, unsigned char *cp, long bc, long tc)
+int tableRead(const char *tablefile)
 {
-  U_BYTEORDER;
-  unsigned char *cp0;
-  unsigned INT32 *up0, *ip0, *ip1, *ip2, *ip3;
-  long head, trail, inner, i, j;
-  long ipack = sizeof(INT32);
-  
-  /* Bytes until first word boundary in destination buffer */
+  char line[1024], *pline;
+  int lnr = 0;
+  int id;
+  char name[256], longname[256], units[256];
+  int tableID = UNDEFID;
+  int err;
+  char *tablename;
+  FILE *tablefp;
 
-  head = ( (long) cp ) & (ipack-1);
-  if ( head != 0 ) head = ipack - head;
+  tablefp = fopen(tablefile, "r");
+  if ( tablefp == NULL ) return (tableID);
 
-  inner = bc - head;
+  tablename = strrchr(tablefile, '/');
+  if ( tablename == 0 ) tablename = (char *) tablefile;
+  else                  tablename++;
 
-  /* Trailing bytes which do not make a full word */
+  tableID = tableDef(-1, 0, tablename);
 
-  trail = inner & (ipack-1);
+  while ( fgets(line, 1023, tablefp) )
+    {
+      size_t len = strlen(line);
+      if ( line[len-1] == '\n' ) line[len-1] = '\0';
+      lnr++;
+      id       = CDI_UNDEFID;
+      name[0]     = 0;
+      longname[0] = 0;
+      units[0]    = 0;
+      if ( line[0] == '#' ) continue;
+      pline = line;
 
-  /* Number of bytes/words to be processed in fast loop */
+      len = strlen(pline);
+      if ( len < 4 ) continue;
+      while ( isspace((int) *pline) ) pline++;
+      id = atoi(pline);
+      /*
+      if ( id > 255 ) id -= 256;
+      */
+      if ( id == 0 ) continue;
 
-  inner -= trail;
-  inner /= ipack;
+      while ( isdigit((int) *pline) ) pline++; 
 
-  ip0 = up + head;
-  ip1 = ip0 + 1;
-  ip2 = ip0 + 2;
-  ip3 = ip0 + 3;
+      if ( strchr(pline, '|') )
+	err = decodeForm2(pline, name, longname, units);
+      else
+	err = decodeForm1(pline, name, longname, units);
 
-  up0 = (unsigned INT32 *) (cp + head);
+      if ( err ) continue;
 
-  /* Here we should process any bytes until the first word boundary 
-   * of our destination buffer 
-   * That code is missing so far  because our output buffer is 
-   * word aligned by FORTRAN 
-   */
+      if ( strlen(name) == 0 ) sprintf(name, "var%d", id);
 
-  j = 0;
+      tableDefEntry(tableID, id, name, longname, units);
+    }
 
-  if ( IS_BIGENDIAN() )
+  return (tableID);
+}
+
+static int tableFromEnv(int modelID, int tablenum)
+{
+  int tableID = UNDEFID;
+  char tablename[256] = {'\0'};
+  int tablenamefound = 0;
+
+  const char *modelName;
+  if ( (modelName = modelInqNamePtr(modelID)) )
     {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-      for ( i = 0 ; i < inner ; i++ )
+      strcpy(tablename, modelName);
+      if ( tablenum )
 	{
-	  up0[i] =          (   ip0[j]          << 24 ) 
-	                 |  ( ( ip1[j] & 0xFF ) << 16 )
-	                 |  ( ( ip2[j] & 0xFF ) <<  8 )
-	                 |    ( ip3[j] & 0xFF ) ;
-	  j += ipack;
+	  size_t len = strlen(tablename);
+	  sprintf(tablename+len, "_%03d", tablenum);
 	}
+      tablenamefound = 1;
     }
   else
     {
-      for ( i = 0 ; i < inner ; i++ )
+      int instID = modelInqInstitut(modelID);
+      if ( instID != UNDEFID )
 	{
-	  up0[i] =          (   ip3[j]          << 24 ) 
-	                 |  ( ( ip2[j] & 0xFF ) << 16 )
-                         |  ( ( ip1[j] & 0xFF ) <<  8 )
-                         |    ( ip0[j] & 0xFF ) ;
-	  j += ipack;
+          const char *instName;
+	  if ( (instName = institutInqNamePtr(instID)) )
+	    {
+	      strcpy(tablename, instName);
+	      if ( tablenum )
+		{
+		  size_t len = strlen(tablename);
+		  sprintf(tablename+len, "_%03d", tablenum);
+		}
+	      tablenamefound = 1;
+	    }
 	}
     }
 
-  cp0 = (unsigned char *) ( up0 + inner );
-  if ( trail > 0 )
+  if ( tablenamefound )
     {
-      up0[inner] = 0;
-      for ( i = 0 ; i < trail ; i ++ )
+      size_t lenp = 0, lenf;
+      char *tablefile = NULL;
+      if ( tablePath )
+	lenp = strlen(tablePath);
+      lenf = strlen(tablename);
+      /* if (tablePath) printf("tablePath = %s\n", tablePath); */
+      /* if (tablename) printf("tableName = %s\n", tablename); */
+      tablefile = (char *) malloc(lenp+lenf+3);
+      if ( tablePath )
 	{
-	  *cp0 = (unsigned char) ip0[ipack*inner+i];
-	  cp0++;
+	  strcpy(tablefile, tablePath);
+	  strcat(tablefile, "/");
 	}
-    }
+      else
+	tablefile[0] = '\0';
+      strcat(tablefile, tablename);
+      /* if (tablefile) printf("tableFile = %s\n", tablefile); */
 
-  if ( tc != -1 )
-    {
-      bc++;
-      *cp0 = (unsigned char) tc;
+      tableID = tableRead(tablefile);
+      if ( tableID != UNDEFID )
+	{
+	  tableDefModelID(tableID, modelID);
+	  tableDefNum(tableID, tablenum);
+	}
+      /* printf("tableID = %d %s\n", tableID, tablefile); */
+
+      free(tablefile);
     }
 
-  return (bc);
+  return (tableID);
 }
-#endif
-
-/* unpack 8-bit bytes from a packed buffer with 32-bit words */
-/* same as : for ( int i = 0; i < bc; ++i ) up[i] = (INT32) cp[i]; */
 
-#if  defined  (INT32)
-long unpackInt32(const unsigned char *cp, unsigned INT32 *up, long bc, long tc)
+int tableInq(int modelID, int tablenum, const char *tablename)
 {
-  U_BYTEORDER;
-  const unsigned char *cp0;
-  unsigned INT32 *up0;
-  unsigned INT32 *ip0, *ip1, *ip2, *ip3;
-  long head, trail, inner, i, j;
-  long offset;
-  long ipack = sizeof(INT32);
-
-  UNUSED(tc);
-
-  /* Bytes until first word boundary in source buffer */
-
-  head = ( (long) cp ) & (ipack-1);
-  if ( head != 0 ) head = ipack - head;
-  if ( head > bc ) head = bc;
-
-  inner = bc - head;
-
-  /* Trailing bytes which do not make a full word */
- 
-  trail = inner & (ipack-1);
- 
-  /* Number of bytes/words to be processed in fast loop */
-
-  inner -= trail;
-  inner /= ipack;
-
-  ip0 = up + head;
-  ip1 = ip0 + 1;
-  ip2 = ip0 + 2;
-  ip3 = ip0 + 3;
-
-  up0 = (unsigned INT32 *) (cp + head);
-
-  /* Process any bytes until the first word boundary 
-   * of our source buffer 
-   */
-  for ( i = 0 ; i < head ; i++ ) up[i] = (unsigned INT32) cp[i];
+  int tableID = UNDEFID;
+  int modelID2 = UNDEFID;
+  char tablefile[256] = {'\0'};
 
-  j = 0;
+  if ( ! ParTableInit ) parTableInit();
 
-  if ( IS_BIGENDIAN() )
+  if ( tablename )
     {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-      for ( i = 0 ; i < inner ; i++ )
+      size_t len;
+      strcpy(tablefile, tablename);
+      /*
+      printf("tableInq: tablefile = >%s<\n", tablefile);
+      */
+      /* search for internal table */
+      for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
 	{
-	  ip0[j] = (up0[i] >> 24) & 0xFF;
-	  ip1[j] = (up0[i] >> 16) & 0xFF;
-	  ip2[j] = (up0[i] >>  8) & 0xFF;
-	  ip3[j] = (up0[i])       & 0xFF;
-
-	  j += ipack;
+	  if ( parTable[tableID].used && parTable[tableID].name )
+	    {
+	      /* len = strlen(parTable[tableID].name); */
+	      len = strlen(tablename);
+	      if ( memcmp(parTable[tableID].name, tablename, len) == 0 ) break;
+	    }
 	}
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
+      if ( CDI_Debug )
+	Message("tableID = %d tablename = %s", tableID, tablename);
     }
   else
     {
-      for ( i = 0 ; i < inner ; i++ )
+      for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
 	{
-	  ip3[j] = (up0[i] >> 24) & 0xFF;
-	  ip2[j] = (up0[i] >> 16) & 0xFF;
-	  ip1[j] = (up0[i] >>  8) & 0xFF;
-	  ip0[j] = (up0[i])       & 0xFF;
-
-	  j += ipack;
+	  if ( parTable[tableID].used )
+	    {
+	      if ( parTable[tableID].modelID == modelID &&
+		   parTable[tableID].number  == tablenum ) break;
+	    }
 	}
-    }
-
-  if ( trail > 0 )
-    {
-      offset = head + ipack*inner;
-      cp0 = cp + offset;
-      for ( i = 0 ; i < trail ; i++ ) up[i+offset] = (unsigned INT32) cp0[i];
-    }
-  /*
-  if ( tc != -1 ) {
-    bc++;
-    *cp0 = (unsigned char) tc;
-  }
-  */
-
-  return (bc);
-}
-#endif
-#include <stdio.h>
-
-void prtbin(int kin, int knbit, int *kout, int *kerr)
-{
-  /*
-
-    Produces a decimal number with ones and zeroes
-    corresponding to the ones and zeroes of the input
-    binary number.
-    eg input number 1011 binary, output number 1011 decimal.
-
 
-    Input Parameters:
-    
-       kin   - Integer variable containing binary number.
-
-       knbit - Number of bits in binary number.
-
-    Output Parameters:
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
 
-       kout  - Integer variable containing decimal value
-               with ones and zeroes corresponding to those of
-	       the input binary number.
+      if ( tableID == UNDEFID )
+	{
+	  if ( modelID != UNDEFID )
+	    {
+              const char *modelName;
+	      if ( (modelName = modelInqNamePtr(modelID)) )
+		{
+		  strcpy(tablefile, modelName);
+		  size_t len = strlen(tablefile);
+		  for ( size_t i = 0; i < len; i++)
+		    if ( tablefile[i] == '.' ) tablefile[i] = '\0';
+		  modelID2 = modelInq(-1, 0, tablefile);
+		}
+	    }
+	  if ( modelID2 != UNDEFID )
+	    for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
+	      {
+		if ( parTable[tableID].used )
+		  {
+		    if ( parTable[tableID].modelID == modelID2 &&
+			 parTable[tableID].number  == tablenum ) break;
+		  }
+	      }
+	}
 
-       kerr  - 0, If no error.
-               1, Number of bits in binary number exceeds
-	          maximum allowed or is less than 1.
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
 
+      if ( tableID == UNDEFID && modelID != UNDEFID )
+	tableID = tableFromEnv(modelID, tablenum);
 
-    Converted from EMOS routine PRTBIN.
+      if ( CDI_Debug )
+	if ( tablename )
+	  Message("tableID = %d tablename = %s", tableID, tablename);
+    }
 
-       Uwe Schulzweida   MPIfM   01/04/2001
+  return (tableID);
+}
 
-  */
-  int idec;
-  int ik;
-  int itemp;
-  int j;
+int tableDef(int modelID, int tablenum, const char *tablename)
+{
+  int tableID = UNDEFID;
 
+  if ( ! ParTableInit ) parTableInit();
   /*
-    Check length of binary number to ensure decimal number
-    generated will fit in the computer word - in this case will
-    it fit in a Cray 48 bit integer?
-  */
-  if ( knbit < 1 || knbit > 14 )
+  if ( ! (modelID == UNDEFID && tablenum == 0) )
+    tableID = tableInq(modelID, tablenum, tablename);
+    */
+  if ( tableID == UNDEFID )
     {
-      *kerr = 1;
-      printf(" prtbin : Error in binary number length - %3d bits.\n", knbit);
-      return;
-    }
-  else
-    *kerr = 0;
-  /*
-    -----------------------------------------------------------------
-    Section 1. Generate required number.
-    -----------------------------------------------------------------
-  */
-  *kout = 0;
-  ik    = kin;
-  idec  = 1;
+      tableID = tableNewEntry();
 
-  for ( j = 0; j < knbit; j++ )
-    {
-      itemp = ik - ( (ik/2)*2 );
-      *kout = (*kout) + itemp * idec;
-      ik    = ik / 2;
-      idec  = idec * 10;
+      parTable[tableID].modelID = modelID;
+      parTable[tableID].number  = tablenum;
+      if ( tablename )
+	parTable[tableID].name = strdupx(tablename);
+
+      parTable[tableID].pars = (PAR *) malloc(MAX_PARS * sizeof(PAR));
     }
 
-  return;
+  return (tableID);
 }
 
-
-void ref2ibm(double *pref, int kbits)
+static void tableDefModelID(int tableID, int modelID)
 {
-  /*
-
-    Purpose:
-    --------
-
-    Code and check reference value in IBM format
-
-    Input Parameters:
-    -----------------
-
-    pref       - Reference value
-    kbits      - Number of bits per computer word.
-
-    Output Parameters:
-    ------------------
-
-    pref       - Reference value
-
-    Method:
-    -------
-
-    Codes in IBM format, then decides to ensure that reference 
-    value used for packing is not different from that stored
-    because of packing differences.
-
-    Externals.
-    ----------
-
-    confp3    - Encode into IBM floating point format.
-    decfp2    - Decode from IBM floating point format.
-
-    Reference:
-    ----------
-
-    None.
+  parTable[tableID].modelID = modelID;
+}
 
-    Comments:
-    --------
+static void tableDefNum(int tableID, int tablenum)
+{
+  parTable[tableID].number  = tablenum;
+}
 
-    None.
+int tableInqNum(int tableID)
+{
+  int number = 0;
 
-    Author:
-    -------
+  if ( tableID >= 0 && tableID < MAX_TABLE )
+    number = parTable[tableID].number;
 
-    J.D.Chambers     ECMWF      17:05:94
+  return (number);
+}
 
-    Modifications:
-    --------------
+int tableInqModel(int tableID)
+{
+  int modelID = -1;
 
-    Uwe Schulzweida   MPIfM   01/04/2001
+  if ( tableID >= 0 && tableID < MAX_TABLE )
+    modelID = parTable[tableID].modelID;
 
-    Convert to C from EMOS library version 130
+  return (modelID);
+}
 
-  */
+static void partabCheckID(int item)
+{
+  if ( item < 0 || item >= parTableSize )
+    Error("item %d undefined!", item);
 
-  static int itrnd;
-  static int kexp, kmant;
-  static double ztemp, zdumm;
-  extern int CGRIBEX_Debug;
+  if ( ! parTable[item].name )
+    Error("item %d name undefined!", item);
+}
 
-  /* ----------------------------------------------------------------- */
-  /*   Section 1. Convert to and from IBM format.                      */
-  /* ----------------------------------------------------------------- */
+const char *tableInqNamePtr(int tableID)
+{
+  const char *tablename = NULL;
 
-  /*  Convert floating point reference value to IBM representation. */
+  if ( CDI_Debug )
+    Message("tableID = %d", tableID);
 
-  itrnd = 1;
-  zdumm = ztemp = *pref;
-  confp3(zdumm, &kexp, &kmant, kbits, itrnd);
+  if ( ! ParTableInit ) parTableInit();
 
-  if ( kexp == 0 && kmant == 0 ) return;
+  if ( tableID >= 0 && tableID < parTableSize )
+    if ( parTable[tableID].name )
+      tablename = parTable[tableID].name;
 
-  /*  Set reference value to that actually stored in the GRIB code. */
+  return (tablename);
+}
 
-  *pref = decfp2(kexp, kmant);
+void tableWrite(const char *ptfile, int tableID)
+{
+  int item, npars;
+  size_t maxname = 4, maxlname = 10, maxunits = 2;
+  FILE *ptfp;
+  int tablenum, modelID, instID = CDI_UNDEFID;
+  int center = 0, subcenter = 0;
+  const char *instnameptr = NULL, *modelnameptr = NULL;
 
-  /*  If the nearest number which can be represented in */
-  /*  GRIB format is greater than the reference value,  */
-  /*  find the nearest number in GRIB format lower      */
-  /*  than the reference value.                         */
+  if ( CDI_Debug )
+    Message("write parameter table %d to %s", tableID, ptfile);
 
-  if ( ztemp < *pref )
+  if ( tableID == UNDEFID )
     {
-      /*  Convert floating point to GRIB representation */
-      /*  using truncation to ensure that the converted */
-      /*  number is smaller than the original one.      */
+      Warning("parameter table ID undefined");
+      return;
+    }
 
-      itrnd = 0;
-      zdumm = *pref = ztemp;
-      confp3(zdumm, &kexp, &kmant, kbits, itrnd);
+  partabCheckID(tableID);
 
-      /*  Set reference value to that stored in the GRIB code. */
+  ptfp = fopen(ptfile, "w");
 
-      *pref = decfp2(kexp, kmant);
+  npars = parTable[tableID].npars;
 
-      if ( ztemp < *pref )
+  for ( item = 0; item < npars; item++)
+    {
+      if ( parTable[tableID].pars[item].name )
 	{
-	  if ( CGRIBEX_Debug )
-	    {
-	      Message("Reference value error.");
-	      Message("Notify Met.Applications Section.");
-	      Message("ZTEMP = ", ztemp);
-	      Message("PREF = ", pref);
-	    }
-	  *pref = ztemp;
+	  size_t lenname = strlen(parTable[tableID].pars[item].name);
+	  if ( lenname  > maxname )  maxname  = lenname;
+	}
+
+      if ( parTable[tableID].pars[item].longname )
+	{
+	  size_t lenlname = strlen(parTable[tableID].pars[item].longname);
+	  if ( lenlname > maxlname ) maxlname = lenlname;
+	}
+
+      if ( parTable[tableID].pars[item].units )
+	{
+	  size_t lenunits = strlen(parTable[tableID].pars[item].units);
+	  if ( lenunits > maxunits ) maxunits = lenunits;
 	}
     }
 
-  return;
-} /* ref2ibm */
-#include <string.h>
+  tablenum = tableInqNum(tableID);
+  modelID = parTable[tableID].modelID;
+  if ( modelID != CDI_UNDEFID )
+    {
+      modelnameptr = modelInqNamePtr(modelID);
+      instID = modelInqInstitut(modelID);
+    }
+  if ( instID != CDI_UNDEFID )
+    {
+      center = institutInqCenter(instID);
+      subcenter = institutInqSubcenter(instID);
+      instnameptr = institutInqNamePtr(instID);
+    }
+
+  fprintf(ptfp, "# Parameter table\n");
+  fprintf(ptfp, "#\n");
+  if ( tablenum )
+    fprintf(ptfp, "# TABLE_ID=%d\n", tablenum);
+  fprintf(ptfp, "# TABLE_NAME=%s\n", parTable[tableID].name);
+  if ( modelnameptr )
+    fprintf(ptfp, "# TABLE_MODEL=%s\n", modelnameptr);
+  if ( instnameptr )
+    fprintf(ptfp, "# TABLE_INSTITUT=%s\n", instnameptr);
+  if ( center )
+    fprintf(ptfp, "# TABLE_CENTER=%d\n", center);
+  if ( subcenter )
+    fprintf(ptfp, "# TABLE_SUBCENTER=%d\n", subcenter);
+  fprintf(ptfp, "#\n");
+  fprintf(ptfp, "#\n");
+  fprintf(ptfp, "# id       = parameter ID\n");
+  fprintf(ptfp, "# name     = variable name\n");
+  fprintf(ptfp, "# title    = long name (description)\n");
+  fprintf(ptfp, "# units    = variable units\n");
+  fprintf(ptfp, "#\n");
+  fprintf(ptfp, "# The format of each record is:\n");
+  fprintf(ptfp, "#\n");
+  fprintf(ptfp, "# id | %-*s | %-*s | %-*s\n",
+	  (int)maxname,  "name",
+	  (int)maxlname, "title",
+	  (int)maxunits, "units");
+	  
+  for ( item = 0; item < npars; item++)
+    {
+      const char *name = parTable[tableID].pars[item].name,
+        *longname = parTable[tableID].pars[item].longname,
+        *units = parTable[tableID].pars[item].units;
+      if ( name == NULL ) name = " ";
+      if ( longname == NULL ) longname = " ";
+      if ( units == NULL ) units = " ";
+      fprintf(ptfp, "%4d | %-*s | %-*s | %-*s\n",
+	      parTable[tableID].pars[item].id,
+	      (int)maxname, name,
+	      (int)maxlname, longname,
+	      (int)maxunits, units);
+    }
 
+  fclose(ptfp);
+}
 
-int correct_bdslen(int bdslen, long recsize, long gribpos)
+
+void tableWriteC(const char *filename, int tableID)
 {
-  /*
-    If a very large product, the section 4 length field holds
-    the number of bytes in the product after section 4 upto
-    the end of the padding bytes.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( recsize > JP23SET ) bdslen = recsize - gribpos - bdslen;
-  return (bdslen);
+  FILE *ptfp = fopen(filename, "w");
+  if (!ptfp)
+    Error("failed to open file \"%s\"!", filename);
+  if ( CDI_Debug )
+    Message("write parameter table %d to %s", tableID, filename);
+  tableFWriteC(ptfp, tableID);
+  fclose(ptfp);
 }
 
-
-int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
-		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize)
+void tableFWriteC(FILE *ptfp, int tableID)
 {
-  unsigned char *pds, *gds, *bms, *bds;
-  unsigned char *bufpointer, *is, *section;
-  int gribversion, grib1offset;
-  long gribsize = 0, recsize;
-  int bdslen;
+  const char chelp[] = "";
+  int item, npars;
+  size_t maxname = 0, maxlname = 0, maxunits = 0;
+  char tablename[256];
 
-  *gribrecsize = 0;
-  *pdsp = NULL;
-  *gdsp = NULL;
-  *bmsp = NULL;
-  *bdsp = NULL;
 
-  section = gribbuffer;
-  is = gribbuffer;
-  if ( ! GRIB_START(section) )
+  if ( tableID == UNDEFID )
     {
-      fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
-	      section[0], section[1], section[2], section[3]);
-      return (-1);
+      Warning("parameter table ID undefined");
+      return;
     }
 
-  recsize = gribrec_len(section[4], section[5], section[6]);
+  partabCheckID(tableID);
 
-  gribversion = GRIB_EDITION(section);
-  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
+  npars = parTable[tableID].npars;
 
-  if ( gribversion == 1 )
-    grib1offset = 4;
-  else
-    grib1offset = 0;
+  for ( item = 0; item < npars; item++)
+    {
+      if ( parTable[tableID].pars[item].name )
+	{
+	  size_t lenname = strlen(parTable[tableID].pars[item].name);
+	  if ( lenname  > maxname )  maxname  = lenname;
+	}
 
-  pds = is + 4 + grib1offset;
-  bufpointer = pds + PDS_Len;
-  gribsize += 4 + grib1offset + PDS_Len;
+      if ( parTable[tableID].pars[item].longname )
+	{
+	  size_t lenlname = strlen(parTable[tableID].pars[item].longname);
+	  if ( lenlname > maxlname ) maxlname = lenlname;
+	}
 
-  if ( PDS_HAS_GDS )
-    {
-      gds = bufpointer;
-      bufpointer += GDS_Len;
-      gribsize += GDS_Len;
-    }
-  else
-    {
-      gds = NULL;
+      if ( parTable[tableID].pars[item].units )
+	{
+	  size_t lenunits = strlen(parTable[tableID].pars[item].units);
+	  if ( lenunits > maxunits ) maxunits = lenunits;
+	}
     }
 
-  if ( PDS_HAS_BMS )
-    {
-      bms = bufpointer;
-      bufpointer += BMS_Len;
-      gribsize += BMS_Len;
-    }
-  else
+  strncpy(tablename, parTable[tableID].name, sizeof (tablename));
+  tablename[sizeof (tablename) - 1] = '\0';
+  {
+    size_t len = strlen(tablename);
+    for (size_t i = 0; i < len; i++ )
+      if ( tablename[i] == '.' ) tablename[i] = '_';
+  }
+  fprintf(ptfp, "static const PAR %s[] = {\n", tablename);
+
+  for ( item = 0; item < npars; item++ )
     {
-      bms = NULL;
+      size_t len = strlen(parTable[tableID].pars[item].name),
+        llen = parTable[tableID].pars[item].longname
+        ? strlen(parTable[tableID].pars[item].longname) : 0,
+        ulen = parTable[tableID].pars[item].units
+        ? strlen(parTable[tableID].pars[item].units) : 0;
+      fprintf(ptfp, "  {%4d, 0, \"%s\", %-*s%c%s%s, %-*s%c%s%s %-*s},\n",
+	      parTable[tableID].pars[item].id,
+	      parTable[tableID].pars[item].name, (int)(maxname-len), chelp,
+              llen?'"':' ',
+              llen?parTable[tableID].pars[item].longname:"NULL",
+              llen?"\"":"",
+              (int)(maxlname-(llen?llen:3)), chelp,
+              ulen?'"':' ',
+              ulen?parTable[tableID].pars[item].units:"NULL",
+              ulen?"\"":"",
+              (int)(maxunits-(ulen?ulen:3)), chelp);
     }
 
-  bds = bufpointer;
-  bdslen = BDS_Len;
-  bdslen = correct_bdslen(bdslen, recsize, gribsize);
-  bufpointer += bdslen;
-  gribsize += bdslen;
-  gribsize += 4;
+  fprintf(ptfp, "};\n\n");
+}
 
-  *pdsp = pds;
-  *gdsp = gds;
-  *bmsp = bms;
-  *bdsp = bds;
 
-  *gribrecsize = gribsize;
+int tableInqParCode(int tableID, char *varname, int *code)
+{
+  int err = 1;
 
-  if ( gribbufsize < gribsize )
+  if ( tableID != UNDEFID && varname != NULL )
     {
-      fprintf(stderr, "Length of GRIB message is inconsistent (grib_buffer_size=%ld < grib_record_size=%ld)!\n", gribbufsize, gribsize);
-      return (1);
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].name
+               && strcmp(parTable[tableID].pars[item].name, varname) == 0 )
+            {
+              *code = parTable[tableID].pars[item].id;
+              err = 0;
+              break;
+            }
+	}
     }
 
-  /* end section - "7777" in ascii */
-  if ( !GRIB_FIN(bufpointer) )
+  return (err);
+}
+
+
+int tableInqParName(int tableID, int code, char *varname)
+{
+  int err = 1;
+
+  if ( tableID != UNDEFID )
     {
-      fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
-	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
-      return (-2);
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      if ( parTable[tableID].pars[item].name )
+		strcpy(varname, parTable[tableID].pars[item].name);     //FIXME: This may overrun the supplied buffer!
+              err = 0;
+	      break;
+	    }
+	}
     }
 
-  return (0);
+  return (err);
 }
 
 
-int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **idsp,
-		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
-		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp)
+const char *tableInqParNamePtr(int tableID, int code)
 {
-  unsigned char *section;
-  long sec_len;
-  int sec_num;
-  int gribversion;
-  int i, msec;
-  long gribsize;
-  long grib_len = 0;
+  const char *name = NULL;
 
-  UNUSED(gribbufsize);
+  if ( tableID != UNDEFID )
+    {
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      name = parTable[tableID].pars[item].name;
+	      break;
+	    }
+	}
+    }
 
-  *idsp = NULL;
-  *lusp = NULL;
-  *gdsp = NULL;
-  *pdsp = NULL;
-  *drsp = NULL;
-  *bmsp = NULL;
-  *bdsp = NULL;
+  return (name);
+}
 
-  section = gribbuffer;
-  sec_len = 16;
 
-  if ( !GRIB_START(section) )
-    {
-      fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
-	      section[0], section[1], section[2], section[3]);
-      return (-1);
-    }
+const char *tableInqParLongnamePtr(int tableID, int code)
+{
+  const char *longname = NULL;
 
-  gribversion = GRIB_EDITION(section);
-  if ( gribversion != 2 )
+  if ( tableID != UNDEFID )
     {
-      fprintf(stderr, "wrong GRIB version %d\n", gribversion);
-      return (-1);      
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      longname = parTable[tableID].pars[item].longname;
+	      break;
+	    }
+	}
     }
 
-  gribsize = 0;
-  for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
+  return (longname);
+}
 
-  grib_len += sec_len;
-  section  += sec_len;
 
-  /* section 1 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "ids %d %ld\n", sec_num, sec_len);
+const char *tableInqParUnitsPtr(int tableID, int code)
+{
+  const char *units = NULL;
 
-  if ( sec_num != 1 )
+  if ( tableID != UNDEFID )
     {
-      fprintf(stderr, "Unexpected section1 number %d\n", sec_num);
-      return (-1);
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      units = parTable[tableID].pars[item].units;
+	      break;
+	    }
+	}
     }
 
-  *idsp = section;
+  return (units);
+}
 
-  grib_len += sec_len;
-  section  += sec_len;
 
-  /* section 2 and 3 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "lus %d %ld\n", sec_num, sec_len);
+int tableInqParLongname(int tableID, int code, char *longname)
+{
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
+    Error("Invalid table ID %d", tableID);
 
-  if ( sec_num == 2 )
+  int err = 1;
+
+  if ( tableID != UNDEFID )
     {
-      *lusp = section;
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      if ( parTable[tableID].pars[item].longname )
+		strcpy(longname, parTable[tableID].pars[item].longname);
+              err = 0;
+	      break;
+	    }
+	}
+    }
 
-      grib_len += sec_len;
-      section  += sec_len;
+  return (err);
+}
 
-      /* section 3 */
-      sec_len = GRIB2_SECLEN(section);
-      sec_num = GRIB2_SECNUM(section);
-      //fprintf(stderr, "gds %d %ld\n", sec_num, sec_len);
 
-      *gdsp = section;
-    }
-  else if ( sec_num == 3 )
-    {
-      *gdsp = section;
-    }
-  else
-    {
-      fprintf(stderr, "Unexpected section3 number %d\n", sec_num);
-      return (-1);
-    }
+int tableInqParUnits(int tableID, int code, char *units)
+{
 
-  grib_len += sec_len;
-  section  += sec_len;
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
+    Error("Invalid table ID %d", tableID);
 
-  /* section 4 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "pds %d %ld\n", sec_num, sec_len);
+  int err = 1;
 
-  if ( sec_num != 4 )
+  if ( tableID != UNDEFID )
     {
-      fprintf(stderr, "Unexpected section4 number %d\n", sec_num);
-      return (-1);
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
+	{
+	  if ( parTable[tableID].pars[item].id == code )
+	    {
+	      if ( parTable[tableID].pars[item].units )
+		strcpy(units, parTable[tableID].pars[item].units);
+              err = 0;
+	      break;
+	    }
+	}
     }
 
-  *pdsp = section;
+  return (err);
+}
 
-  grib_len += sec_len;
-  section  += sec_len;
 
-  /* section 5 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "drs %d %ld\n", sec_num, sec_len);
+void tableInqPar(int tableID, int code, char *name, char *longname, char *units)
+{
 
-  if ( sec_num != 5 )
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
+    Error("Invalid table ID %d", tableID);
+
+  int npars = parTable[tableID].npars;
+
+  for ( int item = 0; item < npars; item++ )
     {
-      fprintf(stderr, "Unexpected section5 number %d\n", sec_num);
-      return (-1);
+      if ( parTable[tableID].pars[item].id == code )
+	{
+	  if ( parTable[tableID].pars[item].name )
+	    strcpy(name, parTable[tableID].pars[item].name);
+	  if ( parTable[tableID].pars[item].longname )
+	    strcpy(longname, parTable[tableID].pars[item].longname);
+	  if ( parTable[tableID].pars[item].units )
+	    strcpy(units, parTable[tableID].pars[item].units);
+	  break;
+	}
     }
+}
 
-  *drsp = section;
-
-  grib_len += sec_len;
-  section  += sec_len;
+int tableInqNumber(void)
+{
+  if ( ! ParTableInit ) parTableInit();
 
-  /* section 6 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "bms %d %ld\n", sec_num, sec_len);
+  return (parTableNum);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-  if ( sec_num != 6 )
-    {
-      fprintf(stderr, "Unexpected section6 number %d\n", sec_num);
-      return (-1);
-    }
+#include <stddef.h>
+#include <string.h>
 
-  *bmsp = section;
 
-  grib_len += sec_len;
-  section  += sec_len;
 
-  /* section 7 */
-  sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
-  //fprintf(stderr, "bds %d %ld\n", sec_num, sec_len);
+extern int cdiDefaultCalendar;
 
-  if ( sec_num != 7 )
-    {
-      fprintf(stderr, "Unexpected section7 number %d\n", sec_num);
-      return (-1);
-    }
+static int DefaultTimeType = TAXIS_ABSOLUTE;
+static int DefaultTimeUnit = TUNIT_HOUR;
 
-  *bdsp = section;
 
-  grib_len += sec_len;
-  section  += sec_len;
+const char *Timeunits[] = {
+  "undefined",
+  "seconds",
+  "minutes",
+  "quarters",
+  "30minutes",
+  "hours",
+  "3hours",
+  "6hours",
+  "12hours",
+  "days",
+  "months",
+  "years",
+};
 
-  /* skip multi GRIB sections */
-  msec = 1;
-  while ( !GRIB_FIN(section) )
-    {
-      sec_len = GRIB2_SECLEN(section);
-      sec_num = GRIB2_SECNUM(section);
 
-      if ( sec_num < 1 || sec_num > 7 ) break;
+static int    taxisCompareP    ( void * taxisptr1, void * taxisptr2 );
+static void   taxisDestroyP    ( void * taxisptr );
+static void   taxisPrintKernel(taxis_t *taxisptr, FILE * fp);
+static int    taxisGetPackSize ( void * taxisptr, void *context );
+static void   taxisPack        ( void * taxisptr, void *buf, int size,
+				 int *position, void *context );
+static int    taxisTxCode      ( void );
 
-      if ( sec_num == 7 )
-	fprintf(stderr, "Skipped unsupported multi GRIB section %d!\n", ++msec);
+const resOps taxisOps = {
+  taxisCompareP,
+  taxisDestroyP,
+  (void (*)(void *, FILE *))taxisPrintKernel,
+  taxisGetPackSize,
+  taxisPack,
+  taxisTxCode
+};
 
-      if ( (grib_len + sec_len) > gribsize ) break;
+#define container_of(ptr, type, member) \
+  ((type *)((unsigned char *)ptr - offsetof(type,member)))
 
-      grib_len += sec_len;
-      section  += sec_len;
-    }
+struct refcount_string
+{
+  int ref_count;
+  char string[];
+};
 
-  /* end section - "7777" in ASCII */
-  if ( !GRIB_FIN(section) )
+static char *
+new_refcount_string(size_t len)
+{
+  struct refcount_string *container
+    = xmalloc(sizeof (*container) + len + 1);
+  container->ref_count = 1;
+  return container->string;
+}
+
+static void
+delete_refcount_string(void *p)
+{
+  if (p)
     {
-      fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
-	      section[0], section[1], section[2], section[3]);
-      return (-2);
+      struct refcount_string *container
+        = container_of(p, struct refcount_string, string);
+      if (!--(container->ref_count))
+        free(container);
     }
-
-  return (0);
 }
 
-
-int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
-			int *intnum, float *fltnum, off_t *bignum)
+static char *
+dup_refcount_string(char *p)
 {
-  unsigned char *pds, *gds, *bms, *bds;
-  unsigned char *bufpointer, *is, *section;
-  int gribversion, grib1offset;
-  long gribsize = 0;
-  off_t dpos, bpos = 0;
-  int bdslen;
-  float bsf;
-
-  section = gribbuffer;
-  is = gribbuffer;
-  if ( ! GRIB_START(section) )
+  if (p)
     {
-      fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
-	      section[0], section[1], section[2], section[3]);
-      return (-1);
+      struct refcount_string *container
+        = container_of(p, struct refcount_string, string);
+      ++(container->ref_count);
     }
+  return p;
+}
 
-  gribversion = GRIB_EDITION(section);
-  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
 
-  if ( gribversion == 1 )
-    grib1offset = 4;
-  else
-    grib1offset = 0;
+#undef container_of
 
-  pds = is + 4 + grib1offset;
-  bufpointer = pds + PDS_Len;
-  gribsize += 4 + grib1offset + PDS_Len;
+static int  TAXIS_Debug = 0;   /* If set to 1, debugging */
 
-  if ( PDS_HAS_GDS )
-    {
-      gds = bufpointer;
-      bufpointer += GDS_Len;
-      gribsize += GDS_Len;
-    }
+
+const char *tunitNamePtr(int unitID)
+{
+  const char *name;
+  int size = sizeof(Timeunits)/sizeof(*Timeunits);
+
+  if ( unitID > 0 && unitID < size )
+    name = Timeunits[unitID];
   else
-    {
-      gds = NULL;
-    }
+    name = Timeunits[0];
 
-  if ( PDS_HAS_BMS )
-    {
-      bms = bufpointer;
-      bufpointer += BMS_Len;
+  return (name);
+}
 
-      bpos = recpos + gribsize + 6;
+#if 0
+static
+void taxis_defaults(void)
+{
+  char *timeunit;
 
-      gribsize += BMS_Len;
-    }
-  else
+  timeunit = getenv("TIMEUNIT");
+  if ( timeunit )
     {
-      bms = NULL;
+      if ( strcmp(timeunit, "minutes") == 0 )
+	DefaultTimeUnit = TUNIT_MINUTE;
+      else if ( strcmp(timeunit, "hours") == 0 )
+	DefaultTimeUnit = TUNIT_HOUR;
+      else if ( strcmp(timeunit, "3hours") == 0 )
+	DefaultTimeUnit = TUNIT_3HOURS;
+      else if ( strcmp(timeunit, "6hours") == 0 )
+	DefaultTimeUnit = TUNIT_6HOURS;
+      else if ( strcmp(timeunit, "12hours") == 0 )
+	DefaultTimeUnit = TUNIT_12HOURS;
+      else if ( strcmp(timeunit, "days") == 0 )
+	DefaultTimeUnit = TUNIT_DAY;
+      else if ( strcmp(timeunit, "months") == 0 )
+	DefaultTimeUnit = TUNIT_MONTH;
+      else if ( strcmp(timeunit, "years") == 0 )
+	DefaultTimeUnit = TUNIT_YEAR;
+      else
+	Warning("Unsupported TIMEUNIT %s!", timeunit);
     }
+}
+#endif
 
-  bds = bufpointer;
-
-  dpos = recpos + gribsize + 11;
+static
+void taxisDefaultValue(taxis_t* taxisptr)
+{
+  taxisptr->self        = CDI_UNDEFID;
+  taxisptr->used        = FALSE;
+  taxisptr->type        = DefaultTimeType;
+  taxisptr->vdate       = 0;
+  taxisptr->vtime       = 0;
+  taxisptr->rdate       = CDI_UNDEFID;
+  taxisptr->rtime       = 0;
+  taxisptr->fdate       = CDI_UNDEFID;
+  taxisptr->ftime       = 0;
+  taxisptr->calendar    = cdiDefaultCalendar;
+  taxisptr->unit        = DefaultTimeUnit;
+  taxisptr->numavg      = 0;
+  taxisptr->climatology = FALSE;
+  taxisptr->has_bounds  = FALSE;
+  taxisptr->vdate_lb    = 0;
+  taxisptr->vtime_lb    = 0;
+  taxisptr->vdate_ub    = 0;
+  taxisptr->vtime_ub    = 0;
+  taxisptr->fc_unit     = DefaultTimeUnit;
+  taxisptr->fc_period   = 0;
+  taxisptr->name        = NULL;
+  taxisptr->longname    = NULL;
+}
 
-  bdslen = BDS_Len;
-  bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
-  bufpointer += bdslen;
-  gribsize += bdslen;
-  gribsize += 4;
+static taxis_t *
+taxisNewEntry(cdiResH resH)
+{
+  taxis_t *taxisptr = (taxis_t*) xmalloc(sizeof(taxis_t));
 
-  if ( gribsize > recsize )
+  taxisDefaultValue(taxisptr);
+  if (resH == CDI_UNDEFID)
+    taxisptr->self = reshPut(taxisptr, &taxisOps);
+  else
     {
-      fprintf(stderr, "GRIB buffer size %ld too small! Min size = %ld\n", recsize, gribsize);
-      return (1);
+      taxisptr->self = resH;
+      reshReplace(resH, taxisptr, &taxisOps);
     }
 
-  /* end section - "7777" in ascii */
-  if ( !GRIB_FIN(bufpointer) )
-    {
-      fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
-	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
-    }
+  return (taxisptr);
+}
 
-  bsf = BDS_BinScale;
-  if ( bsf > 32767 ) bsf = 32768-bsf;
-  bsf = pow(2.0,(double)bsf);
+static
+void taxisInit (void)
+{
+  static int taxisInitialized = 0;
+  char *env;
 
-  bignum[0] = dpos;
-  if ( bms ) bignum[1] = bpos;
-  else       bignum[1] = -999;
-  intnum[0] = BDS_NumBits;
+  if ( taxisInitialized ) return;
 
-  /*  fltnum[0] = 1.0; */
-  fltnum[0] = pow(10.0, (double)PDS_DecimalScale);
-  fltnum[1] = bsf;
-  fltnum[2] = BDS_RefValue;
-  /*
-  printf("intnum %d %d %d\n", intnum[0], intnum[1], intnum[2]);
-  printf("fltnum %g %g %g\n", fltnum[0], fltnum[1], fltnum[2]);
-  */
-  return (0);
-}
+  taxisInitialized = 1;
 
+  env = getenv("TAXIS_DEBUG");
+  if ( env ) TAXIS_Debug = atoi(env);
+}
 
-void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+#if 0
+static
+void taxis_copy(taxis_t *taxisptr2, taxis_t *taxisptr1)
 {
-  static int header = 1;
-  int GridType, level, nerr;
-  unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  double cr = 1;
-  int bdslen;
-  int llarge = 0;
+  int taxisID2 = taxisptr2->self;
+  memcpy(taxisptr2, taxisptr1, sizeof(taxis_t));
+  taxisptr2->self = taxisID2;
+}
+#endif
 
-  if ( header )
-    {
-      fprintf(stdout, 
-      "  Rec : Off Position   Size : V PDS  GDS    BMS    BDS : Code Level :  LType GType: CR LL\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
-    }
+/*
+ at Function  taxisCreate
+ at Title     Create a Time axis
 
-  is = gribbuffer;
+ at Prototype int taxisCreate(int taxistype)
+ at Parameter
+    @Item  taxistype  The type of the Time axis, one of the set of predefined CDI time axis types.
+                      The valid CDI time axis types are @func{TAXIS_ABSOLUTE} and @func{TAXIS_RELATIVE}.
 
-  if ( gribrec_len(is[4], is[5], is[6]) > JP23SET ) llarge = 1;
+ at Description
+The function @func{taxisCreate} creates a Time axis.
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "%5d :%4ld %8ld %6ld : GRIB message error\n", nrec, offset, recpos, recsize);
-      return;
-    }
+ at Result
+ at func{taxisCreate} returns an identifier to the Time axis.
 
-  if ( gds == NULL )
-    GridType = -1;
-  else
-    GridType = GDS_GridType;
+ at Example
+Here is an example using @func{taxisCreate} to create a relative T-axis
+with a standard calendar.
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else if ( PDS_LevelType == 109 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+ at Source
+   ...
+int taxisID;
+   ...
+taxisID = taxisCreate(TAXIS_RELATIVE);
+taxisDefCalendar(taxisID, CALENDAR_STANDARD);
+taxisDefRdate(taxisID, 19850101);
+taxisDefRtime(taxisID, 120000);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int taxisCreate(int taxistype)
+{
+  if ( CDI_Debug )
+    Message("taxistype: %d", taxistype);
 
-  bdslen = BDS_Len;
-  bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
+  taxisInit ();
 
-  if ( ((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130) )
-    {
-      int s1, s2;
-      s1 = gribrec_len(bds[14], bds[15], bds[16]);
-      s2 = gribrec_len(gribbuffer[4], gribbuffer[5], gribbuffer[6]);
-      cr = ((double)s1)/s2;
-    }
+  taxis_t *taxisptr = taxisNewEntry(CDI_UNDEFID);
+  taxisptr->type = taxistype;
 
-  fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d%4d%5d %6d %6d : %3d %6d : %5d %5d %6.4g  %c",
-	  nrec, offset, recpos, recsize, GRIB_EDITION(is),
-	  PDS_Len, GDS_Len, BMS_Len, bdslen,
-	  PDS_Parameter, level, PDS_LevelType, GridType, cr, llarge?'T':'F');
+  int taxisID = taxisptr->self;
 
-  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
-  fprintf(stdout, "\n");
-}
+  if ( CDI_Debug )
+    Message("taxisID: %d", taxisID);
 
+  return (taxisID);
+}
 
-void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+void taxisDestroyKernel(taxis_t *taxisptr)
 {
-  static int header = 1;
-  int nerr;
-  unsigned char *is  = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  unsigned char *ids = NULL, *lus = NULL, *drs = NULL;
-  long ids_len = 0, lus_len = 0, gds_len = 0, pds_len = 0, drs_len = 0, bms_len = 0, bds_len = 0;
-  int gridtype, paramnum, level1type /*, level2type*/;
-  int level1 /*, level1sf*/;
-  /* int level2, level2sf; */
-  double cr = 1;
+  int id = taxisptr->self;
+  delete_refcount_string(taxisptr->name);
+  delete_refcount_string(taxisptr->longname);
+  if (id != CDI_UNDEFID)
+    reshRemove(id, &taxisOps);
+}
 
-  if ( header )
-    {
-      fprintf(stdout, 
-      "  Rec : Off Position   Size : V IDS LUS GDS PDS  DRS    BMS    BDS : Code Level :  LType GType: CR\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
-    }
+/*
+ at Function  taxisDestroy
+ at Title     Destroy a Time axis
 
-  is = gribbuffer;
+ at Prototype void taxisDestroy(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @func{taxisCreate}
 
-  nerr = grib2Sections(gribbuffer, recsize, &ids, &lus, &gds, &pds, &drs, &bms, &bds);
-  if ( nerr )
-    {
-      fprintf(stdout, "%5d :%4ld %8ld %6ld : error\n", nrec, offset, recpos, recsize);
-      return;
-    }
+ at EndFunction
+*/
+void taxisDestroy(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+  taxisDestroyKernel(taxisptr);
+  free(taxisptr);
+}
 
-  if ( ids ) ids_len = GRIB2_SECLEN(ids);
-  if ( lus ) lus_len = GRIB2_SECLEN(lus);
-  if ( gds ) gds_len = GRIB2_SECLEN(gds);
-  if ( pds ) pds_len = GRIB2_SECLEN(pds);
-  if ( drs ) drs_len = GRIB2_SECLEN(drs);
-  if ( bms ) bms_len = GRIB2_SECLEN(bms);
-  if ( bds ) bds_len = GRIB2_SECLEN(bds);
 
-  /*
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
-    {
-      int s1, s2;
-      s1 = ((int) ((bds[14]<<16)+(bds[15]<<8)+bds[16]));
-      s2 = ((int) ((gribbuffer[4]<<16)+(gribbuffer[5]<<8)+gribbuffer[6]));
-      cr = ((double)s1)/s2;
-    }
-  */
-  gridtype   = GET_UINT2(gds[12],gds[13]);
-  paramnum   = GET_UINT1(pds[10]);
-  level1type = GET_UINT1(pds[22]);
-  /* level1sf   = GET_UINT1(pds[23]); */
-  level1     = GET_UINT4(pds[24],pds[25],pds[26],pds[27]);
-  /* level2type = GET_UINT1(pds[28]); */
-  /* level2sf   = GET_UINT1(pds[29]); */
-  /* level2     = GET_UINT4(pds[30],pds[31],pds[32],pds[33]); */
-  /*
-  printf("level %d %d %d %d %d %d %d\n", level1type, level1sf, level1, level1*level1sf, level2sf, level2, level2*level2sf);
-  */
-  fprintf(stdout, "%5d :%4ld %8ld %6ld :%2d %3ld %3ld %3ld %3ld %4ld %6ld %6ld : %3d%7d : %5d %5d %6.4g\n",
-	  nrec, offset, recpos, recsize, GRIB_EDITION(is),
-	  ids_len, lus_len, gds_len, pds_len, drs_len, bms_len, bds_len,
-	  paramnum, level1, level1type, gridtype, cr);
+void taxisDestroyP( void * taxisptr )
+{
+  taxisDestroyKernel((taxis_t *)taxisptr);
+  free(taxisptr);
 }
 
 
-void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
+int taxisDuplicate(int taxisID1)
 {
-  int gribversion;
+  taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps);
+  taxis_t *taxisptr2 = taxisNewEntry(CDI_UNDEFID);
 
-  gribversion = gribVersion(gribbuffer, recsize);
+  int taxisID2 = taxisptr2->self;
 
-  if ( gribversion == 0 || gribversion == 1 )
-    grib1PrintALL(nrec, offset, recpos, recsize, gribbuffer);
-  else if ( gribversion == 2 )
-    grib2PrintALL(nrec, offset, recpos, recsize, gribbuffer);
-  else
-    {
-      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
-	      nrec, offset, recpos, recsize, gribversion); 
-    }
+  if ( CDI_Debug )
+    Message("taxisID2: %d", taxisID2);
+
+  ptaxisCopy(taxisptr2, taxisptr1);
+  return (taxisID2);
 }
 
 
-void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void taxisDefType(int taxisID, int type)
 {
-  static int header = 1;
-  unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int century, subcenter, decimalscale, nerr;
-  int fc_num = 0;
-  int year = 0, date;
-
-  UNUSED(recpos);
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( header )
+  if (taxisptr->type != type)
     {
-      fprintf(stdout, 
-      "  Rec : PDS Tab Cen Sub Ver Grid Code LTyp Level1 Level2    Date  Time P1 P2 TU TR NAVE Scale FCnum CT\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
+      taxisptr->type = type;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  is = gribbuffer;
+/*
+ at Function  taxisDefVdate
+ at Title     Define the verification date
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
-    }
+ at Prototype void taxisDefVdate(int taxisID, int vdate)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  vdate    Verification date (YYYYMMDD)
 
-  switch(GRIB_EDITION(is))
-    {   
-    case 0:
-      year                = GET_UINT1(pds[12]);
-      century             = 1;
-      subcenter           = 0;
-      decimalscale        = 0;
-      break;
-    case 1:
-      year                = PDS_Year;
-      century             = PDS_Century;
-      subcenter           = PDS_Subcenter;
-      decimalscale        = PDS_DecimalScale;
-      break;
-    default:
-      fprintf(stderr, "Grib version %d not supported!", GRIB_EDITION(is));
-      exit(EXIT_FAILURE);
-    }
+ at Description
+The function @func{taxisDefVdate} defines the verification date of a Time axis.
 
-  if ( PDS_Len > 28 )
-    if ( PDS_CenterID    == 98 || PDS_Subcenter == 98 ||
-	(PDS_CenterID    ==  7 && PDS_Subcenter == 98) )
-      if ( pds[40] == 1 )
-	fc_num = GET_UINT1(pds[49]);
+ at EndFunction
+*/
+void taxisDefVdate(int taxisID, int vdate)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  if ( year < 0 )
-    {
-      date = (-year)*10000+PDS_Month*100+PDS_Day;
-      century = -century;
-    }
-  else
+  if (taxisptr->vdate != vdate)
     {
-      date =    year*10000+PDS_Month*100+PDS_Day;
+      taxisptr->vdate = vdate;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
-      
-  fprintf(stdout, "%5d :%4d%4d%4d%4d%4d %4d %4d%4d%7d%7d %8d%6d%3d%3d%3d%3d%5d%6d%5d%4d", nrec,
-	  PDS_Len,  PDS_CodeTable,   PDS_CenterID, subcenter, PDS_ModelID,
-	  PDS_GridDefinition, PDS_Parameter, PDS_LevelType, PDS_Level1, PDS_Level2,
-	  date, PDS_Time, PDS_TimePeriod1, PDS_TimePeriod2, PDS_TimeUnit, PDS_TimeRange,
-	  PDS_AvgNum, decimalscale, fc_num, century);
-
-  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
-  fprintf(stdout, "\n");
 }
 
+/*
+ at Function  taxisDefVtime
+ at Title     Define the verification time
 
-void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
-  int gribversion;
+ at Prototype void taxisDefVtime(int taxisID, int vtime)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  vtime    Verification time (hhmmss)
 
-  gribversion = gribVersion(gribbuffer, recsize);
+ at Description
+The function @func{taxisDefVtime} defines the verification time of a Time axis.
 
-  if ( gribversion == 0 || gribversion == 1 )
-    grib1PrintPDS(nrec, recpos, recsize, gribbuffer);
-  /*
-  else if ( gribversion == 2 )
-    grib2PrintPDS(nrec, recpos, recsize, gribbuffer);
-  */
-  else
+ at EndFunction
+*/
+void taxisDefVtime(int taxisID, int vtime)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+  if (taxisptr->vtime != vtime)
     {
-      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
-	      nrec, 0L, recpos, recsize, gribversion); 
+      taxisptr->vtime = vtime;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
 
+/*
+ at Function  taxisDefRdate
+ at Title     Define the reference date
 
-void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
-  static int header = 1;
-  int nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ at Prototype void taxisDefRdate(int taxisID, int rdate)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  rdate    Reference date (YYYYMMDD)
 
-  UNUSED(recpos);
+ at Description
+The function @func{taxisDefRdate} defines the reference date of a Time axis.
 
-  if ( header )
-    {
-      fprintf(stdout, 
-      "  Rec : GDS  NV PVPL Typ : xsize ysize   Lat1   Lon1   Lat2   Lon2    dx    dy\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
-    }
+ at EndFunction
+*/
+void taxisDefRdate(int taxisID, int rdate)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
+  if (taxisptr->rdate != rdate)
     {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
+      taxisptr->rdate = rdate;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  fprintf(stdout, "%5d :", nrec);
-
-  if ( gds )
-    fprintf(stdout, "%4d%4d%4d %4d :%6d%6d%7d%7d%7d%7d%6d%6d",
-	    GDS_Len,  GDS_NV,   GDS_PVPL, GDS_GridType,
-	    GDS_NumLon,   GDS_NumLat,
-	    GDS_FirstLat, GDS_FirstLon,
-	    GDS_LastLat,  GDS_LastLon,
-	    GDS_LonIncr,  GDS_LatIncr);
-  else
-    fprintf(stdout, " Grid Description Section not defined");
+/*
+ at Function  taxisDefRtime
+ at Title     Define the reference time
 
-  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
-  fprintf(stdout, "\n");
-}
+ at Prototype void taxisDefRtime(int taxisID, int rtime)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  rtime    Reference time (hhmmss)
 
+ at Description
+The function @func{taxisDefRtime} defines the reference time of a Time axis.
 
-void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+ at EndFunction
+*/
+void taxisDefRtime(int taxisID, int rtime)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, recsize);
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( gribversion == 0 || gribversion == 1 )
-    grib1PrintGDS(nrec, recpos, recsize, gribbuffer);
-  /*
-  else if ( gribversion == 2 )
-    grib2PrintGDS(nrec, recpos, recsize, gribbuffer);
-  */
-  else
+  if (taxisptr->rtime != rtime)
     {
-      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
-	      nrec, 0L, recpos, recsize, gribversion); 
+      taxisptr->rtime = rtime;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
 
+/*
+ at Function  taxisDefFdate
+ at Title     Define the forecast reference date
 
-void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
-  static int header = 1;
-  int level, nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ at Prototype void taxisDefFdate(int taxisID, int fdate)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  fdate    Forecast reference date (YYYYMMDD)
 
-  UNUSED(recpos);
+ at Description
+The function @func{taxisDefFdate} defines the forecast reference date of a Time axis.
 
-  if ( header )
-    {
-      fprintf(stdout, 
-      "  Rec : Code Level     BMS    Size\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
-    }
+ at EndFunction
+*/
+void taxisDefFdate(int taxisID, int fdate)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
+  if (taxisptr->fdate != fdate)
     {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
+      taxisptr->fdate = fdate;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+/*
+ at Function  taxisDefFtime
+ at Title     Define the forecast reference time
 
-  fprintf(stdout, "%5d :", nrec);
+ at Prototype void taxisDefFtime(int taxisID, int ftime)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  ftime    Forecast reference time (hhmmss)
 
-  if ( bms )
-    fprintf(stdout, "%4d%7d %7d %7d",
-	    PDS_Parameter, level,
-	    BMS_Len, BMS_BitmapSize);
-  else
-    fprintf(stdout, "%4d%7d Bit Map Section not defined", PDS_Parameter, level);
+ at Description
+The function @func{taxisDefFtime} defines the forecast reference time of a Time axis.
 
-  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
-  fprintf(stdout, "\n");
+ at EndFunction
+*/
+void taxisDefFtime(int taxisID, int ftime)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  if (taxisptr->ftime != ftime)
+    {
+      taxisptr->ftime = ftime;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
+/*
+ at Function  taxisDefCalendar
+ at Title     Define the calendar
 
-void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
-{
-  int gribversion;
+ at Prototype void taxisDefCalendar(int taxisID, int calendar)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  calendar The type of the calendar, one of the set of predefined CDI calendar types.
+                    The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEPTIC},
+                    @func{CALENDAR_360DAYS}, @func{CALENDAR_365DAYS} and @func{CALENDAR_366DAYS}.
 
-  gribversion = gribVersion(gribbuffer, recsize);
+ at Description
+The function @func{taxisDefCalendar} defines the calendar of a Time axis.
 
-  if ( gribversion == 0 || gribversion == 1 )
-    grib1PrintBMS(nrec, recpos, recsize, gribbuffer);
-  /*
-  else if ( gribversion == 2 )
-    grib2PrintBMS(nrec, recpos, recsize, gribbuffer);
-  */
-  else
+ at EndFunction
+*/
+void taxisDefCalendar(int taxisID, int calendar)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  if (taxisptr->calendar != calendar)
     {
-      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
-	      nrec, 0L, recpos, recsize, gribversion); 
+      taxisptr->calendar = calendar;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
 
 
-void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void taxisDefTunit(int taxisID, int unit)
 {
-  static int header = 1;
-  int level, nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  double cr = 1;
-  double refval, scale;
-
-  UNUSED(recpos);
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( header )
+  if (taxisptr->unit != unit)
     {
-      fprintf(stdout, 
-      "  Rec : Code Level     BDS Flag     Scale   RefValue Bits  CR\n");
-/*     ----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+ */
-      header = 0;
+      taxisptr->unit = unit;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
+
+void taxisDefForecastTunit(int taxisID, int unit)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+  if (taxisptr->fc_unit != unit)
     {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
+      taxisptr->fc_unit = unit;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
 
-  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
+void taxisDefForecastPeriod(int taxisID, double fc_period)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  if ( IS_NOT_EQUAL(taxisptr->fc_period, fc_period) )
     {
-      int s1, s2;
-      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
-      cr = ((double)s1)/s2;
+      taxisptr->fc_period = fc_period;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  refval = BDS_RefValue;
 
-  if ( BDS_BinScale < 0 )
-    scale = 1.0/pow(2.0, (double) -BDS_BinScale);
-  else
-    scale = pow(2.0, (double) BDS_BinScale);
+void taxisDefNumavg(int taxisID, int numavg)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( PDS_DecimalScale )
+  if (taxisptr->numavg != numavg)
     {
-      double decscale;
-      decscale = pow(10.0, (double)-PDS_DecimalScale);
-      refval *= decscale;
-      scale  *= decscale;
+      taxisptr->numavg = numavg;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  fprintf(stdout, "%5d :", nrec);
-
-  if ( bds )
-    fprintf(stdout, "%4d%7d %7d %4d %8.5g %11.5g%4d %6.4g",
-	    PDS_Parameter, level,
-	    BDS_Len, BDS_Flag, scale, refval, BDS_NumBits, cr);
-  else
-    fprintf(stdout, " Binary Data Section not defined");
+/*
+The type of the time axis, one of the set of predefined CDI time types.
+The valid CDI time types are TAXIS_ABSOLUTE and TAXIS_RELATIVE.
+*/
+int taxisInqType(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  if ( nerr > 0 ) fprintf(stdout, " <-- GRIB data corrupted!");
-  fprintf(stdout, "\n");
+  return (taxisptr->type);
 }
 
 
-void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+int taxisHasBounds(int taxisID)
 {
-  int gribversion;
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  gribversion = gribVersion(gribbuffer, recsize);
+  return (taxisptr->has_bounds);
+}
 
-  if ( gribversion == 0 || gribversion == 1 )
-    grib1PrintBDS(nrec, recpos, recsize, gribbuffer);
-  /*
-  else if ( gribversion == 2 )
-    grib2PrintBDS(nrec, recpos, recsize, gribbuffer);
-  */
-  else
+
+void taxisDeleteBounds(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  if (taxisptr->has_bounds != FALSE)
     {
-      fprintf(stdout, "%5d :%4ld%9ld%7ld : GRIB version %d unsupported\n",
-	      nrec, 0L, recpos, recsize, gribversion); 
+      taxisptr->has_bounds = FALSE;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
 
 
-void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void taxisCopyTimestep(int taxisID2, int taxisID1)
 {
-  int level, nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  double cr = 1;
+  taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps),
+    *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
 
-  UNUSED(recpos);
+  reshLock();
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
-    }
+  taxisptr2->rdate = taxisptr1->rdate;
+  taxisptr2->rtime = taxisptr1->rtime;
 
-  if ( nerr > 0 )
+  taxisptr2->vdate = taxisptr1->vdate;
+  taxisptr2->vtime = taxisptr1->vtime;
+
+  if ( taxisptr2->has_bounds )
     {
-      fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
-      return;
+      taxisptr2->vdate_lb = taxisptr1->vdate_lb;
+      taxisptr2->vtime_lb = taxisptr1->vtime_lb;
+      taxisptr2->vdate_ub = taxisptr1->vdate_ub;
+      taxisptr2->vtime_ub = taxisptr1->vtime_ub;
     }
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+  taxisptr2->fdate = taxisptr1->fdate;
+  taxisptr2->ftime = taxisptr1->ftime;
 
-  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
-    {
-      int s1, s2;
-      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
-      cr = ((double)s1)/s2;
-    }
+  taxisptr2->fc_unit   = taxisptr1->fc_unit;
+  taxisptr2->fc_period = taxisptr1->fc_period;
 
-  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
-    {
-      fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
-    }
+  reshSetStatus(taxisID2, &taxisOps, RESH_DESYNC_IN_USE);
+  reshUnlock();
 }
 
+/*
+ at Function  taxisInqVdate
+ at Title     Get the verification date
 
-static
-void repair1(unsigned char *gbuf, long gbufsize)
+ at Prototype int taxisInqVdate(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+
+ at Description
+The function @func{taxisInqVdate} returns the verification date of a Time axis.
+
+ at Result
+ at func{taxisInqVdate} returns the verification date.
+
+ at EndFunction
+*/
+int taxisInqVdate(int taxisID)
 {
-  long i;
-  int nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  /* int recLen; */
-  unsigned char *source;
-  size_t sourceLen;
-  int bds_len, bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress */;
-  int bds_head = 11;
-  int bds_ext = 0, bds_ubits;
-  int datstart = 0;
-  /* int llarge = FALSE; */
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  long gribrecsize;
-  nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "GRIB message error\n");
-      return;
-    }
+  return (taxisptr->vdate);
+}
 
-  if ( nerr > 0 )
-    {
-      fprintf(stdout, "GRIB data corrupted!\n");
-      return;
-    }
 
-  /* recLen = gribrec_len(gbuf[4], gbuf[5], gbuf[6]); */
-  /* if ( recLen > JP23SET ) llarge = TRUE; */
+void taxisInqVdateBounds(int taxisID, int *vdate_lb, int *vdate_ub)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  bds_len   = BDS_Len;
-  bds_nbits = BDS_NumBits;
-  bds_flag  = BDS_Flag;
-  bds_ubits = bds_flag & 15;
-  lspherc   =  bds_flag >> 7;
-  lcomplex  = (bds_flag >> 6)&1;
-  /* lcompress = (bds_flag >> 4)&1; */
+  *vdate_lb = taxisptr->vdate_lb;
+  *vdate_ub = taxisptr->vdate_ub;
+}
 
-  if ( lspherc )
+
+void taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  if (taxisptr->vdate_lb != vdate_lb
+      || taxisptr->vdate_ub != vdate_ub
+      || taxisptr->has_bounds != TRUE)
     {
-      if ( lcomplex  )
-	{
-	  int jup, ioff;
-	  jup  = bds[15];
-	  ioff = (jup+1)*(jup+2);
-	  bds_ext = 4 + 3 + 4*ioff;
-	}
-      else
-	{
-	  bds_ext = 4;
-	}
+      taxisptr->vdate_lb = vdate_lb;
+      taxisptr->vdate_ub = vdate_ub;
+      taxisptr->has_bounds = TRUE;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  datstart = bds_head + bds_ext;
+/*
+ at Function  taxisInqVtime
+ at Title     Get the verification time
 
-  source = bds + datstart;
+ at Prototype int taxisInqVtime(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
-  sourceLen = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
+ at Description
+The function @func{taxisInqVtime} returns the verification time of a Time axis.
 
-  if ( bds_nbits == 24 )
-    {
-      long nelem;
-      unsigned char *pbuf;
-      nelem = sourceLen/3;
-      pbuf = (unsigned char*) malloc(sourceLen);
-      for ( i = 0; i < nelem; i++ )
-	{
-	  pbuf[3*i  ] = source[        i];
-	  pbuf[3*i+1] = source[  nelem+i];
-	  pbuf[3*i+2] = source[2*nelem+i];
-	}
-      memcpy(source, pbuf, sourceLen);
-      free(pbuf);
-    }
+ at Result
+ at func{taxisInqVtime} returns the verification time.
+
+ at EndFunction
+*/
+int taxisInqVtime(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+  return (taxisptr->vtime);
 }
 
 
-void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
+void taxisInqVtimeBounds(int taxisID, int *vtime_lb, int *vtime_ub)
 {
-  int level, nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  double cr = 1;
-
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "%5d : GRIB message error\n", nrec);
-      return;
-    }
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  if ( nerr > 0 )
-    {
-      fprintf(stdout, "%5d : <-- GRIB data corrupted!\n", nrec);
-      return;
-    }
+  *vtime_lb = taxisptr->vtime_lb;
+  *vtime_ub = taxisptr->vtime_ub;
+}
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
 
-  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
-    {
-      int s1, s2;
-      s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-      s2 = ((int) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
-      cr = ((double)s1)/s2;
-    }
+void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
+  if (taxisptr->vtime_lb != vtime_lb
+      || taxisptr->vtime_ub != vtime_ub
+      || taxisptr->has_bounds != TRUE)
     {
-      fprintf(stdout, "Repair GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
-      repair1(gribbuffer, recsize);
+      taxisptr->vtime_lb = vtime_lb;
+      taxisptr->vtime_ub = vtime_ub;
+      taxisptr->has_bounds = TRUE;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
-#include <stdio.h>
-#include <string.h>
 
-#if defined (HAVE_CONFIG_H)
-#endif
+/*
+ at Function  taxisInqRdate
+ at Title     Get the reference date
 
-#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
-#if defined(__cplusplus)
-extern "C" {
-#endif
-#if defined (HAVE_LIBAEC)
-#  include <libaec.h>
-#else
-#  include <szlib.h>
-#endif
-#if defined (__cplusplus)
-}
-#endif
+ at Prototype int taxisInqRdate(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
-#if defined (HAVE_LIBAEC)
-#  define AEC_FLAGS           (AEC_DATA_MSB | AEC_DATA_PREPROCESS)
-#else
-#  define OPTIONS_MASK        (SZ_RAW_OPTION_MASK | SZ_MSB_OPTION_MASK | SZ_NN_OPTION_MASK)
-#endif
+ at Description
+The function @func{taxisInqRdate} returns the reference date of a Time axis.
 
-#  define PIXELS_PER_BLOCK    (8)
-#  define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
+ at Result
+ at func{taxisInqRdate} returns the reference date.
 
-#  define MIN_COMPRESS        (0.95)
-#  define MIN_SIZE            (256)
-#endif
+ at EndFunction
+*/
+int taxisInqRdate(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-#define  Z_SZIP  128
-#define  Z_AEC   130
+  if ( taxisptr->rdate == -1 )
+    {
+      taxisptr->rdate = taxisptr->vdate;
+      taxisptr->rtime = taxisptr->vtime;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+    }
 
+  return (taxisptr->rdate);
+}
 
-#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
-				     (var[offset+1] = 0xFF & (value >>  8)), \
-				     (var[offset+2] = 0xFF & (value      )))
-#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
-				     (var[offset+1] = 0xFF & (value >> 16)), \
-				     (var[offset+2] = 0xFF & (value >>  8)), \
-				     (var[offset+3] = 0xFF & (value      )))
+/*
+ at Function  taxisInqRtime
+ at Title     Get the reference time
 
+ at Prototype int taxisInqRtime(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
-int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
-{
-  /* urecsize : uncompressed record size  */
-  int compress = 0;
-  int nerr;
-  /* int  bds_len, bds_nbits, lspherc, lcomplex; */
-  int bds_flag, lcompress;
-  long gribsize = 0;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int gribversion;
+ at Description
+The function @func{taxisInqRtime} returns the reference time of a Time axis.
 
-  gribversion = gribVersion(gribbuffer, recsize);
+ at Result
+ at func{taxisInqRtime} returns the reference time.
 
-  if ( gribversion == 2 ) return (compress);
+ at EndFunction
+*/
+int taxisInqRtime(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
+  if ( taxisptr->rdate == -1 )
     {
-      fprintf(stdout, "GRIB message error\n");
-      return (compress);
+      taxisptr->rdate = taxisptr->vdate;
+      taxisptr->rtime = taxisptr->vtime;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 
-  if ( nerr > 0 )
-    {
-      fprintf(stdout, "GRIB data corrupted!\n");
-      return (compress);
-    }
+  return (taxisptr->rtime);
+}
 
-  /* bds_len   = BDS_Len; */
-  /* bds_nbits = BDS_NumBits; */
-  bds_flag  = BDS_Flag;
-  /* lspherc   =  bds_flag >> 7; */
-  /* lcomplex  = (bds_flag >> 6)&1; */
-  lcompress = (bds_flag >> 4)&1;
+/*
+ at Function  taxisInqFdate
+ at Title     Get the forecast reference date
 
-  *urecsize = 0;
-  if ( lcompress )
+ at Prototype int taxisInqFdate(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
+
+ at Description
+The function @func{taxisInqFdate} returns the forecast reference date of a Time axis.
+
+ at Result
+ at func{taxisInqFdate} returns the forecast reference date.
+
+ at EndFunction
+*/
+int taxisInqFdate(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+  if ( taxisptr->fdate == -1 )
     {
-      compress = BDS_Z;
-      if ( compress == Z_SZIP || compress == Z_AEC )
-	{
-	  gribsize = gribrec_len(bds[14], bds[15], bds[16]);
-	}
+      taxisptr->fdate = taxisptr->vdate;
+      taxisptr->ftime = taxisptr->vtime;
     }
 
-  *urecsize = gribsize;
-
-  return (compress);
+  return (taxisptr->fdate);
 }
 
+/*
+ at Function  taxisInqFtime
+ at Title     Get the forecast reference time
 
-int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
-{
-  int nerr;
-  int gribLen;
-  int rec_len;
-  int llarge = FALSE;
-#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
-  static int libszwarn = 1;
-#endif
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+ at Prototype int taxisInqFtime(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
-  gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
-  if ( gribLen > JP23SET ) llarge = TRUE;
+ at Description
+The function @func{taxisInqFtime} returns the forecast reference time of a Time axis.
 
-  rec_len = gribLen;
+ at Result
+ at func{taxisInqFtime} returns the forecast reference time.
 
-  long gribrecsize;
-  nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "GRIB message error\n");
-      return (rec_len);
-    }
+ at EndFunction
+*/
+int taxisInqFtime(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-  if ( nerr > 0 )
+  if ( taxisptr->fdate == -1 )
     {
-      fprintf(stdout, "GRIB data corrupted!\n");
-      return (rec_len);
+      taxisptr->fdate = taxisptr->vdate;
+      taxisptr->ftime = taxisptr->vtime;
     }
 
-#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
-
-  {
-    long i;
-    int bdsLen;
-    int gribLenOld = 0;
-    int status;
-    size_t datstart, datsize;
-#if defined (HAVE_LIBAEC)
-    struct aec_stream strm;
-#else
-    SZ_com_t sz_param;          /* szip parameter block */
-#endif
-    unsigned char *dest, *source;
-    size_t destLen, sourceLen;
-    int bits_per_sample;
-    int bds_len, bds_nbits, bds_flag, lspherc, lcomplex,/* lcompress,*/ bds_ubits;
-    int bds_head = 11;
-    int bds_ext = 0;
-    int bds_zoffset, bds_zstart;
-    unsigned char *pbuf = NULL;
+  return (taxisptr->ftime);
+}
 
-    bds_zstart  = 14;
-    bds_zoffset = 12;
-    if ( llarge ) bds_zoffset += 2;
+/*
+ at Function  taxisInqCalendar
+ at Title     Get the calendar
 
-    bds_len   = BDS_Len;
-    bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
-    bds_nbits = BDS_NumBits;
-    bds_flag  = BDS_Flag;
-    bds_ubits = bds_flag & 15;
-    lspherc   =  bds_flag >> 7;
-    lcomplex  = (bds_flag >> 6)&1;
-    /* lcompress = (bds_flag >> 4)&1; */
-    
-    if ( bds_nbits != 8 && bds_nbits != 16 && bds_nbits != 24 && bds_nbits != 32 )
-      {
-	static int linfo = 1;
-	if ( linfo && bds_nbits != 0 )
-	  {
-	    linfo = 0;
-	    fprintf(stderr, "GRIB szip only supports 8, 16, 24 and 32 bit data!\n");
-	  }
-	return (rec_len);
-      }
+ at Prototype int taxisInqCalendar(int taxisID)
+ at Parameter
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate} or @fref{vlistInqTaxis}
 
-#if defined (HAVE_LIBSZ)
-    if ( bds_nbits == 24 )
-      bits_per_sample    = 8;
-    else
-#endif
-      bits_per_sample    = bds_nbits;
+ at Description
+The function @func{taxisInqCalendar} returns the calendar of a Time axis.
 
-#if defined (HAVE_LIBAEC)
-    strm.bits_per_sample = bits_per_sample;
-    strm.block_size      = PIXELS_PER_BLOCK;
-    strm.rsi             = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
-    strm.flags           = AEC_FLAGS;
-    if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE; 
-#else
-    sz_param.options_mask        = OPTIONS_MASK;
-    sz_param.bits_per_pixel      = bits_per_sample;
-    sz_param.pixels_per_block    = PIXELS_PER_BLOCK;
-    sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
-#endif
+ at Result
+ at func{taxisInqCalendar} returns the type of the calendar,
+one of the set of predefined CDI calendar types.
+The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEPTIC},
+ at func{CALENDAR_360DAYS}, @func{CALENDAR_365DAYS} and @func{CALENDAR_366DAYS}.
 
-    if ( lspherc )
-      {
-	if ( lcomplex  )
-	  {
-	    int jup, ioff;
-	    jup  = bds[15];
-	    ioff = (jup+1)*(jup+2);
-	    bds_ext = 4 + 3 + 4*ioff;
-	  }
-	else
-	  {
-	    bds_ext = 4;
-	  }
-      }
+ at EndFunction
+*/
+int taxisInqCalendar(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-    datstart = bds_head + bds_ext;
+  return (taxisptr->calendar);
+}
 
-    datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
 
-    if ( datsize < MIN_SIZE ) return (rec_len);
-    /*
-    fprintf(stderr, "%d %d %d %d\n", bds_len, datstart, bds_len - datstart, datsize);
-    */
-    sourceLen = datsize;
-    destLen   = sbufsize;
-    
-    source = bds + datstart;
-    dest = sbuf;
+int taxisInqTunit(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-#if defined (HAVE_LIBSZ)
-    if ( bds_nbits == 24 )
-      {
-	long nelem;
-	nelem = sourceLen/3;
-	pbuf = (unsigned char*) malloc(sourceLen);
-	for ( i = 0; i < nelem; i++ )
-	  {
-	    pbuf[        i] = source[3*i  ];
-	    pbuf[  nelem+i] = source[3*i+1];
-	    pbuf[2*nelem+i] = source[3*i+2];
-	  }
-	source = pbuf;
-      }
-#endif
+  return (taxisptr->unit);
+}
 
-#if defined (HAVE_LIBAEC)
-    strm.next_in = source;
-    strm.avail_in = sourceLen;
-    strm.next_out = dest;
-    strm.avail_out = destLen;
 
-    status = aec_buffer_encode(&strm);
-    if ( status != AEC_OK )
-      {
-       	if ( status != AEC_DATA_ERROR )
-	  Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
-      }
+int taxisInqForecastTunit(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-    destLen = strm.total_out;
-#else
-    status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
-    if ( status != SZ_OK )
-      {
-	if ( status == SZ_NO_ENCODER_ERROR )
-	  Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_PARAM_ERROR )
-	  Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_MEM_ERROR )
-	  Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_OUTBUFF_FULL )
-	  /*Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2)*/;
-	else
-	  Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
-      }
-#endif
-    
-    if ( pbuf ) free(pbuf);
-    /*
-    fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
-    */
-    if ( destLen < MIN_COMPRESS*sourceLen )
-      {
-	source = bds + datstart + bds_zoffset;
-	memcpy(source, dest, destLen);
-	
-	/* ----++++ number of unused bits at end of section) */
+  return (taxisptr->fc_unit);
+}
 
-	BDS_Flag -= bds_ubits;
-    
-	gribLenOld = gribLen;
 
-	if ( bds_ext )
-	  for ( i = bds_ext-1; i >= 0; --i )
-	    bds[bds_zoffset+bds_head+i] = bds[bds_head+i];
+double taxisInqForecastPeriod(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-	/*
-	fprintf(stderr, "destLen, datsize, datstart %d %d %d\n", destLen, datsize, datstart);
-	*/
-	/*	memcpy(bds + datstart + bds_zoffset, source, destLen); */
-	/*
-	  fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
-	    (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
-	*/
-	if ( llarge )
-	  {
-	    if ( gribLenOld%120 )
-	      {
-		fprintf(stderr, "Internal problem, record length not multiple of 120!");
-		while ( gribLenOld%120 ) gribLenOld++;
-	      }
-	    gribLenOld = gribLenOld / (-120);
-	    gribLenOld = JP23SET - gribLenOld + 1;
+  return (taxisptr->fc_period);
+}
 
-	    SetLen3(bds, bds_zstart, gribLenOld);
-	    SetLen4(bds, bds_zstart+3, sourceLen);
-	    SetLen4(bds, bds_zstart+7, destLen);
-	  }
-	else
-	  {
-	    SetLen3(bds, bds_zstart, gribLenOld);
-	    SetLen3(bds, bds_zstart+3, sourceLen);
-	    SetLen3(bds, bds_zstart+6, destLen);
-	  }
 
-	bdsLen = datstart + bds_zoffset + destLen;
+int taxisInqNumavg(int taxisID)
+{
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-	bds[11] = 0;
-	bds[12] = 0;
-#if defined (HAVE_LIBAEC)
-	BDS_Z   = Z_AEC;
-#else
-	BDS_Z   = Z_SZIP;
-#endif
+  return (taxisptr->numavg);
+}
 
-	BDS_Flag += 16;
-	if ( (bdsLen%2) == 1 )
-	  {
-	    BDS_Flag += 8;
-	    bds[bdsLen++] = 0;
-	  }
 
-	SetLen3(bds, 0, bdsLen);
+taxis_t *taxisPtr(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
 
-	gribLen = (bds - dbuf) + bdsLen;
+  return (taxisptr);
+}
 
-	dbuf[gribLen++] = '7';
-	dbuf[gribLen++] = '7';
-	dbuf[gribLen++] = '7';
-	dbuf[gribLen++] = '7';
+void
+ptaxisDefName(taxis_t *taxisptr, const char *name)
+{
+  if (name)
+    {
+      size_t len = strlen(name);
+      delete_refcount_string(taxisptr->name);
+      char *taxisname = taxisptr->name = new_refcount_string(len);
+      strcpy(taxisname, name);
+    }
+}
 
-	if ( llarge )
-	  {
-	    long itemp;
-	    long bdslen = gribLen - 4;
+void
+ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
+{
+  if (longname)
+    {
+      size_t len = strlen(longname);
+      delete_refcount_string(taxisptr->longname);
+      char *taxislongname = taxisptr->longname = new_refcount_string(len);
+      strcpy(taxislongname, longname);
+    }
+}
 
-	    /*
-	      If a very large product, the section 4 length field holds
-	      the number of bytes in the product after section 4 upto
-	      the end of the padding bytes.
-	      This is a fixup to get round the restriction on product lengths
-	      due to the count being only 24 bits. It is only possible because
-	      the (default) rounding for GRIB products is 120 bytes.
-	    */
-	    while ( gribLen%120 ) dbuf[gribLen++] = 0;
 
-	    itemp = gribLen / (-120);
-	    itemp = JP23SET - itemp + 1;
+void cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
+{
+  static int lwarn = TRUE;
 
-	    SetLen3(dbuf, 4, itemp);
+  *days = 0;
+  *secs = 0;
 
-	    bdslen = gribLen - bdslen;
+  if ( timeunit == TUNIT_MINUTE )
+    {
+      timevalue *= 60;
+      timeunit = TUNIT_SECOND;
+    }
+  else if ( timeunit == TUNIT_HOUR )
+    {
+      timevalue /= 24;
+      timeunit = TUNIT_DAY;
+    }
 
-	    SetLen3(bds, 0, bdslen);
-	  }
-	else
-	  {
-	    SetLen3(dbuf, 4, gribLen);
-	  }
-      }
-    else
+  if ( timeunit == TUNIT_SECOND )
+    {
+      *days = (int) (timevalue/86400);
+      double seconds = timevalue - *days*86400.;
+      *secs = lround(seconds);
+      if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
+      /*
       {
+	double cval = *days*86400. + *secs;
+	if ( cval != timevalue )
+	  printf("TUNIT_SECOND error: %g %g %d %d\n", timevalue, cval, *days, *secs);
       }
-    /*
-    fprintf(stderr, "%3d %3d griblen in %6d  out %6d  CR %g   slen %6d dlen %6d  CR %g\n",
-	    PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
-	    ((double)gribLenOld)/gribLen, sourceLen, destLen,
-	    ((double)sourceLen)/destLen);
-    */
-  }
-
-#else
-  if ( libszwarn )
+      */
+    }
+  else if ( timeunit == TUNIT_DAY )
     {
-      Warning("Compression disabled, szlib or libaec not available!");
-      libszwarn = 0;
+      *days = (int) timevalue;
+      double seconds = (timevalue - *days)*86400;
+      *secs = lround(seconds);
+      if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
+      /*
+      {
+	double cval = *days + *secs/86400.;
+	if ( cval != timevalue )
+	  printf("TUNIT_DAY error: %g %g %d %d\n", timevalue, cval, *days, *secs);
+      }
+      */
     }
-#endif
-
-  if ( llarge )
-    while ( gribLen%120 ) dbuf[gribLen++] = 0;
   else
-    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+    {
+      if ( lwarn )
+	{
+	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
+	  lwarn = FALSE;
+	}
+    }
+}
 
-  rec_len = gribLen;
+static
+void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
+{
+  static int lwarn = TRUE;
 
-  return (rec_len);
+  if ( timeunit == TUNIT_SECOND )
+    {
+      *timevalue = days*86400. + secs;
+    }
+  else if ( timeunit == TUNIT_MINUTE  ||
+	    timeunit == TUNIT_QUARTER ||
+	    timeunit == TUNIT_30MINUTES )
+    {
+      *timevalue = days*1440. + secs/60.;
+    }
+  else if ( timeunit == TUNIT_HOUR   ||
+	    timeunit == TUNIT_3HOURS ||
+	    timeunit == TUNIT_6HOURS ||
+	    timeunit == TUNIT_12HOURS )
+    {
+      *timevalue = days*24. + secs/3600.;
+    }
+  else if ( timeunit == TUNIT_DAY )
+    {
+      *timevalue = days + secs/86400.;
+    }
+  else
+    {
+      if ( lwarn )
+	{
+	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
+	  lwarn = FALSE;
+	}
+    }
 }
 
+int days_per_month(int calendar, int year, int month);
 
-int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
+void timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime)
 {
-#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
-  static int libszwarn = 1;
-#endif
-  int nerr;
-  unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int bdsLen, recLen, gribLen = 0;
-  unsigned char *dest, *source;
-  size_t destLen, sourceLen;
-  int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
-  int bds_head = 11;
-  int bds_ext = 0;
-  int bds_zoffset, bds_zstart;
-  int datstart = 0;
-  int llarge = FALSE;
+  int year, month, day, hour, minute, second;
+  int rdate, rtime;
+  int timeunit;
+  int calendar;
+  int julday, secofday, days, secs;
 
-  UNUSED(dbufsize);
+  *vdate = 0;
+  *vtime = 0;
 
-  long gribrecsize;
-  nerr = grib1Sections(sbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
+  timeunit = (*taxis).unit;
+  calendar = (*taxis).calendar;
+
+  rdate  = (*taxis).rdate;
+  rtime  = (*taxis).rtime;
+
+  if ( rdate == 0 && rtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
+
+  cdiDecodeDate(rdate, &year, &month, &day);
+  cdiDecodeTime(rtime, &hour, &minute, &second);
+
+  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
     {
-      fprintf(stdout, "GRIB message error\n");
-      return (0);
+      timeunit = TUNIT_DAY;
+      timevalue *= 30;
     }
 
-  if ( nerr > 0 )
+  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
     {
-      fprintf(stdout, "GRIB data corrupted!\n");
-      return (0);
-    }
+      int nmon, dpm;
+      double fmon;
 
-  bds_zstart = 14;
+      if ( timeunit == TUNIT_YEAR ) timevalue *= 12;
 
-  recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
-  if ( recLen > JP23SET ) llarge = TRUE;
+      nmon = (int) timevalue;
+      fmon = timevalue - nmon;
 
-  bds_zoffset = 12;
-  if ( llarge ) bds_zoffset += 2;
+      month += nmon;
 
-  /* bds_len   = BDS_Len; */
-  bds_nbits = BDS_NumBits;
-  bds_flag  = BDS_Flag;
-  lspherc   =  bds_flag >> 7;
-  lcomplex  = (bds_flag >> 6)&1;
-  /* lcompress = (bds_flag >> 4)&1; */
+      while ( month > 12 ) { month -= 12; year++; }
+      while ( month <  1 ) { month += 12; year--; }
 
-  if ( lspherc )
-    {
-      if ( lcomplex  )
-	{
-	  int jup, ioff;
-	  jup  = bds[bds_zoffset+15];
-	  ioff = (jup+1)*(jup+2);
-	  bds_ext = 4 + 3 + 4*ioff;
-	}
-      else
-	{
-	  bds_ext = 4;
-	}
+      dpm = days_per_month(calendar, year, month);
+      timeunit = TUNIT_DAY;
+      timevalue = fmon*dpm;
     }
 
-  datstart = bds_head + bds_ext;
+  encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
 
-  source = bds + datstart + bds_zoffset;
-  if ( llarge )
-    sourceLen = ((size_t) ((bds[21]<<24)+(bds[22]<<16)+(bds[23]<<8)+bds[24]));
-  else
-    sourceLen = ((size_t) ((bds[20]<<16)+(bds[21]<<8)+bds[22]));
+  cdiDecodeTimevalue(timeunit, timevalue, &days, &secs);
 
-  nerr = grib1Sections(dbuf, sbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
-  if ( nerr < 0 )
-    {
-      fprintf(stdout, "GRIB message error\n");
-      return (0);
-    }
+  julday_add(days, secs, &julday, &secofday);
 
-  if ( nerr > 0 )
+  decode_caldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+
+  *vdate = cdiEncodeDate(year, month, day);
+  *vtime = cdiEncodeTime(hour, minute, second);
+}
+
+
+double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
+{
+  int ryear, rmonth;
+  int year, month, day, hour, minute, second;
+  int rdate, rtime;
+  double value = 0;
+  int timeunit;
+  int timeunit0;
+  int calendar;
+  int julday1, secofday1, julday2, secofday2, days, secs;
+
+  timeunit = (*taxis).unit;
+  calendar = (*taxis).calendar;
+
+  rdate = (*taxis).rdate;
+  rtime = (*taxis).rtime;
+  if ( rdate == -1 )
     {
-      fprintf(stdout, "GRIB data corrupted!\n");
-      return (0);
+      rdate  = (*taxis).vdate;
+      rtime  = (*taxis).vtime;
     }
 
-  dest = bds + datstart;
-   if ( llarge )
-    destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
-  else
-    destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
-
-  BDS_Flag -= 16;
+  if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return(value);
 
-  bdsLen = datstart + destLen;
+  cdiDecodeDate(rdate, &ryear, &rmonth, &day);
+  cdiDecodeTime(rtime, &hour, &minute, &second);
 
-#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
-  {
-    int status;
-    long i;
-    size_t tmpLen;
-    int bds_ubits;
-    int bits_per_sample;
-#if defined (HAVE_LIBAEC)
-    struct aec_stream strm;
-#else
-    SZ_com_t sz_param;          /* szip parameter block */
-#endif
+  encode_caldaysec(calendar, ryear, rmonth, day, hour, minute, second, &julday1, &secofday1);
 
-#if defined (HAVE_LIBSZ)
-    if ( bds_nbits == 24 )
-      bits_per_sample    = 8;
-    else
-#endif
-      bits_per_sample    = bds_nbits;
+  cdiDecodeDate(vdate, &year, &month, &day);
+  cdiDecodeTime(vtime, &hour, &minute, &second);
 
-#if defined (HAVE_LIBAEC)
-    strm.bits_per_sample         = bits_per_sample;
-    strm.block_size              = PIXELS_PER_BLOCK;
-    strm.rsi                     = PIXELS_PER_SCANLINE / PIXELS_PER_BLOCK;
-    strm.flags                   = AEC_FLAGS;
-    if ( bds_nbits == 24 ) strm.flags |= AEC_DATA_3BYTE; 
-#else
-    sz_param.options_mask        = OPTIONS_MASK;
-    sz_param.bits_per_pixel      = bits_per_sample;
-    sz_param.pixels_per_block    = PIXELS_PER_BLOCK;
-    sz_param.pixels_per_scanline = PIXELS_PER_SCANLINE;
-#endif
+  timeunit0 = timeunit;
 
-    if ( bds_ext )
-      for ( i = 0; i < bds_ext; ++i )
-	bds[bds_head+i] = bds[bds_zoffset+bds_head+i];
+  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
+    {
+      timeunit = TUNIT_DAY;
+    }
 
-    /*
-    fprintf(stderr, "gribUnzip: sourceLen %ld; destLen %ld\n", (long)sourceLen, (long)destLen);
-    fprintf(stderr, "gribUnzip: sourceOff %d; destOff %d\n", bds[12], bds[11]);
-    fprintf(stderr, "gribUnzip: reclen %d; bdslen %d\n", recLen, bdsLen);
-    */
+  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
+    {
+      int nmonth, dpm;
 
-    tmpLen = destLen;
-#if defined (HAVE_LIBAEC)
-    strm.next_in   = source;
-    strm.avail_in  = sourceLen;
-    strm.next_out  = dest;
-    strm.avail_out = tmpLen;
+      value = (year-ryear)*12 - rmonth + month;
 
-    status = aec_buffer_decode(&strm);
-    if ( status != AEC_OK )
-      Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+      nmonth = (int) value;
+      month -= nmonth;
 
-    tmpLen = strm.total_out;
-#else
-    status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
-    if ( status != SZ_OK )
-      {
-	if ( status == SZ_NO_ENCODER_ERROR )
-	  Warning("SZ_NO_ENCODER_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_PARAM_ERROR )
-	  Warning("SZ_PARAM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_MEM_ERROR )
-	  Warning("SZ_MEM_ERROR code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else if ( status == SZ_OUTBUFF_FULL )
-	  Warning("SZ_OUTBUFF_FULL code %3d level %3d", PDS_Parameter, PDS_Level2);
-	else
-	  Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
-      }
-#endif
-    /*
-    fprintf(stderr, "gribUnzip: sl = %ld  dl = %ld   tl = %ld\n",
-	    (long)sourceLen, (long)destLen,(long) tmpLen);
-    */
-    if ( tmpLen != destLen )
-      Warning("unzip size differ: code %3d level %3d  ibuflen %ld ubuflen %ld",
-	      PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
+      while ( month > 12 ) { month -= 12; year++; }
+      while ( month <  1 ) { month += 12; year--; }
 
-#if defined (HAVE_LIBSZ)
-    if ( bds_nbits == 24 )
-      {
-	long nelem;
-	unsigned char *pbuf;
-	nelem = tmpLen/3;
-	pbuf = (unsigned char*) malloc(tmpLen);
-	for ( i = 0; i < nelem; i++ )
-	  {
-	    pbuf[3*i  ] = dest[        i];
-	    pbuf[3*i+1] = dest[  nelem+i];
-	    pbuf[3*i+2] = dest[2*nelem+i];
-	  }
-	memcpy(dest, pbuf, tmpLen);
-	free(pbuf);
-      }
-#endif
+      dpm = days_per_month(calendar, year, month);
 
-    bds_ubits = BDS_Flag & 15;
-    BDS_Flag -= bds_ubits;
+      encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
-    if ( (bdsLen%2) == 1 )
-      {
-	BDS_Flag += 8;
-	bds[bdsLen++] = 0;
-      }
+      julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
-    SetLen3(bds, 0, bdsLen);
+      value += (days+secs/86400.)/dpm;
 
-    gribLen = (bds - dbuf) + bdsLen;
-    
-    dbuf[gribLen++] = '7';
-    dbuf[gribLen++] = '7';
-    dbuf[gribLen++] = '7';
-    dbuf[gribLen++] = '7';
+      if ( timeunit == TUNIT_YEAR ) value = value/12;
+    }
+  else
+    {
+      encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
-    if ( llarge )
-      {
-	long itemp;
-        bdsLen = gribLen - 4;
-	/*
-	  If a very large product, the section 4 length field holds
-	  the number of bytes in the product after section 4 upto
-	  the end of the padding bytes.
-	  This is a fixup to get round the restriction on product lengths
-	  due to the count being only 24 bits. It is only possible because
-	  the (default) rounding for GRIB products is 120 bytes.
-	*/
-	while ( gribLen%120 ) dbuf[gribLen++] = 0;
+      julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
-	if ( gribLen != recLen )
-	  fprintf(stderr, "Internal problem, recLen and gribLen differ!\n");
-	
-	itemp = gribLen / (-120);
-	itemp = JP23SET - itemp + 1;
-	
-	SetLen3(dbuf, 4, itemp);
+      cdiEncodeTimevalue(days, secs, timeunit, &value);
+    }
 
-	bdsLen = gribLen - bdsLen;
-	    
-	SetLen3(bds, 0, bdsLen);
-      }
-    else
-      {
-	SetLen3(dbuf, 4, recLen);
-      }
-    /*
-    fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
-    */
-    if ( llarge )
-      while ( gribLen%120 ) dbuf[gribLen++] = 0;
-    else
-      while ( gribLen & 7 ) dbuf[gribLen++] = 0;
-    /*
-    fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
-    */
-  }
-#else
-  if ( libszwarn )
+  if ( timeunit0 == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
     {
-      Warning("Decompression disabled, szlib or libaec not available!");
-      libszwarn = 0;
+      value /= 30;
     }
-#endif
 
-  return (gribLen);
+  return (value);
 }
-#include <stdio.h>
-#include <math.h>
 
 
-/* calculate_pfactor: source code from grib_api-1.8.0 */
-double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation)
+void conv_timeval(double timevalue, int *rvdate, int *rvtime)
 {
-  /*long n_vals = ((fieldTruncation+1)*(fieldTruncation+2));*/
-  long loop, index, m, n = 0;
-  double pFactor, zeps = 1.0e-15;
-  long ismin = (subsetTruncation+1), ismax = (fieldTruncation+1);
-  double* weights, range, * norms;
-  double weightedSumOverX = 0.0, weightedSumOverY = 0.0, sumOfWeights = 0.0, x, y;
-  double numerator = 0.0, denominator = 0.0, slope;
+  int vdate = 0, vtime = 0;
+  int hour, minute, second;
+  int daysec;
 
-  /*
-  // Setup the weights
-   */
+  vdate = (int) timevalue;
+  if ( vdate < 0 )
+    daysec = (int) (-(timevalue - vdate)*86400 + 0.01);
+  else
+    daysec = (int) ( (timevalue - vdate)*86400 + 0.01);
 
-  range = (double) (ismax - ismin +1);
+  hour   =  daysec / 3600;
+  minute = (daysec - hour*3600)/60;
+  second =  daysec - hour*3600 - minute*60;
+  vtime  = cdiEncodeTime(hour, minute, second);
 
-  weights = (double*) malloc((ismax+1)*sizeof(double));
-  for( loop = ismin; loop <= ismax; loop++ )
-    weights[loop] = range / (double) (loop-ismin+1);
-  /*
-  // Compute norms
-  // Handle values 2 at a time (real and imaginary parts).
-   */
-  norms = (double*) malloc((ismax+1)*sizeof(double));
+  *rvdate = vdate;
+  *rvtime = vtime;
+}
 
-  for( loop = 0; loop < ismax+1; loop++ ) norms[loop] = 0.0;
-  /*
-  // Form norms for the rows which contain part of the unscaled subset.
-   */
 
-  index = -2;
-  for( m = 0; m < subsetTruncation; m++ )
-    for( n = m; n <= fieldTruncation; n++ ) {
-      index += 2;
-      if( n >= subsetTruncation ) {
-        double tval = spectralField[index];
-        tval=tval<0?-tval:tval;
-        norms[n] = norms[n] > tval ? norms[n] : tval;
-        tval = spectralField[index+1];
-        tval=tval<0?-tval:tval;
-        norms[n] = norms[n] > tval ? norms[n] : tval;
-      }
+void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
+{
+  int vdate = 0, vtime = 0;
+  int hour, minute, second;
+  int year, month, day;
+  static int lwarn = TRUE;
+
+  if ( timeunit == TUNIT_SECOND )
+    {
+      timevalue /= 86400;
+      conv_timeval(timevalue, &vdate, &vtime);
     }
-  /*
-  // Form norms for the rows which do not contain part of the unscaled subset.
-   */
+  else if ( timeunit == TUNIT_HOUR )
+    {
+      timevalue /= 24;
+      conv_timeval(timevalue, &vdate, &vtime);
+    }
+  else if ( timeunit == TUNIT_DAY )
+    {
+      conv_timeval(timevalue, &vdate, &vtime);
+    }
+  else if ( timeunit == TUNIT_MONTH )
+    {
+      vdate = (int) timevalue*100;
+      vdate += 1;
+      vtime = 0;
+    }
+  else if ( timeunit == TUNIT_YEAR )
+    {
+      if ( timevalue < -214700 )
+	{
+	  Warning("Year %g out of range, set to -214700", timevalue);
+	  timevalue = -214700;
+	}
+      else if ( timevalue > 214700 )
+	{
+	  Warning("Year %g out of range, set to 214700", timevalue);
+	  timevalue = 214700;
+	}
 
-  for( m = subsetTruncation; m <= fieldTruncation; m++ )
-    for( n = m; n <= fieldTruncation; n++ ) {
-      double tval = spectralField[index];
-      index += 2;
-      tval=tval<0?-tval:tval;
-      norms[n] = norms[n] > tval ? norms[n] : tval;
-      tval = spectralField[index+1];
-      tval=tval<0?-tval:tval;
-      norms[n] = norms[n] > tval ? norms[n] : tval;
+      vdate = (int) timevalue*10000;
+      vdate += 101;
+      vtime = 0;
+    }
+  else
+    {
+      if ( lwarn )
+	{
+	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
+	  lwarn = FALSE;
+	}
     }
 
-  /*
-  // Ensure the norms have a value which is not too small in case of
-  // problems with math functions (e.g. LOG).
-   */
+  /* verify date and time */
 
-  for( loop = ismin; loop <= ismax; loop++ ) {
-    norms[n] = norms[n] > zeps ? norms[n] : zeps;
-    if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
-  }
+  cdiDecodeDate(vdate, &year, &month, &day);
+  cdiDecodeTime(vtime, &hour, &minute, &second);
 
-  /*
-  // Do linear fit to find the slope
-   */
+  if ( month > 17 || day > 31 || hour > 23 || minute > 59 || second > 59 )
+    {
+      if ( (month  > 17 || day > 31) && (year < -9999 || year > 9999) ) year = 1;
+      if ( month  > 17 ) month  = 1;
+      if ( day    > 31 ) day    = 1;
+      if ( hour   > 23 ) hour   = 0;
+      if ( minute > 59 ) minute = 0;
+      if ( second > 59 ) second = 0;
 
-  for( loop = ismin; loop <= ismax; loop++ ) {
-    x = log( (double) (loop*(loop+1)) );
-    y = log( norms[loop] );
-    weightedSumOverX = weightedSumOverX + x * weights[loop];
-    weightedSumOverY = weightedSumOverY + y * weights[loop];
-    sumOfWeights = sumOfWeights + weights[loop];
-  }
-  weightedSumOverX = weightedSumOverX / sumOfWeights;
-  weightedSumOverY = weightedSumOverY / sumOfWeights;
+      vdate = cdiEncodeDate(year, month, day);
+      vtime = cdiEncodeTime(hour, minute, second);
 
-  /*
-  // Perform a least square fit for the equation
-   */
+      if ( lwarn )
+        {
+          lwarn = FALSE;
+          Warning("Reset wrong date/time to %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d!",
+                  year, month, day, hour, minute, second);
+        }
+    }
 
-  for( loop = ismin; loop <= ismax; loop++ ) {
+  *date = vdate;
+  *time = vtime;
+}
 
-    x = log( (double)(loop*(loop+1)) );
-    y = log( norms[loop] );
-    numerator =
-      numerator + weights[loop] * (y-weightedSumOverY) * (x-weightedSumOverX);
-    denominator =
-      denominator + weights[loop] * ((x-weightedSumOverX) * (x-weightedSumOverX));
-  }
-  slope = numerator / denominator;
 
-  free(weights);
-  free(norms);
+void cdiSetForecastPeriod(double timevalue, taxis_t *taxis)
+{
+  int year, month, day, hour, minute, second;
+  int vdate, vtime;
+  int timeunit;
+  int calendar;
+  int julday, secofday, days, secs;
 
-  pFactor = -slope;
-  if( pFactor < -9999.9 ) pFactor = -9999.9;
-  if( pFactor > 9999.9 )  pFactor = 9999.9;
+  (*taxis).fc_period = timevalue;
 
-  return pFactor;
-}
+  timeunit = (*taxis).fc_unit;
+  calendar = (*taxis).calendar;
 
-static
-int rowina2(double *p, int ko, int ki, double *pw,
-	    int kcode, double msval, int *kret)
-{
-  /* System generated locals */
-  int pw_dim1, pw_offset, i_1;
+  vdate  = (*taxis).vdate;
+  vtime  = (*taxis).vtime;
 
-  /* Local variables */
-  double zwt1, zrdi, zpos;
-  int jl, ip;
-  double zdo, zwt;
+  if ( vdate == 0 && vtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
 
-  /* Parameter adjustments */
-  --p;
-  pw_dim1 = ko + 3;
-  pw_offset = pw_dim1;
-  pw -= pw_offset;
+  cdiDecodeDate(vdate, &year, &month, &day);
+  cdiDecodeTime(vtime, &hour, &minute, &second);
 
-  /* **** ROWINA2 - Interpolation of row of values. */
-  /*     Input Parameters. */
-  /*     ----------------- */
-  /*     P      - Row of values to be interpolated. */
-  /*              Dimension must be at least KO. */
-  /*     KO     - Number of values required. */
-  /*     KI     - Number of values in P on input. */
-  /*     PW     - Working array. */
-  /*              Dimension must be at least (0:KO+2,3). */
-  /*     KCODE  - Interpolation required. */
-  /*              1 , linear. */
-  /*              3 , cubic. */
-  /*     PMSVAL - Value used for missing data indicator. */
+  if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
+    {
+      timeunit = TUNIT_DAY;
+      timevalue *= 30;
+    }
 
-  /*     Output Parameters. */
-  /*     ------------------ */
-  /*     P     - Now contains KO values. */
-  /*     KRET  - Return code */
-  /*             0, OK */
-  /*             Non-zero, error */
+  if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
+    {
+      int nmon, dpm;
+      double fmon;
 
-  /*     Author. */
-  /*     ------- */
-  /*     J.D.Chambers    ECMWF     22.07.94 */
+      if ( timeunit == TUNIT_YEAR ) timevalue *= 12;
 
-  /*     ********************************    */
-  /*     Section 1.  Linear interpolation .. */
-  /*     ********************************    */
+      nmon = (int) timevalue;
+      fmon = timevalue - nmon;
 
-  *kret = 0;
+      month -= nmon;
 
-  if ( kcode == 1 )
-    {
-      /*    Move input values to work array */
-      for ( jl = 1; jl <= ki; ++jl )
-	pw[jl + pw_dim1] = p[jl];
+      while ( month > 12 ) { month -= 12; year++; }
+      while ( month <  1 ) { month += 12; year--; }
 
-      /*    Arrange wrap-around value in work array */
-      pw[ki + 1 + pw_dim1] = p[1];
+      dpm = days_per_month(calendar, year, month);
+      timeunit = TUNIT_DAY;
+      timevalue = fmon*dpm;
+    }
 
-      /*    Set up constants to be used to figure out weighting for */
-      /*    values in interpolation. */
-      zrdi = (double) ki;
-      zdo = 1.0 / (double) ko;
+  encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
 
-      /*    Loop through the output points */
-      for ( jl = 1; jl <= ko; ++jl )
-	{
+  cdiDecodeTimevalue(timeunit, timevalue, &days, &secs);
 
-	  /*    Calculate weight from the start of row */
-	  zpos = (jl - 1) * zdo;
-	  zwt = zpos * zrdi;
+  julday_add(-days, -secs, &julday, &secofday);
 
-	  /*    Get the current array position(minus 1) from the weight - */
-	  /*    note the implicit truncation. */
-	  ip = (int) zwt;
+  decode_caldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
 
-	  /*    If the left value is missing, use the right value */
-	  if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
-	    {
-	      p[jl] = pw[ip + 2 + pw_dim1];
-	    }
-	  /*    If the right value is missing, use the left value */
-	  else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
-	    {
-	      p[jl] = pw[ip + 1 + pw_dim1];
-	    }
-	  /*    If neither missing, interpolate ... */
-	  else
-	    {
+  (*taxis).fdate = cdiEncodeDate(year, month, day);
+  (*taxis).ftime = cdiEncodeTime(hour, minute, second);
+}
 
-	      /*       Adjust the weight to range (0.0 to 1.0) */
-	      zwt -= ip;
 
-	      /*       Interpolate using the weighted values on either side */
-	      /*       of the output point position */
-	      p[jl] = (1.0 - zwt) * pw[ip + 1 + pw_dim1] +
-		zwt * pw[ip + 2 + pw_dim1];
-	    }
-	}
+void cdiDecodeTimeval(double timevalue, taxis_t *taxis, int *date, int *time)
+{
+  if ( taxis->type == TAXIS_ABSOLUTE )
+    splitTimevalue(timevalue, taxis->unit, date, time);
+  else
+    timeval2vtime(timevalue, taxis, date, time);
+}
 
-      /*     *******************************    */
-      /*     Section 2.  Cubic interpolation .. */
-      /*     *******************************    */
 
-    }
-  else if ( kcode == 3 )
+double cdiEncodeTimeval(int date, int time, taxis_t *taxis)
+{
+  double timevalue;
+
+  if ( taxis->type == TAXIS_ABSOLUTE )
     {
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
+      if ( taxis->unit == TUNIT_YEAR )
 	{
-          if ( IS_EQUAL(p[jl], msval) )
-	    {
-	      fprintf(stderr," ROWINA2: ");
-	      fprintf(stderr," Cubic interpolation not supported");
-	      fprintf(stderr," for fields containing missing data.\n");
-	      *kret = 1;
-	      goto L900;
-	    }
-          pw[jl + pw_dim1] = p[jl];
+	  int year, month, day;
+	  cdiDecodeDate(date, &year, &month, &day);
+
+	  timevalue = year;
 	}
-      pw[pw_dim1] = p[ki];
-      pw[ki + 1 + pw_dim1] = p[1];
-      pw[ki + 2 + pw_dim1] = p[2];
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
+      else if ( taxis->unit == TUNIT_MONTH )
 	{
-          pw[jl + (pw_dim1 << 1)] =
-	        - pw[jl - 1 + pw_dim1] / 3.0 -
-	          pw[jl     + pw_dim1] * 0.5 +
-	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
-          pw[jl + 1 + pw_dim1 * 3] =
-                  pw[jl - 1 + pw_dim1] / 6.0 -
-                  pw[jl     + pw_dim1] +
-                  pw[jl + 1 + pw_dim1] * 0.5 +
-                  pw[jl + 2 + pw_dim1] / 3.0;
+	  int year, month, day;
+	  cdiDecodeDate(date, &year, &month, &day);
+	  if ( day == 0 )
+	    timevalue = date/100;
+	  else
+	    timevalue = date/100 + 0.5;
 	}
-
-      scm0_double(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
-		  &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
-
-      zrdi = (double) ki;
-      zdo = 1.0 / (double) ko;
-      for ( jl = 1; jl <= ko; ++jl )
+      else
 	{
-          zpos = (jl - 1) * zdo;
-          zwt = zpos * zrdi;
-          ip = (int) zwt + 1;
-          zwt = zwt + 1.0 - ip;
-          zwt1 = 1.0 - zwt;
-          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
-                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
-                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
-                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
+	  int hour, minute, second;
+	  cdiDecodeTime(time, &hour, &minute, &second);
+	  if ( date < 0 )
+	    timevalue = -(-date + (hour*3600 + minute*60 + second)/86400.);
+	  else
+	    timevalue =    date + (hour*3600 + minute*60 + second)/86400.;
 	}
-
     }
   else
-    {
-      /*    **************************************    */
-      /*    Section 3.  Invalid interpolation code .. */
-      /*    **************************************    */
-      fprintf(stderr," ROWINA2:");
-      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
-      *kret = 2;
-    }
-
-L900:
-    return 0;
-} /* rowina2 */
+    timevalue = vtime2timeval(date, time, taxis);
 
+  return (timevalue);
+}
 
 
-int qu2reg2(double *pfield, int *kpoint, int klat, int klon,
-	    double *ztemp, double msval, int *kret)
+void ptaxisInit(taxis_t *taxisptr)
 {
-   /* System generated locals */
-   int i_1, i_2;
-   int kcode = 1;
+  taxisDefaultValue ( taxisptr );
+}
 
-   /* Local variables */
-   int ilii, ilio, icode;
-   double *zline = NULL;
-   double *zwork = NULL;
-   int iregno, iquano, j210, j220, j230, j240, j225;
 
+void ptaxisCopy(taxis_t *dest, taxis_t *source)
+{
+  reshLock ();
 
-   zline = (double*) malloc(2*klon*sizeof(double));
-   if ( zline == NULL ) SysError("No Memory!");
+  /* memcpy(dest, source, sizeof(taxis_t)); */
+  dest->used        = source->used;
+  dest->type        = source->type;
+  dest->vdate       = source->vdate;
+  dest->vtime       = source->vtime;
+  dest->rdate       = source->rdate;
+  dest->rtime       = source->rtime;
+  dest->fdate       = source->fdate;
+  dest->ftime       = source->ftime;
+  dest->calendar    = source->calendar;
+  dest->unit        = source->unit;
+  dest->numavg      = source->numavg;
+  dest->climatology = source->climatology;
+  dest->has_bounds  = source->has_bounds;
+  dest->vdate_lb    = source->vdate_lb;
+  dest->vtime_lb    = source->vtime_lb;
+  dest->vdate_ub    = source->vdate_ub;
+  dest->vtime_ub    = source->vtime_ub;
+  dest->fc_unit     = source->fc_unit;
+  dest->fc_period   = source->fc_period;
 
-   zwork = (double*) malloc(3*(2*klon+3)*sizeof(double));
-   if ( zwork == NULL ) SysError("No Memory!");
+  dest->climatology = source->climatology;
+  delete_refcount_string(dest->name);
+  delete_refcount_string(dest->longname);
+  dest->name = dup_refcount_string(source->name);
+  dest->longname = dup_refcount_string(source->longname);
+  if (dest->self != CDI_UNDEFID)
+    reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
+  reshUnlock ();
+}
 
-   /* Parameter adjustments */
-   --pfield;
-   --kpoint;
 
-/* **** QU2REG - Convert quasi-regular grid data to regular. */
-/*     Input Parameters. */
-/*     ----------------- */
-/*     PFIELD     - Array containing quasi-regular grid */
-/*                  data. */
-/*     KPOINT     - Array containing list of the number of */
-/*                  points on each latitude (or longitude) of */
-/*                  the quasi-regular grid. */
-/*     KLAT       - Number of latitude lines */
-/*     KLON       - Number of longitude lines */
-/*     KCODE      - Interpolation required. */
-/*                  1 , linear - data quasi-regular on */
-/*                               latitude lines. */
-/*                  3 , cubic -  data quasi-regular on */
-/*                               latitude lines. */
-/*                  11, linear - data quasi-regular on */
-/*                               longitude lines. */
-/*                  13, cubic -  data quasi-regular on */
-/*                               longitude lines. */
-/*     PMSVAL     - Value used for missing data indicator. */
-/*     Output Parameters. */
-/*     ------------------ */
-/*     KRET       - return code */
-/*                  0 = OK */
-/*                  non-zero indicates fatal error */
-/*     PFIELD     - Array containing regular grid data. */
-/*     Author. */
-/*     ------- */
-/*     J.D.Chambers     ECMWF      22.07.94 */
-/*     J.D.Chambers     ECMWF      13.09.94 */
-/*     Add return code KRET and remove calls to ABORT. */
+static void
+taxisPrintKernel(taxis_t * taxisptr, FILE * fp)
+{
+  int vdate_lb, vdate_ub;
+  int vtime_lb, vtime_ub;
 
+  taxisInqVdateBounds ( taxisptr->self, &vdate_lb, &vdate_ub);
+  taxisInqVtimeBounds ( taxisptr->self, &vtime_lb, &vtime_ub);
 
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "# taxisID %d\n", taxisptr->self);
+  fprintf ( fp, "#\n");
+  fprintf ( fp, "self        = %d\n", taxisptr->self );
+  fprintf ( fp, "used        = %d\n", taxisptr->used );
+  fprintf ( fp, "type        = %d\n", taxisptr->type );
+  fprintf ( fp, "vdate       = %d\n", taxisptr->vdate );
+  fprintf ( fp, "vtime       = %d\n", taxisptr->vtime );
+  fprintf ( fp, "rdate       = %d\n", taxisptr->rdate );
+  fprintf ( fp, "rtime       = %d\n", taxisptr->rtime );
+  fprintf ( fp, "fdate       = %d\n", taxisptr->fdate );
+  fprintf ( fp, "ftime       = %d\n", taxisptr->ftime );
+  fprintf ( fp, "calendar    = %d\n", taxisptr->calendar );
+  fprintf ( fp, "unit        = %d\n", taxisptr->unit );
+  fprintf ( fp, "numavg      = %d\n", taxisptr->numavg );
+  fprintf ( fp, "climatology = %d\n", taxisptr->climatology );
+  fprintf ( fp, "has_bounds  = %d\n", taxisptr->has_bounds );
+  fprintf ( fp, "vdate_lb    = %d\n", vdate_lb );
+  fprintf ( fp, "vtime_lb    = %d\n", vtime_lb );
+  fprintf ( fp, "vdate_ub    = %d\n", vdate_ub );
+  fprintf ( fp, "vtime_ub    = %d\n", vtime_ub );
+  fprintf ( fp, "fc_unit     = %d\n", taxisptr->fc_unit );
+  fprintf ( fp, "fc_period   = %g\n", taxisptr->fc_period );
+  fprintf ( fp, "\n");
+}
 
-   *kret = 0;
+void taxisPrint ( int taxisID )
+{
+  taxis_t * taxisptr;
 
-/* Check input parameters. */
+  taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+  taxisPrintKernel ( taxisptr, stdout );
+}
 
-   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
-      fprintf(stderr," QU2REG :");
-      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
-      *kret = 1;
-      goto L900;
-   }
+static int
+taxisCompareP(void *taxisptr1, void *taxisptr2)
+{
+  taxis_t * t1, * t2;
 
-/* Set array indices to 0. */
+  t1 = ( taxis_t * ) taxisptr1;
+  t2 = ( taxis_t * ) taxisptr2;
 
-   ilii = 0;
-   ilio = 0;
+  xassert ( t1 );
+  xassert ( t2 );
 
-/* Establish values of loop parameters. */
+  return ! ( t1->used        == t2->used        &&
+	     t1->type        == t2->type        &&
+	     t1->vdate       == t2->vdate       &&
+	     t1->vtime       == t2->vtime       &&
+	     t1->rdate       == t2->rdate       &&
+	     t1->rtime       == t2->rtime       &&
+	     t1->fdate       == t2->fdate       &&
+	     t1->ftime       == t2->ftime       &&
+	     t1->calendar    == t2->calendar    &&
+	     t1->unit        == t2->unit        &&
+	     t1->fc_unit     == t2->fc_unit     &&
+	     t1->numavg      == t2->numavg      &&
+	     t1->climatology == t2->climatology &&
+	     t1->has_bounds  == t2->has_bounds  &&
+	     t1->vdate_lb    == t2->vdate_lb    &&
+	     t1->vtime_lb    == t2->vtime_lb    &&
+	     t1->vdate_ub    == t2->vdate_ub    &&
+	     t1->vtime_ub    == t2->vtime_ub );
+}
 
-   if (kcode > 10) {
 
-/*    Quasi-regular along longitude lines. */
+static int
+taxisTxCode ( void )
+{
+  return TAXIS;
+}
 
-      iquano = klon;
-      iregno = klat;
-      icode = kcode - 10;
-   } else {
+enum { taxisNint = 21 };
 
-/*    Quasi-regular along latitude lines. */
+static int
+taxisGetPackSize(void *p, void *context)
+{
+  taxis_t *taxisptr = (taxis_t*) p;
+  int packBufferSize
+    = serializeGetSize(taxisNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
+    + (taxisptr->name ?
+       serializeGetSize((int)strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
+    + (taxisptr->longname ?
+       serializeGetSize((int)strlen(taxisptr->longname), DATATYPE_TXT,
+                        context) : 0);
+  return packBufferSize;
+}
 
-      iquano = klat;
-      iregno = klon;
-      icode = kcode;
-   }
+int
+taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
+            int originNamespace, void *context, int force_id)
+{
+  taxis_t * taxisP;
+  int intBuffer[taxisNint];
+  uint32_t d;
+  int idx = 0;
 
-/*     -------------------------------------------------------- */
-/**    Section 2. Interpolate field from quasi to regular grid. */
-/*     -------------------------------------------------------- */
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  intBuffer, taxisNint, DATATYPE_INT, context);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &d, 1, DATATYPE_UINT32, context);
 
-   i_1 = iquano;
-   for (j230 = 1; j230 <= i_1; ++j230) {
+  xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
 
-      if (iregno != kpoint[j230]) {
+  taxisInit();
 
-/*       Line contains less values than required,so */
-/*       extract quasi-regular grid values for a line */
+  cdiResH targetID = namespaceAdaptKey(intBuffer[idx++], originNamespace);
+  taxisP = taxisNewEntry(force_id?targetID:CDI_UNDEFID);
 
-         i_2 = kpoint[j230];
-         for (j210 = 1; j210 <= i_2; ++j210) {
-            ++ilii;
-            zline[j210 - 1] = pfield[ilii];
-         }
+  xassert(!force_id || targetID == taxisP->self);
 
-/*       and interpolate this line. */
+  taxisP->used        = intBuffer[idx++];
+  taxisP->type        = intBuffer[idx++];
+  taxisP->vdate       = intBuffer[idx++];
+  taxisP->vtime       = intBuffer[idx++];
+  taxisP->rdate       = intBuffer[idx++];
+  taxisP->rtime       = intBuffer[idx++];
+  taxisP->fdate       = intBuffer[idx++];
+  taxisP->ftime       = intBuffer[idx++];
+  taxisP->calendar    = intBuffer[idx++];
+  taxisP->unit        = intBuffer[idx++];
+  taxisP->fc_unit     = intBuffer[idx++];
+  taxisP->numavg      = intBuffer[idx++];
+  taxisP->climatology = intBuffer[idx++];
+  taxisP->has_bounds  = intBuffer[idx++];
+  taxisP->vdate_lb    = intBuffer[idx++];
+  taxisP->vtime_lb    = intBuffer[idx++];
+  taxisP->vdate_ub    = intBuffer[idx++];
+  taxisP->vtime_ub    = intBuffer[idx++];
 
-         rowina2(zline, iregno, kpoint[j230], zwork, icode, msval, kret);
-         if (*kret != 0) goto L900;
+  if (intBuffer[idx])
+    {
+      int len = intBuffer[idx];
+      char *name = new_refcount_string((size_t)len);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      name, len, DATATYPE_TXT, context);
+      name[len] = '\0';
+      taxisP->name = name;
+    }
+  idx++;
+  if (intBuffer[idx])
+    {
+      int len = intBuffer[idx];
+      char *longname = new_refcount_string((size_t)len);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      longname, len, DATATYPE_TXT, context);
+      longname[len] = '\0';
+      taxisP->longname = longname;
+    }
 
-/*       Add regular grid values for this line to the
-         temporary array. */
+  return taxisP->self;
+}
 
-         i_2 = iregno;
-         for (j220 = 1; j220 <= i_2; ++j220) {
-            ++ilio;
-            ztemp[ilio - 1] = zline[j220 - 1];
-         }
 
-      } else {
+static void
+taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferPos,
+          void *context)
+{
+  taxis_t *taxisP = (taxis_t *)voidP;
+  int intBuffer[taxisNint];
+  uint32_t d;
+  int idx = 0;
 
-/*       Line contains the required number of values, so add */
-/*       this line to the temporary array. */
+  intBuffer[idx++] = taxisP->self;
+  intBuffer[idx++] = taxisP->used;
+  intBuffer[idx++] = taxisP->type;
+  intBuffer[idx++] = taxisP->vdate;
+  intBuffer[idx++] = taxisP->vtime;
+  intBuffer[idx++] = taxisP->rdate;
+  intBuffer[idx++] = taxisP->rtime;
+  intBuffer[idx++] = taxisP->fdate;
+  intBuffer[idx++] = taxisP->ftime;
+  intBuffer[idx++] = taxisP->calendar;
+  intBuffer[idx++] = taxisP->unit;
+  intBuffer[idx++] = taxisP->fc_unit;
+  intBuffer[idx++] = taxisP->numavg;
+  intBuffer[idx++] = taxisP->climatology;
+  intBuffer[idx++] = taxisP->has_bounds;
+  intBuffer[idx++] = taxisP->vdate_lb;
+  intBuffer[idx++] = taxisP->vtime_lb;
+  intBuffer[idx++] = taxisP->vdate_ub;
+  intBuffer[idx++] = taxisP->vtime_ub;
+  intBuffer[idx++] = taxisP->name ? (int)strlen(taxisP->name) : 0;
+  intBuffer[idx++] = taxisP->longname ? (int)strlen(taxisP->longname) : 0;
 
-         i_2 = iregno;
-         for (j225 = 1; j225 <= i_2; ++j225) {
-            ++ilio;
-            ++ilii;
-            ztemp[ilio - 1] = pfield[ilii];
-         }
-      }
-   }
+  serializePack(intBuffer, taxisNint, DATATYPE_INT,
+                packBuffer, packBufferSize, packBufferPos, context);
+  d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
+                packBuffer, packBufferSize, packBufferPos, context);
+  if (taxisP->name)
+    serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
+                  packBuffer, packBufferSize, packBufferPos, context);
+  if (taxisP->longname)
+    serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
+                  packBuffer, packBufferSize, packBufferPos, context);
 
-/* Copy temporary array to user array. */
+}
 
-   i_1 = klon * klat;
-   for (j240 = 1; j240 <= i_1; ++j240) {
-      pfield[j240] = ztemp[j240 - 1];
-   }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <math.h>		/* for floor() */
 
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
 
-L900:
+/* convert Julian date into year, months, day */
+void decode_julday(int calendar,
+		   int julday,	/* Julian day number to convert */
+		   int *year,	/* Gregorian year (out)         */
+		   int *mon,	/* Gregorian month (1-12) (out) */
+		   int *day)	/* Gregorian day (1-31) (out)   */
+{
+  int a = julday;
+  double b, c;
+  double d, e, f;
 
-   free(zline);
-   free(zwork);
+  b = floor((a - 1867216.25)/36524.25);
+  c = a + b - floor(b/4) + 1525;
 
-   return 0;
-} /* qu2reg2 */
+  if ( calendar == CALENDAR_STANDARD )
+    if ( a < 2299161 )
+      {
+	c = a + 1524;
+      } 
 
+  d = floor((c - 122.1)/365.25);
+  e = floor(365.25*d);
+  f = floor((c - e)/30.6001);
 
+  *day  = (int)(c - e - floor(30.6001*f));
+  *mon  = (int)(f - 1 - 12*floor(f/14));
+  *year = (int)(d - 4715 - floor((7 + *mon)/10));
+}
 
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
 
-void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
+/* convert year, month, day into Julian calendar day */
+int encode_julday(int calendar, int year, int month, int day)
 {
-  double power;
-  double *scale = (double*) malloc((trunc+1)*sizeof(double));
-  int  n, m;
-  int  index;
-
-  if ( scale == NULL ) SysError("No Memory!");
+  int iy;
+  int im;
+  int ib;
+  int julday;
 
-  if ( pcScale < -10000 || pcScale > 10000 )
+  if ( month <= 2 )
     {
-      fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
-      return;
-   }
-
-  /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
+      iy = year  - 1;
+      im = month + 12;
+    }
+  else
+    {
+      iy = year;
+      im = month;
+    }
 
-  if ( pcScale == 0 ) return;
 
-  power = (double) pcScale / 1000.;
-  scale[0] = 1.0;
+  if ( iy < 0 )
+    ib = (int)((iy+1)/400) - (int)((iy+1)/100);
+  else
+    ib = (int)(iy/400) - (int)(iy/100);
 
-  for ( n = 1; n <= trunc; n++ )
+  if ( calendar == CALENDAR_STANDARD )
     {
-      if (pcScale != 1000)
-         scale[n] = pow((double) (n*(n+1)), power);
+      if ( year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15))) )
+	{
+	  /*
+	  ** 15th October 1582 AD or later
+	  */
+	}
       else
-         scale[n] =     (double) (n*(n+1));
+	{
+	  /*
+	  ** 4th October 1582 AD or earlier
+	  */
+	  ib = -2;
+	}
     }
 
-  if ( inv )
-    for ( n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
+  julday = (int) (floor(365.25*iy) + (int)(30.6001*(im+1)) + ib + 1720996.5 + day + 0.5);
 
-  /* Scale the values */
+  return (julday);
+}
 
-  index = 0;
 
-  for ( m = 0;   m < pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n >= pcStart )
-	  {
-	    fpdata[index  ] *= scale[n];
-	    fpdata[index+1] *= scale[n];
-	  }
-	index += 2;
-      }
+int date_to_julday(int calendar, int date)
+{
+  int julday;
+  int year, month, day;
 
-  for ( m = pcStart; m <= trunc; m++ )
-    for ( n = m;     n <= trunc; n++ )
-      {
-	fpdata[index  ] *= scale[n];
-	fpdata[index+1] *= scale[n];
-	index += 2;
-      }
+  cdiDecodeDate(date, &year, &month, &day);
 
-  free(scale);
+  julday = encode_julday(calendar, year, month, day);
+
+  return (julday);
 }
 
 
-void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+int julday_to_date(int calendar, int julday)
 {
-  T *fphelp = (T*) malloc(nsp*sizeof(T));
-  int  m, n;
-  int  index, inext;
+  int date;
+  int year, month, day;
 
-  if ( fphelp == NULL ) SysError("No Memory!");
+  decode_julday(calendar, julday, &year, &month, &day);
 
-  index = inext = 0;
+  date = cdiEncodeDate(year, month, day);
 
-  for ( m = 0;   m <= pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( pcStart >= n )
-	  {
-	    fphelp[index  ] = fpdata[inext++];
-	    fphelp[index+1] = fpdata[inext++];
-	  }
-	index += 2;
-      }
+  return (date);
+}
 
-  index = 0;
-  for ( m = 0;   m <= trunc; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n > pcStart )
-	  {
-	    fphelp[index  ] = fpdata[inext++];
-	    fphelp[index+1] = fpdata[inext++];
-	  }
-	index += 2;
-      }
 
-  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+int time_to_sec(int time)
+{
+  int secofday;
+  int hour, minute, second;
 
-  free(fphelp);
+  cdiDecodeTime(time, &hour, &minute, &second);
+
+  secofday = hour*3600 + minute*60 + second;
+
+  return (secofday);
 }
 
 
-void TEMPLATE(gather_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+int sec_to_time(int secofday)
 {
-  T *fphelp = (T*) malloc(nsp*sizeof(T));
-  int  m, n;
-  int  index, inext;
+  int time;
+  int hour, minute, second;
 
-  if ( fphelp == NULL ) SysError("No Memory!");
+  hour   = secofday/3600;
+  minute = secofday/60 - hour*60;
+  second = secofday - hour*3600 - minute*60;
 
-  index = inext = 0;
+  time = cdiEncodeTime(hour, minute, second);
 
-  for ( m = 0;   m <= pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( pcStart >= n )
-	  {
-	    fphelp[inext++] = fpdata[index];
-	    fphelp[inext++] = fpdata[index+1];
-	  }
-	index += 2;
-      }
+  return (time);
+}
 
-  index = 0;
-  for ( m = 0;   m <= trunc; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n > pcStart )
-	  {
-	    fphelp[inext++] = fpdata[index];
-	    fphelp[inext++] = fpdata[index+1];
-	  }
-	index += 2;
-      }
+static
+void adjust_seconds(int *julday, int64_t *secofday)
+{
+  int64_t secperday = 86400;
 
-  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+  while ( *secofday >= secperday ) 
+    { 
+      *secofday -= secperday; 
+      (*julday)++;
+    }
 
-  free(fphelp);
+  while ( *secofday <  0 ) 
+    { 
+      *secofday += secperday;
+      (*julday)--;
+    }
 }
 
 
-void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
+void julday_add_seconds(int64_t seconds, int *julday, int *secofday)
 {
-  /* System generated locals */
-  double r_1;
+  int64_t sec_of_day = *secofday;
 
-  /* Local variables */
-  int jl;
-  double zfac, zeps, zbeta;
-  double zalpha;
+  sec_of_day += seconds;
 
-  /* **** SCM0   - Apply SCM0 limiter to derivative estimates. */
-  /* output: */
-  /*   pdl   = the limited derivative at the left edge of the interval */
-  /*   pdr   = the limited derivative at the right edge of the interval */
-  /* inputs */
-  /*   pdl   = the original derivative at the left edge */
-  /*   pdr   = the original derivative at the right edge */
-  /*   pfl   = function value at the left edge of the interval */
-  /*   pfr   = function value at the right edge of the interval */
-  /*   klg   = number of intervals where the derivatives are limited */
+  adjust_seconds(julday, &sec_of_day);
 
-  /*  define constants */
+  *secofday = (int) sec_of_day;
+}
 
-  zeps = 1.0e-12;
-  zfac = (1.0 - zeps) * 3.0;
+/* add days and secs to julday/secofday */
+void julday_add(int days, int secs, int *julday, int *secofday)
+{
+  int64_t sec_of_day = *secofday;
 
-  for ( jl = 0; jl < klg; ++jl )
-    {
-      if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
-	{
-	  zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
-	  zbeta  = pdr[jl] / (pfr[jl] - pfl[jl]);
-	  if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
-	  if ( zbeta  <= 0.0 ) pdr[jl] = 0.0;
-	  if ( zalpha > zfac ) pdl[jl] = zfac * (pfr[jl] - pfl[jl]);
-	  if ( zbeta  > zfac ) pdr[jl] = zfac * (pfr[jl] - pfl[jl]);
-	}
-      else
-	{
-	  pdl[jl] = 0.0;
-	  pdr[jl] = 0.0;
-	}
-    }
-} /* scm0 */
+  sec_of_day += secs;
+  *julday    += days;
 
-static
-int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
-			int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
+  adjust_seconds(julday, &sec_of_day);
+
+  *secofday = (int) sec_of_day;
+}
+
+/* subtract julday1/secofday1 from julday2/secofday2 and returns the result in seconds */
+double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs)
 {
-  /*
-C---->
-C**** ROWINA3 - Interpolation of row of values.
-C
-C     Purpose.
-C     --------
-C
-C     Interpolate a row of values.
-C
-C
-C**   Interface.
-C     ----------
-C
-C     CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
-C
-C
-C     Input Parameters.
-C     -----------------
-C
-C     P      - Row of values to be interpolated.
-C              Dimension must be at least KO.
-C
-C     KO     - Number of values required.
-C
-C     KI     - Number of values in P on input.
-C
-C     PW     - Working array.
-C              Dimension must be at least (0:KO+2,3).
-C
-C     KCODE  - Interpolation required.
-C              1 , linear.
-C              3 , cubic.
-C
-C     PMSVAL - Value used for missing data indicator.
-C
-C     OMISNG - True if missing values are present in field.
-C
-C     OPERIO - True if input field is periodic.
-C
-C     OVEGGY - True if 'nearest neighbour' processing must be used
-C              for interpolation
-C
-C     Output Parameters.
-C     ------------------
-C
-C     P     - Now contains KO values.
-C     KRET  - Return code
-C             0, OK
-C             Non-zero, error
-C
-C
-C     Method.
-C     -------
-C
-C     Linear or cubic interpolation performed as required.
-C
-C     Comments.
-C     ---------
-C
-C     This is a version of ROWINA which allows for missing data
-C     values and hence for bitmapped fields.
-C
-C
-C     Author.
-C     -------
-C
-C     J.D.Chambers    ECMWF     22.07.94
-C
-C
-C     Modifications.
-C     --------------
-C
-C     J.D.Chambers    ECMWF     13.09.94
-C     Add return code KRET and remove calls to ABORT.
-C
-C     J. Clochard, Meteo France, for ECMWF - January 1998.
-C     Addition of OMISNG and OPERIO arguments.
-C
-C
-C     -----------------------------------------------------------------
-*/
-  /* System generated locals */
-  int pw_dim1, pw_offset, i_1;
+  int64_t sec_of_day;
+  int64_t seconds;
+
+  *days = julday2 - julday1;
+  *secs = secofday2 - secofday1;
+
+  sec_of_day = *secs;
+
+  adjust_seconds(days, &sec_of_day);
+
+  *secs = (int) sec_of_day;
+
+  seconds = *days * 86400 + sec_of_day;
+
+  return (double)seconds;
+}
 
-  /* Local variables */
-  int jl, ip;
-  double zwt1, zrdi, zpos;
-  double zdo, zwt;
 
-  UNUSED(omisng);
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday)
+{
+  *julday = encode_julday(calendar, year, month, day);
 
-  /* Parameter adjustments */
-  --p;
-  pw_dim1 = ko + 3;
-  pw_offset = pw_dim1;
-  pw -= pw_offset;
+  *secofday = (hour*60 + minute)*60 + second;
+}
 
-  *kret = 0;
 
-  if ( kcode == 1 )
-    {
-      /*    Move input values to work array */
-      for ( jl = 1; jl <= ki; ++jl )
-	pw[jl + pw_dim1] = p[jl];
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second)
+{
+  decode_julday(calendar, julday, year, month, day);
 
-      if ( operio )
-	{
-	  /* Arrange wrap-around value in work array */
-	  pw[ki + 1 + pw_dim1] = p[1];
+  *hour   = secofday/3600;
+  *minute = secofday/60 - *hour*60;
+  *second = secofday - *hour*3600 - *minute*60;
+}
 
-	  /* Set up constants to be used to figure out weighting for */
-	  /* values in interpolation. */
-	  zrdi = (double) ki;
-	  zdo = 1.0 / (double) ko;
-	}
-      else
-	{
-	  /* Repeat last value, to cope with "implicit truncation" below */
-	  pw[ki + 1 + pw_dim1] = p[ki];
 
-	  /* Set up constants to be used to figure out weighting for */
-	  /* values in interpolation. */
-	  zrdi = (double) (ki-1);
-	  zdo = 1.0 / (double) (ko-1);
- 	}
+#ifdef TEST
+int main(void)
+{
+  int nmin;
+  int vdate0, vtime0;
+  int vdate, vtime;
+  int ijulinc;
+  int i, j = 0;
+  int year, mon, day, hour, minute, second;
+  int julday, secofday;
+  int calendar = CALENDAR_STANDARD;
 
-      /*    Loop through the output points */
-      for ( jl = 1; jl <= ko; ++jl )
-	{
+  /* 1 - Check valid range of years */
 
-	  /* Calculate weight from the start of row */
-	  zpos = (jl - 1) * zdo;
-	  zwt = zpos * zrdi;
+  nmin = 11000;
+  vdate0 = -80001201;
+  vtime0 = 120500;
 
-	  /* Get the current array position(minus 1) from the weight - */
-	  /* note the implicit truncation. */
-	  ip = (int) zwt;
-		  
-	  /* Adjust the weight to range (0.0 to 1.0) */
-	  zwt -= ip;
+  printf("start time: %8d %4d\n", vdate0, vtime0);
 
-          /* If 'nearest neighbour' processing must be used */
-	  if ( oveggy )
-	    {
-              if ( zwt < 0.5 )
-                p[jl] = pw[ip + 1 + pw_dim1];
-	      else
-		p[jl] = pw[ip + 2 + pw_dim1];
-	    }
-	  else
-	    {
-	      /*    If the left value is missing, use the right value */
-	      if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
-		{
-		  p[jl] = pw[ip + 2 + pw_dim1];
-		}
-	      /*    If the right value is missing, use the left value */
-	      else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
-		{
-		  p[jl] = pw[ip + 1 + pw_dim1];
-		}
-	      /*    If neither missing, interpolate ... */
-	      else
-		{
-		  /*  Interpolate using the weighted values on either side */
-		  /*  of the output point position */
-		  p[jl] = (1.0 - zwt) * pw[ip+1 + pw_dim1] +
-		                  zwt * pw[ip+2 + pw_dim1];
-		}
-	    }
-	}
+  for ( i = 0; i < nmin; i++ )
+    {
+      cdiDecodeDate(vdate0, &year, &mon, &day);
+      cdiDecodeTime(vtime0, &hour, &minute, &second);
+
+      julday  = date_to_julday(calendar, vdate0);
+      secofday = time_to_sec(vtime0);
+
+      vdate = julday_to_date(calendar, julday);
+      vtime = sec_to_time(secofday);
+
+      if ( vdate0 != vdate || vtime0 != vtime )
+	printf("%4d %8d %4d %8d %4d %9d %9d\n",
+	       ++j, vdate0, vtime0, vdate, vtime, julday, secofday);
+
+      year++;
+      vdate0 = cdiEncodeDate(year, mon, day);
+      vtime0 = cdiEncodeTime(hour, minute, second);
     }
-  else if ( kcode == 3 )
+
+  printf("stop time: %8d %4d\n", vdate0, vtime0);
+
+  /* 2 - Check time increment of one minute */
+
+  nmin = 120000;
+  ijulinc = 60;
+  vdate0 = 20001201;
+  vtime0 = 0;
+
+  printf("start time: %8d %4d\n", vdate0, vtime0);
+
+  julday = date_to_julday(calendar, vdate0);
+  secofday = time_to_sec(vtime0);
+  for ( i = 0; i < nmin; i++ )
     {
-      /*     *******************************    */
-      /*     Section 2.  Cubic interpolation .. */
-      /*     *******************************    */
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
+      cdiDecodeDate(vdate0, &year, &mon, &day);
+      cdiDecodeTime(vtime0, &hour, &minute, &second);
+
+      if ( ++minute >= 60 )
 	{
-          if ( IS_EQUAL(p[jl], msval) )
+	  minute = 0;
+	  if ( ++hour >= 24 )
 	    {
-	      fprintf(stderr," ROWINA3: ");
-	      fprintf(stderr," Cubic interpolation not supported");
-	      fprintf(stderr," for fields containing missing data.\n");
-	      *kret = 1;
-	      goto L900;
+	      hour = 0;
+	      if ( ++day >= 32 )
+		{
+		  day = 1;
+		  if ( ++mon >= 13 )
+		    {
+		      mon = 1;
+		      year++;
+		    }
+		}
 	    }
-          pw[jl + pw_dim1] = p[jl];
-	}
-      pw[pw_dim1] = p[ki];
-      pw[ki + 1 + pw_dim1] = p[1];
-      pw[ki + 2 + pw_dim1] = p[2];
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
-	{
-          pw[jl + (pw_dim1 << 1)] =
-	        - pw[jl - 1 + pw_dim1] / 3.0 -
-	          pw[jl     + pw_dim1] * 0.5 +
-	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
-          pw[jl + 1 + pw_dim1 * 3] =
-                  pw[jl - 1 + pw_dim1] / 6.0 -
-                  pw[jl     + pw_dim1] +
-                  pw[jl + 1 + pw_dim1] * 0.5 +
-                  pw[jl + 2 + pw_dim1] / 3.0;
 	}
 
-      TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
-		       &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
+      vdate0 = cdiEncodeDate(year, mon, day);
+      vtime0 = cdiEncodeTime(hour, minute, second);
 
-      zrdi = (double) ki;
-      zdo = 1.0 / (double) ko;
-      for ( jl = 1; jl <= ko; ++jl )
-	{
-          zpos = (jl - 1) * zdo;
-          zwt = zpos * zrdi;
-          ip = (int) zwt + 1;
-          zwt = zwt + 1.0 - ip;
-          zwt1 = 1.0 - zwt;
-          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
-                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
-                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
-                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
-	}
+      julday_add_seconds(ijulinc, &julday, &secofday);
 
+      vdate = julday_to_date(calendar, julday);
+      vtime = sec_to_time(secofday);
+      if ( vdate0 != vdate || vtime0 != vtime )
+	printf("%4d %8d %4d %8d %4d %9d %9d\n",
+	       ++j, vdate0, vtime0, vdate, vtime, julday, secofday);
     }
-  else
+
+  printf("stop time: %8d %4d\n", vdate0, vtime0);
+
+  return (0);
+}
+#endif
+
+
+#ifdef TEST2
+int main(void)
+{
+  int i;
+  int julday, secofday;
+  int year, month, day, hour, minute, second;
+  int value = 30;
+  int factor = 86400;
+  int calendar = CALENDAR_STANDARD;
+
+  year=1979; month=1; day=15; hour=12; minute=30, second=17;
+
+  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
+
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
+
+  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, julday, secofday);
+
+  for ( i = 0; i < 420; i++ )
     {
-      /*    **************************************    */
-      /*    Section 3.  Invalid interpolation code .. */
-      /*    **************************************    */
-      fprintf(stderr," ROWINA3:");
-      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
-      *kret = 2;
+
+      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
+      julday_add_seconds(value*factor, &julday, &secofday);
     }
 
-L900:
-    return 0;
-} /* rowina3 */
+  return (0);
+}
+#endif
+#if defined (HAVE_CONFIG_H)
+#endif
 
 
-int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
-			T msval, int *kret, int omisng, int operio, int oveggy)
+
+
+static
+void tstepsInitEntry(stream_t *streamptr, int tsID)
+{
+  streamptr->tsteps[tsID].curRecID     = CDI_UNDEFID;
+  streamptr->tsteps[tsID].position     = 0;
+  streamptr->tsteps[tsID].records      = NULL;
+  streamptr->tsteps[tsID].recordSize   = 0;
+  streamptr->tsteps[tsID].nallrecs     = 0;
+  streamptr->tsteps[tsID].recIDs       = NULL;
+  streamptr->tsteps[tsID].nrecs        = 0;
+  streamptr->tsteps[tsID].next         = 0;
+
+  ptaxisInit(&streamptr->tsteps[tsID].taxis);
+}
+
+
+int tstepsNewEntry(stream_t *streamptr)
 {
+  int tsID = 0;
+  int tstepsTableSize;
+  tsteps_t *tstepsTable;
+
+  tsID            = streamptr->tstepsNextID++;
+  tstepsTableSize = streamptr->tstepsTableSize;
+  tstepsTable     = streamptr->tsteps;
+
   /*
-C**** QU2REG3 - Convert quasi-regular grid data to regular.
-C
-C     Purpose.
-C     --------
-C
-C     Convert quasi-regular grid data to regular,
-C     using either a linear or cubic interpolation.
-C
-C
-C**   Interface.
-C     ----------
-C
-C     CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
-C    X            OVEGGY)
-C
-C
-C     Input Parameters.
-C     -----------------
-C
-C     PFIELD     - Array containing quasi-regular grid data.
-C
-C     KPOINT     - Array containing list of the number of
-C                  points on each latitude (or longitude) of
-C                  the quasi-regular grid.
-C
-C     KLAT       - Number of latitude lines
-C
-C     KLON       - Number of longitude lines
-C
-C     KCODE      - Interpolation required.
-C                  1 , linear - data quasi-regular on latitude lines.
-C                  3 , cubic -  data quasi-regular on latitude lines.
-C                  11, linear - data quasi-regular on longitude lines.
-C                  13, cubic -  data quasi-regular on longitude lines.
-C
-C     PMSVAL     - Value used for missing data indicator.
-C
-C     OMISNG     - True if missing values are present in field.
-C
-C     OPERIO     - True if input field is periodic.
-C
-C     OVEGGY     - True if 'nearest neighbour' processing must be used
-C                  for interpolation
-C
-C
-C     Output Parameters.
-C     ------------------
-C
-C     KRET       - return code
-C                  0 = OK
-C                  non-zero indicates fatal error
-C
-C
-C     Output Parameters.
-C     ------------------
-C
-C     PFIELD     - Array containing regular grid data.
-C
-C
-C     Method.
-C     -------
-C
-C     Data is interpolated and expanded into a temporary array,
-C     which is then copied back into the user's array.
-C     Returns an error code if an invalid interpolation is requested
-C     or field size exceeds array dimensions.
-C
-C     Comments.
-C     ---------
-C
-C     This routine is an adaptation of QU2REG to allow missing data
-C     values, and hence bit mapped fields.
-C
-C
-C     Author.
-C     -------
-C
-C     J.D.Chambers     ECMWF      22.07.94
-C
-C
-C     Modifications.
-C     --------------
-C
-C     J.D.Chambers     ECMWF      13.09.94
-C     Add return code KRET and remove calls to ABORT.
-C
-C     J.D.Chambers     ECMWF        Feb 1997
-C     Allow for 64-bit pointers
-C
-C     J. Clochard, Meteo France, for ECMWF - January 1998.
-C     Addition of OMISNG and OPERIO arguments.
-C     Fix message for longitude number out of bounds, and routine
-C     name in title and formats.
-C
-*/
-   /* System generated locals */
-   int i_1, i_2;
-   int kcode = 1;
+    If the table overflows, double its size.
+  */
+  if ( tsID == tstepsTableSize )
+    {
+      if ( tstepsTableSize == 0 ) tstepsTableSize = 1;
+      tstepsTableSize = 2*tstepsTableSize;
+      tstepsTable = (tsteps_t *)xrealloc(tstepsTable,
+                                         (size_t)tstepsTableSize * sizeof (tsteps_t));
+      if ( tstepsTable == NULL )
+	{
+          Message("tstepsTableSize = %d", tstepsTableSize);
+	  SysError("Reallocation of tsteps_t failed");
+	}
+    }
 
-   /* Local variables */
-   int ilii, ilio, icode;
-   int iregno, iquano, j210, j220, j230, j240, j225;
-   T *ztemp = NULL;
-   T *zline = NULL;
-   T *zwork = NULL;
+  streamptr->tstepsTableSize = tstepsTableSize;
+  streamptr->tsteps          = tstepsTable;
 
-   ztemp = (T*) malloc(klon*klat*sizeof(T));
-   if ( ztemp == NULL ) SysError("No Memory!");
+  tstepsInitEntry(streamptr, tsID);
 
-   zline = (T*) malloc(2*klon*sizeof(T));
-   if ( zline == NULL ) SysError("No Memory!");
+  streamptr->tsteps[tsID].taxis.used = TRUE;
 
-   zwork = (T*) malloc(3*(2*klon+3)*sizeof(T));
-   if ( zwork == NULL ) SysError("No Memory!");
+  return (tsID);
+}
 
-   /* Parameter adjustments */
-   --pfield;
-   --kpoint;
 
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+void cdiCreateTimesteps(stream_t *streamptr)
+{
+  long ntsteps;
+  long tsID;
 
-   *kret = 0;
+  if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
+    return;
 
-/* Check input parameters. */
+  if ( streamptr->ntsteps == 0 ) ntsteps = 1;    /* <<<<<-------- */
+  else ntsteps = streamptr->ntsteps;
 
-   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
-      fprintf(stderr," QU2REG :");
-      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
-      *kret = 1;
-      goto L900;
-   }
+  streamptr->tsteps = (tsteps_t *)xmalloc((size_t)ntsteps*sizeof(tsteps_t));
 
-/* Set array indices to 0. */
+  streamptr->tstepsTableSize = (int)ntsteps;
+  streamptr->tstepsNextID    = (int)ntsteps;
 
-   ilii = 0;
-   ilio = 0;
+  for ( tsID = 0; tsID < ntsteps; tsID++ )
+    {
+      tstepsInitEntry(streamptr, (int)tsID);
+      streamptr->tsteps[tsID].taxis.used = TRUE;
+    }
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-/* Establish values of loop parameters. */
+#define _XOPEN_SOURCE 600
 
-   if (kcode > 10) {
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include <sys/types.h>
 
-/*    Quasi-regular along longitude lines. */
 
-      iquano = klon;
-      iregno = klat;
-      icode = kcode - 10;
-   } else {
 
-/*    Quasi-regular along latitude lines. */
+#undef  IsBigendian
+#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
+
+void cdiPrintDatatypes(void)
+{
+  /* IsBigendian returns 1 for big endian byte order */
+  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
+
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| types       | bytes |\n");
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| void *      |   %3d |\n", (int) sizeof(void *));
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| char        |   %3d |\n", (int) sizeof(char));
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| short       |   %3d |\n", (int) sizeof(short));
+  fprintf (stderr, "| int         |   %3d |\n", (int) sizeof(int));
+  fprintf (stderr, "| long        |   %3d |\n", (int) sizeof(long));
+  fprintf (stderr, "| long long   |   %3d |\n", (int) sizeof(long long));
+  fprintf (stderr, "| size_t      |   %3d |\n", (int) sizeof(size_t));
+  fprintf (stderr, "| off_t       |   %3d |\n", (int) sizeof(off_t));
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| float       |   %3d |\n", (int) sizeof(float));
+  fprintf (stderr, "| double      |   %3d |\n", (int) sizeof(double));
+  fprintf (stderr, "| long double |   %3d |\n", (int) sizeof(long double));
+  fprintf (stderr, "+-------------+-------+\n\n");
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
+  fprintf (stderr, "+-------------+-----------+\n");
+  fprintf (stderr, "| INT32       | %-9s |\n", STRING(INT32));
+  fprintf (stderr, "| INT64       | %-9s |\n", STRING(INT64));
+  fprintf (stderr, "| FLT32       | %-9s |\n", STRING(FLT32));
+  fprintf (stderr, "| FLT64       | %-9s |\n", STRING(FLT64));
+  fprintf (stderr, "+-------------+-----------+\n");
+
+  if ( IsBigendian() )
+    fprintf (stderr, "\n  byte ordering is BIGENDIAN\n\n");
+  else
+    fprintf (stderr, "\n  byte ordering is LITTLEENDIAN\n\n");
+}
+
+static char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-"
+  "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
+  "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
+
+enum {
+  uuidNumHexChars = 36,
+};
 
-      iquano = klat;
-      iregno = klon;
-      icode = kcode;
-   }
+void uuid2str(const unsigned char *uuid, char *uuidstr)
+{
 
-/*     -------------------------------------------------------- */
-/**    Section 2. Interpolate field from quasi to regular grid. */
-/*     -------------------------------------------------------- */
+  if ( uuid == NULL || uuidstr == NULL ) return;
 
-   i_1 = iquano;
-   for (j230 = 1; j230 <= i_1; ++j230) {
+  int iret = sprintf(uuidstr, uuidFmt,
+                     uuid[0], uuid[1], uuid[2], uuid[3],
+                     uuid[4], uuid[5], uuid[6], uuid[7],
+                     uuid[8], uuid[9], uuid[10], uuid[11],
+                     uuid[12], uuid[13], uuid[14], uuid[15]);
 
-      if (iregno != kpoint[j230]) {
+  if ( iret != uuidNumHexChars ) uuidstr[0] = 0;
+}
 
-/*       Line contains less values than required,so */
-/*       extract quasi-regular grid values for a line */
 
-         i_2 = kpoint[j230];
-         for (j210 = 1; j210 <= i_2; ++j210) {
-            ++ilii;
-            zline[j210 - 1] = pfield[ilii];
-         }
+int str2uuid(const char *uuidstr, unsigned char *uuid)
+{
+  if ( uuid == NULL || uuidstr == NULL || strlen(uuidstr) != uuidNumHexChars)
+    return -1;
 
-/*       and interpolate this line. */
+  int iret = sscanf(uuidstr, uuidFmt,
+                    &uuid[0], &uuid[1], &uuid[2], &uuid[3],
+                    &uuid[4], &uuid[5], &uuid[6], &uuid[7],
+                    &uuid[8], &uuid[9], &uuid[10], &uuid[11],
+                    &uuid[12], &uuid[13], &uuid[14], &uuid[15]);
+  if ( iret != CDI_UUID_SIZE ) return -1;
+  return iret;
+}
 
-         TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
-         if (*kret != 0) goto L900;
+//Returns a malloc'ed string that escapes all spaces and backslashes with backslashes.
+char* cdiEscapeSpaces(const char* string)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current; current++)
+    {
+      if(strchr(" \\", *current)) escapeCount++;
+      length++;
+    }
 
-/*       Add regular grid values for this line to the
-         temporary array. */
+  char* result = malloc(length + escapeCount + 1);
+  if(!result) return NULL;
 
-         i_2 = iregno;
-         for (j220 = 1; j220 <= i_2; ++j220) {
-            ++ilio;
-            ztemp[ilio - 1] = zline[j220 - 1];
-         }
+  //Do the escaping.
+  for(size_t in = 0, out = 0; in < length;)
+    {
+      if(strchr(" \\", string[in])) result[out++] = '\\';
+      result[out++] = string[in++];
+    }
+  result[length + escapeCount] = 0;     //termination!
+  return result;
+}
 
-      } else {
+//input: a space terminated string that may contain escaped characters
+//output: a new zero terminated string with the escape characters removed
+//*outStringEnd points to the terminating character upon return.
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current && *current != ' '; current++)
+    {
+      if(*current == '\\')
+        {
+          current++, escapeCount++;
+          if(!current) return NULL;
+        }
+      length++;
+    }
 
-/*       Line contains the required number of values, so add */
-/*       this line to the temporary array. */
+  char* result = malloc(length + 1);
+  if(!result) return NULL;
 
-         i_2 = iregno;
-         for (j225 = 1; j225 <= i_2; ++j225) {
-            ++ilio;
-            ++ilii;
-            ztemp[ilio - 1] = pfield[ilii];
-         }
-      }
-   }
+  //Do the unescaping.
+  for(size_t in = 0, out = 0; out < length;)
+    {
+      if(string[in] == '\\') in++;
+      result[out++] = string[in++];
+    }
+  result[length] = 0;   //termination!
+  if(outStringEnd) *outStringEnd = &string[length + escapeCount];
+  return result;
+}
 
-/* Copy temporary array to user array. */
+#ifdef HAVE_DECL_UUID_GENERATE
+#include <sys/time.h>
+#include <uuid/uuid.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  static int uuid_seeded = 0;
+  static char uuid_rand_state[31 * sizeof (long)];
+  char *caller_rand_state;
+  if (uuid_seeded)
+    caller_rand_state = setstate(uuid_rand_state);
+  else
+    {
+      struct timeval tv;
+      int status = gettimeofday(&tv, NULL);
+      if (status != 0)
+        {
+          perror("uuid random seed generation failed!");
+          exit(1);
+        }
+      unsigned seed = (unsigned)(tv.tv_sec ^ tv.tv_usec);
+      caller_rand_state = initstate(seed, uuid_rand_state,
+                                    sizeof (uuid_rand_state));
+      uuid_seeded = 1;
+    }
+  uuid_generate(uuid);
+  setstate(caller_rand_state);
+}
+#elif defined (HAVE_DECL_UUID_CREATE)
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+#include <uuid.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  unsigned32 status;
+  uuid_create((uuid_t *)uuid, &status);
+  if (status == -1)
+    {
+      perror("uuid generation failed!");
+      exit(1);
+    }
+}
+#else
+#include <sys/time.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  static int uuid_seeded = 0;
+  static char uuid_rand_state[31 * sizeof (long)];
+  char *caller_rand_state;
+  if (uuid_seeded)
+    caller_rand_state = setstate(uuid_rand_state);
+  else
+    {
+      struct timeval tv;
+      int status = gettimeofday(&tv, NULL);
+      if (status != 0)
+        {
+          perror("failed seed generation!");
+          exit(1);
+        }
+      unsigned seed = tv.tv_sec ^ tv.tv_usec;
+      caller_rand_state = initstate(seed, uuid_rand_state,
+                                    sizeof (uuid_rand_state));
+      uuid_seeded = 1;
+    }
+  for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
+    uuid[i] = (unsigned char)random();
+  /* encode variant into msb of octet 8 */
+  uuid[8] = (unsigned char)((uuid[8] & 0x3f) | (1 << 7));
+  /* encode version 4 ((pseudo-)random uuid) into msb of octet 7 */
+  uuid[7] = (unsigned char)((uuid[7] & 0x0f) | (4 << 4));
+  setstate(caller_rand_state);
+}
+#endif
 
-   i_1 = klon * klat;
-   for (j240 = 1; j240 <= i_1; ++j240) {
-      pfield[j240] = ztemp[j240 - 1];
-   }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
 
-L900:
 
-   free(zwork);
-   free(zline);
-   free(ztemp);
 
-   return 0;
-} /* qu2reg3 */
+#undef  UNDEFID
+#define UNDEFID -1
 
-#endif /* T */
+static size_t Vctsize = 0;
+static double *Vct = NULL;
 
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
+static int numberOfVerticalLevels = 0;
+static int numberOfVerticalGrid = 0;
+static unsigned char uuidVGrid[CDI_UUID_SIZE];
 
-void TEMPLATE(scale_complex,T)(T *fpdata, int pcStart, int pcScale, int trunc, int inv)
+typedef struct
 {
-  double power;
-  double *scale = (double*) malloc((trunc+1)*sizeof(double));
-  int  n, m;
-  int  index;
+  int      level1;
+  int      level2;
+  int      recID;
+  int      lindex;
+}
+leveltable_t;
 
-  if ( scale == NULL ) SysError("No Memory!");
+typedef struct
+{
+  int           param;
+  int           prec;
+  int           tsteptype;
+  int           timave;
+  int           timaccu;
+  int           gridID;
+  int           zaxistype;
+  int           ltype1;     /* GRIB first level type */
+  int           ltype2;     /* GRIB second level type */
+  int           lbounds;
+  int           level_sf;
+  int           level_unit;
+  int           zaxisID;
+  unsigned      nlevels;
+  int           levelTableSize;
+  leveltable_t *levelTable;
+  int           instID;
+  int           modelID;
+  int           tableID;
+  int           comptype;       // compression type
+  int           complevel;      // compression level
+  int           lmissval;
+  double        missval;
+  char         *name;
+  char         *stdname;
+  char         *longname;
+  char         *units;
+  ensinfo_t    *ensdata;
+  int           typeOfGeneratingProcess;
+  int           productDefinitionTemplate;
+#if  defined  (HAVE_LIBGRIB_API)
+  /* (Optional) list of keyword/double value pairs */
+  int           opt_grib_dbl_nentries;
+  char         *opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  double        opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int           opt_grib_int_nentries;
+  char         *opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int           opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
+}
+vartable_t;
 
-  if ( pcScale < -10000 || pcScale > 10000 )
-    {
-      fprintf(stderr, " %s: Invalid power given %6d\n", __func__, pcScale);
-      return;
-   }
 
-  /* Setup scaling factors = n(n+1)^^p for n = 1 to truncation */
+static vartable_t *vartable;
+static unsigned varTablesize = 0;
+static unsigned nvars = 0;
 
-  if ( pcScale == 0 ) return;
 
-  power = (double) pcScale / 1000.;
-  scale[0] = 1.0;
+static void
+paramInitEntry(unsigned varID, int param)
+{
+  vartable[varID].param          = param;
+  vartable[varID].prec           = 0;
+  vartable[varID].tsteptype      = TSTEP_INSTANT;
+  vartable[varID].timave         = 0;
+  vartable[varID].timaccu        = 0;
+  vartable[varID].gridID         = UNDEFID;
+  vartable[varID].zaxistype      = 0;
+  vartable[varID].ltype1         = 0;
+  vartable[varID].ltype2         = -1;
+  vartable[varID].lbounds        = 0;
+  vartable[varID].level_sf       = 0;
+  vartable[varID].level_unit     = 0;
+  vartable[varID].levelTable     = NULL;
+  vartable[varID].levelTableSize = 0;
+  vartable[varID].nlevels        = 0;
+  vartable[varID].instID         = UNDEFID;
+  vartable[varID].modelID        = UNDEFID;
+  vartable[varID].tableID        = UNDEFID;
+  vartable[varID].typeOfGeneratingProcess   = UNDEFID;
+  vartable[varID].productDefinitionTemplate = UNDEFID;
+  vartable[varID].comptype       = COMPRESS_NONE;
+  vartable[varID].complevel      = 1;
+  vartable[varID].lmissval       = 0;
+  vartable[varID].missval        = 0;
+  vartable[varID].name           = NULL;
+  vartable[varID].stdname        = NULL;
+  vartable[varID].longname       = NULL;
+  vartable[varID].units          = NULL;
+  vartable[varID].ensdata        = NULL;
+}
 
-  for ( n = 1; n <= trunc; n++ )
+static unsigned
+varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *name)
+{
+  for ( unsigned varID = 0; varID < varTablesize; varID++ )
     {
-      if (pcScale != 1000)
-         scale[n] = pow((double) (n*(n+1)), power);
-      else
-         scale[n] =     (double) (n*(n+1));
+      if ( vartable[varID].param      == param       &&
+	   vartable[varID].zaxistype  == zaxistype   &&
+	   vartable[varID].ltype1     == ltype1      &&
+	   vartable[varID].tsteptype  == tsteptype )
+        {
+          if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
+            {
+              if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
+            }
+          else
+            {
+              return (varID);
+            }
+        }
     }
 
-  if ( inv )
-    for ( n = 1; n <= trunc; n++ ) scale[n] = 1.0 / scale[n];
+  return (unsigned)-1;
+}
 
-  /* Scale the values */
+static
+void varFree(void)
+{
+  for ( unsigned varID = 0; varID < nvars; varID++ )
+    {
+      if ( vartable[varID].levelTable )
+	free(vartable[varID].levelTable);
 
-  index = 0;
+      if ( vartable[varID].name )     free(vartable[varID].name);
+      if ( vartable[varID].stdname )  free(vartable[varID].stdname);
+      if ( vartable[varID].longname ) free(vartable[varID].longname);
+      if ( vartable[varID].units )    free(vartable[varID].units);
+      if ( vartable[varID].ensdata )  free(vartable[varID].ensdata);
+    }
 
-  for ( m = 0;   m < pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n >= pcStart )
-	  {
-	    fpdata[index  ] *= scale[n];
-	    fpdata[index+1] *= scale[n];
-	  }
-	index += 2;
-      }
+  if ( vartable )
+    free(vartable);
 
-  for ( m = pcStart; m <= trunc; m++ )
-    for ( n = m;     n <= trunc; n++ )
-      {
-	fpdata[index  ] *= scale[n];
-	fpdata[index+1] *= scale[n];
-	index += 2;
-      }
+  vartable = NULL;
+  varTablesize = 0;
+  nvars = 0;
 
-  free(scale);
-}
+  if ( Vct )
+    free(Vct);
 
+  Vct = NULL;
+  Vctsize = 0;
+}
 
-void TEMPLATE(scatter_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+static int
+levelNewEntry(unsigned varID, int level1, int level2)
 {
-  T *fphelp = (T*) malloc(nsp*sizeof(T));
-  int  m, n;
-  int  index, inext;
+  int levelID = 0;
+  int levelTableSize;
+  leveltable_t *levelTable;
 
-  if ( fphelp == NULL ) SysError("No Memory!");
+  levelTableSize = vartable[varID].levelTableSize;
+  levelTable     = vartable[varID].levelTable;
 
-  index = inext = 0;
+  /*
+    Look for a free slot in levelTable.
+    (Create the table the first time through).
+  */
+  if ( ! levelTableSize )
+    {
+      int i;
 
-  for ( m = 0;   m <= pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( pcStart >= n )
-	  {
-	    fphelp[index  ] = fpdata[inext++];
-	    fphelp[index+1] = fpdata[inext++];
-	  }
-	index += 2;
-      }
+      levelTableSize = 2;
+      levelTable = (leveltable_t *)xmalloc((size_t)levelTableSize
+                                           * sizeof (leveltable_t));
+      if( levelTable == NULL )
+	{
+          Message("levelTableSize = %d", levelTableSize);
+	  SysError("Allocation of leveltable failed!");
+	}
 
-  index = 0;
-  for ( m = 0;   m <= trunc; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n > pcStart )
-	  {
-	    fphelp[index  ] = fpdata[inext++];
-	    fphelp[index+1] = fpdata[inext++];
-	  }
-	index += 2;
-      }
+      for( i = 0; i < levelTableSize; i++ )
+	levelTable[i].recID = UNDEFID;
+    }
+  else
+    {
+      while( levelID < levelTableSize )
+	{
+	  if ( levelTable[levelID].recID == UNDEFID ) break;
+	  levelID++;
+	}
+    }
+  /*
+    If the table overflows, double its size.
+  */
+  if( levelID == levelTableSize )
+    {
+      int i;
 
-  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+      levelTableSize = 2*levelTableSize;
+      levelTable = (leveltable_t *)xrealloc(levelTable, (size_t)levelTableSize
+                                            * sizeof (leveltable_t));
+      if( levelTable == NULL )
+	{
+          Message("levelTableSize = %d", levelTableSize);
+	  SysError("Reallocation of leveltable failed");
+	}
+      levelID = levelTableSize/2;
 
-  free(fphelp);
+      for( i = levelID; i < levelTableSize; i++ )
+	levelTable[i].recID = UNDEFID;
+    }
+
+  levelTable[levelID].level1   = level1;
+  levelTable[levelID].level2   = level2;
+  levelTable[levelID].lindex   = levelID;
+
+  vartable[varID].nlevels = (unsigned)levelID+1;
+  vartable[varID].levelTableSize = levelTableSize;
+  vartable[varID].levelTable = levelTable;
+
+  return (levelID);
 }
 
+#define  UNDEF_PARAM  -4711
 
-void TEMPLATE(gather_complex,T)(T *fpdata, int pcStart, int trunc, int nsp)
+static unsigned
+paramNewEntry(int param)
 {
-  T *fphelp = (T*) malloc(nsp*sizeof(T));
-  int  m, n;
-  int  index, inext;
+  unsigned varID = 0;
 
-  if ( fphelp == NULL ) SysError("No Memory!");
+  /*
+    Look for a free slot in vartable.
+    (Create the table the first time through).
+  */
+  if ( ! varTablesize )
+    {
+      varTablesize = 2;
+      vartable = (vartable_t *)xmalloc((size_t)varTablesize
+                                       * sizeof (vartable_t));
+      if( vartable == NULL )
+	{
+          Message("varTablesize = %d", varTablesize);
+	  SysError("Allocation of vartable failed");
+	}
 
-  index = inext = 0;
+      for( unsigned i = 0; i < varTablesize; i++ )
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
+    }
+  else
+    {
+      while( varID < varTablesize )
+	{
+	  if ( vartable[varID].param == UNDEF_PARAM ) break;
+	  varID++;
+	}
+    }
+  /*
+    If the table overflows, double its size.
+  */
+  if ( varID == varTablesize )
+    {
 
-  for ( m = 0;   m <= pcStart; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( pcStart >= n )
-	  {
-	    fphelp[inext++] = fpdata[index];
-	    fphelp[inext++] = fpdata[index+1];
-	  }
-	index += 2;
-      }
+      varTablesize = 2 * varTablesize;
+      vartable = (vartable_t *)xrealloc(vartable, (size_t)varTablesize
+                                        * sizeof (vartable_t));
+      if( vartable == NULL )
+	{
+          Message("varTablesize = %d", varTablesize);
+	  SysError("Reallocation of vartable failed!");
+	}
+      varID = varTablesize/2;
 
-  index = 0;
-  for ( m = 0;   m <= trunc; m++ )
-    for ( n = m; n <= trunc; n++ )
-      {
-	if ( n > pcStart )
-	  {
-	    fphelp[inext++] = fpdata[index];
-	    fphelp[inext++] = fpdata[index+1];
-	  }
-	index += 2;
-      }
+      for( unsigned i = varID; i < varTablesize; i++ )
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
+    }
 
-  for ( m = 0; m < nsp; m++ ) fpdata[m] = fphelp[m];
+  paramInitEntry(varID, param);
 
-  free(fphelp);
+  return (varID);
 }
 
 
-void TEMPLATE(scm0,T)(T *pdl, T *pdr, T *pfl, T *pfr, int klg)
+void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
+		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
+		  const char *name, const char *stdname, const char *longname, const char *units)
 {
-  /* System generated locals */
-  double r_1;
-
-  /* Local variables */
-  int jl;
-  double zfac, zeps, zbeta;
-  double zalpha;
-
-  /* **** SCM0   - Apply SCM0 limiter to derivative estimates. */
-  /* output: */
-  /*   pdl   = the limited derivative at the left edge of the interval */
-  /*   pdr   = the limited derivative at the right edge of the interval */
-  /* inputs */
-  /*   pdl   = the original derivative at the left edge */
-  /*   pdr   = the original derivative at the right edge */
-  /*   pfl   = function value at the left edge of the interval */
-  /*   pfr   = function value at the right edge of the interval */
-  /*   klg   = number of intervals where the derivatives are limited */
-
-  /*  define constants */
-
-  zeps = 1.0e-12;
-  zfac = (1.0 - zeps) * 3.0;
+  unsigned varID = (cdiSplitLtype105 != 1 || zaxistype != ZAXIS_HEIGHT) ?
+    varGetEntry(param, zaxistype, ltype1, tsteptype, name) : (unsigned)UNDEFID;
 
-  for ( jl = 0; jl < klg; ++jl )
+  if ( varID == (unsigned)UNDEFID )
     {
-      if ( (r_1 = pfr[jl] - pfl[jl], fabs(r_1)) > zeps )
+      nvars++;
+      varID = paramNewEntry(param);
+      vartable[varID].gridID     = gridID;
+      vartable[varID].zaxistype  = zaxistype;
+      vartable[varID].ltype1     = ltype1;
+      vartable[varID].ltype2     = ltype2;
+      vartable[varID].lbounds    = lbounds;
+      vartable[varID].level_sf   = level_sf;
+      vartable[varID].level_unit = level_unit;
+      vartable[varID].tsteptype  = tsteptype;
+      if ( numavg ) vartable[varID].timave = 1;
+
+      if ( name )     if ( name[0] )     vartable[varID].name     = strdup(name);
+      if ( stdname )  if ( stdname[0] )  vartable[varID].stdname  = strdup(stdname);
+      if ( longname ) if ( longname[0] ) vartable[varID].longname = strdup(longname);
+      if ( units )    if ( units[0] )    vartable[varID].units    = strdup(units);
+    }
+  else
+    {
+      char paramstr[32];
+      cdiParamToString(param, paramstr, sizeof(paramstr));
+
+      if ( vartable[varID].gridID != gridID )
 	{
-	  zalpha = pdl[jl] / (pfr[jl] - pfl[jl]);
-	  zbeta  = pdr[jl] / (pfr[jl] - pfl[jl]);
-	  if ( zalpha <= 0.0 ) pdl[jl] = 0.0;
-	  if ( zbeta  <= 0.0 ) pdr[jl] = 0.0;
-	  if ( zalpha > zfac ) pdl[jl] = zfac * (pfr[jl] - pfl[jl]);
-	  if ( zbeta  > zfac ) pdr[jl] = zfac * (pfr[jl] - pfl[jl]);
+	  Message("param = %s gridID = %d", paramstr, gridID);
+	  Error("horizontal grid must not change for same parameter!");
 	}
-      else
+      if ( vartable[varID].zaxistype != zaxistype )
 	{
-	  pdl[jl] = 0.0;
-	  pdr[jl] = 0.0;
+	  Message("param = %s zaxistype = %d", paramstr, zaxistype);
+	  Error("zaxistype must not change for same parameter!");
 	}
     }
-} /* scm0 */
 
+  if ( prec > vartable[varID].prec ) vartable[varID].prec = prec;
+
+  int levelID = levelNewEntry(varID, level1, level2);
+  vartable[varID].levelTable[levelID].recID = recID;
+
+  *pvarID   = (int)varID;
+  *plevelID = levelID;
+}
+/*
 static
-int TEMPLATE(rowina3,T)(T *p, int ko, int ki, T *pw,
-			int kcode, T msval, int *kret, int omisng, int operio, int oveggy)
+int dblcmp(const void *s1, const void *s2)
 {
-  /*
-C---->
-C**** ROWINA3 - Interpolation of row of values.
-C
-C     Purpose.
-C     --------
-C
-C     Interpolate a row of values.
-C
-C
-C**   Interface.
-C     ----------
-C
-C     CALL ROWINA3( P, KO, KI, PW, KCODE, PMSVAL, KRET, OMISNG, OPERIO)
-C
-C
-C     Input Parameters.
-C     -----------------
-C
-C     P      - Row of values to be interpolated.
-C              Dimension must be at least KO.
-C
-C     KO     - Number of values required.
-C
-C     KI     - Number of values in P on input.
-C
-C     PW     - Working array.
-C              Dimension must be at least (0:KO+2,3).
-C
-C     KCODE  - Interpolation required.
-C              1 , linear.
-C              3 , cubic.
-C
-C     PMSVAL - Value used for missing data indicator.
-C
-C     OMISNG - True if missing values are present in field.
-C
-C     OPERIO - True if input field is periodic.
-C
-C     OVEGGY - True if 'nearest neighbour' processing must be used
-C              for interpolation
-C
-C     Output Parameters.
-C     ------------------
-C
-C     P     - Now contains KO values.
-C     KRET  - Return code
-C             0, OK
-C             Non-zero, error
-C
-C
-C     Method.
-C     -------
-C
-C     Linear or cubic interpolation performed as required.
-C
-C     Comments.
-C     ---------
-C
-C     This is a version of ROWINA which allows for missing data
-C     values and hence for bitmapped fields.
-C
-C
-C     Author.
-C     -------
-C
-C     J.D.Chambers    ECMWF     22.07.94
-C
-C
-C     Modifications.
-C     --------------
-C
-C     J.D.Chambers    ECMWF     13.09.94
-C     Add return code KRET and remove calls to ABORT.
-C
-C     J. Clochard, Meteo France, for ECMWF - January 1998.
-C     Addition of OMISNG and OPERIO arguments.
-C
-C
-C     -----------------------------------------------------------------
+  int cmp = 0;
+
+  if      ( *((double *) s1) < *((double *) s2) ) cmp = -1;
+  else if ( *((double *) s1) > *((double *) s2) ) cmp =  1;
+
+  return (cmp);
+}
 */
-  /* System generated locals */
-  int pw_dim1, pw_offset, i_1;
+static
+int cmpLevelTable(const void* s1, const void* s2)
+{
+  int cmp = 0;
+  const leveltable_t* x = (const leveltable_t*) s1;
+  const leveltable_t* y = (const leveltable_t*) s2;
+  /*
+  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
+  */
+  if      ( x->level1 < y->level1 ) cmp = -1;
+  else if ( x->level1 > y->level1 ) cmp =  1;
 
-  /* Local variables */
-  int jl, ip;
-  double zwt1, zrdi, zpos;
-  double zdo, zwt;
+  return (cmp);
+}
 
-  UNUSED(omisng);
+static
+int cmpLevelTableInv(const void* s1, const void* s2)
+{
+  int cmp = 0;
+  const leveltable_t* x = (const leveltable_t*) s1;
+  const leveltable_t* y = (const leveltable_t*) s2;
+  /*
+  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
+  */
+  if      ( x->level1 < y->level1 ) cmp =  1;
+  else if ( x->level1 > y->level1 ) cmp = -1;
 
-  /* Parameter adjustments */
-  --p;
-  pw_dim1 = ko + 3;
-  pw_offset = pw_dim1;
-  pw -= pw_offset;
+  return (cmp);
+}
 
-  *kret = 0;
 
-  if ( kcode == 1 )
-    {
-      /*    Move input values to work array */
-      for ( jl = 1; jl <= ki; ++jl )
-	pw[jl + pw_dim1] = p[jl];
+typedef struct
+{
+  int      varid;
+  int      param;
+  int      ltype;
+}
+param_t;
 
-      if ( operio )
-	{
-	  /* Arrange wrap-around value in work array */
-	  pw[ki + 1 + pw_dim1] = p[1];
 
-	  /* Set up constants to be used to figure out weighting for */
-	  /* values in interpolation. */
-	  zrdi = (double) ki;
-	  zdo = 1.0 / (double) ko;
-	}
-      else
-	{
-	  /* Repeat last value, to cope with "implicit truncation" below */
-	  pw[ki + 1 + pw_dim1] = p[ki];
+static
+int cmpparam(const void* s1, const void* s2)
+{
+  const param_t* x = (const param_t*) s1;
+  const param_t* y = (const param_t*) s2;
 
-	  /* Set up constants to be used to figure out weighting for */
-	  /* values in interpolation. */
-	  zrdi = (double) (ki-1);
-	  zdo = 1.0 / (double) (ko-1);
- 	}
+  int cmp = (( x->param > y->param ) - ( x->param < y->param )) * 2
+           + ( x->ltype > y->ltype ) - ( x->ltype < y->ltype );
 
-      /*    Loop through the output points */
-      for ( jl = 1; jl <= ko; ++jl )
-	{
+  return (cmp);
+}
 
-	  /* Calculate weight from the start of row */
-	  zpos = (jl - 1) * zdo;
-	  zwt = zpos * zrdi;
 
-	  /* Get the current array position(minus 1) from the weight - */
-	  /* note the implicit truncation. */
-	  ip = (int) zwt;
-		  
-	  /* Adjust the weight to range (0.0 to 1.0) */
-	  zwt -= ip;
+void cdi_generate_vars(stream_t *streamptr)
+{
+  int gridID, zaxisID;
+  int instID, modelID, tableID;
+  int param, zaxistype, ltype1, ltype2;
+  int prec;
+  int tsteptype;
+  int timave, timaccu;
+  int lbounds;
+  int comptype;
+  char name[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
+  double *dlevels = NULL;
+  double *dlevels1 = NULL;
+  double *dlevels2 = NULL;
+  double level_sf = 1;
+  int vlistID = streamptr->vlistID;
 
-          /* If 'nearest neighbour' processing must be used */
-	  if ( oveggy )
-	    {
-              if ( zwt < 0.5 )
-                p[jl] = pw[ip + 1 + pw_dim1];
-	      else
-		p[jl] = pw[ip + 2 + pw_dim1];
-	    }
-	  else
-	    {
-	      /*    If the left value is missing, use the right value */
-	      if ( IS_EQUAL(pw[ip + 1 + pw_dim1], msval) )
-		{
-		  p[jl] = pw[ip + 2 + pw_dim1];
-		}
-	      /*    If the right value is missing, use the left value */
-	      else if ( IS_EQUAL(pw[ip + 2 + pw_dim1], msval) )
-		{
-		  p[jl] = pw[ip + 1 + pw_dim1];
-		}
-	      /*    If neither missing, interpolate ... */
-	      else
-		{
-		  /*  Interpolate using the weighted values on either side */
-		  /*  of the output point position */
-		  p[jl] = (1.0 - zwt) * pw[ip+1 + pw_dim1] +
-		                  zwt * pw[ip+2 + pw_dim1];
-		}
-	    }
-	}
-    }
-  else if ( kcode == 3 )
+  int *varids = (int *)xmalloc(nvars*sizeof(int));
+  for ( unsigned varID = 0; varID < nvars; varID++ ) varids[varID] = (int)varID;
+
+  if ( streamptr->sortname )
     {
-      /*     *******************************    */
-      /*     Section 2.  Cubic interpolation .. */
-      /*     *******************************    */
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
+      param_t *varInfo = (param_t *)xmalloc((size_t)nvars * sizeof (param_t));
+
+      for ( unsigned varID = 0; varID < nvars; varID++ )
 	{
-          if ( IS_EQUAL(p[jl], msval) )
-	    {
-	      fprintf(stderr," ROWINA3: ");
-	      fprintf(stderr," Cubic interpolation not supported");
-	      fprintf(stderr," for fields containing missing data.\n");
-	      *kret = 1;
-	      goto L900;
-	    }
-          pw[jl + pw_dim1] = p[jl];
+	  varInfo[varID].varid = varids[varID];
+	  varInfo[varID].param = vartable[varID].param;
+	  varInfo[varID].ltype = vartable[varID].ltype1;
 	}
-      pw[pw_dim1] = p[ki];
-      pw[ki + 1 + pw_dim1] = p[1];
-      pw[ki + 2 + pw_dim1] = p[2];
-      i_1 = ki;
-      for ( jl = 1; jl <= i_1; ++jl )
+      qsort(varInfo, (size_t)nvars, sizeof(param_t), cmpparam);
+      for ( unsigned varID = 0; varID < nvars; varID++ )
 	{
-          pw[jl + (pw_dim1 << 1)] =
-	        - pw[jl - 1 + pw_dim1] / 3.0 -
-	          pw[jl     + pw_dim1] * 0.5 +
-	          pw[jl + 1 + pw_dim1] - pw[jl + 2 + pw_dim1] / 6.0;
-          pw[jl + 1 + pw_dim1 * 3] =
-                  pw[jl - 1 + pw_dim1] / 6.0 -
-                  pw[jl     + pw_dim1] +
-                  pw[jl + 1 + pw_dim1] * 0.5 +
-                  pw[jl + 2 + pw_dim1] / 3.0;
+	  varids[varID] = varInfo[varID].varid;
 	}
+      free(varInfo);
+    }
 
-      TEMPLATE(scm0,T)(&pw[(pw_dim1 << 1) + 1], &pw[pw_dim1 * 3 + 2],
-		       &pw[pw_dim1 + 1], &pw[pw_dim1 + 2], ki);
+  for ( unsigned index = 0; index < nvars; index++ )
+    {
+      int varid      = varids[index];
 
-      zrdi = (double) ki;
-      zdo = 1.0 / (double) ko;
-      for ( jl = 1; jl <= ko; ++jl )
-	{
-          zpos = (jl - 1) * zdo;
-          zwt = zpos * zrdi;
-          ip = (int) zwt + 1;
-          zwt = zwt + 1.0 - ip;
-          zwt1 = 1.0 - zwt;
-          p[jl] = ((3.0 - zwt1 * 2.0) * pw[ip + pw_dim1] +
-                  zwt * pw[ip + (pw_dim1 << 1)]) * zwt1 * zwt1 +
-                  ((3.0 - zwt * 2.0) * pw[ip + 1 + pw_dim1] -
-                  zwt1 * pw[ip + 1 + pw_dim1 * 3]) * zwt * zwt;
-	}
+      gridID     = vartable[varid].gridID;
+      param      = vartable[varid].param;
+      unsigned nlevels = vartable[varid].nlevels;
+      ltype1     = vartable[varid].ltype1;
+      ltype2     = vartable[varid].ltype2;
+      zaxistype = vartable[varid].zaxistype;
+      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && cdiDefaultLeveltype != -1 )
+	zaxistype = cdiDefaultLeveltype;
+      lbounds    = vartable[varid].lbounds;
+      prec       = vartable[varid].prec;
+      instID     = vartable[varid].instID;
+      modelID    = vartable[varid].modelID;
+      tableID    = vartable[varid].tableID;
+      tsteptype  = vartable[varid].tsteptype;
+      timave     = vartable[varid].timave;
+      timaccu    = vartable[varid].timaccu;
+      comptype   = vartable[varid].comptype;
 
-    }
-  else
-    {
-      /*    **************************************    */
-      /*    Section 3.  Invalid interpolation code .. */
-      /*    **************************************    */
-      fprintf(stderr," ROWINA3:");
-      fprintf(stderr," Invalid interpolation code = %2d\n",kcode);
-      *kret = 2;
-    }
+      level_sf  = 1;
+      if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
 
-L900:
-    return 0;
-} /* rowina3 */
+      zaxisID = UNDEFID;
 
+      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
+	   vartable[varid].levelTable[0].level1 == 0 )
+	zaxistype = ZAXIS_SURFACE;
 
-int TEMPLATE(qu2reg3,T)(T *pfield, int *kpoint, int klat, int klon,
-			T msval, int *kret, int omisng, int operio, int oveggy)
-{
-  /*
-C**** QU2REG3 - Convert quasi-regular grid data to regular.
-C
-C     Purpose.
-C     --------
-C
-C     Convert quasi-regular grid data to regular,
-C     using either a linear or cubic interpolation.
-C
-C
-C**   Interface.
-C     ----------
-C
-C     CALL QU2REG3(PFIELD,KPOINT,KLAT,KLON,KCODE,PMSVAL,OMISNG,OPERIO,
-C    X            OVEGGY)
-C
-C
-C     Input Parameters.
-C     -----------------
-C
-C     PFIELD     - Array containing quasi-regular grid data.
-C
-C     KPOINT     - Array containing list of the number of
-C                  points on each latitude (or longitude) of
-C                  the quasi-regular grid.
-C
-C     KLAT       - Number of latitude lines
-C
-C     KLON       - Number of longitude lines
-C
-C     KCODE      - Interpolation required.
-C                  1 , linear - data quasi-regular on latitude lines.
-C                  3 , cubic -  data quasi-regular on latitude lines.
-C                  11, linear - data quasi-regular on longitude lines.
-C                  13, cubic -  data quasi-regular on longitude lines.
-C
-C     PMSVAL     - Value used for missing data indicator.
-C
-C     OMISNG     - True if missing values are present in field.
-C
-C     OPERIO     - True if input field is periodic.
-C
-C     OVEGGY     - True if 'nearest neighbour' processing must be used
-C                  for interpolation
-C
-C
-C     Output Parameters.
-C     ------------------
-C
-C     KRET       - return code
-C                  0 = OK
-C                  non-zero indicates fatal error
-C
-C
-C     Output Parameters.
-C     ------------------
-C
-C     PFIELD     - Array containing regular grid data.
-C
-C
-C     Method.
-C     -------
-C
-C     Data is interpolated and expanded into a temporary array,
-C     which is then copied back into the user's array.
-C     Returns an error code if an invalid interpolation is requested
-C     or field size exceeds array dimensions.
-C
-C     Comments.
-C     ---------
-C
-C     This routine is an adaptation of QU2REG to allow missing data
-C     values, and hence bit mapped fields.
-C
-C
-C     Author.
-C     -------
-C
-C     J.D.Chambers     ECMWF      22.07.94
-C
-C
-C     Modifications.
-C     --------------
-C
-C     J.D.Chambers     ECMWF      13.09.94
-C     Add return code KRET and remove calls to ABORT.
-C
-C     J.D.Chambers     ECMWF        Feb 1997
-C     Allow for 64-bit pointers
-C
-C     J. Clochard, Meteo France, for ECMWF - January 1998.
-C     Addition of OMISNG and OPERIO arguments.
-C     Fix message for longitude number out of bounds, and routine
-C     name in title and formats.
-C
-*/
-   /* System generated locals */
-   int i_1, i_2;
-   int kcode = 1;
+      dlevels = (double *) malloc(nlevels*sizeof(double));
 
-   /* Local variables */
-   int ilii, ilio, icode;
-   int iregno, iquano, j210, j220, j230, j240, j225;
-   T *ztemp = NULL;
-   T *zline = NULL;
-   T *zwork = NULL;
+      if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
+	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+	  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+	                      level_sf*vartable[varid].levelTable[levelID].level2)/2;
+      else
+	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+	  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
+
+      if ( nlevels > 1 )
+	{
+          bool linc = true, ldec = true, lsort = false;
+          for (unsigned levelID = 1; levelID < nlevels; levelID++ )
+            {
+              /* check increasing of levels */
+              linc &= (dlevels[levelID] > dlevels[levelID-1]);
+              /* check decreasing of levels */
+              ldec &= (dlevels[levelID] < dlevels[levelID-1]);
+            }
+          /*
+           * always sort pressure z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 > levelID2
+           * unless already sorted in decreasing order
+           */
+          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
+            {
+              qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTableInv);
+              lsort = true;
+            }
+          /*
+           * always sort hybrid and depth-below-land z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 < levelID2
+           * unless already sorted in increasing order
+           */
+          else if ( (!linc && !ldec) ||
+                    zaxistype == ZAXIS_HYBRID ||
+                    zaxistype == ZAXIS_DEPTH_BELOW_LAND )
+            {
+              qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
+              lsort = true;
+            }
+
+          if ( lsort )
+            {
+              if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
+                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+                                      level_sf*vartable[varid].levelTable[levelID].level2)/2.;
+              else
+                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
+            }
+	}
 
-   ztemp = (T*) malloc(klon*klat*sizeof(T));
-   if ( ztemp == NULL ) SysError("No Memory!");
+      if ( lbounds )
+	{
+	  dlevels1 = (double *) malloc(nlevels*sizeof(double));
+	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
+	    dlevels1[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
+	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
+	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
+	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
+        }
 
-   zline = (T*) malloc(2*klon*sizeof(T));
-   if ( zline == NULL ) SysError("No Memory!");
+      char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
+      zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                            (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
 
-   zwork = (T*) malloc(3*(2*klon+3)*sizeof(T));
-   if ( zwork == NULL ) SysError("No Memory!");
+      if ( ltype1 != ltype2 && ltype2 != -1 )
+        {
+          zaxisDefLtype2(zaxisID, ltype2);
+        }
 
-   /* Parameter adjustments */
-   --pfield;
-   --kpoint;
+      if ( zaxisInqType(zaxisID) == ZAXIS_REFERENCE )
+        {
+          if ( numberOfVerticalLevels > 0 ) zaxisDefNlevRef(zaxisID, numberOfVerticalLevels);
+          if ( numberOfVerticalGrid > 0 ) zaxisDefNumber(zaxisID, numberOfVerticalGrid);
+          if ( !cdiUUIDIsNull(uuidVGrid) ) zaxisDefUUID(zaxisID, uuidVGrid);
+        }
 
-/* ------------------------------ */
-/* Section 1. Set initial values. */
-/* ------------------------------ */
+      if ( lbounds ) free(dlevels1);
+      if ( lbounds ) free(dlevels2);
+      free(dlevels);
 
-   *kret = 0;
+      int varID = stream_new_var(streamptr, gridID, zaxisID);
+      varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
 
-/* Check input parameters. */
+      vlistDefVarParam(vlistID, varID, param);
+      vlistDefVarDatatype(vlistID, varID, prec);
+      vlistDefVarTimave(vlistID, varID, timave);
+      vlistDefVarTimaccu(vlistID, varID, timaccu);
+      vlistDefVarCompType(vlistID, varID, comptype);
 
-   if (kcode != 1 && kcode != 3 && kcode != 11 && kcode != 13) {
-      fprintf(stderr," QU2REG :");
-      fprintf(stderr," Invalid interpolation type code = %2d\n",kcode);
-      *kret = 1;
-      goto L900;
-   }
+      if ( vartable[varid].typeOfGeneratingProcess != UNDEFID )
+        vlistDefVarTypeOfGeneratingProcess(vlistID, varID, vartable[varid].typeOfGeneratingProcess);
 
-/* Set array indices to 0. */
+      if ( vartable[varid].productDefinitionTemplate != UNDEFID )
+        vlistDefVarProductDefinitionTemplate(vlistID, varID, vartable[varid].productDefinitionTemplate);
 
-   ilii = 0;
-   ilio = 0;
+      if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);
 
-/* Establish values of loop parameters. */
+      if ( vartable[varid].name )     vlistDefVarName(vlistID, varID, vartable[varid].name);
+      if ( vartable[varid].stdname )  vlistDefVarStdname(vlistID, varID, vartable[varid].stdname);
+      if ( vartable[varid].longname ) vlistDefVarLongname(vlistID, varID, vartable[varid].longname);
+      if ( vartable[varid].units )    vlistDefVarUnits(vlistID, varID, vartable[varid].units);
 
-   if (kcode > 10) {
+      if ( vartable[varid].ensdata )  vlistDefVarEnsemble(vlistID, varID, vartable[varid].ensdata->ens_index,
+	                                                  vartable[varid].ensdata->ens_count,
+							  vartable[varid].ensdata->forecast_init_type);
 
-/*    Quasi-regular along longitude lines. */
+#if  defined  (HAVE_LIBGRIB_API)
+      /* ---------------------------------- */
+      /* Local change: 2013-04-23, FP (DWD) */
+      /* ---------------------------------- */
 
-      iquano = klon;
-      iregno = klat;
-      icode = kcode - 10;
-   } else {
+      int    i;
+      vlist_t *vlistptr;
+      vlistptr = vlist_to_pointer(vlistID);
+      for (i=0; i<vartable[varid].opt_grib_int_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_int_nentries;
+          vlistptr->vars[varID].opt_grib_int_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+          vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
+          vlistptr->vars[varID].opt_grib_int_val[idx] = vartable[varid].opt_grib_int_val[idx];
+          vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(vartable[varid].opt_grib_int_keyword[idx]);
+        }
+      for (i=0; i<vartable[varid].opt_grib_dbl_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+          vlistptr->vars[varID].opt_grib_dbl_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+          vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
+          vlistptr->vars[varID].opt_grib_dbl_val[idx] = vartable[varid].opt_grib_dbl_val[idx];
+          vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(vartable[varid].opt_grib_dbl_keyword[idx]);
+        }
+      /* note: if the key is not defined, we do not throw an error! */
+#endif
 
-/*    Quasi-regular along latitude lines. */
+      if ( cdiDefaultTableID != UNDEFID )
+	{
+	  int pdis, pcat, pnum;
+	  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+	  if ( tableInqParNamePtr(cdiDefaultTableID, pnum) )
+	    {
+	      if ( tableID != UNDEFID )
+		{
+		  strcpy(name, tableInqParNamePtr(cdiDefaultTableID, pnum));
+		  vlistDefVarName(vlistID, varID, name);
+		  if ( tableInqParLongnamePtr(cdiDefaultTableID, pnum) )
+		    {
+		      strcpy(longname, tableInqParLongnamePtr(cdiDefaultTableID, pnum));
+		      vlistDefVarLongname(vlistID, varID, longname);
+		    }
+		  if ( tableInqParUnitsPtr(cdiDefaultTableID, pnum) )
+		    {
+		      strcpy(units, tableInqParUnitsPtr(cdiDefaultTableID, pnum));
+		      vlistDefVarUnits(vlistID, varID, units);
+		    }
+		}
+	      else
+		tableID = cdiDefaultTableID;
+	    }
+	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID )  instID = cdiDefaultInstID;
+	}
 
-      iquano = klat;
-      iregno = klon;
-      icode = kcode;
-   }
+      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
+      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
+      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
+    }
 
-/*     -------------------------------------------------------- */
-/**    Section 2. Interpolate field from quasi to regular grid. */
-/*     -------------------------------------------------------- */
+  for ( unsigned index = 0; index < nvars; index++ )
+    {
+      int varID = (int)index;
+      int varid = varids[index];
 
-   i_1 = iquano;
-   for (j230 = 1; j230 <= i_1; ++j230) {
+      unsigned nlevels = vartable[varid].nlevels;
+      /*
+      for ( levelID = 0; levelID < nlevels; levelID++ )
+	{
+	  printf("%d %d %d %d %d\n", varID, levelID,
+		 vartable[varid].levelTable[levelID].lindex,
+		 vartable[varid].levelTable[levelID].recID,
+		 vartable[varid].levelTable[levelID].level1);
+	}
+      */
+      for (unsigned levelID = 0; levelID < nlevels; levelID++)
+	{
+	  streamptr->vars[varID].level[levelID] = vartable[varid].levelTable[levelID].recID;
+          unsigned lindex;
+	  for (lindex = 0; lindex < nlevels; lindex++ )
+	    if ( levelID == (unsigned)vartable[varid].levelTable[lindex].lindex ) break;
 
-      if (iregno != kpoint[j230]) {
+	  if ( lindex == nlevels )
+	    Error("Internal problem! lindex not found.");
 
-/*       Line contains less values than required,so */
-/*       extract quasi-regular grid values for a line */
+	  streamptr->vars[varID].lindex[levelID] = (int)lindex;
+	}
+    }
 
-         i_2 = kpoint[j230];
-         for (j210 = 1; j210 <= i_2; ++j210) {
-            ++ilii;
-            zline[j210 - 1] = pfield[ilii];
-         }
+  free(varids);
 
-/*       and interpolate this line. */
+  varFree();
+}
 
-         TEMPLATE(rowina3,T)(zline, iregno, kpoint[j230], zwork, icode, msval, kret, omisng, operio , oveggy);
-         if (*kret != 0) goto L900;
 
-/*       Add regular grid values for this line to the
-         temporary array. */
+void varDefVCT(size_t vctsize, double *vctptr)
+{
+  if ( Vct == NULL && vctptr != NULL && vctsize > 0 )
+    {
+      Vctsize = vctsize;
+      Vct = (double *) malloc(vctsize*sizeof(double));
+      memcpy(Vct, vctptr, vctsize*sizeof(double));
+    }
+}
 
-         i_2 = iregno;
-         for (j220 = 1; j220 <= i_2; ++j220) {
-            ++ilio;
-            ztemp[ilio - 1] = zline[j220 - 1];
-         }
 
-      } else {
+void varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE])
+{
+  numberOfVerticalLevels = nhlev;
+  numberOfVerticalGrid = nvgrid;
+  memcpy(uuidVGrid, uuid, CDI_UUID_SIZE);
+}
 
-/*       Line contains the required number of values, so add */
-/*       this line to the temporary array. */
+struct varDefGridSearchState
+{
+  int resIDValue;
+  const grid_t *queryKey;
+};
 
-         i_2 = iregno;
-         for (j225 = 1; j225 <= i_2; ++j225) {
-            ++ilio;
-            ++ilii;
-            ztemp[ilio - 1] = pfield[ilii];
-         }
-      }
-   }
+static enum cdiApplyRet
+varDefGridSearch(int id, void *res, void *data)
+{
+  struct varDefGridSearchState *state = data;
+  (void)res;
+  if (gridCompare(id, state->queryKey) == 0)
+    {
+      state->resIDValue = id;
+      return CDI_APPLY_STOP;
+    }
+  else
+    return CDI_APPLY_GO_ON;
+}
 
-/* Copy temporary array to user array. */
+int varDefGrid(int vlistID, const grid_t *grid, int mode)
+{
+  /*
+    mode: 0 search in vlist and grid table
+          1 search in grid table
+   */
+  int gridglobdefined = FALSE;
+  int griddefined;
+  int gridID = CDI_UNDEFID;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-   i_1 = klon * klat;
-   for (j240 = 1; j240 <= i_1; ++j240) {
-      pfield[j240] = ztemp[j240 - 1];
-   }
+  griddefined = FALSE;
+  unsigned ngrids = (unsigned)vlistptr->ngrids;
 
-/* -------------------------------------------------------- */
-/* Section 9. Return to calling routine. Format statements. */
-/* -------------------------------------------------------- */
+  if ( mode == 0 )
+    for (unsigned index = 0; index < ngrids; index++ )
+      {
+	gridID = vlistptr->gridIDs[index];
+	if ( gridID == UNDEFID )
+	  Error("Internal problem: undefined gridID %d!", gridID);
 
-L900:
+	if ( gridCompare(gridID, grid) == 0 )
+	  {
+	    griddefined = TRUE;
+	    break;
+	  }
+      }
 
-   free(zwork);
-   free(zline);
-   free(ztemp);
+  if ( ! griddefined )
+    {
+      struct varDefGridSearchState query = { .queryKey = grid };
+      if ((gridglobdefined
+           = (cdiResHFilterApply(&gridOps, varDefGridSearch, &query)
+              == CDI_APPLY_STOP)))
+        gridID = query.resIDValue;
 
-   return 0;
-} /* qu2reg3 */
+      if ( mode == 1 && gridglobdefined)
+	for (unsigned index = 0; index < ngrids; index++ )
+	  if ( vlistptr->gridIDs[index] == gridID )
+	    {
+	      gridglobdefined = FALSE;
+	      break;
+	    }
+    }
 
-#endif /* T */
-#include <string.h>
+  if ( ! griddefined )
+    {
+      if ( ! gridglobdefined ) gridID = gridGenerate(grid);
+      ngrids = (unsigned)vlistptr->ngrids;
+      vlistptr->gridIDs[ngrids] = gridID;
+      vlistptr->ngrids++;
+    }
 
+  return (gridID);
+}
 
 
-int gribVersion(unsigned char *is, size_t buffersize)
+int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, char *longname, char *units, int ltype1)
 {
-  if ( buffersize < 8 )
-    Error("Buffer too small (current size %d)!", (int) buffersize);
+  int differ = 1;
+  int levelID;
+  int zlbounds = 0;
+  int ltype_is_equal = FALSE;
 
-  return (GRIB_EDITION(is));
-}
+  if ( ltype1 == zaxisInqLtype(zaxisID) ) ltype_is_equal = TRUE;
 
-static 
-double GET_Real(unsigned char *grib)
-{
-  int iexp, imant;
+  if ( ltype_is_equal && (zaxistype == zaxisInqType(zaxisID) || zaxistype == ZAXIS_GENERIC) )
+    {
+      if ( zaxisInqLbounds(zaxisID, NULL) > 0 ) zlbounds = 1;
+      if ( nlevels == zaxisInqSize(zaxisID) && zlbounds == lbounds )
+	{
+	  const double *dlevels;
+	  char zlongname[CDI_MAX_NAME];
+	  char zunits[CDI_MAX_NAME];
 
-  iexp  = GET_UINT1(grib[0]);
-  imant = GET_UINT3(grib[1], grib[2], grib[3]);
+	  dlevels = zaxisInqLevelsPtr(zaxisID);
+	  for ( levelID = 0; levelID < nlevels; levelID++ )
+	    {
+	      if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
+		break;
+	    }
 
-  return (decfp2(iexp, imant));
+	  if ( levelID == nlevels ) differ = 0;
+
+	  if ( ! differ )
+	    {
+	      zaxisInqLongname(zaxisID, zlongname);
+	      zaxisInqUnits(zaxisID, zunits);
+	      if ( longname && zlongname[0] )
+		{
+		  if ( strcmp(longname, zlongname) != 0 ) differ = 1;
+		}
+	      if ( units && zunits[0] )
+		{
+		  if ( strcmp(units, zunits) != 0 ) differ = 1;
+		}
+	    }
+	}
+    }
+
+  return (differ);
 }
 
-static 
-int decodeIS(unsigned char *is, int *isec0, int *iret)
+struct varDefZAxisSearchState
 {
-  int isLen = 0;
-  int grib1offset;
-  int lgrib = FALSE, lbudg = FALSE, ltide = FALSE;
+  int resIDValue;
+  int zaxistype;
+  int nlevels;
+  double *levels;
+  int lbounds;
+  char *longname, *units;
+  int ltype;
+};
 
-  /*
-    Octets 1 - 4 : The letters G R I B.
-    Four 8 bit fields.
-  */
-  /*
-    Check letters -> GRIB, BUDG or TIDE.
-  */
-  /*
-    Check that 'GRIB' is found where expected.
-  */
-  if ( GRIB_START(is) ) lgrib = TRUE;
-  /*
-    ECMWF pseudo-grib data uses 'BUDG' and 'TIDE'.
-  */
-  if ( BUDG_START(is) ) lbudg = TRUE;
-  if ( TIDE_START(is) ) ltide = TRUE;
-  /*
-    Data is not GRIB or pseudo-grib.
-  */
-  if ( lgrib == FALSE && lbudg == FALSE && ltide == FALSE )
-    {
-      *iret = 305;
-      gprintf(__func__, "Input data is not GRIB or pseudo-grib.");
-      gprintf(__func__, "Return code = %d", *iret);
-    }
-  if ( lbudg == TRUE || ltide == TRUE )
+static enum cdiApplyRet
+varDefZAxisSearch(int id, void *res, void *data)
+{
+  struct varDefZAxisSearchState *state = data;
+  (void)res;
+  if (zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
+                   state->levels, state->longname, state->units, state->ltype)
+      == 0)
     {
-      *iret = 305;
-      gprintf(__func__, "Pseudo-grib data unsupported.");
-      gprintf(__func__, "Return code = %d", *iret);
+      state->resIDValue = id;
+      return CDI_APPLY_STOP;
     }
+  else
+    return CDI_APPLY_GO_ON;
+}
 
+
+int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
+		double *levels1, double *levels2, int vctsize, double *vct, char *name,
+		char *longname, char *units, int prec, int mode, int ltype1)
+{
   /*
-    Octets 5 - 7 : Length of message.
-    One 24 bit field.
-  */
-  ISEC0_GRIB_Len = GRIB1_SECLEN(is);
-  /*
-    Octet 8 : GRIB Edition Number.
-    One 8 bit field.
-  */
-  ISEC0_GRIB_Version = GRIB_EDITION(is);
+    mode: 0 search in vlist and zaxis table
+          1 search in zaxis table
+   */
+  int zaxisdefined = 0;
+  int nzaxis;
+  int zaxisID = UNDEFID;
+  int index;
+  int zaxisglobdefined = 0;
+  vlist_t *vlistptr;
 
-  if ( ISEC0_GRIB_Version > 1 )
-    Error("GRIB version %d unsupported!", ISEC0_GRIB_Version);
+  vlistptr = vlist_to_pointer(vlistID);
 
-  grib1offset = ISEC0_GRIB_Version * 4;
+  nzaxis = vlistptr->nzaxis;
 
-  isLen = 4 + grib1offset;
+  if ( mode == 0 )
+    for ( index = 0; index < nzaxis; index++ )
+      {
+	zaxisID = vlistptr->zaxisIDs[index];
 
-  return (isLen);
-}
+	if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
+	  {
+	    zaxisdefined = 1;
+	    break;
+	  }
+      }
 
-static 
-void decodePDS_ECMWF_local_Extension_1(unsigned char *pds, int *isec1)
-{
-  isec1[36] = GET_UINT1(pds[40]);         /* extension identifier       */
-  isec1[37] = GET_UINT1(pds[41]);         /* Class                      */
-  isec1[38] = GET_UINT1(pds[42]);         /* Type                       */
-  isec1[39] = GET_UINT2(pds[43],pds[44]); /* Stream                     */
-  /* isec1[40] = GET_UINT4(pds[45],pds[46],pds[47],pds[48]); */
-  memcpy((char*) &isec1[40], &pds[45], 4);
-  isec1[41] = GET_UINT1(pds[49]);         /* Forecast number            */
-  isec1[42] = GET_UINT1(pds[50]);         /* Total number of forecasts  */
-}
+  if ( ! zaxisdefined )
+    {
+      struct varDefZAxisSearchState query = {
+        .zaxistype = zaxistype,
+        .nlevels = nlevels,
+        .levels = levels,
+        .lbounds = lbounds,
+        .longname = longname,
+        .units = units,
+        .ltype = ltype1,
+      };
+      if ((zaxisglobdefined
+           = (cdiResHFilterApply(&zaxisOps, varDefZAxisSearch, &query)
+              == CDI_APPLY_STOP)))
+        zaxisID = query.resIDValue;
+
+      if ( mode == 1 && zaxisglobdefined)
+	for (int index = 0; index < nzaxis; index++ )
+	  if ( vlistptr->zaxisIDs[index] == zaxisID )
+	    {
+	      zaxisglobdefined = FALSE;
+	      break;
+	    }
+    }
 
-static 
-void decodePDS_DWD_local_Extension_254(unsigned char *pds, int *isec1)
-{
-  long i;
-  int isvn;
+  if ( ! zaxisdefined )
+    {
+      if ( ! zaxisglobdefined )
+	{
+	  zaxisID = zaxisCreate(zaxistype, nlevels);
+	  zaxisDefLevels(zaxisID, levels);
+	  if ( lbounds )
+	    {
+	      zaxisDefLbounds(zaxisID, levels1);
+	      zaxisDefUbounds(zaxisID, levels2);
+	    }
 
-  isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
-  for ( i = 0; i < 11; i++ ) 
-    { 
-      isec1[37+i] =  GET_UINT1(pds[41+i]);
-    } 
+	  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
+	    {
+	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels+1)) */
+	      /* if ( vctsize > 0 && vctsize >= 2*(nlevels)) */
+	      if ( vctsize > 0 )
+		zaxisDefVct(zaxisID, vctsize, vct);
+	      else
+		Warning("VCT missing");
+	    }
 
-  isvn = GET_UINT2(pds[52],pds[53]);
-  
-  isec1[48] =  isvn % 0x8000;              /* DWD experiment identifier            */
-  isec1[49] =  isvn >> 15;                 /* DWD run type (0=main, 2=ass, 3=test) */
+	  zaxisDefName(zaxisID, name);
+	  zaxisDefLongname(zaxisID, longname);
+	  zaxisDefUnits(zaxisID, units);
+	  zaxisDefPrec(zaxisID, prec);
+	  zaxisDefLtype(zaxisID, ltype1);
+	}
+
+      vlistptr->zaxisIDs[nzaxis] = zaxisID;
+      vlistptr->nzaxis++;
+    }
 
+  return (zaxisID);
 }
 
-static 
-void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
+
+void varDefMissval(int varID, double missval)
 {
-  long i;
-  int isvn;
+  vartable[varID].lmissval = 1;
+  vartable[varID].missval = missval;
+}
 
-  isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
-  for ( i = 0; i < 11; i++ ) 
-    { 
-      isec1[37+i] =  GET_UINT1(pds[41+i]);
-    } 
 
-  isvn = GET_UINT2(pds[52],pds[53]);
-  
-  isec1[48] =  isvn % 0x8000;              /* DWD experiment identifier            */
-  isec1[49] =  isvn >> 15;                 /* DWD run type (0=main, 2=ass, 3=test) */
-  isec1[50] =  GET_UINT1(pds[54]);         /* User id, specified by table          */
-  isec1[51] =  GET_UINT2(pds[55],pds[56]); /* Experiment identifier                */
-  isec1[52] =  GET_UINT2(pds[57],pds[58]); /* Ensemble identification by table     */
-  isec1[53] =  GET_UINT2(pds[59],pds[60]); /* Number of ensemble members           */
-  isec1[54] =  GET_UINT2(pds[61],pds[62]); /* Actual number of ensemble member     */
-  isec1[55] =  GET_UINT1(pds[63]);         /* Model major version number           */
-  isec1[56] =  GET_UINT1(pds[64]);         /* Model minor version number           */
+void varDefCompType(int varID, int comptype)
+{
+  if ( vartable[varID].comptype == COMPRESS_NONE )
+    vartable[varID].comptype = comptype;
+}
 
+
+void varDefCompLevel(int varID, int complevel)
+{
+  vartable[varID].complevel = complevel;
 }
 
-static 
-void decodePDS_MPIM_local_Extension_1(unsigned char *pds, int *isec1)
+
+int varInqInst(int varID)
 {
-  isec1[36] = GET_UINT1(pds[40]);         /* extension identifier            */
-  isec1[37] = GET_UINT1(pds[41]);         /* type of ensemble forecast       */
-  isec1[38] = GET_UINT2(pds[42],pds[43]); /* individual ensemble member      */
-  isec1[39] = GET_UINT2(pds[44],pds[45]); /* number of forecasts in ensemble */
+  return (vartable[varID].instID);
 }
 
-static 
-int decodePDS(unsigned char *pds, int *isec0, int *isec1)
+
+void varDefInst(int varID, int instID)
 {
-  int pdsLen;
+  vartable[varID].instID = instID;
+}
 
-  pdsLen = PDS_Len;
 
-  ISEC1_CodeTable      = PDS_CodeTable;
-  ISEC1_CenterID       = PDS_CenterID;
-  ISEC1_ModelID        = PDS_ModelID;
-  ISEC1_GridDefinition = PDS_GridDefinition;
-  ISEC1_Sec2Or3Flag    = PDS_Sec2Or3Flag;
-  ISEC1_Parameter      = PDS_Parameter;
-  ISEC1_LevelType      = PDS_LevelType;
+int varInqModel(int varID)
+{
+  return (vartable[varID].modelID);
+}
 
-  if ( (ISEC1_LevelType !=  20) && 
-       (ISEC1_LevelType != GRIB1_LTYPE_99)        && 
-       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC)  && 
-       (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE)  && 
-       (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT)    && 
-       (ISEC1_LevelType != GRIB1_LTYPE_SIGMA)     && 
-       (ISEC1_LevelType != GRIB1_LTYPE_HYBRID)    && 
-       (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH) && 
-       (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) && 
-       (ISEC1_LevelType != 115) && 
-       (ISEC1_LevelType != 117) && 
-       (ISEC1_LevelType != 125) && 
-       (ISEC1_LevelType != 127) && 
-       (ISEC1_LevelType != GRIB1_LTYPE_SEADEPTH)  && 
-       (ISEC1_LevelType != 210) )
-    {
-      ISEC1_Level1 = PDS_Level1;
-      ISEC1_Level2 = PDS_Level2;
-    }
-  else
-    {
-      ISEC1_Level1 = PDS_Level;
-      ISEC1_Level2 = 0;
-    }
 
-  /* ISEC1_Year        = PDS_Year; */
-  ISEC1_Month          = PDS_Month;
-  ISEC1_Day            = PDS_Day;
-  ISEC1_Hour           = PDS_Hour;
-  ISEC1_Minute         = PDS_Minute;
-  ISEC1_TimeUnit       = PDS_TimeUnit;
-  ISEC1_TimePeriod1    = PDS_TimePeriod1;
-  ISEC1_TimePeriod2    = PDS_TimePeriod2;
-  ISEC1_TimeRange      = PDS_TimeRange;
-  ISEC1_AvgNum         = PDS_AvgNum;
-  ISEC1_AvgMiss        = PDS_AvgMiss;
+void varDefModel(int varID, int modelID)
+{
+  vartable[varID].modelID = modelID;
+}
 
-  if ( ISEC0_GRIB_Version == 1 )
-    {
-      ISEC1_Year           = PDS_Year;
-      ISEC1_Century        = PDS_Century;
-      ISEC1_SubCenterID    = PDS_Subcenter;
-      ISEC1_DecScaleFactor = PDS_DecimalScale;
-    }
-  else
-    {
-      int year;
-      year                 = GET_UINT1(pds[12]);
-      if ( year <= 100 )
-	{
-	  ISEC1_Year       = year;
-	  ISEC1_Century    = 1;
-	}
-      else
-	{
-	  ISEC1_Year       = year%100;
-	  ISEC1_Century    = 1 + (year-ISEC1_Year)/100;
-	}
-      ISEC1_SubCenterID    = 0;
-      ISEC1_DecScaleFactor = 0;
-    }
 
-  if ( ISEC1_Year < 0 )
-    {
-      ISEC1_Year    = -ISEC1_Year;
-      ISEC1_Century = -ISEC1_Century;
-    }
+int varInqTable(int varID)
+{
+  return (vartable[varID].tableID);
+}
 
-  ISEC1_LocalFLag = 0;
-  if ( pdsLen > 28 )
-    {
-      int localextlen;
-      localextlen = pdsLen-28;
 
-      if ( localextlen > 4000 )
-	{
-	  Warning("PDS larger than 4000 bytes not supported!");
-	}
-      else
-	{
-	  ISEC1_LocalFLag = 1;
+void varDefTable(int varID, int tableID)
+{
+  vartable[varID].tableID = tableID;
+}
 
-	  if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
-	    {
-	      if ( pds[40] == 254 ) 
-		{
-		  decodePDS_DWD_local_Extension_254(pds, isec1);
-		}
-	      else if ( pds[40] == 253 )
-		{ 
-		  decodePDS_DWD_local_Extension_253(pds, isec1);
-		}
-	    }
-	  else if ( (ISEC1_CenterID    == 98 && ISEC1_LocalFLag ==  1) ||
-		    (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag ==  1) ||
-		    (ISEC1_CenterID    ==  7 && ISEC1_SubCenterID == 98) )
-	    {
-	      if ( pds[40] == 1 )
-		decodePDS_ECMWF_local_Extension_1(pds, isec1);
-	    }
-	  else if ( ISEC1_CenterID    == 252 && ISEC1_LocalFLag ==  1 )
-	    {
-	      if ( pds[40] == 1 )
-		decodePDS_MPIM_local_Extension_1(pds, isec1);	      
-	    }
-	  else
-	    {
-	      long i;
-	      for ( i = 0; i < localextlen; i++ )
-		{
-		  isec1[24+i] = pds[28+i];
-		}
-	    }
-	}
-    }
 
-  return (pdsLen);
+void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type)
+{
+  if ( vartable[varID].ensdata == NULL )
+      vartable[varID].ensdata = (ensinfo_t *)xmalloc( sizeof( ensinfo_t ) );
+
+  vartable[varID].ensdata->ens_index = ens_idx;
+  vartable[varID].ensdata->ens_count = ens_count;
+  vartable[varID].ensdata->forecast_init_type = forecast_type;
 }
 
 
-void gribPrintSec2_double(int *isec0, int *isec2, double *fsec2) {gribPrintSec2DP(isec0, isec2, fsec2);}
-void gribPrintSec3_double(int *isec0, int *isec3, double *fsec3) {gribPrintSec3DP(isec0, isec3, fsec3);}
-void gribPrintSec4_double(int *isec0, int *isec4, double *fsec4) {gribPrintSec4DP(isec0, isec4, fsec4);}
-void gribPrintSec2_float(int *isec0, int *isec2, float *fsec2) {gribPrintSec2SP(isec0, isec2, fsec2);}
-void gribPrintSec3_float(int *isec0, int *isec3, float *fsec3) {gribPrintSec3SP(isec0, isec3, fsec3);}
-void gribPrintSec4_float(int *isec0, int *isec4, float *fsec4) {gribPrintSec4SP(isec0, isec4, fsec4);}
+void varDefTypeOfGeneratingProcess(int varID, int typeOfGeneratingProcess)
+{
+  vartable[varID].typeOfGeneratingProcess = typeOfGeneratingProcess;
+}
 
 
+void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate)
+{
+  vartable[varID].productDefinitionTemplate = productDefinitionTemplate;
+}
+
 
-#ifdef T
-#undef T
+#if  defined  (HAVE_LIBGRIB_API)
+void varDefOptGribInt(int varID, long lval, const char *keyword)
+{
+  int idx = vartable[varID].opt_grib_int_nentries;
+  vartable[varID].opt_grib_int_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+  vartable[varID].opt_grib_int_val[idx] = (int) lval;
+  vartable[varID].opt_grib_int_keyword[idx] = strdupx(keyword);
+}
 #endif
-#define T double
-#ifdef T
 
-static 
-void TEMPLATE(decode_array_common,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
-				     T fmin, T zscale, T * restrict fpdata)
+
+#if  defined  (HAVE_LIBGRIB_API)
+void varDefOptGribDbl(int varID, double dval, const char *keyword)
 {
-  /* code from wgrib routine BDS_unpack */
-  const unsigned char *bits = igrib;
-  unsigned int jmask;
-  long i;
-  unsigned int tbits = 0;
-  int n_bits = NumBits;
-  int t_bits = 0;
-      
-  jmask = (1 << n_bits) - 1;
-  for ( i = 0; i < jlend; i++ )
-    {
-      if (n_bits - t_bits > 8)
-	{
-	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
-	  bits += 2;
-	  t_bits += 16;
-	}
+  int idx = vartable[varID].opt_grib_dbl_nentries;
+  vartable[varID].opt_grib_dbl_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+  vartable[varID].opt_grib_dbl_val[idx] = dval;
+  vartable[varID].opt_grib_dbl_keyword[idx] = strdupx(keyword);
+}
+#endif
 
-      while ( t_bits < n_bits )
-	{
-	  tbits = (tbits * 256) + *bits++;
-	  t_bits += 8;
-	}
-      t_bits -= n_bits;
-      fpdata[i] = (tbits >> t_bits) & jmask;
-    }
-  /* at least this vectorizes :) */
-  for ( i = 0; i < jlend; i++ )
-    fpdata[i] = fmin + zscale*fpdata[i];
+
+#if  defined  (HAVE_LIBGRIB_API)
+int varOptGribNentries(int varID)
+{
+  int nentries = 0;
+  nentries = vartable[varID].opt_grib_int_nentries + vartable[varID].opt_grib_dbl_nentries;
+  return (nentries);
 }
+#endif
 
-#if !defined(_MASK_AND_SHIFT_)
-#define _MASK_AND_SHIFT_
-static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef VLIST_VAR_H
+#define VLIST_VAR_H
+
+#ifdef HAVE_CONFIG_H
 #endif
 
-static 
-void TEMPLATE(decode_array_common2,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
-				      T fmin, T zscale, T * restrict fpdata)
-{
-  /* code from wgrib routine BDS_unpack */
-  const unsigned char *bits = igrib;
-  long i;
-  int n_bits = NumBits;
-  int c_bits, j_bits;
-  double jj;
+#ifndef _VLIST_H
+#endif
 
-  /* older unoptimized code, not often used */
-  c_bits = 8;
-  for ( i = 0; i < jlend; i++ )
-    {
-      jj = 0.0;
-      j_bits = n_bits;
-      while (c_bits <= j_bits)
-	{
-	  if (c_bits == 8)
-	    {
-	      jj = jj * 256.0  + (double) (*bits++);
-	      j_bits -= 8;
-	    }
-	  else
-	    {
-	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
-	      bits++;
-	      j_bits -= c_bits;
-	      c_bits = 8;
-	    }
-	}
+int  vlistVarGetPackSize(vlist_t *p, int varID, void *context);
+void vlistVarPack(vlist_t *p, int varID,
+                  char * buffer, int bufferSize, int * pos, void *context);
+void vlistVarUnpack(int vlistID,
+                    char * buf, int size, int *position, int, void *context);
+int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB);
+void vlistDefVarIOrank    ( int, int, int );
+int  vlistInqVarIOrank    ( int, int );
 
-      if (j_bits)
-	{
-	  c_bits -= j_bits;
-	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
-	}
-      
-      fpdata[i] = fmin + zscale*jj;
-    }
-} 
+void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
 
-static 
-void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits, 
-			      T fmin, T zscale, T *restrict fpdata)
-{
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
-  uint64_t start_decode, end_decode;
 #endif
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef VLIST_ATT_H
+#define VLIST_ATT_H
 
-  long i;
-  T dval;
-#if defined (VECTORCODE)
-  GRIBPACK *lgrib = NULL;
+#ifdef HAVE_CONFIG_H
+#endif
 
-  if ( numBits%8 == 0 )
-    {
-      long jlenc = jlend * numBits / 8;
-      if ( jlenc > 0 ) 
-	{
-	  lgrib = (GRIBPACK*) malloc(jlenc*sizeof(GRIBPACK));
-	  if ( lgrib == NULL ) SysError("No Memory!");
+int
+vlistAttsGetSize(vlist_t *p, int varID, void *context);
 
-	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
-	}
-    }
+void
+vlistAttsPack(vlist_t *p, int varID,
+              void * buf, int size, int *position, void *context);
 
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)lgrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
-	  	 (int)lgrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
-		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      Error("Unimplemented packing factor %d!", numBits);
-    }
+void
+vlistAttsUnpack(int vlistID, int varID,
+                void * buf, int size, int *position, void *context);
 
-  if ( lgrib ) free(lgrib);
 
-#else
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)igrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(6, "unpack 16 bit base");
-#elif defined _GET_X86_COUNTER 
-      start_decode = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      start_decode = mach_absolute_time();
 #endif
-      
-      if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-	  printf("AVX selected ...\n");
-	  avx_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
-#elif defined _ENABLE_SSE4_1
-	  printf("SSE4 selected ...\n");
-	  sse41_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
-#else
-	  for ( i = 0; i < jlend; i++ )
-	    {
-	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	      fpdata[i] = fmin + zscale * dval;
-	    }
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
 #endif
-	}
-      else
-	{
-	  for ( i = 0; i < jlend; i++ )
-	    {
-	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	      fpdata[i] = fmin + zscale * dval;
-	    }
-	}
 
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER 
-      end_decode = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      end_decode = mach_absolute_time();
+
+
+#if  defined  (HAVE_LIBGRIB_API)
+/* list of additional GRIB2 keywords which are read by the open process */
+int    cdiNAdditionalGRIBKeys = 0;
+char*  cdiAdditionalGRIBKeys[MAX_OPT_GRIB_ENTRIES];
 #endif
-#if defined _ENABLE_AVX
-      printf("AVX encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
-#elif defined _ENABLE_SSE4_1
-      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
+
+static int VLIST_Debug = 0;
+
+static void vlist_initialize(void);
+
+#if  defined  (HAVE_LIBPTHREAD)
+#  include <pthread.h>
+
+static pthread_once_t  _vlist_init_thread = PTHREAD_ONCE_INIT;
+
+#  define VLIST_INIT()        \
+  pthread_once(&_vlist_init_thread, vlist_initialize)
+
 #else
-      printf("loop encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
-#endif  
+
+static int vlistIsInitialized = 0;
+
+#  define VLIST_INIT()               \
+  if ( !vlistIsInitialized ) vlist_initialize()
 #endif
-      
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(6);
+
+
+static int
+vlist_compare(vlist_t *a, vlist_t *b)
+{
+  int diff;
+  diff = (a->nvars != b->nvars) | (a->ngrids != b->ngrids)
+    | (a->nzaxis != b->nzaxis) | (a->instID != b->instID)
+    | (a->modelID != b->modelID) | (a->tableID != b->tableID)
+    | (a->ntsteps != b->ntsteps) | (a->atts.nelems != b->atts.nelems);
+  int nvars = a->nvars;
+  for (int varID = 0; varID < nvars; ++varID)
+    diff |= vlistVarCompare(a, varID, b, varID);
+  size_t natts = a->atts.nelems;
+  for (size_t attID = 0; attID < natts; ++attID)
+    diff |= vlist_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
+  return diff;
+}
+
+static void
+vlistPrintKernel(vlist_t *vlistptr, FILE * fp );
+static void
+vlist_delete(vlist_t *vlistptr);
+
+static int  vlistGetSizeP ( void * vlistptr, void *context);
+static void vlistPackP    ( void * vlistptr, void * buff, int size,
+                            int *position, void *context);
+static int  vlistTxCode   ( void );
+
+#if !defined(__cplusplus)
+const
 #endif
-    }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
-		 (int)igrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
-		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
+resOps vlistOps = {
+  (valCompareFunc)vlist_compare,
+  (valDestroyFunc)vlist_delete,
+  (valPrintFunc)vlistPrintKernel
+  , vlistGetSizeP,
+  vlistPackP,
+  vlistTxCode
+};
+
+
+vlist_t *vlist_to_pointer(int vlistID)
+{
+  VLIST_INIT();
+  return (vlist_t*) reshGetVal(vlistID, &vlistOps );
+}
+
+static
+void vlist_init_entry(vlist_t *vlistptr)
+{
+  vlistptr->locked         = 0;
+  vlistptr->self           = CDI_UNDEFID;
+  vlistptr->nvars          = 0;
+  vlistptr->vars           = NULL;
+  vlistptr->ngrids         = 0;
+  vlistptr->nzaxis         = 0;
+  vlistptr->taxisID        = CDI_UNDEFID;
+  vlistptr->instID         = cdiDefaultInstID;
+  vlistptr->modelID        = cdiDefaultModelID;
+  vlistptr->tableID        = cdiDefaultTableID;
+  vlistptr->varsAllocated  = 0;
+  vlistptr->ntsteps        = CDI_UNDEFID;
+  vlistptr->atts.nalloc    = MAX_ATTRIBUTES;
+  vlistptr->atts.nelems    = 0;
+}
+
+static
+vlist_t *vlist_new_entry(cdiResH resH)
+{
+  vlist_t *vlistptr = (vlist_t*) xmalloc(sizeof(vlist_t));
+  vlist_init_entry(vlistptr);
+  if (resH == CDI_UNDEFID)
+    vlistptr->self = reshPut(vlistptr, &vlistOps);
   else
     {
-      Error("Unimplemented packing factor %d!", numBits);
+      vlistptr->self = resH;
+      reshReplace(resH, vlistptr, &vlistOps);
     }
-#endif
+  return (vlistptr);
 }
 
-#endif /* T */
+static
+void vlist_delete_entry(vlist_t *vlistptr)
+{
+  int idx;
 
-#ifdef T
-#undef T
+  idx = vlistptr->self;
+
+  reshRemove(idx, &vlistOps );
+
+  free(vlistptr);
+
+  if ( VLIST_Debug )
+    Message("Removed idx %d from vlist list", idx);
+}
+
+static
+void vlist_initialize(void)
+{
+  char *env;
+
+  env = getenv("VLIST_DEBUG");
+  if ( env ) VLIST_Debug = atoi(env);
+#ifndef HAVE_LIBPTHREAD
+  vlistIsInitialized = TRUE;
 #endif
-#define T float
-#ifdef T
+}
 
-static 
-void TEMPLATE(decode_array_common,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
-				     T fmin, T zscale, T * restrict fpdata)
+static
+void vlist_copy(vlist_t *vlistptr2, vlist_t *vlistptr1)
 {
-  /* code from wgrib routine BDS_unpack */
-  const unsigned char *bits = igrib;
-  unsigned int jmask;
-  long i;
-  unsigned int tbits = 0;
-  int n_bits = NumBits;
-  int t_bits = 0;
-      
-  jmask = (1 << n_bits) - 1;
-  for ( i = 0; i < jlend; i++ )
-    {
-      if (n_bits - t_bits > 8)
-	{
-	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
-	  bits += 2;
-	  t_bits += 16;
-	}
+  int vlistID2 = vlistptr2->self;
+  memcpy(vlistptr2, vlistptr1, sizeof(vlist_t));
+  vlistptr2->atts.nelems = 0;
+  vlistptr2->self = vlistID2;
+}
 
-      while ( t_bits < n_bits )
-	{
-	  tbits = (tbits * 256) + *bits++;
-	  t_bits += 8;
-	}
-      t_bits -= n_bits;
-      fpdata[i] = (tbits >> t_bits) & jmask;
+void vlist_lock(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  if ( !vlistptr->locked )
+    {
+      vlistptr->locked = 1;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-  /* at least this vectorizes :) */
-  for ( i = 0; i < jlend; i++ )
-    fpdata[i] = fmin + zscale*fpdata[i];
 }
 
-#if !defined(_MASK_AND_SHIFT_)
-#define _MASK_AND_SHIFT_
-static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
-#endif
 
-static 
-void TEMPLATE(decode_array_common2,T)(const unsigned char * restrict igrib, long jlend, int NumBits, 
-				      T fmin, T zscale, T * restrict fpdata)
+void vlist_unlock(int vlistID)
 {
-  /* code from wgrib routine BDS_unpack */
-  const unsigned char *bits = igrib;
-  long i;
-  int n_bits = NumBits;
-  int c_bits, j_bits;
-  double jj;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  /* older unoptimized code, not often used */
-  c_bits = 8;
-  for ( i = 0; i < jlend; i++ )
+  if ( vlistptr->locked )
     {
-      jj = 0.0;
-      j_bits = n_bits;
-      while (c_bits <= j_bits)
-	{
-	  if (c_bits == 8)
-	    {
-	      jj = jj * 256.0  + (double) (*bits++);
-	      j_bits -= 8;
-	    }
-	  else
-	    {
-	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
-	      bits++;
-	      j_bits -= c_bits;
-	      c_bits = 8;
-	    }
-	}
-
-      if (j_bits)
-	{
-	  c_bits -= j_bits;
-	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
-	}
-      
-      fpdata[i] = fmin + zscale*jj;
+      vlistptr->locked = 0;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-} 
+}
 
-static 
-void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, int numBits, 
-			      T fmin, T zscale, T *restrict fpdata)
+/*
+ at Function  vlistCreate
+ at Title     Create a variable list
+
+ at Prototype int vlistCreate(void)
+
+ at Example
+Here is an example using @func{vlistCreate} to create a variable list
+and add a variable with @func{vlistDefVar}.
+
+ at Source
+   ...
+int vlistID, varID;
+   ...
+vlistID = vlistCreate();
+varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+   ...
+streamDefVlist(streamID, vlistID);
+   ...
+vlistDestroy(vlistID);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int vlistCreate(void)
 {
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
-  uint64_t start_decode, end_decode;
-#endif
+  cdiInitialize();
 
-  long i;
-  T dval;
-#if defined (VECTORCODE)
-  GRIBPACK *lgrib = NULL;
+  VLIST_INIT();
 
-  if ( numBits%8 == 0 )
-    {
-      long jlenc = jlend * numBits / 8;
-      if ( jlenc > 0 ) 
-	{
-	  lgrib = (GRIBPACK*) malloc(jlenc*sizeof(GRIBPACK));
-	  if ( lgrib == NULL ) SysError("No Memory!");
+  vlist_t *vlistptr = vlist_new_entry(CDI_UNDEFID);
+  return (vlistptr->self);
+}
 
-	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
-	}
-    }
+static void
+vlist_delete(vlist_t *vlistptr)
+{
+  int vlistID = vlistptr->self;
 
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)lgrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
-	  	 (int)lgrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
-		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      Error("Unimplemented packing factor %d!", numBits);
-    }
+  vlistDelAtts(vlistID, CDI_GLOBAL);
 
-  if ( lgrib ) free(lgrib);
+  int nvars = vlistptr->nvars;
+  var_t *vars = vlistptr->vars;
 
-#else
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)igrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
+  for ( int varID = 0; varID < nvars; varID++ )
     {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(6, "unpack 16 bit base");
-#elif defined _GET_X86_COUNTER 
-      start_decode = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      start_decode = mach_absolute_time();
-#endif
-      
-      if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-	  printf("AVX selected ...\n");
-	  avx_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
-#elif defined _ENABLE_SSE4_1
-	  printf("SSE4 selected ...\n");
-	  sse41_decode_array_2byte_double((size_t) jlend, igrib, fpdata, fmin, zscale);
-#else
-	  for ( i = 0; i < jlend; i++ )
-	    {
-	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	      fpdata[i] = fmin + zscale * dval;
-	    }
-#endif
-	}
-      else
-	{
-	  for ( i = 0; i < jlend; i++ )
-	    {
-	      dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	      fpdata[i] = fmin + zscale * dval;
-	    }
-	}
+      if ( vars[varID].levinfo )  free(vars[varID].levinfo);
+      if ( vars[varID].name )     free(vars[varID].name);
+      if ( vars[varID].longname ) free(vars[varID].longname);
+      if ( vars[varID].stdname )  free(vars[varID].stdname);
+      if ( vars[varID].units )    free(vars[varID].units);
+      if ( vars[varID].ensdata )  free(vars[varID].ensdata);
 
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER 
-      end_decode = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      end_decode = mach_absolute_time();
-#endif
-#if defined _ENABLE_AVX
-      printf("AVX encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
-#elif defined _ENABLE_SSE4_1
-      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
-#else
-      printf("loop encoding cycles:: %" PRIu64 "\n", end_decode-start_decode);
-#endif  
-#endif
-      
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(6);
+#if  defined  (HAVE_LIBGRIB_API)
+      for ( int i=0; i<vars[varID].opt_grib_int_nentries; i++ )
+        {
+          if ( vars[varID].opt_grib_int_keyword[i] )
+            free(vars[varID].opt_grib_int_keyword[i]);
+        }
+      for ( int i=0; i<vars[varID].opt_grib_dbl_nentries; i++ )
+        {
+          if ( vars[varID].opt_grib_dbl_keyword[i] )
+            free(vars[varID].opt_grib_dbl_keyword[i]);
+        }
 #endif
+
+      vlistDelAtts(vlistID, varID);
     }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
-		 (int)igrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
-		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
+
+  if ( vars ) free(vars);
+
+  vlist_delete_entry(vlistptr);
+}
+
+
+/*
+ at Function  vlistDestroy
+ at Title     Destroy a variable list
+
+ at Prototype void vlistDestroy(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+
+ at EndFunction
+*/
+void vlistDestroy(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  if ( vlistptr->locked )
+    Warning("Destroying of a locked object (vlistID=%d) failed!", vlistID);
+  else
+    vlist_delete(vlistptr);
+}
+
+static
+void var_copy_entries(var_t *var2, var_t *var1)
+{
+  if ( var1->name )     var2->name     = strdupx(var1->name);
+  if ( var1->longname ) var2->longname = strdupx(var1->longname);
+  if ( var1->stdname )  var2->stdname  = strdupx(var1->stdname);
+  if ( var1->units )    var2->units    = strdupx(var1->units);
+  if ( var1->ensdata )
     {
-      TEMPLATE(decode_array_common,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+      var2->ensdata = (ensinfo_t *)xmalloc(sizeof(ensinfo_t));
+      memcpy(var2->ensdata, var1->ensdata, sizeof(ensinfo_t));
     }
-  else if ( numBits > 25 && numBits < 32 )
+#if  defined  (HAVE_LIBGRIB_API)
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+  var2->opt_grib_int_nentries = var1->opt_grib_int_nentries;
+  for ( int i = 0; i < var1->opt_grib_int_nentries; i++ )
     {
-      TEMPLATE(decode_array_common2,T)(igrib, jlend, numBits, fmin, zscale, fpdata);
+      if ( var1->opt_grib_int_keyword[i] )
+        {
+          var2->opt_grib_int_keyword[i] = strdupx(var1->opt_grib_int_keyword[i]);
+          var2->opt_grib_int_val[i]     = var1->opt_grib_int_val[i];
+          var2->opt_grib_int_update[i]  = TRUE;
+        }
     }
-  else
+  var2->opt_grib_dbl_nentries = var1->opt_grib_dbl_nentries;
+  for ( int i = 0; i < var1->opt_grib_dbl_nentries; i++ )
     {
-      Error("Unimplemented packing factor %d!", numBits);
+      if ( var1->opt_grib_dbl_keyword[i] )
+        {
+          var2->opt_grib_dbl_keyword[i] = strdupx(var1->opt_grib_dbl_keyword[i]);
+          var2->opt_grib_dbl_val[i]     = var1->opt_grib_dbl_val[i];
+          var2->opt_grib_dbl_update[i]  = TRUE;
+        }
     }
 #endif
 }
 
-#endif /* T */
+/*
+ at Function  vlistCopy
+ at Title     Copy a variable list
 
+ at Prototype void vlistCopy(int vlistID2, int vlistID1)
+ at Parameter
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
+ at Description
+The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
 
-static 
-int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
+ at EndFunction
+*/
+void vlistCopy(int vlistID2, int vlistID1)
 {
-  /* int imisng = 0; */
-  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
-  int  locnv = 0, locnl;
-  int  jlenl;
-  long i;
-  int iexp, imant;
-  int ipvpl, ipl;
-  int gdsLen = 0;
-#if defined (VECTORCODE)
-  unsigned char *igrib;
-  GRIBPACK *lgrib = NULL;
-  size_t lGribLen = 0;
-#endif
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
 
-  *numGridVals = 0;
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
+  vlist_copy(vlistptr2, vlistptr1);
+
+  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+
+  if ( vars1 )
+    {
+      int nvars = vlistptr1->nvars;
+      //vlistptr2->varsAllocated = nvars;
+
+      size_t n = (size_t)vlistptr2->varsAllocated;
+      vars2 = xrealloc(vars2, n*sizeof(var_t));
+      memcpy(vars2, vars1, n*sizeof(var_t));
+      vlistptr2->vars = vars2;
+
+      for ( int varID = 0; varID < nvars; varID++ )
+        {
+          var_copy_entries(&vars2[varID], &vars1[varID]);
+
+	  vars2[varID].atts.nelems = 0;
+	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
+
+          if ( vars1[varID].levinfo )
+            {
+              n = (size_t)zaxisInqSize(vars1[varID].zaxisID);
+              vars2[varID].levinfo = xmalloc(n*sizeof(levinfo_t));
+              memcpy(vars2[varID].levinfo, vars1[varID].levinfo, n*sizeof(levinfo_t));
+            }
+	}
+    }
+}
+
+/*
+ at Function  vlistDuplicate
+ at Title     Duplicate a variable list
+
+ at Prototype int vlistDuplicate(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+
+ at Description
+The function @func{vlistDuplicate} duplicates the variable list from vlistID1.
+
+ at Result
+ at func{vlistDuplicate} returns an identifier to the duplicated variable list.
+
+ at EndFunction
+*/
+int vlistDuplicate(int vlistID)
+{
+  int vlistIDnew = vlistCreate();
+  vlistCopy(vlistIDnew, vlistID);
+  return (vlistIDnew);
+}
+
+
+void vlistClearFlag(int vlistID)
+{
+  int varID, levID;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  for ( varID = 0; varID < vlistptr->nvars; varID++ )
+    {
+      vlistptr->vars[varID].flag = FALSE;
+      if ( vlistptr->vars[varID].levinfo )
+        {
+          int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+          for ( levID = 0; levID < nlevs; levID++ )
+            vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+        }
+    }
+}
 
-  memset(isec2, 0, 22*sizeof(int));
+static
+int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *levels,
+                         const double *lbounds, const double *ubounds, int vctsize, const double *vct)
+{
+  int zaxisID = CDI_UNDEFID;
+  int zaxisglobdefined = 0;
+  int has_bounds = FALSE;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int zaxisdefined = 0;
+  int nzaxis = vlistptr->nzaxis;
 
-  gdsLen = GDS_Len;
+  if ( lbounds && ubounds ) has_bounds = TRUE;
 
-  ipvpl = GDS_PVPL;
-  if ( ipvpl == 0 ) ipvpl = 0xFF;
+  for ( int index = 0; index < nzaxis; ++index )
+    {
+      zaxisID = vlistptr->zaxisIDs[index];
 
-  if ( ipvpl != 0xFF )
-    { /* Either vct or reduced grid */
-      if ( GDS_NV != 0 )
-	{ /* we have vct */
-	  VertCoorTab = TRUE;
-	  ipl =  4*GDS_NV + ipvpl - 1;
-	  if ( ipl < gdsLen )
-	    {
-	      ReducedGrid = TRUE;
-	    }
-	}
-      else
-	{
-	  VertCoorTab = FALSE;
-	  ReducedGrid = TRUE;
-	}
-      /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
+      if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
+        {
+          zaxisdefined = 1;
+          break;
+        }
     }
- 
-  if ( ISEC0_GRIB_Version == 0 )
+
+  if ( ! zaxisdefined )
     {
-      if ((gdsLen - 32) > 0) VertCoorTab = TRUE;
-      else                   VertCoorTab = FALSE;
+      unsigned nzaxis = cdiZaxisCount();
+      if ( nzaxis > 0 )
+        {
+          int *zaxisIndexList = (int *)xmalloc((size_t)nzaxis * sizeof (int));
+          reshLock();
+          cdiZaxisGetIndexList(nzaxis, zaxisIndexList);
+          for (unsigned index = 0; index < nzaxis; ++index)
+            {
+              zaxisID = zaxisIndexList[index];
+              if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
+                {
+                  zaxisglobdefined = 1;
+                  break;
+                }
+            }
+          reshUnlock();
+          free(zaxisIndexList);
+        }
     }
-  
-  if ( ReducedGrid )
+
+  if ( ! zaxisdefined )
     {
-      locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
-      jlenl = (gdsLen - locnl)  >> 1;
-      if ( jlenl == GDS_NumLat )
+      if ( ! zaxisglobdefined )
 	{
-	  *numGridVals = 0;
-	  ISEC2_Reduced = TRUE;
-	  for ( i = 0; i < jlenl; i++ )
+	  zaxisID = zaxisCreate(zaxistype, nlevels);
+	  zaxisDefLevels(zaxisID, levels);
+	  if ( has_bounds )
 	    {
-	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
-	      *numGridVals += ISEC2_RowLon(i);
+	      zaxisDefLbounds(zaxisID, lbounds);
+	      zaxisDefUbounds(zaxisID, ubounds);
+	    }
+
+	  if ( zaxistype == ZAXIS_HYBRID )
+	    {
+	      if ( vctsize > 0 )
+		zaxisDefVct(zaxisID, vctsize, vct);
+	      else
+		Warning("VCT missing");
 	    }
 	}
-      else
-	{
-	  ReducedGrid = FALSE;
-	}
+
+      nzaxis = vlistptr->nzaxis;
+      vlistptr->zaxisIDs[nzaxis] = zaxisID;
+      vlistptr->nzaxis++;
     }
 
-  ISEC2_GridType = GDS_GridType;
+  return (zaxisID);
+}
 
-  /*
-     Gaussian grid definition.
-  */
-  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
-       ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
-       ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-    {
-      ISEC2_NumLat    = GDS_NumLat;
-      if ( ! ReducedGrid )
-	{
-	  ISEC2_NumLon = GDS_NumLon;
-	  *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-	}
-      ISEC2_FirstLat  = GDS_FirstLat;
-      ISEC2_FirstLon  = GDS_FirstLon;
-      ISEC2_ResFlag   = GDS_ResFlag;
-      ISEC2_LastLat   = GDS_LastLat;
-      ISEC2_LastLon   = GDS_LastLon;
-      ISEC2_LonIncr   = GDS_LonIncr;
+/*
+ at Function  vlistCopyFlag
+ at Title     Copy some entries of a variable list
 
-      ISEC2_NumPar    = GDS_NumPar;
-      ISEC2_ScanFlag  = GDS_ScanFlag;
-      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-	{
-	  ISEC2_LatSP     = GDS_LatSP;
-	  ISEC2_LonSP     = GDS_LonSP;
-	  FSEC2_RotAngle  = GDS_RotAngle;
-	}
-      /*
-	if ( Lons != Longitudes || Lats != Latitudes )
-	Error("Latitude/Longitude Conflict");
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN     ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
-    {
-      /*
-      iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON     ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
-    {
-      /*
-      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
-    {
-      ISEC2_NumLon    = GDS_NumLon;
-      ISEC2_NumLat    = GDS_NumLat;
-      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      ISEC2_FirstLat  = GDS_FirstLat;
-      ISEC2_FirstLon  = GDS_FirstLon;
-      ISEC2_ResFlag   = GDS_ResFlag;
-      ISEC2_Lambert_Lov   = GDS_Lambert_Lov;
-      ISEC2_Lambert_dx    = GDS_Lambert_dx;
-      ISEC2_Lambert_dy    = GDS_Lambert_dy;
-      ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
-      ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
-      ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
-      ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
-      ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
-      ISEC2_ScanFlag      = GDS_ScanFlag;
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
-    {
-      ISEC2_PentaJ  = GDS_PentaJ; /* Truncation */
-      ISEC2_PentaK  = GDS_PentaK;
-      ISEC2_PentaM  = GDS_PentaM;
-      ISEC2_RepType = GDS_RepType;
-      ISEC2_RepMode = GDS_RepMode;
-      *numGridVals  = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
-      isec2[ 6] = 0;
-      isec2[ 7] = 0;
-      isec2[ 8] = 0;
-      isec2[ 9] = 0;
-      isec2[10] = 0;
-      /*
-      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
-    {
-      ISEC2_GME_NI2    = GDS_GME_NI2;
-      ISEC2_GME_NI3    = GDS_GME_NI3;
-      ISEC2_GME_ND     = GDS_GME_ND;
-      ISEC2_GME_NI     = GDS_GME_NI;
-      ISEC2_GME_AFlag  = GDS_GME_AFlag;
-      ISEC2_GME_LatPP  = GDS_GME_LatPP;
-      ISEC2_GME_LonPP  = GDS_GME_LonPP;
-      ISEC2_GME_LonMPL = GDS_GME_LonMPL;
-      ISEC2_GME_BFlag  = GDS_GME_BFlag;
-      *numGridVals  = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
-      /*
-      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else
-    {
-      ISEC2_NumLon = GDS_NumLon;
-      ISEC2_NumLat = GDS_NumLat;
-      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      Message("Gridtype %d unsupported", ISEC2_GridType);
-    }
+ at Prototype void vlistCopyFlag(int vlistID2, int vlistID1)
+ at Parameter
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
-  /*    vertical coordinate parameters for hybrid levels.     */
-  /*    get number of vertical coordinate parameters, if any. */
+ at Description
+The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 to vlistID2.
 
-  ISEC2_NumVCP = 0;
+ at EndFunction
+*/
+void vlistCopyFlag(int vlistID2, int vlistID1)
+{
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
 
-  isec2[17] = 0;
-  isec2[18] = 0;
+  vlist_copy(vlistptr2, vlistptr1);
 
-  if ( VertCoorTab == TRUE )
+  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+
+  if ( vlistptr1->vars )
     {
-      if ( ISEC0_GRIB_Version  == 0 )
-	{
-	  locnv = 32;
-	  ISEC2_NumVCP = (gdsLen - 32) >> 2;
-	}
+      int nvars = vlistptr1->nvars;
+      int nvars2 = 0;
+      int varID2;
+
+      vlistptr2->ngrids = 0;
+      vlistptr2->nzaxis = 0;
+
+      for ( int varID = 0; varID < nvars; varID++ )
+        nvars2 += (vars1[varID].flag != 0);
+
+      vlistptr2->nvars = nvars2;
+      vlistptr2->varsAllocated = nvars2;
+      if ( nvars2 > 0 )
+        vars2 = (var_t *)xmalloc((size_t)nvars2*sizeof(var_t));
       else
-	{
-	  locnv = GDS_PVPL - 1;
-	  ISEC2_NumVCP = GDS_NV;
-	}
-#if defined (SX)
-      lGribLen = 4*ISEC2_NumVCP;	      
-      lgrib    = (GRIBPACK*) malloc(lGribLen*sizeof(GRIBPACK));
+        vars2 = NULL;
 
-      igrib = &gds[locnv];
-      if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
-      for ( i = 0; i < ISEC2_NumVCP; i++ )
-	{
-	  iexp   = (lgrib[4*i  ]);
-	  imant  =((lgrib[4*i+1]) << 16) +
-	          ((lgrib[4*i+2]) <<  8) +
-	           (lgrib[4*i+3]);
-	  fsec2[10+i] = POW_2_M24 * imant * pow(16.0, (double)(iexp - 64));
-	}
+      vlistptr2->vars = vars2;
 
-      free(lgrib);
-#else
-      for ( i = 0; i < ISEC2_NumVCP; i++ )
-	{
-	  iexp   = (gds[locnv+4*i  ]);
-	  imant  =((gds[locnv+4*i+1]) << 16) +
-	          ((gds[locnv+4*i+2]) <<  8) +
-	           (gds[locnv+4*i+3]);
-	  fsec2[10+i] = decfp2(iexp,imant);
-	}
-#endif
-    }
+      varID2 = 0;
+      for ( int varID = 0; varID < nvars; varID++ )
+	if ( vars1[varID].flag )
+	  {
+	    vars2[varID2].flag = FALSE;
+	    int zaxisID = vars1[varID].zaxisID;
+	    int gridID  = vars1[varID].gridID;
 
-  return (gdsLen);
+	    memcpy(&vars2[varID2], &vars1[varID], sizeof(var_t));
+
+	    vars1[varID].fvarID = varID2;
+	    vars2[varID2].fvarID = varID;
+
+	    vars2[varID2].mvarID = varID2;
+
+            var_copy_entries(&vars2[varID2], &vars1[varID]);
+
+	    vars2[varID2].atts.nelems = 0;
+	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
+
+	    int nlevs  = zaxisInqSize(vars1[varID].zaxisID);
+	    int nlevs2 = 0;
+            if ( vars1[varID].levinfo )
+              for ( int levID = 0; levID < nlevs; levID++ )
+                nlevs2 += (vars1[varID].levinfo[levID].flag != 0);
+
+	    vars2[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs2 * sizeof(levinfo_t));
+
+	    if ( nlevs != nlevs2 )
+	      {
+		int nvct = 0;
+		double *lbounds = NULL, *ubounds = NULL;
+		const double *vct = NULL;
+                char ctemp[CDI_MAX_NAME];
+
+		zaxisID = vars1[varID].zaxisID;
+		double *levels = (double *)xmalloc((size_t)nlevs2 * sizeof (double));
+                int levID2 = 0;
+                if ( !vars1[varID].levinfo )
+                  cdiVlistCreateVarLevInfo(vlistptr1, varID);
+                for ( int levID = 0; levID < nlevs; ++levID )
+                  if ( vars1[varID].levinfo[levID].flag )
+                    {
+                      vars1[varID].levinfo[levID].flevelID = levID2;
+                      vars1[varID].levinfo[levID].mlevelID = levID2;
+                      levels[levID2++] = zaxisInqLevel(zaxisID, levID);
+                    }
+		int zaxisType = zaxisInqType(zaxisID);
+
+		if ( zaxisType == ZAXIS_HYBRID )
+		  {
+		    nvct = zaxisInqVctSize(zaxisID);
+		    vct  = zaxisInqVctPtr(zaxisID);
+		  }
+
+                if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+                  {
+                    lbounds = (double *)xmalloc(2 * (size_t)nlevs2 * sizeof (double));
+                    ubounds = lbounds + nlevs2;
+
+                    double *lbounds1 = (double *)xmalloc(2 * (size_t)nlevs * sizeof (double)),
+                      *ubounds1 = lbounds1 + nlevs;
+
+                    zaxisInqLbounds(zaxisID, lbounds1);
+                    zaxisInqUbounds(zaxisID, ubounds1);
+
+                    int levID2 = 0;
+                    for ( int levID = 0; levID < nlevs; ++levID )
+                      if ( vars1[varID].levinfo[levID].flag )
+                        {
+                          lbounds[levID2] = lbounds1[levID];
+                          ubounds[levID2] = ubounds1[levID];
+                          levID2++;
+                        }
+
+                    free(lbounds1);
+                  }
+
+		int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct);
+		free(levels);
+                free(lbounds);
+
+                zaxisInqName(zaxisID, ctemp);
+                zaxisDefName(zaxisID2, ctemp);
+                zaxisInqLongname(zaxisID, ctemp);
+                zaxisDefLongname(zaxisID2, ctemp);
+                zaxisInqUnits(zaxisID, ctemp);
+                zaxisDefUnits(zaxisID2, ctemp);
+
+		zaxisID = zaxisID2;
+		vars2[varID2].zaxisID = zaxisID2;
+	      }
+
+	    for ( int levID = 0; levID < nlevs2; levID++ )
+	      {
+		vars2[varID2].levinfo[levID].flag  = FALSE;
+		vars2[varID2].levinfo[levID].index = -1;
+	      }
+
+	    int levID2 = 0;
+	    for ( int levID = 0; levID < nlevs; levID++ )
+	      if ( vars1[varID].levinfo[levID].flag )
+		{
+		  vars2[varID2].levinfo[levID2].flevelID = levID;
+		  vars2[varID2].levinfo[levID2].mlevelID = levID;
+		  levID2++;
+		}
+
+            vlistAdd2GridIDs(vlistptr2, gridID);
+            vlistAdd2ZaxisIDs(vlistptr2, zaxisID);
+
+	    varID2++;
+	  }
+    }
 }
 
-static
-int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
-			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
+/*
+ at Function  vlistCat
+ at Title     Concatenate two variable lists
+
+ at Prototype void vlistCat(int vlistID2, int vlistID1)
+ at Parameter
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
+
+ at Description
+Concatenate the variable list vlistID1 at the end of vlistID2.
+
+ at EndFunction
+*/
+void vlistCat(int vlistID2, int vlistID1)
 {
-  unsigned char *igrib;
-  int lspherc = FALSE, lcomplex = FALSE;
-  int lcompress;
-  int jup, kup, mup;
-  int locnd;
-  long jlend;
-  long i;
-  int bds_flag, jscale, imiss;
-  int bds_ubits;
-  int ioff = 0;
-  int iexp, imant;
-  int zoff;
-  int bds_head = 11;
-  double zscale = 0.;
-  T fmin = 0.;
-  T *fpdata = fsec4;
-  int bdsLen;
-  extern int CGRIBEX_Fix_ZSE;
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
+  int nvars1 = vlistptr1->nvars;
+  int nvars2 = vlistptr2->nvars;
+  int nvars = nvars1 + nvars2;
+  vlistptr2->nvars = nvars;
 
-  *iret = 0;
-  igrib = bds;
+  if ( nvars > vlistptr2->varsAllocated )
+    {
+      vlistptr2->varsAllocated = nvars;
+      vars2 = xrealloc(vars2, (size_t)nvars*sizeof(var_t));
+      vlistptr2->vars = vars2;
+    }
+  memcpy(vars2+nvars2, vars1, (size_t)nvars1 * sizeof(var_t));
 
-  memset(isec4, 0, 42*sizeof(int));
+  for ( int varID = 0; varID < nvars1; varID++ )
+    {
+      int varID2 = varID + nvars2;
+      vars1[varID].fvarID = varID2;
+      vars2[varID2].fvarID = varID;
 
-  /* get length of binary data block. */
+      vars1[varID].mvarID = varID2;
+      vars2[varID2].mvarID = varID;
 
-  bdsLen = BDS_Len;
-  /*
-    If a very large product, the section 4 length field holds
-    the number of bytes in the product after section 4 upto
-    the end of the padding bytes.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( llarge ) bdsLen = bdsLenIn - bdsLen;
+      if ( vars1[varID].param < 0 )
+	{
+	  int pnum, pcat, pdis;
+	  cdiDecodeParam(vars1[varID].param, &pnum, &pcat, &pdis);
+	  pnum = -(varID2+1);
+	  vars2[varID2].param = cdiEncodeParam(pnum, pcat, pdis);
+	}
 
-  /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
+      var_copy_entries(&vars2[varID2], &vars1[varID]);
 
-  bds_flag = BDS_Flag;
+      int nlevs = zaxisInqSize(vars1[varID].zaxisID);
+      if ( vars1[varID].levinfo )
+        {
+          vars2[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs * sizeof(levinfo_t));
+          memcpy(vars2[varID2].levinfo, vars1[varID].levinfo,
+                 (size_t)nlevs * sizeof(levinfo_t));
+        }
 
-  /* 0------- grid point           */
-  /* 1------- spherical harmonics  */
+      vars2[varID2].atts.nelems = 0;
+      vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
-  lspherc = bds_flag >> 7;
+      vlistAdd2GridIDs(vlistptr2, vars1[varID].gridID);
+      vlistAdd2ZaxisIDs(vlistptr2, vars1[varID].zaxisID);
+    }
+}
 
-  if ( lspherc ) isec4[2] = 128;
-  else           isec4[2] = 0;
+/*
+ at Function  vlistMerge
+ at Title     Merge two variable lists
 
-  /* -0------  simple packing */
-  /* -1------ complex packing */
+ at Prototype void vlistMerge(int vlistID2, int vlistID1)
+ at Parameter
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
-  lcomplex = (bds_flag >> 6)&1;
+ at Description
+Merge the variable list vlistID1 to the variable list vlistID2.
 
-  if ( lcomplex ) isec4[3] = 64;
-  else            isec4[3] =  0;
+ at EndFunction
+*/
+void vlistMerge(int vlistID2, int vlistID1)
+{
+  int varID = 0;
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
+  int nvars1 = vlistptr1->nvars;
+  int nvars2 = vlistptr2->nvars;
 
-  /* ---0---- No additional flags */
-  /* ---1---- No additional flags */
+  if ( nvars1 == nvars2 )
+    {
+      for ( varID = 0; varID < nvars2; varID++ )
+	{
+          int ngp1 = gridInqSize(vars1[varID].gridID);
+          int ngp2 = gridInqSize(vars2[varID].gridID);
+          if ( ngp1 != ngp2 ) break;
 
-  lcompress = (bds_flag >> 4)&1; /* compress */
+	  if ( vars1[varID].name && vars2[varID].name )
+	    {
+	      if ( strcmp(vars1[varID].name, vars2[varID].name) != 0 ) break;
+	    }
+	  else
+	    {
+	      if ( vars1[varID].param != vars2[varID].param ) break;
+	    }
+	}
+    }
 
-  if ( lcompress )
-    { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
-  else
-    { isec4[5] =  0; isec4[6] = 0;     zoff =  0; }
+  if ( varID == nvars2 ) /* same variables in vlistID1 and vlistID2 */
+    {
+      for ( varID = 0; varID < nvars2; varID++ )
+        {
+          vars1[varID].fvarID = varID;
+          vars2[varID].fvarID = varID;
 
-  /* ----++++ number of unused bits at end of section) */
+          vars1[varID].mvarID = varID;
+          vars2[varID].mvarID = varID;
 
-  bds_ubits = bds_flag & 0xF;
-  
-  /* scale factor (2 bytes) */;
+          int nlevs1 = zaxisInqSize(vars1[varID].zaxisID);
+          int nlevs2 = zaxisInqSize(vars2[varID].zaxisID);
 
-  jscale = BDS_BinScale;
+          int nlevs = nlevs1 + nlevs2;
 
-  /* check for missing data indicators. */
+          /*
+          fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
+          */
+          if ( vars1[varID].levinfo )
+            {
+              vars2[varID].levinfo = (levinfo_t*)xrealloc(vars2[varID].levinfo,
+                                     (size_t)nlevs * sizeof(levinfo_t));
 
-  iexp  = bds[ 6];
-  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+              memcpy(vars2[varID].levinfo+nlevs2, vars1[varID].levinfo,
+                     (size_t)nlevs1 * sizeof(levinfo_t));
+            }
+          else
+            cdiVlistCreateVarLevInfo(vlistptr1, varID);
+
+	  for ( int levID = 0; levID < nlevs1; levID++ )
+            vars1[varID].levinfo[levID].mlevelID = nlevs2 + levID;
+	}
+
+      int *lvar = (int *)xcalloc((size_t)nvars2, sizeof(int));
+
+      for ( varID = 0; varID < nvars2; varID++ )
+        {
+          if ( lvar[varID] == TRUE ) continue;
 
-  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+          int zaxisID1 = vars1[varID].zaxisID;
+          int zaxisID2 = vars2[varID].zaxisID;
+          /*
+          nlevs1 = zaxisInqSize(vars1[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vars2[varID].zaxisID);
+          */
+          int nlevs1 = zaxisInqSize(zaxisID1);
+          int nlevs2 = zaxisInqSize(zaxisID2);
+          /*
+          fprintf(stderr, "zaxis %d %d %d %d\n", zaxisID1, zaxisID2, nlevs1, nlevs2);
+          */
+          int nlevs = nlevs1 + nlevs2;
 
-  /* convert reference value and scale factor. */
+          int zaxisID = zaxisDuplicate(zaxisID2);
 
-  if ( ! (dfunc == 'J') )
-    if ( imiss == 0 )
-      {
-	fmin = BDS_RefValue;
-	
-	if ( jscale < 0 )
-	  zscale = 1.0/intpow2(-jscale);
-	else
-	  zscale = intpow2(jscale);
-      }
+          zaxisResize(zaxisID, nlevs);
 
-  /* get number of bits in each data value. */
+          double *levels = (double *)xmalloc((size_t)nlevs1 * sizeof(double));
 
-  ISEC4_NumBits = BDS_NumBits;
+          zaxisInqLevels(zaxisID1, levels);
+          /*
+          for ( levID = 0; levID < nlevs1; levID++ )
+            fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
+          */
+          for ( int levID = 0; levID < nlevs1; levID++ )
+            zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
 
-  /* octet number of start of packed data */
-  /* calculated from start of block 4 - 1 */
+          free(levels);
 
-  locnd = zoff + bds_head;
+          for ( int index = 0; index < vlistptr2->nzaxis; index++ )
+            if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
+              vlistptr2->zaxisIDs[index] = zaxisID;
 
-  /* if data is in spherical harmonic form, distinguish   */
-  /* between simple/complex packing (lcomplex = 0/1)      */
+          for ( int varID2 = 0; varID2 < nvars2; varID2++ )
+            if ( lvar[varID2] == FALSE && vars2[varID2].zaxisID == zaxisID2 )
+              {
+                vars2[varID2].zaxisID = zaxisID;
+                lvar[varID2] = TRUE;
+              }
+        }
 
-  if ( lspherc )
+      free(lvar);
+    }
+  else
     {
-      if ( !lcomplex )
-	{
-	  /*    no unpacked binary data present */
+      vlistCat(vlistID2, vlistID1);
+    }
+}
 
-	  jup = kup = mup = 0;
+/*
+ at Function  vlistNvars
+ at Title     Number of variables in a variable list
 
-	  /*    octet number of start of packed data */
-	  /*    calculated from start of block 4 - 1 */
+ at Prototype int vlistNvars(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
-	  ioff   = 1;
-	  locnd += 4*ioff;  /* RealCoef */
+ at Description
+The function @func{vlistNvars} returns the number of variables in the variable list vlistID.
 
-	  /*    get real (0,0) coefficient in grib format and     */
-	  /*    convert to floating point.                        */
+ at Result
+ at func{vlistNvars} returns the number of variables in a variable list.
 
-	  if ( dfunc != 'J' )
-	    {
-	      if ( imiss ) *fpdata++ = 0.0;
-	      else         *fpdata++ = BDS_RealCoef;
-	    }
-	}
-      else /* complex packed spherical harmonics */
-	{
-	  isec4[15] = BDS_PackData;
-	  /*    scaling factor */
-	  isec4[16] = BDS_Power;
+ at EndFunction
+*/
+int vlistNvars(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->nvars);
+}
 
-	  /*    pentagonal resolution parameters of the */
-	  /*    unpacked section of data field          */
 
-	  jup = bds[zoff+15];
-	  kup = bds[zoff+16];
-	  mup = bds[zoff+17];
+int vlistNrecs(int vlistID)
+{
+  int nrecs = 0;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-	  isec4[zoff+17] = jup;
-	  isec4[zoff+18] = kup;
-	  isec4[zoff+19] = mup;
+  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
+    nrecs +=  zaxisInqSize(vlistptr->vars[varID].zaxisID);
 
-	  /*    unpacked binary data */
+  return (nrecs);
+}
 
-	  locnd += 4; /* 2 + power */
-	  locnd += 3; /* j, k, m   */
-	  ioff   = (jup+1)*(jup+2);
 
-	  if ( dfunc != 'J' )
-	    for ( i = 0; i < ioff; i++ )
-	      {
-		if ( imiss )
-		  *fpdata++ = 0.0;
-		else
-		  {
-		    iexp   = (bds[locnd+4*i  ]);
-		    imant  =((bds[locnd+4*i+1]) << 16) +
-		            ((bds[locnd+4*i+2]) <<  8) +
-		             (bds[locnd+4*i+3]);
+int vlistNumber(int vlistID)
+{
+  int number, number2, datatype;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-		    *fpdata++ = decfp2(iexp,imant);
-		  }
-	      }
-	  
-	  locnd += 4*ioff;  /* RealCoef */
-	}
-    }
+  datatype = vlistptr->vars[0].datatype;
+  if (  datatype== DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    number = CDI_COMP;
   else
+    number = CDI_REAL;
+
+  for ( int varID = 1; varID < vlistptr->nvars; varID++ )
     {
-      if ( lcomplex )
-	{
-	  *iret = 1999;
-	  gprintf(__func__, " Second order packed grids unsupported!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
-    }
+      datatype = vlistptr->vars[varID].datatype;
+      if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+        number2 = CDI_COMP;
+      else
+        number2 = CDI_REAL;
 
-  /* Decode data values to floating point and store in fsec4.  */
-  /* First calculate the number of data values.                */
-  /* Take into account that spherical harmonics can be packed  */
-  /* simple (lcomplex = 0) or complex (lcomplex = 1)           */
+      if ( number2 != number )
+        {
+          number = CDI_BOTH;
+          break;
+        }
+    }
 
-  jlend = bdsLen - locnd;
+  return (number);
+}
 
-  if ( ISEC4_NumBits == 0 )
-    {
-      if ( jlend > 1 )
-	{
-	  *iret = 2001;
-	  gprintf(__func__, " Number of bits per data value = 0!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
+/*
+ at Function  vlistNgrids
+ at Title     Number of grids in a variable list
 
-      if ( numGridVals == 0 )
-	{
-	  *iret = 2002;
-	  gprintf(__func__, " Constant field unsupported for this grid type!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
+ at Prototype int vlistNgrids(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
-      jlend = numGridVals;
-      jlend -= ioff;
-    }
-  else
-    {
-      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
-    }
+ at Description
+The function @func{vlistNgrids} returns the number of grids in the variable list vlistID.
 
-  ISEC4_NumValues        = jlend + ioff;
-  ISEC4_NumNonMissValues = 0;
+ at Result
+ at func{vlistNgrids} returns the number of grids in a variable list.
 
-  if ( lcompress )
-    {
-      size_t len;
+ at EndFunction
+*/
+int vlistNgrids(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
-	len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
-      else
-        len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
+  return (vlistptr->ngrids);
+}
 
-      ISEC4_NumValues = len*8/ISEC4_NumBits;
+/*
+ at Function  vlistNzaxis
+ at Title     Number of zaxis in a variable list
 
-      if ( lspherc )
-	{
-	  if ( lcomplex )
-	    ISEC4_NumValues += ioff;
-	  else
-	    ISEC4_NumValues++;
-	}
-    }
+ at Prototype int vlistNzaxis(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
-  if ( dfunc == 'J' ) return (bdsLen);
+ at Description
+The function @func{vlistNzaxis} returns the number of zaxis in the variable list vlistID.
 
-  /* check length of output array. */
-  
-  if ( ISEC4_NumValues > fsec4len )
-    {
-      *iret = 710;
-      gprintf(__func__, " Output array too small. Length = %d", fsec4len);
-      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
-      gprintf(__func__, " Return code =  %d", *iret);
-      return (0);
-    }
+ at Result
+ at func{vlistNzaxis} returns the number of zaxis in a variable list.
 
-  if ( imiss ) memset((char *)fpdata, 0, jlend*sizeof(T));
-  else
-    {
-      igrib += locnd;
+ at EndFunction
+*/
+int vlistNzaxis(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
-    }
+  return (vlistptr->nzaxis);
+}
 
-  if ( lspherc && lcomplex )
-    {
-      int pcStart, pcScale;
-      pcStart = isec4[19];
-      pcScale = isec4[16];
-      TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
-      TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
-    }
 
-  if ( CGRIBEX_Fix_ZSE )  /* Fix ZeroShiftError of simple packed spherical harmonics */
-    if ( lspherc && !lcomplex )
-      {
-        /* 20100705: Fix ZeroShiftError - Edi Kirk */
-	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
-	  {
-	    T zserr = fsec4[1];
-	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
-	  }
-      }
+void vlistDefNtsteps(int vlistID, int nts)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( decscale )
+  if (vlistptr->ntsteps != nts)
     {
-      T scale = (T) pow(10.0, (double)-decscale);
-      for ( i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
+      vlistptr->ntsteps = nts;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-
-  return (bdsLen);
 }
 
-
-void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
-			     T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
-			     int kleng, int *kword, int dfunc, int *iret)
+// This function is used in CDO!
+int vlistNtsteps(int vlistID)
 {
-  UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
-  int gribLen = 0;
-  int gdsIncluded = FALSE;
-  int bmsIncluded = FALSE;
-  int bitmapSize = 0;
-  int imaskSize = 0;
-  int ldebug = FALSE;
-  int llarge = FALSE, l_iorj = FALSE;
-  int lsect2 = FALSE, lsect3 = FALSE;
-  int numGridVals = 0;
-  static int lmissvalinfo = 1;
-
-  UNUSED(kleng);
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *iret = 0;
+  return (int)vlistptr->ntsteps;
+}
 
-  grsdef();
+static void
+vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
+{
+  char paramstr[32];
 
-  ISEC2_Reduced = FALSE;
+  fprintf ( fp, "#\n# vlistID %d\n#\n", vlistptr->self);
 
-  /*
-    ----------------------------------------------------------------
-    IS Indicator Section (Section 0)
-    ----------------------------------------------------------------
-  */
-  is = (unsigned char *) &kgrib[0];
+  int nvars = vlistptr->nvars;
 
-  isLen = decodeIS(is, isec0, iret);
+  fprintf(fp, "nvars   %d\n"
+          "ngrids  %d\n"
+          "nzaxis  %d\n"
+          "taxisID %d\n"
+          "instID  %d\n"
+          "modelID %d\n"
+          "tableID %d\n",
+          nvars, vlistptr->ngrids, vlistptr->nzaxis, vlistptr->taxisID,
+          vlistptr->instID, vlistptr->modelID, vlistptr->tableID);
 
-  /*
-    If count is negative, have to rescale by factor of -120.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( ISEC0_GRIB_Len < 0 )
+  if ( nvars > 0 )
     {
-      if ( ldebug )
-	gprintf(__func__, "Special case, negative length multiplied by -120");
-      llarge = TRUE;
-      ISEC0_GRIB_Len *= (-120);
-    }
-  /*
-    When decoding or calculating length, previous editions
-    of the GRIB code must be taken into account.
+      fprintf(fp, " varID param    gridID zaxisID tsteptype flag "
+              " name     longname iorank\n");
+      for ( int varID = 0; varID < nvars; varID++ )
+        {
+          int param = vlistptr->vars[varID].param;
+          int gridID = vlistptr->vars[varID].gridID;
+          int zaxisID = vlistptr->vars[varID].zaxisID;
+	  int tsteptype = vlistptr->vars[varID].tsteptype;
+          const char *name = vlistptr->vars[varID].name;
+          const char *longname = vlistptr->vars[varID].longname;
+          const char *units = vlistptr->vars[varID].units;
+          int flag = vlistptr->vars[varID].flag;
+          int iorank = vlistptr->vars[varID].iorank;
 
-    In the table below, covering sections 0 and 1 of the GRIB
-    code, octet numbering is from the beginning of the GRIB
-    message;
-    * indicates that the value is not available in the code edition;
-    R indicates reserved, should be set to 0;
-    Experimental edition is considered as edition -1.
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          fprintf(fp, "%6d %-8s %6d %6d %6d %5d %-8s"
+                  " %s %6d",
+                  varID, paramstr, gridID, zaxisID, tsteptype, flag,
+                  name ? name : "", longname ? longname : "",
+                  iorank);
 
-    GRIB code edition -1 has fixed length of 20 octets for
-    section 1, the length not included in the message.
-    GRIB code edition 0 has fixed length of 24 octets for
-    section 1, the length being included in the message.
-    GRIB code edition 1 can have different lengths for section
-    1, the minimum being 28 octets, length being included in
-    the message.
+          if ( units ) fprintf(fp, "   [%s]", units);
+          fputs("\n", fp);
+        }
 
-                                         Octet numbers for code
-                                                  editions
+      fputs("\n"
+            " varID  levID fvarID flevID mvarID mlevID  index  dtype  flag  level\n", fp);
+      for ( int varID = 0; varID < nvars; varID++ )
+        {
+          int zaxisID = vlistptr->vars[varID].zaxisID;
+          int nlevs = zaxisInqSize(zaxisID);
+          int fvarID = vlistptr->vars[varID].fvarID;
+          int mvarID = vlistptr->vars[varID].mvarID;
+          int dtype    = vlistptr->vars[varID].datatype;
+          for ( int levID = 0; levID < nlevs; levID++ )
+            {
+              levinfo_t li;
+              if (vlistptr->vars[varID].levinfo)
+                li = vlistptr->vars[varID].levinfo[levID];
+              else
+                li = DEFAULT_LEVINFO(levID);
+              int flevID = li.flevelID;
+              int mlevID = li.mlevelID;
+              int index  = li.index;
+              int flag   = li.flag;
+              double level  = zaxisInqLevel(zaxisID, levID);
 
-                 Contents.                   -1      0      1
-                 ---------                ----------------------
-       Letters GRIB                          1-4    1-4    1-4
-       Total length of GRIB message.          *      *     5-7
-       GRIB code edition number               *      *      8
-       Length of Section 1.                   *     5-7    9-11
-       Reserved octet (R).                    *      8(R)   *
-       Version no. of Code Table 2.           *      *     12
-       Identification of centre.              5      9     13
-       Generating process.                    6     10     14
-       Grid definition .                      7     11     15
-       Flag (Code Table 1).                   8     12     16
-       Indicator of parameter.                9     13     17
-       Indicator of type of level.           10     14     18
-       Height, pressure etc of levels.      11-12  15-16  19-20
-       Year of century.                      13     17     21
-       Month.                                14     18     22
-       Day.                                  15     19     23
-       Hour.                                 16     20     24
-       Minute.                               17     21     25
-       Indicator of unit of time.            18     22     26
-       P1 - Period of time.                  19     23     27
-       P2 - Period of time                  20(R)   24     28
-       or reserved octet (R).
-       Time range indicator.                21(R)   25     29
-       or reserved octet (R).
-       Number included in average.       22-23(R)  26-27  30-31
-       or reserved octet (R).
-       Number missing from average.         24(R)  28(R)   32
-       or reserved octet (R).
-       Century of data.                       *      *     33
-       Designates sub-centre if not 0.        *      *     34
-       Decimal scale factor.                  *      *    35-36
-       Reserved. Set to 0.                    *      *    37-48
-       (Need not be present)
-       For originating centre use only.       *      *    49-nn
-       (Need not be present)
+              fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
+                      varID, levID, fvarID, flevID, mvarID, mlevID, index,
+                      dtype, flag, level);
+            }
+        }
 
-    Identify which GRIB code edition is being decoded.
+      fputs("\n"
+            " varID  size iorank\n", fp);
+      for ( int varID = 0; varID < nvars; varID++ )
+        fprintf(fp, "%3d %8d %6d\n", varID,
+                zaxisInqSize(vlistptr->vars[varID].zaxisID)
+                * gridInqSize(vlistptr->vars[varID].gridID),
+                vlistptr->vars[varID].iorank);
+    }
+}
 
-    In GRIB edition 1, the edition number is in octet 8.
-    In GRIB edition 0, octet 8 is reserved and set to 0.
-    In GRIB edition -1, octet 8 is a flag field and can have a
-    a valid value of 0, 1, 2 or 3.
 
-    However, GRIB edition number 0 has a fixed
-    length of 24, included in the message, for section 1, so
-    if the value extracted from octets 5-7 is 24 and that from
-    octet 8 is 0, it is safe to assume edition 0 of the code.
+void vlistPrint(int vlistID)
+{
+  if ( vlistID == CDI_UNDEFID ) return;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  vlistPrintKernel(vlistptr, stdout);
+}
 
-  */
-  if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
-    {
-      /*
-	Set length of GRIB message to missing data value.
-      */
-      ISEC0_GRIB_Len = 0;
-    }
-  /*
-    If Grib Edition 1 and only length is required, go to section 9.
-  */
-  if ( dfunc == 'L' ) goto LABEL900;
+/*
+ at Function  vlistDefTaxis
+ at Title     Define the time axis
 
-  /*
-    ----------------------------------------------------------------
-    PDS Product Definition Section (Section 1)
-    ----------------------------------------------------------------
-  */ 
-  pds = is + isLen;
+ at Prototype void vlistDefTaxis(int vlistID, int taxisID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}.
 
-  pdsLen = decodePDS(pds, isec0, isec1);
+ at Description
+The function @func{vlistDefTaxis} defines the time axis of a variable list.
 
-  /*
-    ----------------------------------------------------------------
-    GDS Grid Description Section (Section 2)
-    ----------------------------------------------------------------
-  */
-  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ at EndFunction
+*/
+void vlistDefTaxis(int vlistID, int taxisID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( gdsIncluded )
+  if (vlistptr->taxisID != taxisID)
     {
-      gds = is + isLen + pdsLen;
-
-      gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
+      //FIXME: This code seems to leak a taxis_t object if `vlistptr->taxisID` was valid before the call to vlistDefTaxis.
+      vlistptr->taxisID = taxisID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+/*
+ at Function  vlistInqTaxis
+ at Title     Get the time axis
 
-  isec3[0] = 0;
-  if ( bmsIncluded )
-    {
-      bms = is + isLen + pdsLen + gdsLen;
+ at Prototype int vlistInqTaxis(int vlistID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
-      bmsLen = BMS_Len;
-      imaskSize = (bmsLen - 6)<<3;
-      bitmapSize = imaskSize - BMS_UnusedBits;
-      /*
-      fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
-      */
-    }
+ at Description
+The function @func{vlistInqTaxis} returns the time axis of a variable list.
 
-  /*
-    ----------------------------------------------------------------
-    BDS Binary Data Section (Section 4)
-    ----------------------------------------------------------------
-  */
-  bds = is + isLen + pdsLen + gdsLen + bmsLen;
+ at Result
+ at func{vlistInqTaxis} returns an identifier to the time axis.
 
-  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+ at EndFunction
+*/
+int vlistInqTaxis(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
-				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
+  return (vlistptr->taxisID);
+}
 
-  if ( *iret != 0 ) return;
 
-  ISEC4_NumNonMissValues = ISEC4_NumValues;
+void vlistDefTable(int vlistID, int tableID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( bitmapSize > 0 )
+  if (vlistptr->tableID != tableID)
     {
-      if ( dfunc != 'L' && dfunc != 'J' )
-	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
-	  {
-	    lmissvalinfo = 0;
-	    FSEC3_MissVal = GRIB_MISSVAL;
-	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
-	  }
+      vlistptr->tableID = tableID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-      /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
-      ISEC4_NumValues        = bitmapSize;
 
-      if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
-	{
-	  long i, j;
-	  GRIBPACK *pbitmap;
-	  GRIBPACK bitmap;
-	  GRIBPACK *imask;
+int vlistInqTable(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-	  /*
-	  unsigned char *bitmap;
-	  bitmap = BMS_Bitmap;
-	  j = ISEC4_NumNonMissValues;
-	  for ( i = ISEC4_NumValues-1; i >= 0; i-- )
-	    {
-	      if ( (bitmap[i/8]>>(7-(i&7)))&1 )
-		fsec4[i] = fsec4[--j];
-	      else
-		fsec4[i] = FSEC3_MissVal;
-	    }
-	  */
+  return (vlistptr->tableID);
+}
 
-	  imask = (GRIBPACK*) malloc(imaskSize*sizeof(GRIBPACK));
 
-#if defined (VECTORCODE)
-	  (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
-	  pbitmap = imask;
-#else
-	  pbitmap = BMS_Bitmap;
-#endif
+void vlistDefInstitut(int vlistID, int instID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-	  for ( i = imaskSize/8-1; i >= 0; i-- )
-	    {
-	      bitmap = pbitmap[i];
-	      imask[i*8+0] = 1 & (bitmap >> 7);
-	      imask[i*8+1] = 1 & (bitmap >> 6);
-	      imask[i*8+2] = 1 & (bitmap >> 5);
-	      imask[i*8+3] = 1 & (bitmap >> 4);
-	      imask[i*8+4] = 1 & (bitmap >> 3);
-	      imask[i*8+5] = 1 & (bitmap >> 2);
-	      imask[i*8+6] = 1 & (bitmap >> 1);
-	      imask[i*8+7] = 1 & (bitmap);
-	    }
+  if (vlistptr->instID != instID)
+    {
+      vlistptr->instID = instID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-	  j = 0;
-	  for ( i = 0; i < ISEC4_NumValues; i++ )
-	    if ( imask[i] ) j++;
 
-	  if ( ISEC4_NumNonMissValues != j )
-	    {
-	      if ( dfunc != 'J' && ISEC4_NumBits != 0 )
-		Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
-			j, ISEC4_NumNonMissValues);
+int vlistInqInstitut(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-	      ISEC4_NumNonMissValues = j;
-	    }
+  int instID = vlistptr->instID;
 
-	  if ( dfunc != 'J' )
-	    {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-	      for ( i = ISEC4_NumValues-1; i >= 0; i-- )
-		fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
-	    }
+  if ( instID == CDI_UNDEFID )
+    {
+      instID  = vlistInqVarInstitut(vlistID, 0);
 
-	  free(imask);
-	}
+      for ( int varID = 1; varID < vlistptr->nvars; varID++ )
+        if ( instID != vlistInqVarInstitut(vlistID, varID) )
+          {
+            instID = CDI_UNDEFID;
+            break;
+      }
+      vlistDefInstitut(vlistID, instID);
     }
 
-  if ( ISEC2_Reduced )
-    {
-      int nlon, nlat;
-      int lsect3, lperio = 1, lveggy;
-      int ilat;
-      int nvalues = 0;
-      int dlon;
-
-      nlat = ISEC2_NumLat;
-      nlon = ISEC2_RowLonPtr[0];
-      for ( ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
-      for ( ilat = 1; ilat < nlat; ++ilat )
-	if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+  return (instID);
+}
 
-      dlon = ISEC2_LastLon-ISEC2_FirstLon;
-      if ( dlon < 0 ) dlon += 360000;
-	  
-      if ( nvalues != ISEC4_NumValues )
-	{
-	  *iret = -801;
-	}
-      //printf("nlat %d  nlon %d \n", nlat, nlon);
-      //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
 
-      if ( dfunc == 'R' && *iret == -801 )
-	gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
-		ISEC4_NumValues, nvalues);
-      
-      if ( dfunc == 'R' && *iret != -801 )
-	{
-	  ISEC2_Reduced = 0;
-	  ISEC2_NumLon = nlon;
-	  ISEC4_NumValues = nlon*nlat;
+void vlistDefModel(int vlistID, int modelID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-	  lsect3 = bitmapSize > 0;
-	  lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) && 
-	          ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) || 
-	           (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30));
-	
-	  (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
-	      
-	  if ( bitmapSize > 0 )
-	    {
-	      long i;
-	      int j = 0;
-	      
-	      for ( i = 0; i < ISEC4_NumValues; i++ )
-		if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
-		  
-	      ISEC4_NumNonMissValues = j;
-	    }
-	}
+  if (vlistptr->modelID != modelID)
+    {
+      vlistptr->modelID = modelID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
 
-  if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
-  esLen = 4;
-
-  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
+int vlistInqModel(int vlistID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( ISEC0_GRIB_Len )
-    if ( ISEC0_GRIB_Len < gribLen )
-      Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
+  int modelID = vlistptr->modelID;
 
-  ISEC0_GRIB_Len = gribLen;
+  if ( modelID == CDI_UNDEFID )
+    {
+      modelID = vlistInqVarModel(vlistID, 0);
 
-  *kword = gribLen / sizeof(int);
-  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
+      for ( int varID = 1; varID < vlistptr->nvars; varID++ )
+        if ( modelID != vlistInqVarModel(vlistID, varID) )
+          {
+            modelID = CDI_UNDEFID;
+            break;
+          }
 
-  /*
-    ----------------------------------------------------------------
-    Section 9 . Abort/return to calling routine.
-    ----------------------------------------------------------------
-  */
- LABEL900:;
+      vlistDefModel(vlistID, modelID);
+    }
 
-  if ( ldebug )
-    {
-      gprintf(__func__, "Section 9.");
-      gprintf(__func__, "Output values set -");
+  return (modelID);
+}
 
-      gribPrintSec0(isec0);
-      gribPrintSec1(isec0, isec1);
-      /*
-	Print section 2 if present.
-      */
-      if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
 
-      if ( ! l_iorj )
-	{
-	  /*
-	    Print section 3 if present.
-	  */
-	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+int vlistGridsizeMax(int vlistID)
+{
+  int gridsizemax = 0;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
-	  /*
-	    Special print for 2D spectra wave field real values in
-	    section 4
-	  */
-	  if ( (isec1[ 0] ==  140) && 
-	       (isec1[ 1] ==   98) && 
-	       (isec1[23] ==    1) && 
-	       ((isec1[39] == 1045) || (isec1[39] == 1081))  && 
-	       ((isec1[ 5] ==  250) || (isec1[ 5] ==  251)) )
-	    gribPrintSec4Wave(isec4);
-	}
+  for ( int index = 0 ; index < vlistptr->ngrids ; index++ )
+    {
+      int gridID = vlistptr->gridIDs[index];
+      int gridsize = gridInqSize(gridID);
+      if ( gridsize > gridsizemax ) gridsizemax = gridsize;
     }
+
+  return (gridsizemax);
 }
 
-#endif /* T */
 
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
+int vlistGrid(int vlistID, int index)
+{
+  int gridID = CDI_UNDEFID;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-static 
-int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
+  if ( index < vlistptr->ngrids && index >= 0 )
+    gridID = vlistptr->gridIDs[index];
+
+  return (gridID);
+}
+
+
+int vlistGridIndex(int vlistID, int gridID)
 {
-  /* int imisng = 0; */
-  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
-  int  locnv = 0, locnl;
-  int  jlenl;
-  long i;
-  int iexp, imant;
-  int ipvpl, ipl;
-  int gdsLen = 0;
-#if defined (VECTORCODE)
-  unsigned char *igrib;
-  GRIBPACK *lgrib = NULL;
-  size_t lGribLen = 0;
-#endif
+  int index;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *numGridVals = 0;
+  for ( index = 0 ; index < vlistptr->ngrids ; index++ )
+    if ( gridID == vlistptr->gridIDs[index] ) break;
 
-  memset(isec2, 0, 22*sizeof(int));
+  if ( index == vlistptr->ngrids ) index = -1;
 
-  gdsLen = GDS_Len;
+  return (index);
+}
 
-  ipvpl = GDS_PVPL;
-  if ( ipvpl == 0 ) ipvpl = 0xFF;
 
-  if ( ipvpl != 0xFF )
-    { /* Either vct or reduced grid */
-      if ( GDS_NV != 0 )
-	{ /* we have vct */
-	  VertCoorTab = TRUE;
-	  ipl =  4*GDS_NV + ipvpl - 1;
-	  if ( ipl < gdsLen )
-	    {
-	      ReducedGrid = TRUE;
-	    }
-	}
-      else
-	{
-	  VertCoorTab = FALSE;
-	  ReducedGrid = TRUE;
-	}
-      /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
-    }
- 
-  if ( ISEC0_GRIB_Version == 0 )
-    {
-      if ((gdsLen - 32) > 0) VertCoorTab = TRUE;
-      else                   VertCoorTab = FALSE;
-    }
-  
-  if ( ReducedGrid )
+void vlistChangeGridIndex(int vlistID, int index, int gridID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  int gridIDold = vlistptr->gridIDs[index];
+  if (gridIDold != gridID)
     {
-      locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
-      jlenl = (gdsLen - locnl)  >> 1;
-      if ( jlenl == GDS_NumLat )
-	{
-	  *numGridVals = 0;
-	  ISEC2_Reduced = TRUE;
-	  for ( i = 0; i < jlenl; i++ )
-	    {
-	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
-	      *numGridVals += ISEC2_RowLon(i);
-	    }
-	}
-      else
-	{
-	  ReducedGrid = FALSE;
-	}
+      vlistptr->gridIDs[index] = gridID;
+
+      int nvars = vlistptr->nvars;
+      for ( int varID = 0; varID < nvars; varID++ )
+        if ( vlistptr->vars[varID].gridID == gridIDold )
+          vlistptr->vars[varID].gridID = gridID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  ISEC2_GridType = GDS_GridType;
 
-  /*
-     Gaussian grid definition.
-  */
-  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
-       ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
-       ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-    {
-      ISEC2_NumLat    = GDS_NumLat;
-      if ( ! ReducedGrid )
-	{
-	  ISEC2_NumLon = GDS_NumLon;
-	  *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-	}
-      ISEC2_FirstLat  = GDS_FirstLat;
-      ISEC2_FirstLon  = GDS_FirstLon;
-      ISEC2_ResFlag   = GDS_ResFlag;
-      ISEC2_LastLat   = GDS_LastLat;
-      ISEC2_LastLon   = GDS_LastLon;
-      ISEC2_LonIncr   = GDS_LonIncr;
+void vlistChangeGrid(int vlistID, int gridID1, int gridID2)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      ISEC2_NumPar    = GDS_NumPar;
-      ISEC2_ScanFlag  = GDS_ScanFlag;
-      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-	{
-	  ISEC2_LatSP     = GDS_LatSP;
-	  ISEC2_LonSP     = GDS_LonSP;
-	  FSEC2_RotAngle  = GDS_RotAngle;
-	}
-      /*
-	if ( Lons != Longitudes || Lats != Latitudes )
-	Error("Latitude/Longitude Conflict");
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN     ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROT ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
-    {
-      /*
-      iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON     ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_STR ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROTSTR )
-    {
-      /*
-      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
-    {
-      ISEC2_NumLon    = GDS_NumLon;
-      ISEC2_NumLat    = GDS_NumLat;
-      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      ISEC2_FirstLat  = GDS_FirstLat;
-      ISEC2_FirstLon  = GDS_FirstLon;
-      ISEC2_ResFlag   = GDS_ResFlag;
-      ISEC2_Lambert_Lov   = GDS_Lambert_Lov;
-      ISEC2_Lambert_dx    = GDS_Lambert_dx;
-      ISEC2_Lambert_dy    = GDS_Lambert_dy;
-      ISEC2_Lambert_LatS1 = GDS_Lambert_LatS1;
-      ISEC2_Lambert_LatS2 = GDS_Lambert_LatS2;
-      ISEC2_Lambert_LatSP = GDS_Lambert_LatSP;
-      ISEC2_Lambert_LonSP = GDS_Lambert_LonSP;
-      ISEC2_Lambert_ProjFlag = GDS_Lambert_ProjFlag;
-      ISEC2_ScanFlag      = GDS_ScanFlag;
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
-    {
-      ISEC2_PentaJ  = GDS_PentaJ; /* Truncation */
-      ISEC2_PentaK  = GDS_PentaK;
-      ISEC2_PentaM  = GDS_PentaM;
-      ISEC2_RepType = GDS_RepType;
-      ISEC2_RepMode = GDS_RepMode;
-      *numGridVals  = (ISEC2_PentaJ+1)*(ISEC2_PentaJ+2);
-      isec2[ 6] = 0;
-      isec2[ 7] = 0;
-      isec2[ 8] = 0;
-      isec2[ 9] = 0;
-      isec2[10] = 0;
-      /*
-      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
-    {
-      ISEC2_GME_NI2    = GDS_GME_NI2;
-      ISEC2_GME_NI3    = GDS_GME_NI3;
-      ISEC2_GME_ND     = GDS_GME_ND;
-      ISEC2_GME_NI     = GDS_GME_NI;
-      ISEC2_GME_AFlag  = GDS_GME_AFlag;
-      ISEC2_GME_LatPP  = GDS_GME_LatPP;
-      ISEC2_GME_LonPP  = GDS_GME_LonPP;
-      ISEC2_GME_LonMPL = GDS_GME_LonMPL;
-      ISEC2_GME_BFlag  = GDS_GME_BFlag;
-      *numGridVals  = (ISEC2_GME_NI+1)*(ISEC2_GME_NI+1)*10;
-      /*
-      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
-      */
-    }
-  else
+  if (gridID1 != gridID2)
     {
-      ISEC2_NumLon = GDS_NumLon;
-      ISEC2_NumLat = GDS_NumLat;
-      *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      Message("Gridtype %d unsupported", ISEC2_GridType);
+      int ngrids = vlistptr->ngrids;
+      for ( int index = 0; index < ngrids; index++ )
+        {
+          if ( vlistptr->gridIDs[index] == gridID1 )
+            {
+              vlistptr->gridIDs[index] = gridID2;
+              break;
+            }
+        }
+      int nvars = vlistptr->nvars;
+      for ( int varID = 0; varID < nvars; varID++ )
+        if ( vlistptr->vars[varID].gridID == gridID1 )
+          vlistptr->vars[varID].gridID = gridID2;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  /*    vertical coordinate parameters for hybrid levels.     */
-  /*    get number of vertical coordinate parameters, if any. */
 
-  ISEC2_NumVCP = 0;
+int vlistZaxis(int vlistID, int index)
+{
+  int zaxisID = CDI_UNDEFID;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  isec2[17] = 0;
-  isec2[18] = 0;
+  if ( index < vlistptr->nzaxis && index >= 0 )
+    zaxisID = vlistptr->zaxisIDs[index];
 
-  if ( VertCoorTab == TRUE )
-    {
-      if ( ISEC0_GRIB_Version  == 0 )
-	{
-	  locnv = 32;
-	  ISEC2_NumVCP = (gdsLen - 32) >> 2;
-	}
-      else
-	{
-	  locnv = GDS_PVPL - 1;
-	  ISEC2_NumVCP = GDS_NV;
-	}
-#if defined (SX)
-      lGribLen = 4*ISEC2_NumVCP;	      
-      lgrib    = (GRIBPACK*) malloc(lGribLen*sizeof(GRIBPACK));
+  return (zaxisID);
+}
 
-      igrib = &gds[locnv];
-      if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
-      for ( i = 0; i < ISEC2_NumVCP; i++ )
-	{
-	  iexp   = (lgrib[4*i  ]);
-	  imant  =((lgrib[4*i+1]) << 16) +
-	          ((lgrib[4*i+2]) <<  8) +
-	           (lgrib[4*i+3]);
-	  fsec2[10+i] = POW_2_M24 * imant * pow(16.0, (double)(iexp - 64));
-	}
+int vlistZaxisIndex(int vlistID, int zaxisID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      free(lgrib);
-#else
-      for ( i = 0; i < ISEC2_NumVCP; i++ )
-	{
-	  iexp   = (gds[locnv+4*i  ]);
-	  imant  =((gds[locnv+4*i+1]) << 16) +
-	          ((gds[locnv+4*i+2]) <<  8) +
-	           (gds[locnv+4*i+3]);
-	  fsec2[10+i] = decfp2(iexp,imant);
-	}
-#endif
-    }
+  int index;
+  for ( index = 0 ; index < vlistptr->nzaxis ; index++ )
+    if ( zaxisID == vlistptr->zaxisIDs[index] ) break;
 
-  return (gdsLen);
+  if ( index == vlistptr->nzaxis ) index = -1;
+
+  return (index);
 }
 
-static
-int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
-			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
+
+void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
 {
-  unsigned char *igrib;
-  int lspherc = FALSE, lcomplex = FALSE;
-  int lcompress;
-  int jup, kup, mup;
-  int locnd;
-  long jlend;
-  long i;
-  int bds_flag, jscale, imiss;
-  int bds_ubits;
-  int ioff = 0;
-  int iexp, imant;
-  int zoff;
-  int bds_head = 11;
-  double zscale = 0.;
-  T fmin = 0.;
-  T *fpdata = fsec4;
-  int bdsLen;
-  extern int CGRIBEX_Fix_ZSE;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *iret = 0;
-  igrib = bds;
+  int zaxisIDold = vlistptr->zaxisIDs[index];
+  if (zaxisIDold != zaxisID)
+    {
+      vlistptr->zaxisIDs[index] = zaxisID;
 
-  memset(isec4, 0, 42*sizeof(int));
+      int nlevs = zaxisInqSize(zaxisID),
+        nlevsOld = zaxisInqSize(zaxisIDold);
+      int nvars = vlistptr->nvars;
+      for ( int varID = 0; varID < nvars; varID++ )
+        if ( vlistptr->vars[varID].zaxisID == zaxisIDold )
+          {
+            vlistptr->vars[varID].zaxisID = zaxisID;
+            if ( vlistptr->vars[varID].levinfo && nlevs != nlevsOld )
+              {
+                vlistptr->vars[varID].levinfo = (levinfo_t *)xrealloc(vlistptr->vars[varID].levinfo, (size_t)nlevs * sizeof (levinfo_t));
 
-  /* get length of binary data block. */
+                for ( int levID = 0; levID < nlevs; levID++ )
+                  vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
+              }
+          }
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-  bdsLen = BDS_Len;
-  /*
-    If a very large product, the section 4 length field holds
-    the number of bytes in the product after section 4 upto
-    the end of the padding bytes.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( llarge ) bdsLen = bdsLenIn - bdsLen;
 
-  /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
+void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
+{
+  int nlevs1 = zaxisInqSize(zaxisID1), nlevs2 = zaxisInqSize(zaxisID2);
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  bds_flag = BDS_Flag;
+  int nzaxis = vlistptr->nzaxis;
+  for ( int index = 0; index < nzaxis; index++ )
+    {
+      if ( vlistptr->zaxisIDs[index] == zaxisID1 )
+        {
+          vlistptr->zaxisIDs[index] = zaxisID2;
+          break;
+        }
+    }
 
-  /* 0------- grid point           */
-  /* 1------- spherical harmonics  */
+  int nvars = vlistptr->nvars;
+  for ( int varID = 0; varID < nvars; varID++ )
+    if ( vlistptr->vars[varID].zaxisID == zaxisID1 )
+      {
+        vlistptr->vars[varID].zaxisID = zaxisID2;
 
-  lspherc = bds_flag >> 7;
+        if ( vlistptr->vars[varID].levinfo && nlevs2 != nlevs1 )
+          {
+            vlistptr->vars[varID].levinfo
+              = (levinfo_t *)xrealloc(vlistptr->vars[varID].levinfo,
+                                      (size_t)nlevs2 * sizeof(levinfo_t));
 
-  if ( lspherc ) isec4[2] = 128;
-  else           isec4[2] = 0;
+            for ( int levID = 0; levID < nlevs2; levID++ )
+              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
+          }
+      }
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
 
-  /* -0------  simple packing */
-  /* -1------ complex packing */
 
-  lcomplex = (bds_flag >> 6)&1;
+int vlistHasTime(int vlistID)
+{
+  int hastime = FALSE;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( lcomplex ) isec4[3] = 64;
-  else            isec4[3] =  0;
+  for ( int varID = 0; varID <  vlistptr->nvars; varID++ )
+    if ( vlistptr->vars[varID].tsteptype != TSTEP_CONSTANT )
+      {
+        hastime = TRUE;
+        break;
+      }
 
-  /* ---0---- No additional flags */
-  /* ---1---- No additional flags */
+  return (hastime);
+}
 
-  lcompress = (bds_flag >> 4)&1; /* compress */
+enum {
+  vlist_nints=6,
+};
 
-  if ( lcompress )
-    { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
-  else
-    { isec4[5] =  0; isec4[6] = 0;     zoff =  0; }
+static int
+vlistTxCode ( void )
+{
+  return VLIST;
+}
 
-  /* ----++++ number of unused bits at end of section) */
 
-  bds_ubits = bds_flag & 0xF;
-  
-  /* scale factor (2 bytes) */;
+static
+int  vlistGetSizeP ( void * vlistptr, void *context)
+{
+  int txsize, varID;
+  vlist_t *p = (vlist_t*) vlistptr;
+  txsize = serializeGetSize(vlist_nints, DATATYPE_INT, context);
+  txsize += serializeGetSize(1, DATATYPE_LONG, context);
+  txsize += vlistAttsGetSize(p, CDI_GLOBAL, context);
+  for ( varID = 0; varID <  p->nvars; varID++ )
+    txsize += vlistVarGetPackSize(p, varID, context);
+  return txsize;
+}
 
-  jscale = BDS_BinScale;
 
-  /* check for missing data indicators. */
+static
+void vlistPackP ( void * vlistptr, void * buf, int size, int *position,
+                  void *context )
+{
+  int varID, tempbuf[vlist_nints];
+  vlist_t *p = (vlist_t*) vlistptr;
+  tempbuf[0] = p->self;
+  tempbuf[1] = p->nvars;
+  tempbuf[2] = p->taxisID;
+  tempbuf[3] = p->tableID;
+  tempbuf[4] = p->instID;
+  tempbuf[5] = p->modelID;
+  serializePack(tempbuf, vlist_nints, DATATYPE_INT, buf, size, position, context);
+  serializePack(&p->ntsteps, 1, DATATYPE_LONG, buf, size, position, context);
 
-  iexp  = bds[ 6];
-  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+  vlistAttsPack(p, CDI_GLOBAL, buf, size, position, context);
+  for ( varID = 0; varID < p->nvars; varID++ )
+    {
+      vlistVarPack(p, varID, buf, size, position, context);
+    }
+}
 
-  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+void vlistUnpack(char * buf, int size, int *position, int originNamespace,
+                 void *context, int force_id)
+{
+  int tempbuf[vlist_nints];
+  serializeUnpack(buf, size, position, tempbuf, vlist_nints, DATATYPE_INT, context);
+  int nvars = tempbuf[1];
+  int targetID = namespaceAdaptKey(tempbuf[0], originNamespace);
+  vlist_t *p = vlist_new_entry(force_id?targetID:CDI_UNDEFID);
+  xassert(!force_id || p->self == targetID);
+  if (!force_id)
+    targetID = p->self;
+  p->taxisID = namespaceAdaptKey(tempbuf[2], originNamespace);
+  p->tableID = tempbuf[3];
+  p->instID = namespaceAdaptKey(tempbuf[4], originNamespace);
+  p->modelID = namespaceAdaptKey(tempbuf[5], originNamespace);
+  serializeUnpack(buf, size, position, &p->ntsteps, 1, DATATYPE_LONG, context);
+  vlistAttsUnpack(targetID, CDI_GLOBAL, buf, size, position, context);
+  for (int varID = 0; varID < nvars; varID++ )
+    vlistVarUnpack(targetID, buf, size, position, originNamespace, context);
+}
 
-  /* convert reference value and scale factor. */
 
-  if ( ! (dfunc == 'J') )
-    if ( imiss == 0 )
-      {
-	fmin = BDS_RefValue;
-	
-	if ( jscale < 0 )
-	  zscale = 1.0/intpow2(-jscale);
-	else
-	  zscale = intpow2(jscale);
-      }
+void vlist_check_contents(int vlistID)
+{
+  int index, nzaxis, zaxisID;
 
-  /* get number of bits in each data value. */
+  nzaxis = vlistNzaxis(vlistID);
 
-  ISEC4_NumBits = BDS_NumBits;
+  for ( index = 0; index < nzaxis; index++ )
+    {
+      zaxisID = vlistZaxis(vlistID, index);
+      if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
+	cdiCheckZaxis(zaxisID);
+    }
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifdef HAVE_CONFIG_H
+#endif
 
-  /* octet number of start of packed data */
-  /* calculated from start of block 4 - 1 */
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
 
-  locnd = zoff + bds_head;
 
-  /* if data is in spherical harmonic form, distinguish   */
-  /* between simple/complex packing (lcomplex = 0/1)      */
 
-  if ( lspherc )
+static
+cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
+{
+  cdi_atts_t *attsp = NULL;
+
+  if ( varID == CDI_GLOBAL )
     {
-      if ( !lcomplex )
-	{
-	  /*    no unpacked binary data present */
+      attsp = &vlistptr->atts;
+    }
+  else
+    {
+      if ( varID >= 0 && varID < vlistptr->nvars )
+	attsp = &(vlistptr->vars[varID].atts);
+    }
 
-	  jup = kup = mup = 0;
+  return (attsp);
+}
 
-	  /*    octet number of start of packed data */
-	  /*    calculated from start of block 4 - 1 */
+static
+cdi_att_t *find_att(cdi_atts_t *attsp, const char *name)
+{
+  xassert(attsp != NULL);
 
-	  ioff   = 1;
-	  locnd += 4*ioff;  /* RealCoef */
+  if ( attsp->nelems == 0 ) return NULL;
 
-	  /*    get real (0,0) coefficient in grib format and     */
-	  /*    convert to floating point.                        */
+  size_t slen = strlen(name);
+  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
 
-	  if ( dfunc != 'J' )
-	    {
-	      if ( imiss ) *fpdata++ = 0.0;
-	      else         *fpdata++ = BDS_RealCoef;
-	    }
-	}
-      else /* complex packed spherical harmonics */
-	{
-	  isec4[15] = BDS_PackData;
-	  /*    scaling factor */
-	  isec4[16] = BDS_Power;
+  cdi_att_t *atts = attsp->value;
+  for ( size_t attid = 0; attid < attsp->nelems; attid++ )
+    {
+      cdi_att_t *attp = atts + attid;
+      if ( attp->namesz == slen && memcmp(attp->name, name, slen) == 0 )
+        return (attp); /* Normal return */
+    }
 
-	  /*    pentagonal resolution parameters of the */
-	  /*    unpacked section of data field          */
+  return (NULL);
+}
 
-	  jup = bds[zoff+15];
-	  kup = bds[zoff+16];
-	  mup = bds[zoff+17];
+static
+cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
+{
+  cdi_att_t *attp;
+  size_t slen;
 
-	  isec4[zoff+17] = jup;
-	  isec4[zoff+18] = kup;
-	  isec4[zoff+19] = mup;
+  xassert(attsp != NULL);
+  xassert(name  != NULL);
 
-	  /*    unpacked binary data */
+  if ( attsp->nelems == attsp->nalloc ) return (NULL);
 
-	  locnd += 4; /* 2 + power */
-	  locnd += 3; /* j, k, m   */
-	  ioff   = (jup+1)*(jup+2);
+  attp = &(attsp->value[attsp->nelems]);
+  attsp->nelems++;
 
-	  if ( dfunc != 'J' )
-	    for ( i = 0; i < ioff; i++ )
-	      {
-		if ( imiss )
-		  *fpdata++ = 0.0;
-		else
-		  {
-		    iexp   = (bds[locnd+4*i  ]);
-		    imant  =((bds[locnd+4*i+1]) << 16) +
-		            ((bds[locnd+4*i+2]) <<  8) +
-		             (bds[locnd+4*i+3]);
+  slen = strlen(name);
+  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
 
-		    *fpdata++ = decfp2(iexp,imant);
-		  }
-	      }
-	  
-	  locnd += 4*ioff;  /* RealCoef */
-	}
-    }
-  else
+  attp->name = (char *) malloc(slen+1);
+  memcpy(attp->name, name, slen+1);
+  attp->namesz = slen;
+  attp->xvalue = NULL;
+
+  return (attp);
+}
+
+static
+void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t xsz, const void *xvalue)
+{
+  xassert(attp != NULL);
+
+  attp->xsz = xsz;
+  attp->indtype = indtype;
+  attp->exdtype = exdtype;
+  attp->nelems  = nelems;
+
+  if ( xsz > 0 )
     {
-      if ( lcomplex )
-	{
-	  *iret = 1999;
-	  gprintf(__func__, " Second order packed grids unsupported!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
+      attp->xvalue = xrealloc(attp->xvalue, xsz);
+      memcpy(attp->xvalue, xvalue, xsz);
     }
+}
 
-  /* Decode data values to floating point and store in fsec4.  */
-  /* First calculate the number of data values.                */
-  /* Take into account that spherical harmonics can be packed  */
-  /* simple (lcomplex = 0) or complex (lcomplex = 1)           */
+/*
+ at Function  vlistInqNatts
+ at Title     Get number of variable attributes
 
-  jlend = bdsLen - locnd;
+ at Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  nattsp   Pointer to location for returned number of variable attributes.
 
-  if ( ISEC4_NumBits == 0 )
-    {
-      if ( jlend > 1 )
-	{
-	  *iret = 2001;
-	  gprintf(__func__, " Number of bits per data value = 0!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
+ at Description
+The function @func{vlistInqNatts} gets the number of variable attributes assigned to this variable.
 
-      if ( numGridVals == 0 )
-	{
-	  *iret = 2002;
-	  gprintf(__func__, " Constant field unsupported for this grid type!");
-	  gprintf(__func__, " Return code =  %d", *iret);
-	  return (0);
-	}
+ at EndFunction
+*/
+int vlistInqNatts(int vlistID, int varID, int *nattsp)
+{
+  int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_atts_t *attsp;
+
+  vlistptr = vlist_to_pointer(vlistID);
+
+  attsp = get_attsp(vlistptr, varID);
+  xassert(attsp != NULL);
+
+  *nattsp = (int)attsp->nelems;
+
+  return (status);
+}
+
+/*
+ at Function  vlistInqAtt
+ at Title     Get information about an attribute
+
+ at Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  attnum   Attribute number (from 0 to natts-1).
+    @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+    @Item  typep    Pointer to location for returned attribute type.
+    @Item  lenp     Pointer to location for returned attribute number.
+
+ at Description
+The function @func{vlistInqAtt} gets information about an attribute.
+
+ at EndFunction
+*/
+int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
+{
+  int status = CDI_NOERR;
+  cdi_att_t *attp = NULL;
+
+  xassert(name != NULL);
+
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      jlend = numGridVals;
-      jlend -= ioff;
+  cdi_atts_t *attsp = get_attsp(vlistptr, varID);
+  xassert(attsp != NULL);
+
+  if ( attnum >= 0 && attnum < (int)attsp->nelems )
+    attp = &(attsp->value[attnum]);
+
+  if ( attp != NULL ) /* name in use */
+    {
+      memcpy(name, attp->name, attp->namesz+1);
+      *typep  = attp->exdtype;
+      *lenp   = (int)attp->nelems;
     }
   else
     {
-      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+      name[0] =  0;
+      *typep  = -1;
+      *lenp   =  0;
+      status  = -1;
     }
 
-  ISEC4_NumValues        = jlend + ioff;
-  ISEC4_NumNonMissValues = 0;
-
-  if ( lcompress )
-    {
-      size_t len;
+  return (status);
+}
 
-      if ( gribrec_len(bds[14], bds[15], bds[16]) > JP23SET )
-	len = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
-      else
-        len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
-      ISEC4_NumValues = len*8/ISEC4_NumBits;
+int vlistDelAtts(int vlistID, int varID)
+{
+  int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_att_t *attp = NULL;
+  cdi_atts_t *attsp;
+  int attid;
 
-      if ( lspherc )
-	{
-	  if ( lcomplex )
-	    ISEC4_NumValues += ioff;
-	  else
-	    ISEC4_NumValues++;
-	}
-    }
+  vlistptr = vlist_to_pointer(vlistID);
 
-  if ( dfunc == 'J' ) return (bdsLen);
+  attsp = get_attsp(vlistptr, varID);
+  xassert(attsp != NULL);
 
-  /* check length of output array. */
-  
-  if ( ISEC4_NumValues > fsec4len )
+  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
     {
-      *iret = 710;
-      gprintf(__func__, " Output array too small. Length = %d", fsec4len);
-      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
-      gprintf(__func__, " Return code =  %d", *iret);
-      return (0);
+      attp = &(attsp->value[attid]);
+      if ( attp->name   ) free(attp->name);
+      if ( attp->xvalue ) free(attp->xvalue);
     }
 
-  if ( imiss ) memset((char *)fpdata, 0, jlend*sizeof(T));
-  else
-    {
-      igrib += locnd;
+  attsp->nelems = 0;
 
-      TEMPLATE(decode_array,T)(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
-    }
+  return (status);
+}
 
-  if ( lspherc && lcomplex )
-    {
-      int pcStart, pcScale;
-      pcStart = isec4[19];
-      pcScale = isec4[16];
-      TEMPLATE(scatter_complex,T)(fsec4, pcStart, ISEC2_PentaJ, ISEC4_NumValues);
-      TEMPLATE(scale_complex,T)(fsec4, pcStart, pcScale, ISEC2_PentaJ, 1);
-    }
 
-  if ( CGRIBEX_Fix_ZSE )  /* Fix ZeroShiftError of simple packed spherical harmonics */
-    if ( lspherc && !lcomplex )
-      {
-        /* 20100705: Fix ZeroShiftError - Edi Kirk */
-	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
-	  {
-	    T zserr = fsec4[1];
-	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
-	  }
-      }
+int vlistDelAtt(int vlistID, int varID, const char *name)
+{
+  int status = CDI_NOERR;
 
-  if ( decscale )
-    {
-      T scale = (T) pow(10.0, (double)-decscale);
-      for ( i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
-    }
+  UNUSED(vlistID);
+  UNUSED(varID);
+  UNUSED(name);
 
-  return (bdsLen);
-}
+  fprintf(stderr, "vlistDelAtt not implemented!\n");
 
+  return (status);
+}
 
-void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
-			     T *fsec3, int *isec4, T *fsec4, int fsec4len, int *kgrib,
-			     int kleng, int *kword, int dfunc, int *iret)
+static
+int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
 {
-  UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
-  int gribLen = 0;
-  int gdsIncluded = FALSE;
-  int bmsIncluded = FALSE;
-  int bitmapSize = 0;
-  int imaskSize = 0;
-  int ldebug = FALSE;
-  int llarge = FALSE, l_iorj = FALSE;
-  int lsect2 = FALSE, lsect3 = FALSE;
-  int numGridVals = 0;
-  static int lmissvalinfo = 1;
+  int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_att_t *attp;
+  cdi_atts_t *attsp;
 
-  UNUSED(kleng);
+  if ( len != 0 && xp == NULL ) /* Null arg */
+    {
+      return (CDI_EINVAL);
+    }
 
-  *iret = 0;
+  vlistptr = vlist_to_pointer(vlistID);
 
-  grsdef();
+  attsp = get_attsp(vlistptr, varID);
+  xassert(attsp != NULL);
 
-  ISEC2_Reduced = FALSE;
+  attp = find_att(attsp, name);
+  if ( attp == NULL )
+    attp = new_att(attsp, name);
 
-  /*
-    ----------------------------------------------------------------
-    IS Indicator Section (Section 0)
-    ----------------------------------------------------------------
-  */
-  is = (unsigned char *) &kgrib[0];
+  if ( attp != NULL )
+    fill_att(attp, indtype, exdtype, len, xsz, xp);
 
-  isLen = decodeIS(is, isec0, iret);
+  return (status);
+}
 
-  /*
-    If count is negative, have to rescale by factor of -120.
-    This is a fixup to get round the restriction on product lengths
-    due to the count being only 24 bits. It is only possible because
-    the (default) rounding for GRIB products is 120 bytes.
-  */
-  if ( ISEC0_GRIB_Len < 0 )
+static
+int vlist_inq_att(int indtype, int vlistID, int varID, const char *name, size_t mxsz, void *xp)
+{
+  int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_att_t *attp;
+  cdi_atts_t *attsp;
+  size_t xsz;
+
+  if ( mxsz != 0 && xp == NULL ) /* Null arg */
     {
-      if ( ldebug )
-	gprintf(__func__, "Special case, negative length multiplied by -120");
-      llarge = TRUE;
-      ISEC0_GRIB_Len *= (-120);
+      return (CDI_EINVAL);
     }
-  /*
-    When decoding or calculating length, previous editions
-    of the GRIB code must be taken into account.
 
-    In the table below, covering sections 0 and 1 of the GRIB
-    code, octet numbering is from the beginning of the GRIB
-    message;
-    * indicates that the value is not available in the code edition;
-    R indicates reserved, should be set to 0;
-    Experimental edition is considered as edition -1.
+  vlistptr = vlist_to_pointer(vlistID);
 
-    GRIB code edition -1 has fixed length of 20 octets for
-    section 1, the length not included in the message.
-    GRIB code edition 0 has fixed length of 24 octets for
-    section 1, the length being included in the message.
-    GRIB code edition 1 can have different lengths for section
-    1, the minimum being 28 octets, length being included in
-    the message.
+  attsp = get_attsp(vlistptr, varID);
+  xassert(attsp != NULL);
 
-                                         Octet numbers for code
-                                                  editions
+  attp = find_att(attsp, name);
+  if ( attp != NULL ) /* name in use */
+    {
+      if ( attp->indtype == indtype )
+	{
+	  xsz = attp->xsz;
+	  if ( mxsz < xsz ) xsz = mxsz;
+	  if ( xsz > 0 )
+	    memcpy(xp, attp->xvalue, xsz);
+	}
+      else
+	{
+	  Warning("Attribute %s has wrong data type!", name);
+          status = -2;
+	}
+    }
+  else
+    {
+      //Warning("Internal problem, attribute %s not found!", name);
+      status = -1;
+    }
 
-                 Contents.                   -1      0      1
-                 ---------                ----------------------
-       Letters GRIB                          1-4    1-4    1-4
-       Total length of GRIB message.          *      *     5-7
-       GRIB code edition number               *      *      8
-       Length of Section 1.                   *     5-7    9-11
-       Reserved octet (R).                    *      8(R)   *
-       Version no. of Code Table 2.           *      *     12
-       Identification of centre.              5      9     13
-       Generating process.                    6     10     14
-       Grid definition .                      7     11     15
-       Flag (Code Table 1).                   8     12     16
-       Indicator of parameter.                9     13     17
-       Indicator of type of level.           10     14     18
-       Height, pressure etc of levels.      11-12  15-16  19-20
-       Year of century.                      13     17     21
-       Month.                                14     18     22
-       Day.                                  15     19     23
-       Hour.                                 16     20     24
-       Minute.                               17     21     25
-       Indicator of unit of time.            18     22     26
-       P1 - Period of time.                  19     23     27
-       P2 - Period of time                  20(R)   24     28
-       or reserved octet (R).
-       Time range indicator.                21(R)   25     29
-       or reserved octet (R).
-       Number included in average.       22-23(R)  26-27  30-31
-       or reserved octet (R).
-       Number missing from average.         24(R)  28(R)   32
-       or reserved octet (R).
-       Century of data.                       *      *     33
-       Designates sub-centre if not 0.        *      *     34
-       Decimal scale factor.                  *      *    35-36
-       Reserved. Set to 0.                    *      *    37-48
-       (Need not be present)
-       For originating centre use only.       *      *    49-nn
-       (Need not be present)
+  return (status);
+}
 
-    Identify which GRIB code edition is being decoded.
 
-    In GRIB edition 1, the edition number is in octet 8.
-    In GRIB edition 0, octet 8 is reserved and set to 0.
-    In GRIB edition -1, octet 8 is a flag field and can have a
-    a valid value of 0, 1, 2 or 3.
+int vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2)
+{
+  int status = CDI_NOERR;
+  vlist_t *vlistptr1;
+  cdi_att_t *attp = NULL;
+  cdi_atts_t *attsp1;
+  int attid;
 
-    However, GRIB edition number 0 has a fixed
-    length of 24, included in the message, for section 1, so
-    if the value extracted from octets 5-7 is 24 and that from
-    octet 8 is 0, it is safe to assume edition 0 of the code.
+  vlistptr1 = vlist_to_pointer(vlistID1);
 
-  */
-  if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
+  attsp1 = get_attsp(vlistptr1, varID_1);
+  xassert(attsp1 != NULL);
+
+  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
     {
-      /*
-	Set length of GRIB message to missing data value.
-      */
-      ISEC0_GRIB_Len = 0;
+      attp = &(attsp1->value[attid]);
+      vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
     }
-  /*
-    If Grib Edition 1 and only length is required, go to section 9.
-  */
-  if ( dfunc == 'L' ) goto LABEL900;
 
-  /*
-    ----------------------------------------------------------------
-    PDS Product Definition Section (Section 1)
-    ----------------------------------------------------------------
-  */ 
-  pds = is + isLen;
+  return (status);
+}
 
-  pdsLen = decodePDS(pds, isec0, isec1);
+/*
+ at Function  vlistDefAttInt
+ at Title     Define an integer attribute
 
-  /*
-    ----------------------------------------------------------------
-    GDS Grid Description Section (Section 2)
-    ----------------------------------------------------------------
-  */
-  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+ at Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
 
-  if ( gdsIncluded )
-    {
-      gds = is + isLen + pdsLen;
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  type     External data type (@func{DATATYPE_INT16} or @func{DATATYPE_INT32}).
+    @Item  len      Number of values provided for the attribute.
+    @Item  ip       Pointer to one or more integer values.
 
-      gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
-    }
+ at Description
+The function @func{vlistDefAttInt} defines an integer attribute.
 
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+ at EndFunction
+*/
+int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
+{
+  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (int), ip);
+}
 
-  isec3[0] = 0;
-  if ( bmsIncluded )
-    {
-      bms = is + isLen + pdsLen + gdsLen;
+/*
+ at Function  vlistDefAttFlt
+ at Title     Define a floating point attribute
 
-      bmsLen = BMS_Len;
-      imaskSize = (bmsLen - 6)<<3;
-      bitmapSize = imaskSize - BMS_UnusedBits;
-      /*
-      fprintf(stderr," bitmapSize = %d %d %d\n", bitmapSize, imaskSize, BMS_UnusedBits);
-      */
-    }
+ at Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
 
-  /*
-    ----------------------------------------------------------------
-    BDS Binary Data Section (Section 4)
-    ----------------------------------------------------------------
-  */
-  bds = is + isLen + pdsLen + gdsLen + bmsLen;
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  type     External data type (@func{DATATYPE_FLT32} or @func{DATATYPE_FLT64}).
+    @Item  len      Number of values provided for the attribute.
+    @Item  dp       Pointer to one or more floating point values.
 
-  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+ at Description
+The function @func{vlistDefAttFlt} defines a floating point attribute.
 
-  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
-				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
+ at EndFunction
+*/
+int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
+{
+  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (double), dp);
+}
 
-  if ( *iret != 0 ) return;
+/*
+ at Function  vlistDefAttTxt
+ at Title     Define a text attribute
 
-  ISEC4_NumNonMissValues = ISEC4_NumValues;
+ at Prototype int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
 
-  if ( bitmapSize > 0 )
-    {
-      if ( dfunc != 'L' && dfunc != 'J' )
-	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
-	  {
-	    lmissvalinfo = 0;
-	    FSEC3_MissVal = GRIB_MISSVAL;
-	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
-	  }
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  len      Number of values provided for the attribute.
+    @Item  tp       Pointer to one or more character values.
 
-      /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
-      ISEC4_NumValues        = bitmapSize;
+ at Description
+The function @func{vlistDefAttTxt} defines a text attribute.
 
-      if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
-	{
-	  long i, j;
-	  GRIBPACK *pbitmap;
-	  GRIBPACK bitmap;
-	  GRIBPACK *imask;
+ at EndFunction
+*/
+int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
+{
+  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t)len, (size_t)len, tp);
+}
 
-	  /*
-	  unsigned char *bitmap;
-	  bitmap = BMS_Bitmap;
-	  j = ISEC4_NumNonMissValues;
-	  for ( i = ISEC4_NumValues-1; i >= 0; i-- )
-	    {
-	      if ( (bitmap[i/8]>>(7-(i&7)))&1 )
-		fsec4[i] = fsec4[--j];
-	      else
-		fsec4[i] = FSEC3_MissVal;
-	    }
-	  */
+/*
+ at Function  vlistInqAttInt
+ at Title     Get the value(s) of an integer attribute
 
-	  imask = (GRIBPACK*) malloc(imaskSize*sizeof(GRIBPACK));
+ at Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  mlen     Number of allocated values provided for the attribute.
+    @Item  ip       Pointer location for returned integer attribute value(s).
 
-#if defined (VECTORCODE)
-	  (void) UNPACK_GRIB(BMS_Bitmap, imask, imaskSize/8, -1L);
-	  pbitmap = imask;
-#else
-	  pbitmap = BMS_Bitmap;
-#endif
+ at Description
+The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-	  for ( i = imaskSize/8-1; i >= 0; i-- )
-	    {
-	      bitmap = pbitmap[i];
-	      imask[i*8+0] = 1 & (bitmap >> 7);
-	      imask[i*8+1] = 1 & (bitmap >> 6);
-	      imask[i*8+2] = 1 & (bitmap >> 5);
-	      imask[i*8+3] = 1 & (bitmap >> 4);
-	      imask[i*8+4] = 1 & (bitmap >> 3);
-	      imask[i*8+5] = 1 & (bitmap >> 2);
-	      imask[i*8+6] = 1 & (bitmap >> 1);
-	      imask[i*8+7] = 1 & (bitmap);
-	    }
+ at EndFunction
+*/
+int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
+{
+  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, (size_t)mlen * sizeof (int), ip);
+}
 
-	  j = 0;
-	  for ( i = 0; i < ISEC4_NumValues; i++ )
-	    if ( imask[i] ) j++;
+/*
+ at Function  vlistInqAttFlt
+ at Title     Get the value(s) of a floating point attribute
 
-	  if ( ISEC4_NumNonMissValues != j )
-	    {
-	      if ( dfunc != 'J' && ISEC4_NumBits != 0 )
-		Warning("Bitmap (%d) and data (%d) section differ, using bitmap section!",
-			j, ISEC4_NumNonMissValues);
+ at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  mlen     Number of allocated values provided for the attribute.
+    @Item  dp       Pointer location for returned floating point attribute value(s).
 
-	      ISEC4_NumNonMissValues = j;
-	    }
+ at Description
+The function @func{vlistInqAttFlt} gets the values(s) of a floating point attribute.
 
-	  if ( dfunc != 'J' )
-	    {
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-	      for ( i = ISEC4_NumValues-1; i >= 0; i-- )
-		fsec4[i] = imask[i] ? fsec4[--j] : FSEC3_MissVal;
-	    }
+ at EndFunction
+*/
+int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
+{
+  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, (size_t)mlen * sizeof (double), dp);
+}
+
+/*
+ at Function  vlistInqAttTxt
+ at Title     Get the value(s) of a text attribute
 
-	  free(imask);
-	}
-    }
+ at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
+    @Item  name     Attribute name.
+    @Item  mlen     Number of allocated values provided for the attribute.
+    @Item  tp       Pointer location for returned text attribute value(s).
 
-  if ( ISEC2_Reduced )
-    {
-      int nlon, nlat;
-      int lsect3, lperio = 1, lveggy;
-      int ilat;
-      int nvalues = 0;
-      int dlon;
+ at Description
+The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
 
-      nlat = ISEC2_NumLat;
-      nlon = ISEC2_RowLonPtr[0];
-      for ( ilat = 0; ilat < nlat; ++ilat ) nvalues += ISEC2_RowLon(ilat);
-      for ( ilat = 1; ilat < nlat; ++ilat )
-	if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
+ at EndFunction
+*/
+int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
+{
+  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, (size_t)mlen * sizeof (char), tp);
+}
 
-      dlon = ISEC2_LastLon-ISEC2_FirstLon;
-      if ( dlon < 0 ) dlon += 360000;
-	  
-      if ( nvalues != ISEC4_NumValues )
-	{
-	  *iret = -801;
-	}
-      //printf("nlat %d  nlon %d \n", nlat, nlon);
-      //printf("nvalues %d %d\n", nvalues, ISEC4_NumValues);
+enum {
+  vlist_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
+};
 
-      if ( dfunc == 'R' && *iret == -801 )
-	gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular Gaussian grid!",
-		ISEC4_NumValues, nvalues);
-      
-      if ( dfunc == 'R' && *iret != -801 )
-	{
-	  ISEC2_Reduced = 0;
-	  ISEC2_NumLon = nlon;
-	  ISEC4_NumValues = nlon*nlat;
+static inline int
+vlistAttTypeLookup(cdi_att_t *attp)
+{
+  int type;
+  switch (attp->indtype)
+  {
+  case DATATYPE_FLT:
+    type = DATATYPE_FLT64;
+    break;
+  case DATATYPE_INT:
+  case DATATYPE_TXT:
+    type = attp->indtype;
+    break;
+  default:
+    xabort("Unknown datatype encountered in attribute %s: %d\n",
+            attp->name, attp->indtype);
+  }
+  return type;
+}
 
-	  lsect3 = bitmapSize > 0;
-	  lveggy = (ISEC1_CodeTable == 128) && (ISEC1_CenterID == 98) && 
-	          ((ISEC1_Parameter == 27) || (ISEC1_Parameter == 28) || 
-	           (ISEC1_Parameter == 29) || (ISEC1_Parameter == 30));
-	
-	  (void) TEMPLATE(qu2reg3,T)(fsec4, ISEC2_RowLonPtr, nlat, nlon, FSEC3_MissVal, iret, lsect3, lperio, lveggy);
-	      
-	  if ( bitmapSize > 0 )
-	    {
-	      long i;
-	      int j = 0;
-	      
-	      for ( i = 0; i < ISEC4_NumValues; i++ )
-		if ( IS_NOT_EQUAL(fsec4[i], FSEC3_MissVal) ) j++;
-		  
-	      ISEC4_NumNonMissValues = j;
-	    }
-	}
-    }
 
+int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB,
+                      int attnum)
+{
+  cdi_atts_t *attspa = get_attsp(a, varIDA),
+    *attspb = get_attsp(b, varIDB);
+  if (attspa == NULL && attspb == NULL)
+    return 0;
+  xassert(attnum >= 0 && attnum < (int)attspa->nelems
+          && attnum < (int)attspb->nelems);
+  cdi_att_t *attpa = attspa->value + attnum,
+    *attpb = attspb->value + attnum;
+  size_t len;
+  if ((len = attpa->namesz) != attpb->namesz)
+    return 1;
+  int diff;
+  if ((diff = memcmp(attpa->name, attpb->name, len)))
+    return 1;
+  if (attpa->indtype != attpb->indtype
+      || attpa->exdtype != attpb->exdtype
+      || attpa->nelems != attpb->nelems)
+    return 1;
+  return memcmp(attpa->xvalue, attpb->xvalue, attpa->xsz);
+}
 
-  if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
-  esLen = 4;
 
-  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
+static int
+vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
+{
+  cdi_atts_t *attsp;
+  cdi_att_t *attp;
 
-  if ( ISEC0_GRIB_Len )
-    if ( ISEC0_GRIB_Len < gribLen )
-      Warning("Length of GRIB message is inconsistent (grib_message_size=7867 < grib_record_size=9718)!", ISEC0_GRIB_Len, gribLen);
+  xassert(attsp = get_attsp(vlistptr, varID));
+  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
+  attp = &(attsp->value[attnum]);
+  int txsize = serializeGetSize(vlist_att_nints, DATATYPE_INT, context)
+    + serializeGetSize((int)attp->namesz, DATATYPE_TXT, context);
+  txsize += serializeGetSize((int)attp->nelems, vlistAttTypeLookup(attp), context);
+  return txsize;
+}
 
-  ISEC0_GRIB_Len = gribLen;
+int
+vlistAttsGetSize(vlist_t *p, int varID, void *context)
+{
+  cdi_atts_t *attsp = get_attsp(p, varID);
+  int txsize = serializeGetSize(1, DATATYPE_INT, context);
+  size_t numAtts = attsp->nelems;
+  for (size_t i = 0; i < numAtts; ++i)
+    txsize += vlistAttGetSize(p, varID, (int)i, context);
+  return txsize;
+}
 
-  *kword = gribLen / sizeof(int);
-  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
+static void
+vlistAttPack(vlist_t *vlistptr, int varID, int attnum,
+             void * buf, int size, int *position, void *context)
+{
+  cdi_atts_t *attsp;
+  cdi_att_t *attp;
+  int tempbuf[vlist_att_nints];
 
-  /*
-    ----------------------------------------------------------------
-    Section 9 . Abort/return to calling routine.
-    ----------------------------------------------------------------
-  */
- LABEL900:;
+  xassert(attsp = get_attsp(vlistptr, varID));
+  xassert(attnum >= 0 && attnum < (int)attsp->nelems);
+  attp = &(attsp->value[attnum]);
+  tempbuf[0] = (int)attp->namesz;
+  tempbuf[1] = attp->exdtype;
+  tempbuf[2] = attp->indtype;
+  tempbuf[3] = (int)attp->nelems;
+  serializePack(tempbuf, vlist_att_nints, DATATYPE_INT, buf, size, position, context);
+  serializePack(attp->name, (int)attp->namesz, DATATYPE_TXT, buf, size, position, context);
+  serializePack(attp->xvalue, (int)attp->nelems, vlistAttTypeLookup(attp),
+                buf, size, position, context);
+}
 
-  if ( ldebug )
-    {
-      gprintf(__func__, "Section 9.");
-      gprintf(__func__, "Output values set -");
+void
+vlistAttsPack(vlist_t *p, int varID,
+              void * buf, int size, int *position, void *context)
+{
+  cdi_atts_t *attsp = get_attsp(p, varID);
+  size_t numAtts = attsp->nelems;
+  int numAttsI = (int)numAtts;
+  xassert(numAtts <= INT_MAX);
+  serializePack(&numAttsI, 1, DATATYPE_INT, buf, size, position, context);
+  for (size_t i = 0; i < numAtts; ++i)
+    vlistAttPack(p, varID, (int)i, buf, size, position, context);
+}
 
-      gribPrintSec0(isec0);
-      gribPrintSec1(isec0, isec1);
-      /*
-	Print section 2 if present.
-      */
-      if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
+static void
+vlistAttUnpack(int vlistID, int varID,
+               void * buf, int size, int *position, void *context)
+{
+  int tempbuf[vlist_att_nints];
 
-      if ( ! l_iorj )
-	{
-	  /*
-	    Print section 3 if present.
-	  */
-	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
+  serializeUnpack(buf, size, position,
+                  tempbuf, vlist_att_nints, DATATYPE_INT, context);
+  char *attName = (char *)xmalloc((size_t)tempbuf[0] + 1);
+  serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
+  attName[tempbuf[0]] = '\0';
+  int attVDt;
+  size_t elemSize;
+  switch (tempbuf[2])
+  {
+  case DATATYPE_FLT:
+    attVDt = DATATYPE_FLT64;
+    elemSize = sizeof(double);
+    break;
+  case DATATYPE_INT:
+    attVDt = DATATYPE_INT;
+    elemSize = sizeof(int);
+    break;
+  case DATATYPE_TXT:
+    attVDt = DATATYPE_TXT;
+    elemSize = 1;
+    break;
+  default:
+    xabort("Unknown datatype encountered in attribute %s: %d\n",
+           attName, tempbuf[2]);
+  }
+  void *attData = (void *)xmalloc(elemSize * (size_t)tempbuf[3]);
+  serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
+  vlist_def_att(tempbuf[2], tempbuf[1], vlistID, varID, attName,
+                (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
+  free(attName);
+  free(attData);
+}
 
-	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
-	  /*
-	    Special print for 2D spectra wave field real values in
-	    section 4
-	  */
-	  if ( (isec1[ 0] ==  140) && 
-	       (isec1[ 1] ==   98) && 
-	       (isec1[23] ==    1) && 
-	       ((isec1[39] == 1045) || (isec1[39] == 1081))  && 
-	       ((isec1[ 5] ==  250) || (isec1[ 5] ==  251)) )
-	    gribPrintSec4Wave(isec4);
-	}
-    }
+void
+vlistAttsUnpack(int vlistID, int varID,
+                void * buf, int size, int *position, void *context)
+{
+  int numAtts, i;
+  serializeUnpack(buf, size, position, &numAtts, 1, DATATYPE_INT, context);
+  for (i = 0; i < numAtts; ++i)
+  {
+    vlistAttUnpack(vlistID, varID, buf, size, position, context);
+  }
 }
 
-#endif /* T */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-/* GRIB block 0 - indicator block */
-static
-void encodeIS(GRIBPACK *lGrib, long *gribLen)
-{
-  long z = *gribLen;
+#include <limits.h>
 
-  lGrib[0] = 'G';
-  lGrib[1] = 'R';
-  lGrib[2] = 'I';
-  lGrib[3] = 'B';
 
-  /* 
-   * lGrib[4]-lGrib[6] contains full length of grib record. 
-   * included before finished CODEGB
-   */
+#if  defined  (HAVE_LIBGRIB_API)
 
-  z = 7;   
-  Put1Byte(1); /* grib version */
-  z = 8;
+#  include <grib_api.h>
+#endif
 
-  *gribLen = z;
-}
 
-/* GRIB block 5 - end block */
 static
-void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
+void vlistvarInitEntry(int vlistID, int varID)
 {
-  long z = *gribLen;
-
-  lGrib[z++] = '7';
-  lGrib[z++] = '7';
-  lGrib[z++] = '7';
-  lGrib[z++] = '7';
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( z > JP23SET )
-    {
-      long itemp;
-      long bdslen = z - 4;
-      /*
-      fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET);
-      exit(1);
-      */
-      /*
-	If a very large product, the section 4 length field holds
-	the number of bytes in the product after section 4 upto
-	the end of the padding bytes.
-	This is a fixup to get round the restriction on product lengths
-	due to the count being only 24 bits. It is only possible because
-	the (default) rounding for GRIB products is 120 bytes.
-      */
-      while ( z%120 ) lGrib[z++] = 0;
+  vlistptr->vars[varID].fvarID        = varID;
+  vlistptr->vars[varID].mvarID        = varID;
+  vlistptr->vars[varID].flag          = 0;
+  vlistptr->vars[varID].param         = 0;
+  vlistptr->vars[varID].datatype      = CDI_UNDEFID;
+  vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
+  vlistptr->vars[varID].timave        = 0;
+  vlistptr->vars[varID].timaccu       = 0;
+  vlistptr->vars[varID].typeOfGeneratingProcess   = 0;
+  vlistptr->vars[varID].productDefinitionTemplate = -1;
+  vlistptr->vars[varID].chunktype     = cdiChunkType;
+  vlistptr->vars[varID].xyz           = 321;
+  vlistptr->vars[varID].gridID        = CDI_UNDEFID;
+  vlistptr->vars[varID].zaxisID       = CDI_UNDEFID;
+  vlistptr->vars[varID].instID        = CDI_UNDEFID;
+  vlistptr->vars[varID].modelID       = CDI_UNDEFID;
+  vlistptr->vars[varID].tableID       = CDI_UNDEFID;
+  vlistptr->vars[varID].missvalused   = FALSE;
+  vlistptr->vars[varID].missval       = cdiDefaultMissval;
+  vlistptr->vars[varID].addoffset     = 0.0;
+  vlistptr->vars[varID].scalefactor   = 1.0;
+  vlistptr->vars[varID].name          = NULL;
+  vlistptr->vars[varID].longname      = NULL;
+  vlistptr->vars[varID].stdname       = NULL;
+  vlistptr->vars[varID].units         = NULL;
+  vlistptr->vars[varID].extra         = NULL;
+  vlistptr->vars[varID].levinfo       = NULL;
+  vlistptr->vars[varID].comptype      = COMPRESS_NONE;
+  vlistptr->vars[varID].complevel     = 1;
+  vlistptr->vars[varID].atts.nalloc   = MAX_ATTRIBUTES;
+  vlistptr->vars[varID].atts.nelems   = 0;
+  vlistptr->vars[varID].lvalidrange   = 0;
+  vlistptr->vars[varID].validrange[0] = VALIDMISS;
+  vlistptr->vars[varID].validrange[1] = VALIDMISS;
+  vlistptr->vars[varID].ensdata       = NULL;
+  vlistptr->vars[varID].iorank        = CDI_UNDEFID;
 
-      if ( z > JP23SET*120 )
-	{
-	  fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET*120);
-	  exit(1);
-	}
+#if  defined  (HAVE_LIBGRIB_API)
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
 
-      itemp = z / (-120);
-      itemp = JP23SET - itemp + 1;
+  vlistptr->vars[varID].opt_grib_dbl_nentries = 0;
+  vlistptr->vars[varID].opt_grib_int_nentries = 0;
+  int i;
+  for (i=0; i<MAX_OPT_GRIB_ENTRIES; i++) {
+    vlistptr->vars[varID].opt_grib_int_val[i] =   0;
+    vlistptr->vars[varID].opt_grib_dbl_val[i] = 0.0;
+    vlistptr->vars[varID].opt_grib_int_update[i] = FALSE;
+    vlistptr->vars[varID].opt_grib_dbl_update[i] = FALSE;
+    vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
+    vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
+  } // for
+#endif
+}
 
-      lGrib[4] = itemp >> 16;
-      lGrib[5] = itemp >>  8;
-      lGrib[6] = itemp;
+static
+int vlistvarNewEntry(int vlistID)
+{
+  int varID = 0;
+  int vlistvarSize;
+  var_t *vlistvar;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      bdslen = z - bdslen;
-      lGrib[bdsstart  ] = bdslen >> 16;
-      lGrib[bdsstart+1] = bdslen >>  8;
-      lGrib[bdsstart+2] = bdslen;
+  vlistvarSize = vlistptr->varsAllocated;
+  vlistvar     = vlistptr->vars;
+  /*
+    Look for a free slot in vlistvar.
+    (Create the table the first time through).
+  */
+  if ( ! vlistvarSize )
+    {
+      vlistvarSize = 2;
+      vlistvar = (var_t *)xmalloc((size_t)vlistvarSize * sizeof (var_t));
+      for (int i = 0; i < vlistvarSize; i++ )
+	vlistvar[i].isUsed = FALSE;
     }
   else
     {
-      lGrib[4] = z >> 16;
-      lGrib[5] = z >>  8;
-      lGrib[6] = z;
-
-      while ( z%8 ) lGrib[z++] = 0;
+      while (varID < vlistvarSize && vlistvar[varID].isUsed)
+        ++varID;
     }
+  /*
+    If the table overflows, double its size.
+  */
+  if ( varID == vlistvarSize )
+    {
+      int i;
 
-  *gribLen = z;
-}
+      vlistvarSize = 2*vlistvarSize;
+      vlistvar = (var_t *)xrealloc(vlistvar,
+                                   (size_t)vlistvarSize * sizeof(var_t));
+      varID = vlistvarSize/2;
 
-/* GRIB block 1 - product definition block. */
+      for ( i = varID; i < vlistvarSize; i++ )
+	vlistvar[i].isUsed = FALSE;
+    }
 
-#define DWD_extension_253_len 38
-#define DWD_extension_254_len 26
-#define ECMWF_extension_1_len 24
-#define MPIM_extension_1_len  18
+  vlistptr->varsAllocated = vlistvarSize;
+  vlistptr->vars          = vlistvar;
 
-static
-long getLocalExtLen(int *isec1)
-{
-  long extlen = 0;
+  vlistvarInitEntry(vlistID, varID);
 
-  if ( ISEC1_LocalFLag )
-    {
-      if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
-	{
-	  if      ( isec1[36] == 254 ) extlen = DWD_extension_254_len;
-	  else if ( isec1[36] == 253 ) extlen = DWD_extension_253_len;
-	}
-      else if ( ISEC1_CenterID == 98 )
-        {
-	  if ( isec1[36] == 1 )   extlen = ECMWF_extension_1_len;
-        }
-      else if ( ISEC1_CenterID == 252 )
-        {
-	  if ( isec1[36] == 1 ) extlen = MPIM_extension_1_len;
-        }
-    }
+  vlistptr->vars[varID].isUsed = TRUE;
 
-  return (extlen);
+  return (varID);
 }
 
-static
-long getPdsLen(int *isec1)
+void vlistCheckVarID(const char *caller, int vlistID, int varID)
 {
-  long pdslen = 28;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  pdslen += getLocalExtLen(isec1);
+  if ( vlistptr == NULL )
+    Errorc("vlist undefined!");
 
-  return (pdslen);
+  if ( varID < 0 || varID >= vlistptr->nvars )
+    Errorc("varID %d undefined!", varID);
+
+  if ( ! vlistptr->vars[varID].isUsed )
+    Errorc("varID %d undefined!", varID);
 }
 
-static
-void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
-{
-  int isvn;
-  long localextlen, i;
-  long z = *zs;
+/*
+ at Function  vlistDefVar
+ at Title     Define a Variable
 
-  localextlen = getLocalExtLen(isec1);
-  for ( i = 0; i < localextlen-2; i++ )
-    {
-      Put1Byte(isec1[24+i]);
-    }
+ at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+ at Parameter
+    @Item  vlistID   Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  zaxisID   Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  tsteptype One of the set of predefined CDI timestep types.
+                     The valid CDI timestep types are @func{TSTEP_CONSTANT} and @func{TSTEP_INSTANT}.
+
+ at Description
+The function @func{vlistDefVar} adds a new variable to vlistID.
+
+ at Result
+ at func{vlistDefVar} returns an identifier to the new variable.
+
+ at Example
+Here is an example using @func{vlistCreate} to create a variable list
+and add a variable with @func{vlistDefVar}.
+
+ at Source
+   ...
+int vlistID, varID;
+   ...
+vlistID = vlistCreate();
+varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_INSTANT);
+   ...
+streamDefVlist(streamID, vlistID);
+   ...
+vlistDestroy(vlistID);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( CDI_Debug )
+    Message("gridID = %d  zaxisID = %d  tsteptype = %d", gridID, zaxisID, tsteptype);
 
-  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
-  Put2Byte(isvn);             /* DWD run type (0=main, 2=ass, 3=test) */
+  int varID = vlistvarNewEntry(vlistID);
 
-  *zs = z;
-}
+  vlistptr->nvars++;
 
-static
-void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
-{
-  int isvn;
-  long localextlen, i;
-  long z = *zs;
+  vlistptr->vars[varID].gridID  = gridID;
+  vlistptr->vars[varID].zaxisID = zaxisID;
+  vlistptr->vars[varID].tsteptype = tsteptype;
 
-  localextlen = DWD_extension_254_len;
-  for ( i = 0; i < localextlen-2; i++ )
+  if ( tsteptype < 0 )
     {
-      Put1Byte(isec1[24+i]);
+      Message("Unexpected tstep type %d, set to TSTEP_INSTANT!", tsteptype);
+      vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
     }
 
-  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
-  Put2Byte(isvn);             /* DWD run type (0=main, 2=ass, 3=test) */
-  Put1Byte(isec1[50]);        /* 55 User id, specified by table       */
-  Put2Byte(isec1[51]);        /* 56 Experiment identifier             */
-  Put2Byte(isec1[52]);        /* 58 Ensemble identification by table  */
-  Put2Byte(isec1[53]);        /* 60 Number of ensemble members        */
-  Put2Byte(isec1[54]);        /* 62 Actual number of ensemble member  */
-  Put1Byte(isec1[55]);        /* 64 Model major version number        */ 
-  Put1Byte(isec1[56]);        /* 65 Model minor version number        */ 
-  Put1Byte(0);                /* 66 Blank for even buffer length      */
+  vlistAdd2GridIDs(vlistptr, gridID);
+  vlistAdd2ZaxisIDs(vlistptr, zaxisID);
 
-  *zs = z;
+  vlistptr->vars[varID].param = cdiEncodeParam(-(varID + 1), 255, 255);
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+  return (varID);
 }
 
-static
-void encodePDS_ECMWF_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
+void
+cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID)
 {
-  // int isvn;
-  long localextlen, i;
-  long z = *zs;
+  xassert(varID >= 0 && varID < vlistptr->nvars
+          && vlistptr->vars[varID].levinfo == NULL);
+  int zaxisID = vlistptr->vars[varID].zaxisID;
+  size_t nlevs = (size_t)zaxisInqSize(zaxisID);
 
-  localextlen = getLocalExtLen(isec1);
-  for ( i = 0; i < localextlen-12; i++ )
-    {
-      Put1Byte(isec1[24+i]);
-    }
-                              /* 12 bytes explicitly encoded below:         */
-  Put1Byte(isec1[36]);        /* ECMWF local GRIB use definition identifier */
-                              /*    1=MARS labelling or ensemble fcst. data */
-  Put1Byte(isec1[37]);        /* Class                                      */
-  Put1Byte(isec1[38]);        /* Type                                       */
-  Put2Byte(isec1[39]);        /* Stream                                     */
+  vlistptr->vars[varID].levinfo
+    = (levinfo_t*)xmalloc((size_t)nlevs * sizeof(levinfo_t));
 
-  /* Version number or experiment identifier    */
-  Put1Byte(((unsigned char*) &isec1[40])[0]);
-  Put1Byte(((unsigned char*) &isec1[40])[1]);
-  Put1Byte(((unsigned char*) &isec1[40])[2]);
-  Put1Byte(((unsigned char*) &isec1[40])[3]);
+  for (size_t levID = 0; levID < nlevs; levID++ )
+    vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO((int)levID);
+}
 
-  Put1Byte(isec1[41]);        /* Ensemble forecast number                   */
-  Put1Byte(isec1[42]);        /* Total number of forecasts in ensemble      */
-  Put1Byte(0);                /* (Spare)                                    */
+/*
+ at Function  vlistDefVarParam
+ at Title     Define the parameter number of a Variable
 
-  *zs = z;
-}
+ at Prototype void vlistDefVarParam(int vlistID, int varID, int param)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  param    Parameter number.
 
-static
-void encodePDS_MPIM_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
+ at Description
+The function @func{vlistDefVarParam} defines the parameter number of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarParam(int vlistID, int varID, int param)
 {
-  // int isvn;
-  long localextlen, i;
-  long z = *zs;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  localextlen = getLocalExtLen(isec1);
-  for ( i = 0; i < localextlen-6; i++ )
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if (vlistptr->vars[varID].param != param)
     {
-      Put1Byte(isec1[24+i]);
+      vlistptr->vars[varID].param = param;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-                              /* 6 bytes explicitly encoded below:          */
-  Put1Byte(isec1[36]);        /* MPIM local GRIB use definition identifier  */
-                              /*    (extension identifier)                  */
-  Put1Byte(isec1[37]);        /* type of ensemble forecast                  */
-  Put2Byte(isec1[38]);        /* individual ensemble member                 */
-  Put2Byte(isec1[39]);        /* number of forecasts in ensemble            */
-
-  *zs = z;
 }
 
-/* GRIB BLOCK 1 - PRODUCT DESCRIPTION SECTION */
-static
-void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
+/*
+ at Function  vlistDefVarCode
+ at Title     Define the code number of a Variable
+
+ at Prototype void vlistDefVarCode(int vlistID, int varID, int code)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  code     Code number.
+
+ at Description
+The function @func{vlistDefVarCode} defines the code number of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarCode(int vlistID, int varID, int code)
 {
-  GRIBPACK *lGrib = lpds;
-  long z = 0;
-  int ival, century, year;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  century = ISEC1_Century;
-  year    = ISEC1_Year;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  if ( century < 0 )
+  int param = vlistptr->vars[varID].param;
+  int pnum, pcat, pdis;
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  int newParam = cdiEncodeParam(code, pcat, pdis);
+  if (vlistptr->vars[varID].param != newParam)
     {
-      century = -century;
-      year    = -year;
+      vlistptr->vars[varID].param = newParam;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  Put3Byte(pdsLen);               /*  0 Length of Block 1        */
-  Put1Byte(ISEC1_CodeTable);      /*  3 Local table number       */
-  Put1Byte(ISEC1_CenterID);       /*  4 Identification of centre */
-  Put1Byte(ISEC1_ModelID);        /*  5 Identification of model  */
-  Put1Byte(ISEC1_GridDefinition); /*  6 Grid definition          */
-  Put1Byte(ISEC1_Sec2Or3Flag);    /*  7 Block 2 included         */
-  Put1Byte(ISEC1_Parameter);      /*  8 Parameter Code           */
-  Put1Byte(ISEC1_LevelType);      /*  9 Type of level            */
-  if ( (ISEC1_LevelType !=  20) &&
-       (ISEC1_LevelType != GRIB1_LTYPE_99)         &&
-       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC)   &&
-       (ISEC1_LevelType != GRIB1_LTYPE_ALTITUDE)   &&
-       (ISEC1_LevelType != GRIB1_LTYPE_HEIGHT)     &&
-       (ISEC1_LevelType != GRIB1_LTYPE_SIGMA)      &&
-       (ISEC1_LevelType != GRIB1_LTYPE_HYBRID)     &&
-       (ISEC1_LevelType != GRIB1_LTYPE_LANDDEPTH)  &&
-       (ISEC1_LevelType != GRIB1_LTYPE_ISENTROPIC) &&
-       (ISEC1_LevelType != 115) &&
-       (ISEC1_LevelType != 117) &&
-       (ISEC1_LevelType != 125) &&
-       (ISEC1_LevelType != 127) &&
-       (ISEC1_LevelType != 160) &&
-       (ISEC1_LevelType != 210) )
-    {
-      Put1Byte(ISEC1_Level1);
-      Put1Byte(ISEC1_Level2);
-    }
-  else
-    {
-      Put2Byte(ISEC1_Level1);     /* 10 Level                    */    
-    }
 
-  Put1Int(year);                  /* 12 Year of Century          */
-  Put1Byte(ISEC1_Month);          /* 13 Month                    */
-  Put1Byte(ISEC1_Day);            /* 14 Day                      */
-  Put1Byte(ISEC1_Hour);           /* 15 Hour                     */
-  Put1Byte(ISEC1_Minute);         /* 16 Minute                   */
+void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  Put1Byte(ISEC1_TimeUnit);       /* 17 Time unit                */
-  if ( ISEC1_TimeRange == 10 )
-    {
-      Put1Byte(ISEC1_TimePeriod1);
-      Put1Byte(ISEC1_TimePeriod2);
-    }
-  else if ( ISEC1_TimeRange == 113 || ISEC1_TimeRange ==   0 )
-    {
-      Put1Byte(ISEC1_TimePeriod1);
-      Put1Byte(0);
-    }
-  else if ( ISEC1_TimeRange ==   5 || ISEC1_TimeRange ==   4 || 
-	    ISEC1_TimeRange ==   3 || ISEC1_TimeRange ==   2 )
-    {
-      Put1Byte(0);
-      Put1Byte(ISEC1_TimePeriod2);
-    }
-  else
-    {
-      Put1Byte(0);
-      Put1Byte(0); 
-    }
-  Put1Byte(ISEC1_TimeRange);      /* 20 Timerange flag           */
-  Put2Byte(ISEC1_AvgNum);         /* 21 Average                  */
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  Put1Byte(ISEC1_AvgMiss);        /* 23 Missing from averages    */
-  Put1Byte(century);              /* 24 Century                  */
-  Put1Byte(ISEC1_SubCenterID);    /* 25 Subcenter                */
-  Put2Byte(ISEC1_DecScaleFactor); /* 26 Decimal scale factor     */
+  *gridID    = vlistptr->vars[varID].gridID;
+  *zaxisID   = vlistptr->vars[varID].zaxisID;
+  *tsteptype = vlistptr->vars[varID].tsteptype;
 
-  if ( ISEC1_LocalFLag )
-    {
-      if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
-	{
-	  if      ( isec1[36] == 254 ) encodePDS_DWD_local_Extension_254(lGrib, &z, isec1);
-	  else if ( isec1[36] == 253 ) encodePDS_DWD_local_Extension_253(lGrib, &z, isec1);
-	}
-      else if ( ISEC1_CenterID == 98 )
-	{
-	  if ( isec1[36] == 1 ) encodePDS_ECMWF_local_Extension_1(lGrib, &z, isec1);
-	}
-      else if ( ISEC1_CenterID == 252 )
-	{
-	  if ( isec1[36] == 1 ) encodePDS_MPIM_local_Extension_1(lGrib, &z, isec1);
-	}
-      else
-	{
-	  long i, localextlen;
-	  localextlen = getLocalExtLen(isec1);
-	  for ( i = 0; i < localextlen; i++ )
-	    {
-	      Put1Byte(isec1[24+i]);
-	    }
-	}
-    }
+  return;
 }
 
-int  BitsPerInt = (int) (sizeof(int) * 8);
+/*
+ at Function  vlistInqVarGrid
+ at Title     Get the Grid ID of a Variable
 
+ at Prototype int vlistInqVarGrid(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
 
+ at Description
+The function @func{vlistInqVarGrid} returns the grid ID of a variable.
 
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
+ at Result
+ at func{vlistInqVarGrid} returns the grid ID of the variable.
 
-static
-void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
-				     const T *data, T zref, T factor, size_t *gz)
+ at EndFunction
+*/
+int vlistInqVarGrid(int vlistID, int varID)
 {
-  size_t i, z = *gz;
-  unsigned int ival;
-  int cbits, jbits;
-  unsigned int c;
-  static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-    
-  /* code from gribw routine flist2bitstream */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  cbits = 8;
-  c = 0;
-  for ( i = packStart; i < datasize; i++ )
-    {
-      /* note float -> unsigned int .. truncate */
-      ival = (unsigned int) ((data[i] - zref) * factor + 0.5);
-      /*
-	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
-	if ( ival < 0 ) ival = 0;
-      */
-      jbits = numBits;
-      while ( cbits <= jbits ) 
-	{
-	  if ( cbits == 8 )
-	    {
-	      jbits -= 8;
-	      lGrib[z++] = (ival >> jbits) & 0xFF;
-	    }
-	  else
-	    {
-	      jbits -= cbits;
-	      lGrib[z++] = (c << cbits) + ((ival >> jbits) & mask[cbits]);
-	      cbits = 8;
-	      c = 0;
-	    }
-	}
-      /* now jbits < cbits */
-      if ( jbits )
-	{
-	  c = (c << jbits) + (ival & mask[jbits]);
-	  cbits -= jbits;
-	}
-    }
-  if ( cbits != 8 ) lGrib[z++] = c << cbits;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *gz = z;
+  return (vlistptr->vars[varID].gridID);
 }
 
-static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
-				    const T *restrict data, T zref, T factor, size_t *gz)
+/*
+ at Function  vlistInqVarZaxis
+ at Title     Get the Zaxis ID of a Variable
+
+ at Prototype int vlistInqVarZaxis(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+
+ at Description
+The function @func{vlistInqVarZaxis} returns the zaxis ID of a variable.
+
+ at Result
+ at func{vlistInqVarZaxis} returns the zaxis ID of the variable.
+
+ at EndFunction
+*/
+int vlistInqVarZaxis(int vlistID, int varID)
 {
-  size_t i, z = *gz;
-  uint16_t ui16;
-  T tmp;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-  for ( i = 0; i < datasize; i++ )
-    {
-      tmp = ((data[i] - zref) * factor + 0.5);
-      ui16 = (uint16_t) tmp;
-      lGrib[z  ] = ui16 >>  8;
-      lGrib[z+1] = ui16;
-      z += 2;
-    }
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *gz = z;
+  return (vlistptr->vars[varID].zaxisID);
 }
 
-static
-void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize, 
-			      GRIBPACK *restrict lGrib,
-			      const T *restrict data, 
-			      T zref, T factor, size_t *gz)
-{
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
-  uint64_t start_minmax, end_minmax;
-#endif
+/*
+ at Function  vlistInqVarParam
+ at Title     Get the parameter number of a Variable
 
-  uint32_t ui32;
-  size_t i, z = *gz;
-  T tmp;
+ at Prototype int vlistInqVarParam(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
 
-  data += packStart;
-  datasize -= packStart;
+ at Description
+The function @func{vlistInqVarParam} returns the parameter number of a variable.
 
-  if      ( numBits ==  8 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(2, "pack 8 bit base");
-#endif
+ at Result
+ at func{vlistInqVarParam} returns the parameter number of the variable.
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-	  lGrib[z  ] = (uint16_t) tmp;
-          z++;
-	}
+ at EndFunction
+*/
+int vlistInqVarParam(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(2);
-#endif
-    }
-  else if ( numBits == 16 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(3, "pack 16 bit base");
-#elif defined _GET_X86_COUNTER 
-      start_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      start_minmax = mach_absolute_time();
-#endif
+  vlistCheckVarID(__func__, vlistID, varID);
 
-      if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-          avx_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#elif defined _ENABLE_SSE4_1
-          sse41_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#else
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-#endif
-        }
-      else
-        {
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-        }
+  return (vlistptr->vars[varID].param);
+}
 
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER 
-      end_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      end_minmax = mach_absolute_time();
-#endif
-#if defined _ENABLE_AVX
-      printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#elif defined _ENABLE_SSE4_1
-      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#else
-      printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#endif  
-#endif
-      
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(3);
-#endif
-    }
-  else if ( numBits == 24 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(4, "pack 24 bit base");
-#endif
+/*
+ at Function  vlistInqVarCode
+ at Title     Get the Code number of a Variable
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-          ui32 = (uint32_t) tmp;
-          lGrib[z  ] =  ui32 >> 16;
-          lGrib[z+1] =  ui32 >>  8;
-          lGrib[z+2] =  ui32;
-          z += 3;
-	}
+ at Prototype int vlistInqVarCode(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(4);
-#endif
-    }
-  else if ( numBits == 32 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(5, "pack 32 bit base");
-#endif
+ at Description
+The function @func{vlistInqVarCode} returns the code number of a variable.
+
+ at Result
+ at func{vlistInqVarCode} returns the code number of the variable.
+
+ at EndFunction
+*/
+int vlistInqVarCode(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-          ui32 = (uint32_t) tmp;
-          lGrib[z  ] =  ui32 >> 24;
-          lGrib[z+1] =  ui32 >> 16;
-          lGrib[z+2] =  ui32 >>  8;
-          lGrib[z+3] =  ui32;
-          z += 4;
-	}
+  vlistCheckVarID(__func__, vlistID, varID);
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(5);
-#endif
-    }
-  else if ( numBits > 0 && numBits <= 32 )
-    {
-      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
-    }
-  else if ( numBits == 0 )
-    {
-    }
-  else
+  int param = vlistptr->vars[varID].param;
+  int pdis, pcat, pnum;
+  cdiDecodeParam(param, &pnum, &pcat, &pdis);
+  int code = pdis == 255 ? pnum : -varID-1;
+
+  if ( code < 0 && vlistptr->vars[varID].tableID != -1 && vlistptr->vars[varID].name != NULL )
     {
-      Error("Unimplemented packing factor %d!", numBits);
+      tableInqParCode(vlistptr->vars[varID].tableID, vlistptr->vars[varID].name, &code);
     }
 
-  *gz = z;
+  return (code);
 }
 
-static
-void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize, 
-				       GRIBPACK *restrict lGrib,
-				       const T *restrict data, 
-				       T zref, T factor, size_t *gz)
+
+const char *vlistInqVarNamePtr(int vlistID, int varID)
 {
-  U_BYTEORDER;
-  size_t i, j, z = *gz;
-#ifdef _ARCH_PWR6
-#define __UNROLL_DEPTH_2 8
-#else
-#define __UNROLL_DEPTH_2 8
-#endif
-  size_t residual;
-  size_t ofs;
-  T dval[__UNROLL_DEPTH_2];
-  unsigned long ival;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  data += packStart;
-  datasize -= packStart;
-  residual =  datasize % __UNROLL_DEPTH_2;
-  ofs = datasize - residual;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  // reducing FP operations to single FMA is slowing down on pwr6 ...
+  return (vlistptr->vars[varID].name);
+}
 
-  if      ( numBits ==  8 )
-    {
-      unsigned char *cgrib = (unsigned char *) (lGrib + z);
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(2, "pack 8 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      *cgrib++ =  (unsigned long) dval[j];
-	    }
-	  z += __UNROLL_DEPTH_2;
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  *cgrib++ = (unsigned long) dval[j];
-	}
-      z += residual;
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(2);
-#endif
-    }
-  else if ( numBits == 16 )
+const char *vlistInqVarLongnamePtr(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  return (vlistptr->vars[varID].longname);
+}
+
+
+const char *vlistInqVarStdnamePtr(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  return (vlistptr->vars[varID].stdname);
+}
+
+
+const char *vlistInqVarUnitsPtr(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  return (vlistptr->vars[varID].units);
+}
+
+/*
+ at Function  vlistInqVarName
+ at Title     Get the name of a Variable
+
+ at Prototype void vlistInqVarName(int vlistID, int varID, char *name)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+    @Item  name     Returned variable name. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{vlistInqVarName} returns the name of a variable.
+
+ at Result
+ at func{vlistInqVarName} returns the name of the variable to the parameter name if available,
+otherwise the result is an empty string.
+
+ at EndFunction
+*/
+void vlistInqVarName(int vlistID, int varID, char *name)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( vlistptr->vars[varID].name == NULL )
     {
-      unsigned short *sgrib = (unsigned short *) (lGrib + z);
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(3, "pack 16 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  if ( IS_BIGENDIAN() )
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  *sgrib++ = (unsigned long) dval[j];
-		}
-	      z += 2*__UNROLL_DEPTH_2;
-	    }
-	  else
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  ival = (unsigned long) dval[j];
-		  lGrib[z  ] = ival >>  8;
-		  lGrib[z+1] = ival;
-		  z += 2;
-		}
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      if ( IS_BIGENDIAN() )
+      int param = vlistptr->vars[varID].param;
+      int pdis, pcat, pnum;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+      if ( pdis == 255 )
 	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      *sgrib++ = (unsigned long) dval[j];
-	    }
-	  z += 2*residual;
+	  int code = pnum;
+	  int tableID = vlistptr->vars[varID].tableID;
+	  if ( tableInqParName(tableID, code, name) != 0 )
+	    sprintf(name, "var%d", code);
 	}
       else
 	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] = ival >>  8;
-	      lGrib[z+1] = ival;
-	      z += 2;
-	    }
+	  sprintf(name, "param%d.%d.%d", pnum, pcat, pdis);
 	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(3);
-#endif
     }
-  else if ( numBits == 24 )
+  else
+    strcpy(name, vlistptr->vars[varID].name);   //FIXME: This may overrun the provided buffer.
+
+  return;
+}
+
+/*
+ at Function vlistCopyVarName
+ at Tatle    Get the name of a Variable in a safe way
+
+ at Prototype char* vlistCopyVarName(int vlistId, int varId)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+
+ at Return A pointer to a malloc'ed string. Must be cleaned up with free().
+
+ at Description
+This is the buffer overflow immune version of vlistInqVarName().
+The memory for the returned string is allocated to fit the string via malloc().
+
+ at EndFunction
+*/
+char* vlistCopyVarName(int vlistId, int varId)
+{
+  vlist_t* vlistptr = vlist_to_pointer(vlistId);
+  vlistCheckVarID(__func__, vlistId, varId);
+
+  //If a name is set in the variable description, use that.
+  const char* name = vlistptr->vars[varId].name;
+  if(name) return myStrDup(name);
+
+  //Otherwise we check if we should use the table of parameter descriptions.
+  int param = vlistptr->vars[varId].param;
+  int discipline, category, number;
+  cdiDecodeParam(param, &number, &category, &discipline);
+  if(discipline == 255)
     {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(4, "pack 24 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] =  ival >> 16;
-	      lGrib[z+1] =  ival >>  8;
-	      lGrib[z+2] =  ival;
-	      z += 3;
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  ival = (unsigned long) dval[j];
-	  lGrib[z  ] =  ival >> 16;
-	  lGrib[z+1] =  ival >>  8;
-	  lGrib[z+2] =  ival;
-	  z += 3;
-	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(4);
-#endif
+      int tableId = vlistptr->vars[varId].tableID;
+      if(( name = tableInqParNamePtr(tableId, number) )) return myStrDup(name);
+
+      //No luck, fall back to outputting a name of the format "var<num>".
+      return myAsprintf("var%d", number);
     }
-  else if ( numBits == 32 )
+
+  //Finally, we fall back to outputting a name of the format "param<num>.<cat>.<dis>".
+  return myAsprintf("param%d.%d.%d", number, category, discipline);
+}
+
+/*
+ at Function  vlistInqVarLongname
+ at Title     Get the longname of a Variable
+
+ at Prototype void vlistInqVarLongname(int vlistID, int varID, char *longname)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+    @Item  longname Long name of the variable. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{vlistInqVarLongname} returns the longname of a variable if available,
+otherwise the result is an empty string.
+
+ at Result
+ at func{vlistInqVaeLongname} returns the longname of the variable to the parameter longname.
+
+ at EndFunction
+*/
+void vlistInqVarLongname(int vlistID, int varID, char *longname)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  longname[0] = '\0';
+
+  if ( vlistptr->vars[varID].longname == NULL )
     {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(5, "pack 32 bit unrolled");
-#endif
-      unsigned int *igrib = (unsigned int *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  if ( IS_BIGENDIAN() )
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  *igrib = (unsigned long) dval[j];
-		  igrib++;
-		  z += 4;
-		}
-	    }
-	  else
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  ival = (unsigned long) dval[j];
-		  lGrib[z  ] =  ival >> 24;
-		  lGrib[z+1] =  ival >> 16;
-		  lGrib[z+2] =  ival >>  8;
-		  lGrib[z+3] =  ival;
-		  z += 4;
-		}
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      if ( IS_BIGENDIAN() )
-	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      *igrib = (unsigned long) dval[j];
-	      igrib++;
-	      z += 4;
-	    }
-	}
-      else
+      int param = vlistptr->vars[varID].param;
+      int pdis, pcat, pnum;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+      if ( pdis == 255 )
 	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] =  ival >> 24;
-	      lGrib[z+1] =  ival >> 16;
-	      lGrib[z+2] =  ival >>  8;
-	      lGrib[z+3] =  ival;
-	      z += 4;
-	    }
+	  int code = pnum;
+          int tableID = vlistptr->vars[varID].tableID;
+	  if ( tableInqParLongname(tableID, code, longname) != 0 )
+	    longname[0] = '\0';
 	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(5);
-#endif
-    }
-  else if ( numBits > 0 && numBits <= 32 )
-    {
-      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
-    }
-  else if ( numBits == 0 )
-    {
     }
   else
+    strcpy(longname, vlistptr->vars[varID].longname);
+
+  return;
+}
+
+/*
+ at Function  vlistInqVarStdname
+ at Title     Get the standard name of a Variable
+
+ at Prototype void vlistInqVarStdname(int vlistID, int varID, char *stdname)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+    @Item  stdname  Standard name of the variable. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{vlistInqVarStdname} returns the standard name of a variable if available,
+otherwise the result is an empty string.
+
+ at Result
+ at func{vlistInqVarName} returns the standard name of the variable to the parameter stdname.
+
+ at EndFunction
+*/
+void vlistInqVarStdname(int vlistID, int varID, char *stdname)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( vlistptr->vars[varID].stdname == NULL )
     {
-      Error("Unimplemented packing factor %d!", numBits);
+      stdname[0] = '\0';
     }
+  else
+    strcpy(stdname, vlistptr->vars[varID].stdname);
 
-  *gz = z;
-#undef __UNROLL_DEPTH_2
+  return;
 }
 
-#endif /* T */
+/*
+ at Function  vlistInqVarUnits
+ at Title     Get the units of a Variable
 
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
+ at Prototype void vlistInqVarUnits(int vlistID, int varID, char *units)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+    @Item  units    Units of the variable. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-static
-void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datasize, GRIBPACK *lGrib,
-				     const T *data, T zref, T factor, size_t *gz)
+ at Description
+The function @func{vlistInqVarUnits} returns the units of a variable if available,
+otherwise the result is an empty string.
+
+ at Result
+ at func{vlistInqVarUnits} returns the units of the variable to the parameter units.
+
+ at EndFunction
+*/
+void vlistInqVarUnits(int vlistID, int varID, char *units)
 {
-  size_t i, z = *gz;
-  unsigned int ival;
-  int cbits, jbits;
-  unsigned int c;
-  static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-    
-  /* code from gribw routine flist2bitstream */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  cbits = 8;
-  c = 0;
-  for ( i = packStart; i < datasize; i++ )
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  units[0] = '\0';
+
+  if ( vlistptr->vars[varID].units == NULL )
     {
-      /* note float -> unsigned int .. truncate */
-      ival = (unsigned int) ((data[i] - zref) * factor + 0.5);
-      /*
-	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
-	if ( ival < 0 ) ival = 0;
-      */
-      jbits = numBits;
-      while ( cbits <= jbits ) 
-	{
-	  if ( cbits == 8 )
-	    {
-	      jbits -= 8;
-	      lGrib[z++] = (ival >> jbits) & 0xFF;
-	    }
-	  else
-	    {
-	      jbits -= cbits;
-	      lGrib[z++] = (c << cbits) + ((ival >> jbits) & mask[cbits]);
-	      cbits = 8;
-	      c = 0;
-	    }
-	}
-      /* now jbits < cbits */
-      if ( jbits )
+      int param = vlistptr->vars[varID].param;
+      int pdis, pcat, pnum;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+      if ( pdis == 255 )
 	{
-	  c = (c << jbits) + (ival & mask[jbits]);
-	  cbits -= jbits;
+	  int code = pnum;
+	  int tableID = vlistptr->vars[varID].tableID;
+	  if ( tableInqParUnits(tableID, code, units) != 0 )
+	    units[0] = '\0';
 	}
     }
-  if ( cbits != 8 ) lGrib[z++] = c << cbits;
+  else
+    strcpy(units, vlistptr->vars[varID].units);
 
-  *gz = z;
+  return;
 }
 
-static
-void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
-				    const T *restrict data, T zref, T factor, size_t *gz)
+/* used in MPIOM ! */
+int vlistInqVarID(int vlistID, int code)
 {
-  size_t i, z = *gz;
-  uint16_t ui16;
-  T tmp;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-  for ( i = 0; i < datasize; i++ )
+  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
     {
-      tmp = ((data[i] - zref) * factor + 0.5);
-      ui16 = (uint16_t) tmp;
-      lGrib[z  ] = ui16 >>  8;
-      lGrib[z+1] = ui16;
-      z += 2;
+      int param = vlistptr->vars[varID].param;
+      int pdis, pcat, pnum;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+      if ( pnum == code ) return (varID);
     }
 
-  *gz = z;
+  return (CDI_UNDEFID);
 }
 
-static
-void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize, 
-			      GRIBPACK *restrict lGrib,
-			      const T *restrict data, 
-			      T zref, T factor, size_t *gz)
+
+int vlistInqVarSize(int vlistID, int varID)
 {
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
-  uint64_t start_minmax, end_minmax;
-#endif
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  uint32_t ui32;
-  size_t i, z = *gz;
-  T tmp;
+  int zaxisID, gridID;
+  int tsteptype;
+  vlistInqVar(vlistID, varID, &gridID, &zaxisID, &tsteptype);
 
-  data += packStart;
-  datasize -= packStart;
+  int nlevs = zaxisInqSize(zaxisID);
 
-  if      ( numBits ==  8 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(2, "pack 8 bit base");
-#endif
+  int gridsize = gridInqSize(gridID);
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-	  lGrib[z  ] = (uint16_t) tmp;
-          z++;
-	}
+  int size = gridsize*nlevs;
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(2);
-#endif
-    }
-  else if ( numBits == 16 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(3, "pack 16 bit base");
-#elif defined _GET_X86_COUNTER 
-      start_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      start_minmax = mach_absolute_time();
-#endif
+  return (size);
+}
 
-      if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-          avx_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#elif defined _ENABLE_SSE4_1
-          sse41_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#else
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-#endif
-        }
-      else
-        {
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-        }
+/*
+ at Function  vlistInqVarDatatype
+ at Title     Get the data type of a Variable
 
-#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
-#if defined _GET_X86_COUNTER 
-      end_minmax = _rdtsc();
-#elif defined _GET_MACH_COUNTER 
-      end_minmax = mach_absolute_time();
-#endif
-#if defined _ENABLE_AVX
-      printf("AVX encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#elif defined _ENABLE_SSE4_1
-      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#else
-      printf("loop encoding cycles:: %" PRIu64 "\n", end_minmax-start_minmax);
-#endif  
-#endif
-      
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(3);
-#endif
-    }
-  else if ( numBits == 24 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(4, "pack 24 bit base");
-#endif
+ at Prototype int vlistInqVarDatatype(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-          ui32 = (uint32_t) tmp;
-          lGrib[z  ] =  ui32 >> 16;
-          lGrib[z+1] =  ui32 >>  8;
-          lGrib[z+2] =  ui32;
-          z += 3;
-	}
+ at Description
+The function @func{vlistInqVarDatatype} returns the data type of a variable.
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(4);
-#endif
-    }
-  else if ( numBits == 32 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(5, "pack 32 bit base");
-#endif
+ at Result
+ at func{vlistInqVarDatatype} returns an identifier to the data type of the variable.
+The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16}, @func{DATATYPE_PACK24},
+ at func{DATATYPE_FLT32}, @func{DATATYPE_FLT64}, @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and 
+ at func{DATATYPE_INT32}.
 
-#if   defined (CRAY)
-#pragma _CRI ivdep
-#elif defined (SX)
-#pragma vdir nodep
-#elif defined (__uxp__)
-#pragma loop novrec
-#elif defined (__ICC)
-#pragma ivdep
-#endif
-      for ( i = 0; i < datasize; i++ )
-	{
-	  tmp = ((data[i] - zref) * factor + 0.5);
-          ui32 = (uint32_t) tmp;
-          lGrib[z  ] =  ui32 >> 24;
-          lGrib[z+1] =  ui32 >> 16;
-          lGrib[z+2] =  ui32 >>  8;
-          lGrib[z+3] =  ui32;
-          z += 4;
-	}
+ at EndFunction
+*/
+int vlistInqVarDatatype(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(5);
-#endif
-    }
-  else if ( numBits > 0 && numBits <= 32 )
-    {
-      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
-    }
-  else if ( numBits == 0 )
-    {
-    }
-  else
-    {
-      Error("Unimplemented packing factor %d!", numBits);
-    }
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *gz = z;
+  return (vlistptr->vars[varID].datatype);
 }
 
-static
-void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t datasize, 
-				       GRIBPACK *restrict lGrib,
-				       const T *restrict data, 
-				       T zref, T factor, size_t *gz)
+
+int vlistInqVarNumber(int vlistID, int varID)
 {
-  U_BYTEORDER;
-  size_t i, j, z = *gz;
-#ifdef _ARCH_PWR6
-#define __UNROLL_DEPTH_2 8
-#else
-#define __UNROLL_DEPTH_2 8
-#endif
-  size_t residual;
-  size_t ofs;
-  T dval[__UNROLL_DEPTH_2];
-  unsigned long ival;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  data += packStart;
-  datasize -= packStart;
-  residual =  datasize % __UNROLL_DEPTH_2;
-  ofs = datasize - residual;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  // reducing FP operations to single FMA is slowing down on pwr6 ...
+  int number = CDI_REAL;
+  if ( vlistptr->vars[varID].datatype == DATATYPE_CPX32 ||
+       vlistptr->vars[varID].datatype == DATATYPE_CPX64 )
+    number = CDI_COMP;
 
-  if      ( numBits ==  8 )
-    {
-      unsigned char *cgrib = (unsigned char *) (lGrib + z);
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(2, "pack 8 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      *cgrib++ =  (unsigned long) dval[j];
-	    }
-	  z += __UNROLL_DEPTH_2;
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  *cgrib++ = (unsigned long) dval[j];
-	}
-      z += residual;
+  return (number);
+}
 
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(2);
-#endif
-    }
-  else if ( numBits == 16 )
-    {
-      unsigned short *sgrib = (unsigned short *) (lGrib + z);
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(3, "pack 16 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  if ( IS_BIGENDIAN() )
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  *sgrib++ = (unsigned long) dval[j];
-		}
-	      z += 2*__UNROLL_DEPTH_2;
-	    }
-	  else
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  ival = (unsigned long) dval[j];
-		  lGrib[z  ] = ival >>  8;
-		  lGrib[z+1] = ival;
-		  z += 2;
-		}
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      if ( IS_BIGENDIAN() )
-	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      *sgrib++ = (unsigned long) dval[j];
-	    }
-	  z += 2*residual;
-	}
-      else
-	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] = ival >>  8;
-	      lGrib[z+1] = ival;
-	      z += 2;
-	    }
-	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(3);
-#endif
-    }
-  else if ( numBits == 24 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(4, "pack 24 bit unrolled");
-#endif
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] =  ival >> 16;
-	      lGrib[z+1] =  ival >>  8;
-	      lGrib[z+2] =  ival;
-	      z += 3;
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  ival = (unsigned long) dval[j];
-	  lGrib[z  ] =  ival >> 16;
-	  lGrib[z+1] =  ival >>  8;
-	  lGrib[z+2] =  ival;
-	  z += 3;
-	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(4);
-#endif
-    }
-  else if ( numBits == 32 )
-    {
-#ifdef _GET_IBM_COUNTER 
-      hpmStart(5, "pack 32 bit unrolled");
-#endif
-      unsigned int *igrib = (unsigned int *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
-	{
-	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-	    {
-	      dval[j] = ((data[i+j] - zref) * factor + 0.5);
-	    }
-	  if ( IS_BIGENDIAN() )
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  *igrib = (unsigned long) dval[j];
-		  igrib++;
-		  z += 4;
-		}
-	    }
-	  else
-	    {
-	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
-		{
-		  ival = (unsigned long) dval[j];
-		  lGrib[z  ] =  ival >> 24;
-		  lGrib[z+1] =  ival >> 16;
-		  lGrib[z+2] =  ival >>  8;
-		  lGrib[z+3] =  ival;
-		  z += 4;
-		}
-	    }
-	}
-      for (j = 0; j < residual; j++) 
-	{
-	  dval[j] = ((data[ofs+j] - zref) * factor + 0.5);
-	}
-      if ( IS_BIGENDIAN() )
-	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      *igrib = (unsigned long) dval[j];
-	      igrib++;
-	      z += 4;
-	    }
-	}
-      else
-	{
-	  for (j = 0; j < residual; j++) 
-	    {
-	      ival = (unsigned long) dval[j];
-	      lGrib[z  ] =  ival >> 24;
-	      lGrib[z+1] =  ival >> 16;
-	      lGrib[z+2] =  ival >>  8;
-	      lGrib[z+3] =  ival;
-	      z += 4;
-	    }
-	}
-#ifdef _GET_IBM_COUNTER 
-      hpmStop(5);
-#endif
-    }
-  else if ( numBits > 0 && numBits <= 32 )
-    {
-      TEMPLATE(encode_array_common,T)(numBits, 0, datasize, lGrib, data, zref, factor, &z);
-    }
-  else if ( numBits == 0 )
+/*
+ at Function  vlistDefVarDatatype
+ at Title     Define the data type of a Variable
+
+ at Prototype void vlistDefVarDatatype(int vlistID, int varID, int datatype)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  datatype The data type identifier.
+                    The valid CDI data types are @func{DATATYPE_PACK8}, @func{DATATYPE_PACK16},
+                    @func{DATATYPE_PACK24}, @func{DATATYPE_FLT32}, @func{DATATYPE_FLT64},
+                    @func{DATATYPE_INT8}, @func{DATATYPE_INT16} and @func{DATATYPE_INT32}.
+
+ at Description
+The function @func{vlistDefVarDatatype} defines the data type of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarDatatype(int vlistID, int varID, int datatype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if (vlistptr->vars[varID].datatype != datatype)
     {
+      vlistptr->vars[varID].datatype = datatype;
+
+      if ( vlistptr->vars[varID].missvalused == FALSE )
+        switch (datatype)
+          {
+          case DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
+          case DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
+          case DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
+          case DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
+          case DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
+          case DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
+          }
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-  else
+}
+
+
+void vlistDefVarInstitut(int vlistID, int varID, int instID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].instID != instID)
     {
-      Error("Unimplemented packing factor %d!", numBits);
+      vlistptr->vars[varID].instID = instID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  *gz = z;
-#undef __UNROLL_DEPTH_2
+
+int vlistInqVarInstitut(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].instID);
 }
 
-#endif /* T */
 
+void vlistDefVarModel(int vlistID, int varID, int modelID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].modelID != modelID)
+    {
+      vlistptr->vars[varID].modelID = modelID;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-#ifdef T
-#undef T
-#endif
-#define T double
-#ifdef T
 
-/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
-static
-void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
+int vlistInqVarModel(int vlistID, int varID)
 {
-  long z = *gribLen;
-  int exponent, mantissa;
-  long i;
-  int ival;
-  int pvoffset = 0xFF;
-  int gdslen = 32;
-  unsigned lonIncr, latIncr;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].modelID);
+}
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )  gdslen += 10;
+void vlistDefVarTable(int vlistID, int varID, int tableID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  if (vlistptr->vars[varID].tableID != tableID)
+    {
+      vlistptr->vars[varID].tableID = tableID;
+      int tablenum = tableInqNum(tableID);
 
-  if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
+      int param = vlistptr->vars[varID].param;
 
-  if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
+      int pnum, pcat, pdis;
+      cdiDecodeParam(param, &pnum, &pcat, &pdis);
+      vlistptr->vars[varID].param = cdiEncodeParam(pnum, tablenum, pdis);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-  gdslen += ISEC2_NumVCP * 4;
 
-  Put3Byte(gdslen);             /*  0- 2 Length of Block 2 Byte 0 */
-  Put1Byte(ISEC2_NumVCP);       /*  3    NV */
-  Put1Byte(pvoffset);           /*  4    PV */
-  Put1Byte(ISEC2_GridType);     /*  5    LatLon=0 Gauss=4 Spectral=50 */
+int vlistInqVarTable(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].tableID);
+}
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
-    {
-      Put2Byte(ISEC2_PentaJ);   /*  6- 7 Pentagonal resolution J  */
-      Put2Byte(ISEC2_PentaK);   /*  8- 9 Pentagonal resolution K  */
-      Put2Byte(ISEC2_PentaM);   /* 10-11 Pentagonal resolution M  */
-      Put1Byte(ISEC2_RepType);  /* 12    Representation type      */
-      Put1Byte(ISEC2_RepMode);  /* 13    Representation mode      */
-      PutnZero(18);             /* 14-31 reserved                 */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
-    {
-      Put2Byte(ISEC2_GME_NI2);
-      Put2Byte(ISEC2_GME_NI3);
-      Put3Byte(ISEC2_GME_ND);
-      Put3Byte(ISEC2_GME_NI);
-      Put1Byte(ISEC2_GME_AFlag);
-      Put3Int(ISEC2_GME_LatPP);
-      Put3Int(ISEC2_GME_LonPP);
-      Put3Int(ISEC2_GME_LonMPL);
-      Put1Byte(ISEC2_GME_BFlag);
-      PutnZero(5);
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
-    {
-      Put2Byte(ISEC2_NumLon);          /*  6- 7 Longitudes               */
+/*
+ at Function  vlistDefVarName
+ at Title     Define the name of a Variable
 
-      Put2Byte(ISEC2_NumLat);          /*  8- 9 Latitudes                */
-      Put3Int(ISEC2_FirstLat);
-      Put3Int(ISEC2_FirstLon);
-      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
-      Put3Int(ISEC2_Lambert_Lov);      /* 17-19 */
-      Put3Int(ISEC2_Lambert_dx);       /* 20-22 */
-      Put3Int(ISEC2_Lambert_dy);       /* 23-25 */
-      Put1Byte(ISEC2_Lambert_ProjFlag);/* 26    Projection flag          */
-      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
-      Put3Int(ISEC2_Lambert_LatS1);    /* 28-30 */  
-      Put3Int(ISEC2_Lambert_LatS2);    /* 31-33 */
-      Put3Int(ISEC2_Lambert_LatSP);    /* 34-36 */  
-      Put3Int(ISEC2_Lambert_LonSP);    /* 37-39 */
-      PutnZero(2);                     /* 34-41 */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-    {
-      int numlon;
-      if ( ISEC2_Reduced )
-	numlon = 0xFFFF;
-      else
-	numlon = ISEC2_NumLon;
+ at Prototype void vlistDefVarName(int vlistID, int varID, const char *name)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  name     Name of the variable.
 
-      Put2Byte(numlon);                /*  6- 7 Number of Longitudes     */
+ at Description
+The function @func{vlistDefVarName} defines the name of a variable.
 
-      Put2Byte(ISEC2_NumLat);          /*  8- 9 Number of Latitudes      */
-      Put3Int(ISEC2_FirstLat);
-      Put3Int(ISEC2_FirstLon);
-      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
-      Put3Int(ISEC2_LastLat);
-      Put3Int(ISEC2_LastLon);
-      if ( ISEC2_ResFlag == 0 )
-	{
-	  lonIncr = 0xFFFF;
-	  latIncr = 0xFFFF;
-	}
-      else
-	{
-	  lonIncr = ISEC2_LonIncr;
-	  latIncr = ISEC2_LatIncr;
-	}
-      Put2Byte(lonIncr);               /* 23-24 i - direction increment  */
-      if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
-	Put2Byte(ISEC2_NumPar);        /* 25-26 Latitudes Pole->Equator  */
-      else
-	Put2Byte(latIncr);             /* 25-26 j - direction increment  */
+ at EndFunction
+*/
+void vlistDefVarName(int vlistID, int varID, const char *name)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
-      PutnZero(4);                     /* 28-31 reserved                 */
+  vlistCheckVarID(__func__, vlistID, varID);
 
-      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
+  if ( name )
+    {
+      if ( vlistptr->vars[varID].name )
 	{
-	  Put3Int(ISEC2_LatSP);
-	  Put3Int(ISEC2_LonSP);
-	  Put1Real((double)(FSEC2_RotAngle));
+	  free(vlistptr->vars[varID].name);
+	  vlistptr->vars[varID].name = NULL;
 	}
-    }
-  else
-    {
-      Error("Unsupported grid type %d", ISEC2_GridType);
-    }
 
-#if defined (SX)
-#pragma vdir novector     /* vectorization gives wrong results on NEC */
-#endif
-  for ( i = 0; i < ISEC2_NumVCP; ++i )
-    {
-      Put1Real((double)(fsec2[10+i]));
+      vlistptr->vars[varID].name = strdupx(name);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  if ( ISEC2_Reduced )
-    for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
+/*
+ at Function  vlistDefVarLongname
+ at Title     Define the long name of a Variable
 
-  *gribLen = z;
-}
+ at Prototype void vlistDefVarLongname(int vlistID, int varID, const char *longname)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  longname Long name of the variable.
 
-/* GRIB BLOCK 3 - BIT MAP SECTION */
-static
-void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
+ at Description
+The function @func{vlistDefVarLongname} defines the long name of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarLongname(int vlistID, int varID, const char *longname)
 {
-  GRIBPACK *bitmap;
-  long bitmapSize;
-  long imaskSize;
-  long i;
-  long bmsLen, bmsUnusedBits;
-  long fsec4size;
-  long z = *gribLen;
-#if defined (VECTORCODE)
-  unsigned int *imask;
-#endif
-  static int lmissvalinfo = 1;
-  /*  unsigned int c, imask; */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( longname )
     {
-      lmissvalinfo = 0;
-      Message("Missing value = NaN is unsupported!");
+      if ( vlistptr->vars[varID].longname )
+	{
+	  free(vlistptr->vars[varID].longname);
+	  vlistptr->vars[varID].longname = 0;
+	}
+
+      vlistptr->vars[varID].longname = strdupx(longname);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  bitmapSize = ISEC4_NumValues;
-  imaskSize = ((bitmapSize+7)>>3)<<3;
-  bitmap = &lGrib[z+6];
-  fsec4size = 0;
+/*
+ at Function  vlistDefVarStdname
+ at Title     Define the standard name of a Variable
 
-#if defined (VECTORCODE)
-  imask = (unsigned int*) malloc(imaskSize*sizeof(unsigned int));
-  memset(imask, 0, imaskSize*sizeof(int));
+ at Prototype void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  stdname  Standard name of the variable.
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-  for ( i = 0; i < bitmapSize; i++ )
+ at Description
+The function @func{vlistDefVarStdname} defines the standard name of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( stdname )
     {
-      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+      if ( vlistptr->vars[varID].stdname )
 	{
-	  data[fsec4size++] = data[i];
-	  imask[i] = 1;
+	  free(vlistptr->vars[varID].stdname);
+	  vlistptr->vars[varID].stdname = 0;
 	}
-    }
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-  for ( i = 0; i < imaskSize/8; i++ )
-    {
-      bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
-	          (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
-	          (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
-	          (imask[i*8+6] << 1) | (imask[i*8+7]);
+      vlistptr->vars[varID].stdname = strdupx(stdname);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  free(imask);
-#else
-  for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
+/*
+ at Function  vlistDefVarUnits
+ at Title     Define the units of a Variable
 
-  for ( i = 0; i < bitmapSize; i++ )
+ at Prototype void vlistDefVarUnits(int vlistID, int varID, const char *units)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  units    Units of the variable.
+
+ at Description
+The function @func{vlistDefVarUnits} defines the units of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarUnits(int vlistID, int varID, const char *units)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( units )
     {
-      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
+      if ( vlistptr->vars[varID].units )
 	{
-	  data[fsec4size++] = data[i];
-	  bitmap[i/8] |= 1<<(7-(i&7));
+	  free(vlistptr->vars[varID].units);
+	  vlistptr->vars[varID].units = 0;
 	}
+
+      vlistptr->vars[varID].units = strdupx(units);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-#endif
+}
 
-  bmsLen = imaskSize/8 + 6;
-  bmsUnusedBits = imaskSize - bitmapSize;
+/*
+ at Function  vlistInqVarMissval
+ at Title     Get the missing value of a Variable
 
-  Put3Byte(bmsLen);   /*  0- 2 Length of Block 3 Byte 0 */
-  Put1Byte(bmsUnusedBits);
-  Put2Byte(0);
+ at Prototype double vlistInqVarMissval(int vlistID, int varID)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
 
-  *gribLen += bmsLen;
+ at Description
+The function @func{vlistInqVarMissval} returns the missing value of a variable.
 
-  *datasize = fsec4size;
+ at Result
+ at func{vlistInqVarMissval} returns the missing value of the variable.
+
+ at EndFunction
+*/
+double vlistInqVarMissval(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  return (vlistptr->vars[varID].missval);
 }
 
+/*
+ at Function  vlistDefVarMissval
+ at Title     Define the missing value of a Variable
 
-/* GRIB BLOCK 4 - BINARY DATA SECTION */
-static
-int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
-			  long *datstart, long *datsize, int code)
-{
-  /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
-  /* Uwe Schulzweida,  6/05/2003 : Copy result to fpval to prevent integer overflow */
+ at Prototype void vlistDefVarMissval(int vlistID, int varID, double missval)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  missval  Missing value.
 
-  size_t z = *gribLen;
-  long i, jloop;
-  int numBits;
-  int ival;
-  int blockLength, PackStart = 0, Flag = 0;
-  int binscale = 0;
-  int nbpv;
-  int bds_head = 11;
-  int bds_ext = 0;
-  /* ibits = BitsPerInt; */
-  unsigned int max_nbpv_pow2;
-  int exponent, mantissa;
-  int unused_bits = 0;
-  int lspherc = FALSE, lcomplex = FALSE;
-  int isubset = 0, itemp = 0, itrunc = 0;
-  T factor = 1, fmin, fmax;
-  double zref;
-  double range, rangec;
-  double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
-                                /*        of floating point numbers - needed   */
-		                /*        on some platforms (eg vpp700, linux) */
-  extern const double _pow2tab[158];
-  extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
+ at Description
+The function @func{vlistDefVarMissval} defines the missing value of a variable.
 
-  if ( isec2 )
-    {
-      /* If section 2 is present, it says if data is spherical harmonic */
+ at EndFunction
+*/
+void vlistDefVarMissval(int vlistID, int varID, double missval)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      if ( isec2[0] == 50 || isec2[0] == 60 || 
-	   isec2[0] == 70 || isec2[0] == 80 ) lspherc = TRUE;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-      if ( lspherc )
-	isec4[2] = 128;
-      else
-	isec4[2] = 0;
-    }
-  else
-    {
-      /* Section 4 says if it's spherical harmonic data.. */
+  vlistptr->vars[varID].missval = missval;
+  vlistptr->vars[varID].missvalused = TRUE;
+}
 
-      lspherc = ( isec4[2] == 128 );
-    }
+/*
+ at Function  vlistDefVarExtra
+ at Title     Define extra information of a Variable
 
-  /* Complex packing supported for spherical harmonics. */
+ at Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Extra information.
 
-  lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
-             ( lspherc && isec2 && ( isec2[5] == 2 ) );
+ at Description
+The function @func{vlistDefVarExtra} defines the extra information of a variable.
 
-  /* Check input specification is consistent */
+ at EndFunction
+*/
+void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( lcomplex && isec2 )
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( extra )
     {
-      if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
-	{
-	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
-	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
-	  return (807);
-	}
-      else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
-	{
-	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
-	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
-	  return (807);
-        }
-      else if ( lcomplex )
+      if ( vlistptr->vars[varID].extra )
 	{
-	  /*
-	    Truncation of full spectrum, which is supposed triangular,
-	    has to be diagnosed. Define also sub-set truncation.
-	  */
-	  isubset = isec4[17];
-	  /* When encoding, use the total number of data. */
-	  itemp   = isec4[0];
-	  itrunc  = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
+	  free(vlistptr->vars[varID].extra);
+	  vlistptr->vars[varID].extra = NULL;
 	}
-    }
 
-  if ( decscale )
-    {
-      T scale = (T) pow(10.0, (double) decscale);
-      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+      vlistptr->vars[varID].extra = strdupx(extra);
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  if ( lspherc )
-    {
-      if ( lcomplex )
-	{
-	  int jup, ioff;
-	  jup  = isubset;
-	  ioff = (jup+1)*(jup+2);
-	  bds_ext = 4 + 3 + 4*ioff;
-	  PackStart = ioff;
-	  Flag = 192;
-	}
-      else
-	{
-	  bds_ext = 4;
-	  PackStart = 1;
-	  Flag = 128;
-	}
-    }
+/*
+ at Function  vlistInqVarExtra
+ at Title     Get extra information of a Variable
 
-  *datstart = bds_head + bds_ext;
+ at Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Returned variable extra information. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-  nbpv = numBits = ISEC4_NumBits;
+ at Description
+The function @func{vlistInqVarExtra} returns the extra information of a variable.
 
-  if ( lspherc && lcomplex )
+ at Result
+ at func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available,
+otherwise the result is an empty string.
+
+ at EndFunction
+*/
+void vlistInqVarExtra(int vlistID, int varID, char *extra)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( vlistptr->vars[varID].extra == NULL )
+      sprintf(extra, "-");
+  else
+    strcpy(extra, vlistptr->vars[varID].extra);
+
+  return;
+}
+
+
+int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( validrange != NULL && vlistptr->vars[varID].lvalidrange )
     {
-      int pcStart, pcScale;
-      pcStart = isubset;
-      pcScale = isec4[16];
-      TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
-      TEMPLATE(gather_complex,T)(data, pcStart, itrunc, datasize);
+      validrange[0] = vlistptr->vars[varID].validrange[0];
+      validrange[1] = vlistptr->vars[varID].validrange[1];
     }
 
-  fmin = fmax = data[PackStart];
+  return (vlistptr->vars[varID].lvalidrange);
+}
+
+
+void vlistDefVarValidrange(int vlistID, int varID, const double *validrange)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  vlistptr->vars[varID].validrange[0] = validrange[0];
+  vlistptr->vars[varID].validrange[1] = validrange[1];
+  vlistptr->vars[varID].lvalidrange = TRUE;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
+
 
-  TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
+double vlistInqVarScalefactor(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  zref = (double)fmin;
+  vlistCheckVarID(__func__, vlistID, varID);
 
+  return (vlistptr->vars[varID].scalefactor);
+}
 
-  if ( CGRIBEX_Const && !lspherc )
-    {
-      if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
-    }
 
+double vlistInqVarAddoffset(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
-  if ( (blockLength%2) == 1 ) blockLength++;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
+  return (vlistptr->vars[varID].addoffset);
+}
 
-  Flag += unused_bits;
 
+void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  /*
-    Adjust number of bits per value if full integer length to
-    avoid hitting most significant bit (sign bit).
-  */
-  /* if( nbpv == ibits ) nbpv = nbpv - 1; */
-  /*
-    Calculate the binary scaling factor to spread the range of
-    values over the number of bits per value.
-    Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
-    as a guideline).           
-  */
-  range = fabs(fmax - fmin);
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  if ( fabs(fmin) < FLT_MIN ) fmin = 0;
-  /*
-    Have to allow tolerance in comparisons on some platforms
-    (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
-    to avoid clipping ranges which are a power of 2.
-  */
-  if ( range <= jpepsln )
-    {
-      binscale = 0;
-    }
-  else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
-    {
-      binscale = 0;
-    }
-  else if ( fabs(range-1.0) <= jpepsln )
-    {
-      binscale = 1 - nbpv;
-    }
-  else if ( range > 1.0 )
+  if ( IS_NOT_EQUAL(vlistptr->vars[varID].scalefactor, scalefactor) )
     {
-      rangec = range + jpepsln;
-      for ( jloop = 1; jloop < 128; jloop++ )
-	{
-	  if ( _pow2tab[jloop] > rangec ) break;
-	}
-      if ( jloop == 128 )
-	{
-	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
-	  gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
-	  return (707);
-	}
-      else
-	{
-	  binscale = jloop - nbpv;
-	}
+      vlistptr->vars[varID].scalefactor = scalefactor;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-  else
+}
+
+
+void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( IS_NOT_EQUAL(vlistptr->vars[varID].addoffset, addoffset))
     {
-      rangec = range - jpepsln;
-      for ( jloop = 1; jloop < 127; jloop++ )
-	{
-	  if ( 1.0/_pow2tab[jloop] < rangec ) break;
-	}
-      if ( jloop == 127 )
-	{
-	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
-	  gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
-	  return (707);
-	}
-      else
-	{
-	  binscale = 1 - jloop - nbpv;
-	}
+      vlistptr->vars[varID].addoffset = addoffset;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  //max_nbpv_pow2 = (unsigned) (intpow2(nbpv) - 1);
-  max_nbpv_pow2 = (unsigned) ((1ULL << nbpv) - 1);
 
-  if ( binscale != 0 )
+void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].tsteptype != tsteptype)
     {
-      if ( binscale < 0 )
-	{
-	  if ( (unsigned)(range*intpow2(-binscale)+0.5) > max_nbpv_pow2 ) binscale++;
-	}
-      else
-	{
-	  if ( (unsigned)(range/intpow2(binscale)+0.5) > max_nbpv_pow2 ) binscale--;
-	}
-
-      if ( binscale < 0 ) factor =     intpow2(-binscale);
-      else                factor = 1.0/intpow2( binscale);
+      vlistptr->vars[varID].tsteptype = tsteptype;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  ref2ibm(&zref, BitsPerInt);
 
-  Put3Byte(blockLength);      /*  0-2 Length of Block 4        */
-  Put1Byte(Flag);             /*  3   Flag & Unused bits       */
-  if ( binscale < 0 ) binscale = 32768 - binscale;
-  Put2Byte(binscale);         /*  4-5 Scale factor             */
-  Put1Real(zref);             /*  6-9 Reference value          */
-  Put1Byte(nbpv);             /*   10 Packing size             */
+int vlistInqVarTsteptype(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].tsteptype);
+}
 
-  if ( lspherc )
+
+void vlistDefVarTimave(int vlistID, int varID, int timave)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].timave != timave)
     {
-      if ( lcomplex )
-	{
-	  int jup = isubset;
-	  int ioff = z + bds_ext;
-	  if ( ioff > 0xFFFF ) ioff = 0;
-	  Put2Byte(ioff);
-	  Put2Int(isec4[16]);
-	  Put1Byte(jup);
-	  Put1Byte(jup);
-	  Put1Byte(jup);
-	  for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
-	}
-      else
-	{
-	  Put1Real((double)(data[0]));
-	}
+      vlistptr->vars[varID].timave = timave;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  *datsize  = ((datasize-PackStart)*nbpv + 7)/8;
-
-#if  defined  (_ARCH_PWR6)
-  TEMPLATE(encode_array_unrolled,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
-#else
-  TEMPLATE(encode_array,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
-#endif
 
-  if ( unused_bits >= 8 ) Put1Byte(0);  /*  Fillbyte                     */
+int vlistInqVarTimave(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].timave);
+}
 
-  *gribLen = z;
 
-  return (0);
+void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].timaccu != timaccu)
+    {
+      vlistptr->vars[varID].timaccu = timaccu;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 
-void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
-			     T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
-			     int kleng, int *kword, int efunc, int *kret)
+int vlistInqVarTimaccu(int vlistID, int varID)
 {
-  long gribLen = 0; /* Counter of GRIB length for output */
-  long isLen, pdsLen;
-  GRIBPACK *lpds;
-  unsigned char *CGrib;
-  long fsec4size = 0;
-  int numBytes;
-  int bmsIncluded;
-  size_t len;
-  GRIBPACK *lGrib;
-  long datstart, datsize, bdsstart;
-  int status = 0;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].timaccu);
+}
 
-  UNUSED(isec3);
-  UNUSED(efunc);
 
-  grsdef();
+void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGeneratingProcess)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].typeOfGeneratingProcess != typeOfGeneratingProcess)
+    {
+      vlistptr->vars[varID].typeOfGeneratingProcess = typeOfGeneratingProcess;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-  CGrib = (unsigned char *) kgrib;
 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].typeOfGeneratingProcess);
+}
 
-  /* set max header len */
-  len = 16384;
 
-  /* add data len */
-  numBytes = (ISEC4_NumBits+7)>>3;
+void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDefinitionTemplate)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  len += numBytes*klenp;
+  if (vlistptr->vars[varID].productDefinitionTemplate != productDefinitionTemplate)
+    {
+      vlistptr->vars[varID].productDefinitionTemplate = productDefinitionTemplate;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-  /* add bitmap len */
-  if ( bmsIncluded ) len += (klenp+7)>>3;
 
-#if defined (VECTORCODE)
-  lGrib = (GRIBPACK*) malloc(len*sizeof(GRIBPACK));
-  if ( lGrib == NULL ) SysError("No Memory!");
-#else
-  lGrib = CGrib;
-#endif
+int vlistInqVarProductDefinitionTemplate(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  isLen = 8;
-  encodeIS(lGrib, &gribLen);
-  lpds = &lGrib[isLen];
-  pdsLen = getPdsLen(isec1);
+  return (vlistptr->vars[varID].productDefinitionTemplate);
+}
 
-  encodePDS(lpds, pdsLen,  isec1);
-  gribLen += pdsLen;
-  /*
-  if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
+
+void vlistDestroyVarName(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if ( vlistptr->vars[varID].name )
     {
-      static int lwarn_cplx = TRUE;
+      free(vlistptr->vars[varID].name);
+      vlistptr->vars[varID].name = NULL;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-      if ( lwarn_cplx )
-	Message("Complex packing of spectral data unsupported, using simple packing!");
 
-      isec2[5] = 1;
-      isec4[3] = 0;
+void vlistDestroyVarLongname(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      lwarn_cplx = FALSE;
-    }
-  */
-  TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  if ( bmsIncluded )
-    {
-      TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
-    }
-  else
+  if ( vlistptr->vars[varID].longname )
     {
-      fsec4size = ISEC4_NumValues;
+      free(vlistptr->vars[varID].longname);
+      vlistptr->vars[varID].longname = NULL;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  bdsstart = gribLen;
-  status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
-				 isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
-  if ( status )
+
+void vlistDestroyVarStdname(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  if ( vlistptr->vars[varID].stdname )
     {
-      *kret = status;
-      return;
+      free(vlistptr->vars[varID].stdname);
+      vlistptr->vars[varID].stdname = NULL;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  encodeES(lGrib, &gribLen, bdsstart);
 
-  if ( (size_t) gribLen > kleng*sizeof(int) )
-    Error("kgrib buffer too small! kleng = %d  gribLen = %d", kleng, gribLen);
+void vlistDestroyVarUnits(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if defined (VECTORCODE)
-  if ( (size_t) gribLen > len )
-    Error("lGrib buffer too small! len = %d  gribLen = %d", len, gribLen);
+  if ( vlistptr->vars[varID].units )
+    {
+      free(vlistptr->vars[varID].units);
+      vlistptr->vars[varID].units = NULL;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-  (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
 
-  free(lGrib);
-#endif
+int vlistInqVarMissvalUsed(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].missvalused);
+}
 
-  ISEC0_GRIB_Len     = gribLen;
-  ISEC0_GRIB_Version = 1;
 
-  *kword = gribLen / sizeof(int);
-  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
+void vlistDefFlag(int vlistID, int varID, int levID, int flag)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *kret = status;
-}
+  levinfo_t li = DEFAULT_LEVINFO(levID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (flag != li.flag)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
 
-#endif /* T */
+  vlistptr->vars[varID].levinfo[levID].flag = flag;
 
-#ifdef T
-#undef T
-#endif
-#define T float
-#ifdef T
+  vlistptr->vars[varID].flag = 0;
 
-/* GRIB BLOCK 2 - GRID DESCRIPTION SECTION */
-static
-void TEMPLATE(encodeGDS,T)(GRIBPACK *lGrib, long *gribLen, int *isec2, T *fsec2)
-{
-  long z = *gribLen;
-  int exponent, mantissa;
-  long i;
-  int ival;
-  int pvoffset = 0xFF;
-  int gdslen = 32;
-  unsigned lonIncr, latIncr;
+  int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+  for ( int levelID = 0; levelID < nlevs; levelID++ )
+    {
+      if ( vlistptr->vars[varID].levinfo[levelID].flag )
+        {
+          vlistptr->vars[varID].flag = 1;
+          break;
+        }
+    }
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_LCC ) gdslen += 10;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )  gdslen += 10;
 
-  if ( ISEC2_NumVCP || ISEC2_Reduced ) pvoffset = gdslen + 1;
+int vlistInqFlag(int vlistID, int varID, int levID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( ISEC2_Reduced ) gdslen += 2 * ISEC2_NumLat;
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levID].flag);
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levID);
+      return li.flag;
+    }
+}
 
-  gdslen += ISEC2_NumVCP * 4;
 
-  Put3Byte(gdslen);             /*  0- 2 Length of Block 2 Byte 0 */
-  Put1Byte(ISEC2_NumVCP);       /*  3    NV */
-  Put1Byte(pvoffset);           /*  4    PV */
-  Put1Byte(ISEC2_GridType);     /*  5    LatLon=0 Gauss=4 Spectral=50 */
+int vlistFindVar(int vlistID, int fvarID)
+{
+  int varID;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( ISEC2_GridType == GRIB1_GTYPE_SPECTRAL )
+  for ( varID = 0; varID < vlistptr->nvars; varID++ )
     {
-      Put2Byte(ISEC2_PentaJ);   /*  6- 7 Pentagonal resolution J  */
-      Put2Byte(ISEC2_PentaK);   /*  8- 9 Pentagonal resolution K  */
-      Put2Byte(ISEC2_PentaM);   /* 10-11 Pentagonal resolution M  */
-      Put1Byte(ISEC2_RepType);  /* 12    Representation type      */
-      Put1Byte(ISEC2_RepMode);  /* 13    Representation mode      */
-      PutnZero(18);             /* 14-31 reserved                 */
+      if ( vlistptr->vars[varID].fvarID == fvarID ) break;
     }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
+
+  if ( varID == vlistptr->nvars )
     {
-      Put2Byte(ISEC2_GME_NI2);
-      Put2Byte(ISEC2_GME_NI3);
-      Put3Byte(ISEC2_GME_ND);
-      Put3Byte(ISEC2_GME_NI);
-      Put1Byte(ISEC2_GME_AFlag);
-      Put3Int(ISEC2_GME_LatPP);
-      Put3Int(ISEC2_GME_LonPP);
-      Put3Int(ISEC2_GME_LonMPL);
-      Put1Byte(ISEC2_GME_BFlag);
-      PutnZero(5);
+      varID = -1;
+      Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
     }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
-    {
-      Put2Byte(ISEC2_NumLon);          /*  6- 7 Longitudes               */
 
-      Put2Byte(ISEC2_NumLat);          /*  8- 9 Latitudes                */
-      Put3Int(ISEC2_FirstLat);
-      Put3Int(ISEC2_FirstLon);
-      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
-      Put3Int(ISEC2_Lambert_Lov);      /* 17-19 */
-      Put3Int(ISEC2_Lambert_dx);       /* 20-22 */
-      Put3Int(ISEC2_Lambert_dy);       /* 23-25 */
-      Put1Byte(ISEC2_Lambert_ProjFlag);/* 26    Projection flag          */
-      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
-      Put3Int(ISEC2_Lambert_LatS1);    /* 28-30 */  
-      Put3Int(ISEC2_Lambert_LatS2);    /* 31-33 */
-      Put3Int(ISEC2_Lambert_LatSP);    /* 34-36 */  
-      Put3Int(ISEC2_Lambert_LonSP);    /* 37-39 */
-      PutnZero(2);                     /* 34-41 */
-    }
-  else if ( ISEC2_GridType == GRIB1_GTYPE_LATLON    ||
-	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN  ||
-	    ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-    {
-      int numlon;
-      if ( ISEC2_Reduced )
-	numlon = 0xFFFF;
-      else
-	numlon = ISEC2_NumLon;
+  return (varID);
+}
 
-      Put2Byte(numlon);                /*  6- 7 Number of Longitudes     */
 
-      Put2Byte(ISEC2_NumLat);          /*  8- 9 Number of Latitudes      */
-      Put3Int(ISEC2_FirstLat);
-      Put3Int(ISEC2_FirstLon);
-      Put1Byte(ISEC2_ResFlag);         /* 16    Resolution flag          */
-      Put3Int(ISEC2_LastLat);
-      Put3Int(ISEC2_LastLon);
-      if ( ISEC2_ResFlag == 0 )
+int vlistFindLevel(int vlistID, int fvarID, int flevelID)
+{
+  int levelID = -1;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  int varID = vlistFindVar(vlistID, fvarID);
+
+  if ( varID != -1 )
+    {
+      int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+      for ( levelID = 0; levelID < nlevs; levelID++ )
 	{
-	  lonIncr = 0xFFFF;
-	  latIncr = 0xFFFF;
+	  if ( vlistptr->vars[varID].levinfo[levelID].flevelID == flevelID ) break;
 	}
-      else
+
+      if ( levelID == nlevs )
 	{
-	  lonIncr = ISEC2_LonIncr;
-	  latIncr = ISEC2_LatIncr;
+	  levelID = -1;
+	  Message("levelID not found for fvarID %d and levelID %d in vlistID %d!",
+		  fvarID, flevelID, vlistID);
 	}
-      Put2Byte(lonIncr);               /* 23-24 i - direction increment  */
-      if ( ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN )
-	Put2Byte(ISEC2_NumPar);        /* 25-26 Latitudes Pole->Equator  */
-      else
-	Put2Byte(latIncr);             /* 25-26 j - direction increment  */
+    }
 
-      Put1Byte(ISEC2_ScanFlag);        /* 27    Scanning mode            */
-      PutnZero(4);                     /* 28-31 reserved                 */
+  return (levelID);
+}
+
+
+int vlistMergedVar(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return (vlistptr->vars[varID].mvarID);
+}
+
+
+int vlistMergedLevel(int vlistID, int varID, int levelID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      if ( ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT )
-	{
-	  Put3Int(ISEC2_LatSP);
-	  Put3Int(ISEC2_LonSP);
-	  Put1Real((double)(FSEC2_RotAngle));
-	}
-    }
+  if (vlistptr->vars[varID].levinfo)
+    return vlistptr->vars[varID].levinfo[levelID].mlevelID;
   else
     {
-      Error("Unsupported grid type %d", ISEC2_GridType);
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.mlevelID;
     }
+}
 
-#if defined (SX)
-#pragma vdir novector     /* vectorization gives wrong results on NEC */
-#endif
-  for ( i = 0; i < ISEC2_NumVCP; ++i )
-    {
-      Put1Real((double)(fsec2[10+i]));
-    }
 
-  if ( ISEC2_Reduced )
-    for ( i = 0; i < ISEC2_NumLat; i++ ) Put2Byte(ISEC2_RowLon(i));
+void vlistDefIndex(int vlistID, int varID, int levelID, int index)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *gribLen = z;
+  levinfo_t li = DEFAULT_LEVINFO(levelID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (index != li.index)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
+  vlistptr->vars[varID].levinfo[levelID].index = index;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
 }
 
-/* GRIB BLOCK 3 - BIT MAP SECTION */
-static
-void TEMPLATE(encodeBMS,T)(GRIBPACK *lGrib, long *gribLen, T *fsec3, int *isec4, T *data, long *datasize)
+
+int vlistInqIndex(int vlistID, int varID, int levelID)
 {
-  GRIBPACK *bitmap;
-  long bitmapSize;
-  long imaskSize;
-  long i;
-  long bmsLen, bmsUnusedBits;
-  long fsec4size;
-  long z = *gribLen;
-#if defined (VECTORCODE)
-  unsigned int *imask;
-#endif
-  static int lmissvalinfo = 1;
-  /*  unsigned int c, imask; */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo)
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levelID].index);
+  else
     {
-      lmissvalinfo = 0;
-      Message("Missing value = NaN is unsupported!");
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.index;
     }
+}
 
-  bitmapSize = ISEC4_NumValues;
-  imaskSize = ((bitmapSize+7)>>3)<<3;
-  bitmap = &lGrib[z+6];
-  fsec4size = 0;
 
-#if defined (VECTORCODE)
-  imask = (unsigned int*) malloc(imaskSize*sizeof(unsigned int));
-  memset(imask, 0, imaskSize*sizeof(int));
+void vlistChangeVarZaxis(int vlistID, int varID, int zaxisID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-  for ( i = 0; i < bitmapSize; i++ )
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  int nlevs1 = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+  int nlevs2 = zaxisInqSize(zaxisID);
+
+  if ( nlevs1 != nlevs2 ) Error("Number of levels must not change!");
+
+  int nvars = vlistptr->nvars;
+  int found = 0;
+  int oldZaxisID = vlistptr->vars[varID].zaxisID;
+  for ( int i = 0; i < varID; ++i)
+    found |= (vlistptr->vars[i].zaxisID == oldZaxisID);
+  for ( int i = varID + 1; i < nvars; ++i)
+    found |= (vlistptr->vars[i].zaxisID == oldZaxisID);
+
+  if (found)
     {
-      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
-	{
-	  data[fsec4size++] = data[i];
-	  imask[i] = 1;
-	}
+      int nzaxis = vlistptr->nzaxis;
+      for (int i = 0; i < nzaxis; ++i)
+	if (vlistptr->zaxisIDs[i] == oldZaxisID )
+	  vlistptr->zaxisIDs[i] = zaxisID;
     }
+  else
+    vlistAdd2ZaxisIDs(vlistptr, zaxisID);
 
-#if defined (CRAY)
-#pragma _CRI ivdep
-#endif
-#if defined (SX)
-#pragma vdir nodep
-#endif
-#ifdef __uxpch__
-#pragma loop novrec
-#endif
-  for ( i = 0; i < imaskSize/8; i++ )
+  vlistptr->vars[varID].zaxisID = zaxisID;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
+
+
+void vlistChangeVarGrid(int vlistID, int varID, int gridID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  int nvars = vlistptr->nvars;
+  int index;
+  for ( index = 0; index < nvars; index++ )
+    if ( index != varID )
+      if ( vlistptr->vars[index].gridID == vlistptr->vars[varID].gridID ) break;
+
+  if ( index == nvars )
     {
-      bitmap[i] = (imask[i*8+0] << 7) | (imask[i*8+1] << 6) |
-	          (imask[i*8+2] << 5) | (imask[i*8+3] << 4) |
-	          (imask[i*8+4] << 3) | (imask[i*8+5] << 2) |
-	          (imask[i*8+6] << 1) | (imask[i*8+7]);
+      for ( index = 0; index < vlistptr->ngrids; index++ )
+	if ( vlistptr->gridIDs[index] == vlistptr->vars[varID].gridID )
+	  vlistptr->gridIDs[index] = gridID;
     }
+  else
+    vlistAdd2GridIDs(vlistptr, gridID);
 
-  free(imask);
-#else
-  for ( i = 0; i < imaskSize/8; i++ ) bitmap[i] = 0;
+  vlistptr->vars[varID].gridID = gridID;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
 
-  for ( i = 0; i < bitmapSize; i++ )
+
+void vlistDefVarCompType(int vlistID, int varID, int comptype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if (vlistptr->vars[varID].comptype != comptype)
     {
-      if ( IS_NOT_EQUAL(data[i], FSEC3_MissVal) )
-	{
-	  data[fsec4size++] = data[i];
-	  bitmap[i/8] |= 1<<(7-(i&7));
-	}
+      vlistptr->vars[varID].comptype = comptype;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-#endif
+}
 
-  bmsLen = imaskSize/8 + 6;
-  bmsUnusedBits = imaskSize - bitmapSize;
 
-  Put3Byte(bmsLen);   /*  0- 2 Length of Block 3 Byte 0 */
-  Put1Byte(bmsUnusedBits);
-  Put2Byte(0);
+int vlistInqVarCompType(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  *gribLen += bmsLen;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *datasize = fsec4size;
+  return (vlistptr->vars[varID].comptype);
 }
 
 
-/* GRIB BLOCK 4 - BINARY DATA SECTION */
-static
-int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *isec4, long datasize, T *data,
-			  long *datstart, long *datsize, int code)
+void vlistDefVarCompLevel(int vlistID, int varID, int complevel)
 {
-  /* Uwe Schulzweida, 11/04/2003 : Check that number of bits per value is not exceeded */
-  /* Uwe Schulzweida,  6/05/2003 : Copy result to fpval to prevent integer overflow */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  size_t z = *gribLen;
-  long i, jloop;
-  int numBits;
-  int ival;
-  int blockLength, PackStart = 0, Flag = 0;
-  int binscale = 0;
-  int nbpv;
-  int bds_head = 11;
-  int bds_ext = 0;
-  /* ibits = BitsPerInt; */
-  unsigned int max_nbpv_pow2;
-  int exponent, mantissa;
-  int unused_bits = 0;
-  int lspherc = FALSE, lcomplex = FALSE;
-  int isubset = 0, itemp = 0, itrunc = 0;
-  T factor = 1, fmin, fmax;
-  double zref;
-  double range, rangec;
-  double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
-                                /*        of floating point numbers - needed   */
-		                /*        on some platforms (eg vpp700, linux) */
-  extern const double _pow2tab[158];
-  extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  if ( isec2 )
+  if (vlistptr->vars[varID].complevel != complevel)
     {
-      /* If section 2 is present, it says if data is spherical harmonic */
+      vlistptr->vars[varID].complevel = complevel;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
 
-      if ( isec2[0] == 50 || isec2[0] == 60 || 
-	   isec2[0] == 70 || isec2[0] == 80 ) lspherc = TRUE;
 
-      if ( lspherc )
-	isec4[2] = 128;
-      else
-	isec4[2] = 0;
-    }
-  else
-    {
-      /* Section 4 says if it's spherical harmonic data.. */
+int vlistInqVarCompLevel(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-      lspherc = ( isec4[2] == 128 );
-    }
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  /* Complex packing supported for spherical harmonics. */
+  return (vlistptr->vars[varID].complevel);
+}
 
-  lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
-             ( lspherc && isec2 && ( isec2[5] == 2 ) );
 
-  /* Check input specification is consistent */
+void  vlistDefVarChunkType(int vlistID, int varID, int chunktype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( lcomplex && isec2 )
-    {
-      if ( ( isec4[3] != 64 ) && ( isec2[5] == 2 ) )
-	{
-	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
-	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
-	  return (807);
-	}
-      else if ( ( isec4[3] == 64 ) && ( isec2[5] != 2 ) )
-	{
-	  gprintf(__func__, "  COMPLEX mismatch. isec4[3] = %d\n", isec4[3]);
-	  gprintf(__func__, "  COMPLEX mismatch. isec2[5] = %d\n", isec2[5]);
-	  return (807);
-        }
-      else if ( lcomplex )
-	{
-	  /*
-	    Truncation of full spectrum, which is supposed triangular,
-	    has to be diagnosed. Define also sub-set truncation.
-	  */
-	  isubset = isec4[17];
-	  /* When encoding, use the total number of data. */
-	  itemp   = isec4[0];
-	  itrunc  = (int) (sqrt(itemp*4 + 1.) - 3) / 2;
-	}
-    }
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  if ( decscale )
+  if (vlistptr->vars[varID].chunktype != chunktype)
     {
-      T scale = (T) pow(10.0, (double) decscale);
-      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+      vlistptr->vars[varID].chunktype = chunktype;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
+}
 
-  if ( lspherc )
-    {
-      if ( lcomplex )
-	{
-	  int jup, ioff;
-	  jup  = isubset;
-	  ioff = (jup+1)*(jup+2);
-	  bds_ext = 4 + 3 + 4*ioff;
-	  PackStart = ioff;
-	  Flag = 192;
-	}
-      else
-	{
-	  bds_ext = 4;
-	  PackStart = 1;
-	  Flag = 128;
-	}
-    }
 
-  *datstart = bds_head + bds_ext;
+int vlistInqVarChunkType(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  nbpv = numBits = ISEC4_NumBits;
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  if ( lspherc && lcomplex )
-    {
-      int pcStart, pcScale;
-      pcStart = isubset;
-      pcScale = isec4[16];
-      TEMPLATE(scale_complex,T)(data, pcStart, pcScale, itrunc, 0);
-      TEMPLATE(gather_complex,T)(data, pcStart, itrunc, datasize);
-    }
+  return (vlistptr->vars[varID].chunktype);
+}
 
-  fmin = fmax = data[PackStart];
+static
+int vlistEncodeXyz(int (*dimorder)[3])
+{
+  return (*dimorder)[0]*100 + (*dimorder)[1]*10 + (*dimorder)[2];
+}
 
-  TEMPLATE(minmax_val,T)(data+PackStart, datasize-PackStart, &fmin, &fmax);
 
-  zref = (double)fmin;
+static
+void vlistDecodeXyz(int xyz, int (*outDimorder)[3])
+{
+  (*outDimorder)[0] = xyz/100, xyz -= (*outDimorder)[0]*100;
+  (*outDimorder)[1] = xyz/10, xyz -= (*outDimorder)[1]*10;
+  (*outDimorder)[2] = xyz;
+}
 
 
-  if ( CGRIBEX_Const && !lspherc )
-    {
-      if ( IS_EQUAL(fmin, fmax) ) nbpv = 0;
-    }
+void  vlistDefVarXYZ(int vlistID, int varID, int xyz)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  blockLength = (*datstart) + (nbpv*(datasize - PackStart) + 7)/8;
-  if ( (blockLength%2) == 1 ) blockLength++;
+  if ( xyz == 3 ) xyz = 321;
 
-  unused_bits = blockLength*8 - (*datstart)*8 - nbpv*(datasize - PackStart);
+  /* check xyz dimension order */
+  {
+    int dimorder[3];
+    vlistDecodeXyz(xyz, &dimorder);
+    int dimx = 0, dimy = 0, dimz = 0;
+    for ( int id = 0; id < 3; ++id )
+      {
+        switch ( dimorder[id] )
+          {
+            case 1: dimx++; break;
+            case 2: dimy++; break;
+            case 3: dimz++; break;
+            default: dimorder[id] = 0; break;    //Ensure that we assign a valid dimension to this position.
+          }
+     }
+    if ( dimz > 1 || dimy > 1 || dimx > 1 ) xyz = 321; // ZYX
+    else
+      {
+        if ( dimz == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 3; break;}
+        if ( dimy == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 2; break;}
+        if ( dimx == 0 ) for ( int id = 0; id < 3; ++id ) if ( dimorder[id] == 0 ) {dimorder[id] = 1; break;}
+        xyz = vlistEncodeXyz(&dimorder);
+      }
+  }
 
-  Flag += unused_bits;
+  assert(xyz == 123 || xyz == 312 || xyz == 231 || xyz == 321 || xyz == 132 || xyz == 213);
 
+  vlistptr->vars[varID].xyz = xyz;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+}
 
-  /*
-    Adjust number of bits per value if full integer length to
-    avoid hitting most significant bit (sign bit).
-  */
-  /* if( nbpv == ibits ) nbpv = nbpv - 1; */
-  /*
-    Calculate the binary scaling factor to spread the range of
-    values over the number of bits per value.
-    Limit scaling to 2**-126 to 2**127 (using IEEE 32-bit floats
-    as a guideline).           
-  */
-  range = fabs(fmax - fmin);
 
-  if ( fabs(fmin) < FLT_MIN ) fmin = 0;
-  /*
-    Have to allow tolerance in comparisons on some platforms
-    (eg vpp700 and linux), such as 0.9999999999999999 = 1.0,
-    to avoid clipping ranges which are a power of 2.
-  */
-  if ( range <= jpepsln )
-    {
-      binscale = 0;
-    }
-  else if ( IS_NOT_EQUAL(fmin, 0.0) && (fabs(range/fmin) <= jpepsln) )
-    {
-      binscale = 0;
-    }
-  else if ( fabs(range-1.0) <= jpepsln )
-    {
-      binscale = 1 - nbpv;
-    }
-  else if ( range > 1.0 )
-    {
-      rangec = range + jpepsln;
-      for ( jloop = 1; jloop < 128; jloop++ )
-	{
-	  if ( _pow2tab[jloop] > rangec ) break;
-	}
-      if ( jloop == 128 )
-	{
-	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
-	  gprintf(__func__, "> range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
-	  return (707);
-	}
-      else
-	{
-	  binscale = jloop - nbpv;
-	}
-    }
-  else
-    {
-      rangec = range - jpepsln;
-      for ( jloop = 1; jloop < 127; jloop++ )
-	{
-	  if ( 1.0/_pow2tab[jloop] < rangec ) break;
-	}
-      if ( jloop == 127 )
-	{
-	  gprintf(__func__, "Problem calculating binary scale value for encode code %d!", code);
-	  gprintf(__func__, "< range %g rangec %g fmin %g fmax %g", range, rangec, fmin, fmax);
-	  return (707);
-	}
-      else
-	{
-	  binscale = 1 - jloop - nbpv;
-	}
-    }
+void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3])
+{
+  vlist_t *vlistptr;
 
-  //max_nbpv_pow2 = (unsigned) (intpow2(nbpv) - 1);
-  max_nbpv_pow2 = (unsigned) ((1ULL << nbpv) - 1);
+  vlistptr = vlist_to_pointer(vlistID);
 
-  if ( binscale != 0 )
-    {
-      if ( binscale < 0 )
-	{
-	  if ( (unsigned)(range*intpow2(-binscale)+0.5) > max_nbpv_pow2 ) binscale++;
-	}
-      else
-	{
-	  if ( (unsigned)(range/intpow2(binscale)+0.5) > max_nbpv_pow2 ) binscale--;
-	}
+  vlistCheckVarID(__func__, vlistID, varID);
 
-      if ( binscale < 0 ) factor =     intpow2(-binscale);
-      else                factor = 1.0/intpow2( binscale);
-    }
+  vlistDecodeXyz(vlistptr->vars[varID].xyz, outDimorder);
+}
 
-  ref2ibm(&zref, BitsPerInt);
 
-  Put3Byte(blockLength);      /*  0-2 Length of Block 4        */
-  Put1Byte(Flag);             /*  3   Flag & Unused bits       */
-  if ( binscale < 0 ) binscale = 32768 - binscale;
-  Put2Byte(binscale);         /*  4-5 Scale factor             */
-  Put1Real(zref);             /*  6-9 Reference value          */
-  Put1Byte(nbpv);             /*   10 Packing size             */
+int vlistInqVarXYZ(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( lspherc )
-    {
-      if ( lcomplex )
-	{
-	  int jup = isubset;
-	  int ioff = z + bds_ext;
-	  if ( ioff > 0xFFFF ) ioff = 0;
-	  Put2Byte(ioff);
-	  Put2Int(isec4[16]);
-	  Put1Byte(jup);
-	  Put1Byte(jup);
-	  Put1Byte(jup);
-	  for ( i = 0; i < ((jup+1)*(jup+2)); i++ ) Put1Real((double)(data[i]));
-	}
-      else
-	{
-	  Put1Real((double)(data[0]));
-	}
-    }
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *datsize  = ((datasize-PackStart)*nbpv + 7)/8;
+  return (vlistptr->vars[varID].xyz);
+}
 
-#if  defined  (_ARCH_PWR6)
-  TEMPLATE(encode_array_unrolled,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
-#else
-  TEMPLATE(encode_array,T)(nbpv, PackStart, datasize, lGrib, data, (T)zref, factor, &z);
-#endif
+/* Ensemble Info Routines */
+void vlistDefVarEnsemble(int vlistID, int varID, int ensID, int ensCount, int forecast_type )
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( unused_bits >= 8 ) Put1Byte(0);  /*  Fillbyte                     */
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  *gribLen = z;
+  if ( vlistptr->vars[varID].ensdata == NULL )
+    vlistptr->vars[varID].ensdata
+      = (ensinfo_t *)xmalloc( sizeof( ensinfo_t ) );
 
-  return (0);
+  vlistptr->vars[varID].ensdata->ens_index          = ensID;
+  vlistptr->vars[varID].ensdata->ens_count          = ensCount;
+  vlistptr->vars[varID].ensdata->forecast_init_type = forecast_type;
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
 }
 
 
-void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *isec3,
-			     T *fsec3, int *isec4, T *fsec4, int klenp, int *kgrib,
-			     int kleng, int *kword, int efunc, int *kret)
+int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int *forecast_type )
 {
-  long gribLen = 0; /* Counter of GRIB length for output */
-  long isLen, pdsLen;
-  GRIBPACK *lpds;
-  unsigned char *CGrib;
-  long fsec4size = 0;
-  int numBytes;
-  int bmsIncluded;
-  size_t len;
-  GRIBPACK *lGrib;
-  long datstart, datsize, bdsstart;
   int status = 0;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  UNUSED(isec3);
-  UNUSED(efunc);
+  vlistCheckVarID(__func__, vlistID, varID);
 
-  grsdef();
+  if ( vlistptr->vars[varID].ensdata )
+    {
+      *ensID = vlistptr->vars[varID].ensdata->ens_index;
+      *ensCount = vlistptr->vars[varID].ensdata->ens_count;
+      *forecast_type = vlistptr->vars[varID].ensdata->forecast_init_type;
 
-  CGrib = (unsigned char *) kgrib;
+      status = 1;
+    }
 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
+  return (status);
+}
 
-  /* set max header len */
-  len = 16384;
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
 
-  /* add data len */
-  numBytes = (ISEC4_NumBits+7)>>3;
+/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
+void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int idx;
 
-  len += numBytes*klenp;
+  if ( !vlistptr->locked )
+    Error("User defined vlist object (vlistID=%d) isn't allowed!\n"
+          "Need a CDI internal vlist object from streamInqVlist(streamID).", vlistID);
 
-  /* add bitmap len */
-  if ( bmsIncluded ) len += (klenp+7)>>3;
+  for ( idx=0; idx<vlistptr->vars[varID].opt_grib_int_nentries; idx++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[idx]) == 0 ) break;
 
-#if defined (VECTORCODE)
-  lGrib = (GRIBPACK*) malloc(len*sizeof(GRIBPACK));
-  if ( lGrib == NULL ) SysError("No Memory!");
+  if ( idx < vlistptr->vars[varID].opt_grib_int_nentries )
+    {
+      vlistptr->vars[varID].opt_grib_int_val[idx] = value;
+      vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
+    }
+  else
+    {
+      idx = vlistptr->vars[varID].opt_grib_int_nentries;
+      vlistptr->vars[varID].opt_grib_int_nentries++;
+      if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+      vlistptr->vars[varID].opt_grib_int_val[idx] = value;
+      vlistptr->vars[varID].opt_grib_int_update[idx] = TRUE;
+      if ( name )
+        vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
+      else
+        Error("Internal error, name undefined!");
+    }
+
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
 #else
-  lGrib = CGrib;
+  (void)vlistID;
+  (void)varID;
+  (void)name;
+  (void)value;
 #endif
+}
 
-  isLen = 8;
-  encodeIS(lGrib, &gribLen);
-  lpds = &lGrib[isLen];
-  pdsLen = getPdsLen(isec1);
-
-  encodePDS(lpds, pdsLen,  isec1);
-  gribLen += pdsLen;
-  /*
-  if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
-    {
-      static int lwarn_cplx = TRUE;
+/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
+void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int idx;
 
-      if ( lwarn_cplx )
-	Message("Complex packing of spectral data unsupported, using simple packing!");
+  if ( !vlistptr->locked )
+    Error("User defined vlist object (vlistID=%d) isn't allowed!\n"
+          "Need a CDI internal vlist object from streamInqVlist(streamID).", vlistID);
 
-      isec2[5] = 1;
-      isec4[3] = 0;
+  for ( idx=0; idx<vlistptr->vars[varID].opt_grib_dbl_nentries; idx++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[idx]) == 0 ) break;
 
-      lwarn_cplx = FALSE;
-    }
-  */
-  TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  if ( bmsIncluded )
+  if ( idx < vlistptr->vars[varID].opt_grib_dbl_nentries )
     {
-      TEMPLATE(encodeBMS,T)(lGrib, &gribLen, fsec3, isec4, fsec4, &fsec4size);
+      vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
+      vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
     }
   else
     {
-      fsec4size = ISEC4_NumValues;
-    }
-
-  bdsstart = gribLen;
-  status = TEMPLATE(encodeBDS,T)(lGrib, &gribLen, ISEC1_DecScaleFactor, isec2,
-				 isec4, fsec4size, fsec4, &datstart, &datsize, ISEC1_Parameter);
-  if ( status )
-    {
-      *kret = status;
-      return;
+      idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+      vlistptr->vars[varID].opt_grib_dbl_nentries++;
+      if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+      vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
+      vlistptr->vars[varID].opt_grib_dbl_update[idx] = TRUE;
+      if ( name )
+        vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
+      else
+        Error("Internal error, name undefined!");
     }
 
-  encodeES(lGrib, &gribLen, bdsstart);
-
-  if ( (size_t) gribLen > kleng*sizeof(int) )
-    Error("kgrib buffer too small! kleng = %d  gribLen = %d", kleng, gribLen);
-
-#if defined (VECTORCODE)
-  if ( (size_t) gribLen > len )
-    Error("lGrib buffer too small! len = %d  gribLen = %d", len, gribLen);
-
-  (void) PACK_GRIB(lGrib, (unsigned char *)CGrib, gribLen, -1L);
-
-  free(lGrib);
+  reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+#else
+  (void)vlistID;
+  (void)varID;
+  (void)name;
+  (void)value;
 #endif
-
-  ISEC0_GRIB_Len     = gribLen;
-  ISEC0_GRIB_Version = 1;
-
-  *kword = gribLen / sizeof(int);
-  if ( (size_t) gribLen != *kword * sizeof(int) ) *kword += 1;
-
-  *kret = status;
 }
 
-#endif /* T */
 
-void encode_dummy(void)
-{
-  (void) encode_array_unrolled_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
-  (void) encode_array_unrolled_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
-}
-static const char grb_libvers[] = "1.7.0" " of ""Dec  3 2014"" ""08:52:12";
-const char *
-cgribexLibraryVersion(void)
+/* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
+void cdiClearAdditionalKeys()
 {
-  return (grb_libvers);
-}
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic pop
-#endif
-
-#if defined (HAVE_CONFIG_H)
+#if  defined  (HAVE_LIBGRIB_API)
+  for (int i=0; i<cdiNAdditionalGRIBKeys; i++)  free(cdiAdditionalGRIBKeys[i]);
+  cdiNAdditionalGRIBKeys = 0;
 #endif
+}
 
+/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
+void cdiDefAdditionalKey(const char *name)
+{
 #if  defined  (HAVE_LIBGRIB_API)
-#  include <grib_api.h>
+  int idx = cdiNAdditionalGRIBKeys;
+  cdiNAdditionalGRIBKeys++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many additional keywords!");
+  if ( name )
+    cdiAdditionalGRIBKeys[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+#else
+  (void)name;
 #endif
+}
 
-#include <stdio.h>
+/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
+int vlistHasVarKey(int vlistID, int varID, const char* name)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  /* check if the GRIB key was previously read and is stored */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
+  for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+	return 1;
+    }
 
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
+  for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+	return 1;
+    }
+#else
+  (void)vlistID;
+  (void)varID;
+  (void)name;
+#endif
+  return 0;
+}
 
-static char gribapi_libvers[64] = "";
+/* vlistInqVarDblKey: raw access to GRIB meta-data */
+double vlistInqVarDblKey(int vlistID, int varID, const char* name)
+{
+  double value = 0;
 #if  defined  (HAVE_LIBGRIB_API)
-static int gribapi_libvers_init;
+  /* check if the GRIB key was previously read and is stored in "opt_grib_dbl_val" */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_dbl_val[i];
+#else
+  (void)vlistID;
+  (void)varID;
+  (void)name;
 #endif
+  return value;
+}
 
 
-void gribapiLibraryVersion(int* major_version, int* minor_version, int* revision_version)
+/* vlistInqVarIntKey: raw access to GRIB meta-data */
+int vlistInqVarIntKey(int vlistID, int varID, const char* name)
 {
+  long int value = 0;
 #if  defined  (HAVE_LIBGRIB_API)
-  long version = grib_get_api_version();
-  (*major_version)    = version/10000;
-  (*minor_version)    = (version-(*major_version)*10000)/100;
-  (*revision_version) = (version-(*major_version)*10000-(*minor_version)*100);
+  /* check if the GRIB key was previously read and is stored in "opt_grib_int_val" */
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_int_val[i];
 #else
-  (*major_version)    = 0;
-  (*minor_version)    = 0;
-  (*revision_version) = 0;
+  (void)vlistID;
+  (void)varID;
+  (void)name;
 #endif
+  return (int) value;
 }
 
-const char *gribapiLibraryVersionString(void)
+
+void vlistDefVarIOrank(int vlistID, int varID, int iorank)
 {
-#if  defined  (HAVE_LIBGRIB_API)
-  if (!gribapi_libvers_init)
-    {
-      int major_version, minor_version, revision_version;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID );
 
-      gribapiLibraryVersion(&major_version, &minor_version, &revision_version);
+  vlistCheckVarID ( __func__, vlistID, varID );
 
-      sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version);
-      gribapi_libvers_init = 1;
+  if (vlistptr->vars[varID].iorank != iorank)
+    {
+      vlistptr->vars[varID].iorank = iorank;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
-#endif
-
-  return (gribapi_libvers);
 }
 
 
-void gribContainersNew(stream_t * streamptr)
+int vlistInqVarIOrank(int vlistID, int varID)
 {
-  int editionNumber = 2;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
-  (void)editionNumber;
-#if  defined  (HAVE_LIBCGRIBEX)
-  if ( streamptr->filetype == FILETYPE_GRB )
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  return vlistptr->vars[varID].iorank;
+}
+
+
+int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
+{
+  xassert(a && b
+          && varIDA >= 0 && varIDA < a->nvars
+          && varIDB >= 0 && varIDB < b->nvars);
+  var_t *pva = a->vars + varIDA, *pvb = b->vars + varIDB;
+#define FCMP(f) ((pva->f) != (pvb->f))
+#define FCMPFLT(f) (IS_NOT_EQUAL((pva->f), (pvb->f)))
+#define FCMPSTR(fs) ((pva->fs) != (pvb->fs) && strcmp((pva->fs), (pvb->fs)))
+#define FCMP2(f) (namespaceResHDecode(pva->f).idx       \
+                  != namespaceResHDecode(pvb->f).idx)
+  int diff = FCMP(fvarID) | FCMP(mvarID) | FCMP(flag) | FCMP(param)
+    | FCMP(datatype) | FCMP(tsteptype) | FCMP(timave) | FCMP(timaccu)
+    | FCMP(chunktype) | FCMP(xyz) | FCMP2(gridID) | FCMP2(zaxisID)
+    | FCMP2(instID) | FCMP2(modelID) | FCMP2(tableID) | FCMP(missvalused)
+    | FCMPFLT(missval) | FCMPFLT(addoffset) | FCMPFLT(scalefactor) | FCMPSTR(name)
+    | FCMPSTR(longname) | FCMPSTR(stdname) | FCMPSTR(units) | FCMPSTR(extra)
+    | FCMP(comptype) | FCMP(complevel) | FCMP(lvalidrange)
+    | FCMPFLT(validrange[0]) | FCMPFLT(validrange[1]);
+#undef FCMP
+#undef FCMPFLT
+#undef FCMP2
+  if ((diff |= ((pva->levinfo == NULL) ^ (pvb->levinfo == NULL))))
+    return 1;
+  if (pva->levinfo)
     {
+      int zaxisID = pva->zaxisID;
+      size_t nlevs = (size_t)zaxisInqSize(zaxisID);
+      diff |= (memcmp(pva->levinfo, pvb->levinfo, sizeof (levinfo_t) * nlevs)
+               != 0);
+      if (diff)
+        return 1;
     }
-  else
-#endif
-    {
-      int nvars = streamptr->nvars;
+  size_t natts = a->vars[varIDA].atts.nelems;
+  if (natts != b->vars[varIDB].atts.nelems)
+    return 1;
+  for (size_t attID = 0; attID < natts; ++attID)
+    diff |= vlist_att_compare(a, varIDA, b, varIDB, (int)attID);
+  if ((diff |= ((pva->ensdata == NULL) ^ (pvb->ensdata == NULL))))
+    return 1;
+  if (pva->ensdata)
+    diff = (memcmp(pva->ensdata, pvb->ensdata, sizeof (*(pva->ensdata)))) != 0;
+  return diff;
+}
 
-#if defined (GRIBCONTAINER2D)
-      gribContainer_t **gribContainers;
-      gribContainers = (gribContainer_t **) malloc(nvars*sizeof(gribContainer_t *));
 
-      for ( int varID = 0; varID < nvars; ++varID )
+
+enum {
+  vlistvar_nints = 20,
+  vlistvar_ndbls = 3,
+};
+
+int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
+{
+  var_t *var = p->vars + varID;
+  int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
+    + serializeGetSize(vlistvar_ndbls, DATATYPE_FLT64, context);
+  if (var->name)
+    varsize += serializeGetSize((int)strlen(var->name), DATATYPE_TXT, context);
+  if (var->longname)
+    varsize += serializeGetSize((int)strlen(var->longname), DATATYPE_TXT, context);
+  if (var->stdname)
+    varsize += serializeGetSize((int)strlen(var->stdname), DATATYPE_TXT, context);
+  if (var->units)
+    varsize += serializeGetSize((int)strlen(var->units), DATATYPE_TXT, context);
+  varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
+                              DATATYPE_INT, context);
+  varsize += vlistAttsGetSize(p, varID, context);
+  return varsize;
+}
+
+void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
+                  void *context)
+{
+  double dtempbuf[vlistvar_ndbls];
+  var_t *var = p->vars + varID;
+  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz;
+
+  tempbuf[0] = var->flag;
+  tempbuf[1] = var->gridID;
+  tempbuf[2] = var->zaxisID;
+  tempbuf[3] = var->tsteptype;
+  tempbuf[4] = namesz = var->name?(int)strlen(var->name):0;
+  tempbuf[5] = longnamesz = var->longname?(int)strlen(var->longname):0;
+  tempbuf[6] = stdnamesz = var->stdname?(int)strlen(var->stdname):0;
+  tempbuf[7] = unitssz = var->units?(int)strlen(var->units):0;
+  tempbuf[8] = var->datatype;
+  tempbuf[9] = var->param;
+  tempbuf[10] = var->instID;
+  tempbuf[11] = var->modelID;
+  tempbuf[12] = var->tableID;
+  tempbuf[13] = var->timave;
+  tempbuf[14] = var->timaccu;
+  tempbuf[15] = var->missvalused;
+  tempbuf[16] = var->comptype;
+  tempbuf[17] = var->complevel;
+  int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
+  tempbuf[18] = nlevs;
+  tempbuf[19] = var->iorank;
+  dtempbuf[0] = var->missval;
+  dtempbuf[1] = var->scalefactor;
+  dtempbuf[2] = var->addoffset;
+  serializePack(tempbuf, vlistvar_nints, DATATYPE_INT,
+                buf, size, position, context);
+  serializePack(dtempbuf, vlistvar_ndbls, DATATYPE_FLT64,
+                buf, size, position, context);
+  if (namesz)
+    serializePack(var->name, namesz, DATATYPE_TXT, buf, size, position, context);
+  if (longnamesz)
+    serializePack(var->longname, longnamesz, DATATYPE_TXT,
+                  buf, size, position, context);
+  if (stdnamesz)
+    serializePack(var->stdname, stdnamesz, DATATYPE_TXT,
+                  buf, size, position, context);
+  if (unitssz)
+    serializePack(var->units, unitssz, DATATYPE_TXT,
+                  buf, size, position, context);
+  if (nlevs)
+    {
+      int levbuf[nlevs][4];
+      for (int levID = 0; levID < nlevs; ++levID)
         {
-          int nlevs = streamptr->vars[varID].nlevs;
-          gribContainers[varID] = (gribContainer_t *) malloc(nlevs*sizeof(gribContainer_t));
+          levbuf[levID][0] = var->levinfo[levID].flag;
+          levbuf[levID][1] = var->levinfo[levID].index;
+          levbuf[levID][2] = var->levinfo[levID].mlevelID;
+          levbuf[levID][3] = var->levinfo[levID].flevelID;
+        }
+      serializePack(levbuf, nlevs * 4, DATATYPE_INT,
+                    buf, size, position, context);
+    }
+  vlistAttsPack(p, varID, buf, size, position, context);
+}
 
-          for ( int levelID = 0; levelID < nlevs; ++levelID )
-            {
-              gribContainers[varID][levelID].gribHandle = gribHandleNew(editionNumber);
-              gribContainers[varID][levelID].init = FALSE;
-            }
-	}
+static inline int
+imax(int a, int b)
+{
+  return a>=b?a:b;
+}
 
-      streamptr->gribContainers = (void **) gribContainers;
-#else
-      gribContainer_t *gribContainers
-        = (gribContainer_t *)xmalloc((size_t)nvars*sizeof(gribContainer_t));
 
-      for ( int varID = 0; varID < nvars; ++varID )
+void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
+		    int originNamespace, void *context)
+{
+  double dtempbuf[vlistvar_ndbls];
+  int tempbuf[vlistvar_nints];
+  char *varname = NULL;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  serializeUnpack(buf, size, position,
+                  tempbuf, vlistvar_nints, DATATYPE_INT, context);
+  serializeUnpack(buf, size, position,
+                  dtempbuf, vlistvar_ndbls, DATATYPE_FLT64, context);
+
+  int newvar = vlistDefVar ( vlistID,
+			 namespaceAdaptKey ( tempbuf[1], originNamespace ),
+			 namespaceAdaptKey ( tempbuf[2], originNamespace ),
+			 tempbuf[3]);
+  if (tempbuf[4] || tempbuf[5] || tempbuf[6] || tempbuf[7])
+    varname = (char *)xmalloc((size_t)imax(imax(imax(tempbuf[4],tempbuf[5]),
+                                                tempbuf[6]),
+                                           tempbuf[7]) + 1);
+  if (tempbuf[4])
+  {
+    serializeUnpack(buf, size, position,
+                    varname, tempbuf[4], DATATYPE_TXT, context);
+    varname[tempbuf[4]] = '\0';
+    vlistDefVarName(vlistID, newvar, varname);
+  }
+  if (tempbuf[5])
+  {
+    serializeUnpack(buf, size, position,
+                    varname, tempbuf[5], DATATYPE_TXT, context);
+    varname[tempbuf[5]] = '\0';
+    vlistDefVarLongname(vlistID, newvar, varname);
+  }
+  if (tempbuf[6])
+  {
+    serializeUnpack(buf, size, position,
+                    varname, tempbuf[6], DATATYPE_TXT, context);
+    varname[tempbuf[6]] = '\0';
+    vlistDefVarStdname(vlistID, newvar, varname);
+  }
+  if (tempbuf[7])
+  {
+    serializeUnpack(buf, size, position,
+                    varname, tempbuf[7], DATATYPE_TXT, context);
+    varname[tempbuf[7]] = '\0';
+    vlistDefVarUnits(vlistID, newvar, varname);
+  }
+  free(varname);
+  vlistDefVarDatatype(vlistID, newvar, tempbuf[8]);
+  vlistDefVarInstitut ( vlistID, newvar,
+			namespaceAdaptKey ( tempbuf[10], originNamespace ));
+  vlistDefVarModel ( vlistID, newvar,
+		     namespaceAdaptKey ( tempbuf[11], originNamespace ));
+  vlistDefVarTable(vlistID, newvar, tempbuf[12]);
+  /* FIXME: changing the table might change the param code */
+  vlistDefVarParam(vlistID, newvar, tempbuf[9]);
+  vlistDefVarTimave(vlistID, newvar, tempbuf[13]);
+  vlistDefVarTimaccu(vlistID, newvar, tempbuf[14]);
+  if (tempbuf[15])
+    vlistDefVarMissval(vlistID, newvar, dtempbuf[0]);
+  vlistDefVarScalefactor(vlistID, newvar, dtempbuf[1]);
+  vlistDefVarAddoffset(vlistID, newvar, dtempbuf[2]);
+  vlistDefVarCompType(vlistID, newvar, tempbuf[16]);
+  vlistDefVarCompLevel(vlistID, newvar, tempbuf[17]);
+  int nlevs = tempbuf[18];
+  if (nlevs)
+    {
+      int levbuf[nlevs][4];
+      var_t *var = vlistptr->vars + newvar;
+      int i, flagSetLev = 0;
+      cdiVlistCreateVarLevInfo(vlistptr, newvar);
+      serializeUnpack(buf, size, position,
+                      levbuf, nlevs * 4, DATATYPE_INT, context);
+      for (i = 0; i < nlevs; ++i)
         {
-          gribContainers[varID].gribHandle = gribHandleNew(editionNumber);
-          gribContainers[varID].init = FALSE;
-	}
-
-      streamptr->gribContainers = (void *) gribContainers;
-#endif
+          vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
+          vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
+          // FIXME: these lack an accessor function
+          var->levinfo[i].mlevelID = levbuf[i][2];
+          var->levinfo[i].flevelID = levbuf[i][3];
+          if (levbuf[i][0] == tempbuf[0])
+            flagSetLev = i;
+        }
+      vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
     }
+  vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
+  vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
 }
 
 
-void gribContainersDelete(stream_t * streamptr)
-{
-  if ( streamptr->gribContainers )
-    {
-      int nvars = streamptr->nvars;
-
-#if defined (GRIBCONTAINER2D)
-      gribContainer_t **gribContainers = (gribContainer_t **) streamptr->gribContainers;
-
-      for ( int varID = 0; varID < nvars; ++varID )
-	{
-          int nlevs = streamptr->vars[varID].nlevs;
-          for ( int levelID = 0; levelID < nlevs; ++levelID )
-            {
-              gribHandleDelete(gribContainers[varID][levelID].gribHandle);
-            }
-          free(gribContainers[varID]);
-	}
-#else
-      gribContainer_t *gribContainers = (gribContainer_t *) streamptr->gribContainers;
-
-      for ( int varID = 0; varID < nvars; ++varID )
-	{
-          gribHandleDelete(gribContainers[varID].gribHandle);
-	}
-#endif
-
-      free(gribContainers);
-
-      streamptr->gribContainers = NULL;
-    }
-}
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -62223,1738 +65077,1657 @@ void gribContainersDelete(stream_t * streamptr)
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#include <inttypes.h>
-#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
 
 
-void swap4byte(void *ptr, size_t size)
-{
-  int32_t *ptrtmp = ptr;
 
-  if (sizeof (int32_t) == 4)
-    for (size_t i = 0; i < size; ++i)
-      ptrtmp[i] = (((ptrtmp[i] >> 24) & 0x00ff) | ((ptrtmp[i] & 0x00ff) << 24) |
-                   ((ptrtmp[i] >>  8) & 0xff00) | ((ptrtmp[i] & 0xff00) <<  8));
-  else
-    Error("not implemented for %d byte data", sizeof(int32_t));
-}
+#define  LevelUp    1
+#define  LevelDown  2
 
-void swap8byte(void *ptr, size_t size)
-{
-  int64_t *ptrtmp = ptr;
 
-  if (sizeof (int64_t) == 8)
-    for (size_t i = 0; i < size; ++i)
-      ptrtmp[i] = (((ptrtmp[i] >> 56) & 0x000000ff) | ((ptrtmp[i] & 0x000000ff) << 56) |
-                   ((ptrtmp[i] >> 40) & 0x0000ff00) | ((ptrtmp[i] & 0x0000ff00) << 40) |
-                   ((ptrtmp[i] >> 24) & 0x00ff0000) | ((ptrtmp[i] & 0x00ff0000) << 24) |
-                   ((ptrtmp[i] >>  8) & 0xff000000) | ((ptrtmp[i] & 0xff000000) <<  8));
-  else
-    Error("not implemented for %d byte data", sizeof(int64_t));
+static const struct {
+  unsigned char positive;   // 1: up;  2: down
+  char *name;
+  char *longname;
+  char *stdname;
+  char *units;
 }
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-
-
-#undef  IsBigendian
-#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
+ZaxistypeEntry[] = {
+  { /*  0 */ 0, "sfc",               "surface",                "",               ""},
+  { /*  1 */ 0, "lev",               "generic",                "",               "level"},
+  { /*  2 */ 2, "lev",               "hybrid",                 "",               "level"},
+  { /*  3 */ 2, "lev",               "hybrid_half",            "",               "level"},
+  { /*  4 */ 2, "lev",               "pressure",               "air_pressure",   "Pa"},
+  { /*  5 */ 1, "height",            "height",                 "height",         "m"},
+  { /*  6 */ 2, "depth",             "depth_below_sea",        "depth",          "m"},
+  { /*  7 */ 2, "depth",             "depth_below_land",       "",               "cm"},
+  { /*  8 */ 0, "lev",               "isentropic",             "",               "K"},
+  { /*  9 */ 0, "lev",               "trajectory",             "",               ""},
+  { /* 10 */ 1, "alt",               "altitude",               "",               "m"},
+  { /* 11 */ 0, "lev",               "sigma",                  "",               "level"},
+  { /* 12 */ 0, "lev",               "meansea",                "",               "level"},
+  { /* 13 */ 0, "toa",               "top_of_atmosphere",      "",               ""},
+  { /* 14 */ 0, "seabottom",         "sea_bottom",             "",               ""},
+  { /* 15 */ 0, "atmosphere",        "atmosphere",             "",               ""},
+  { /* 16 */ 0, "cloudbase",         "cloud_base",             "",               ""},
+  { /* 17 */ 0, "cloudtop",          "cloud_top",              "",               ""},
+  { /* 18 */ 0, "isotherm0",         "isotherm_zero",          "",               ""},
+  { /* 19 */ 0, "snow",              "snow",                   "",               ""},
+  { /* 20 */ 0, "lakebottom",        "lake_bottom",            "",               ""},
+  { /* 21 */ 0, "sedimentbottom",    "sediment_bottom",        "",               ""},
+  { /* 22 */ 0, "sedimentbottomta",  "sediment_bottom_ta",     "",               ""},
+  { /* 23 */ 0, "sedimentbottomtw",  "sediment_bottom_tw",     "",               ""},
+  { /* 24 */ 0, "mixlayer",          "mix_layer",              "",               ""},
+  { /* 25 */ 0, "height",            "generalized height",     "height",         ""},
+};
 
+enum {
+  CDI_NumZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]),
+};
 
-UINT32 get_UINT32(unsigned char *x)
-{
-  /* IsBigendian returns 1 for big endian byte order */
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  if ( IsBigendian() )
-    return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
-  else
-    return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
+typedef struct {
+  unsigned char positive;
+  char     name[CDI_MAX_NAME];
+  char     longname[CDI_MAX_NAME];
+  char     stdname[CDI_MAX_NAME];
+  char     units[CDI_MAX_NAME];
+  double  *vals;
+  double  *lbounds;
+  double  *ubounds;
+  double  *weights;
+  int      self;
+  int      prec;
+  int      type;
+  int      ltype;    /* GRIB level type */
+  int      ltype2;
+  int      size;
+  int      direction;
+  int      vctsize;
+  double  *vct;
+  int      number;   /* Reference number to a generalized Z-axis */
+  int      nhlev;
+  unsigned char uuid[CDI_UUID_SIZE];
 }
+zaxis_t;
 
+static int zaxisCompareP(zaxis_t *z1, zaxis_t *z2);
+static void   zaxisDestroyP    ( void * zaxisptr );
+static void   zaxisPrintP      ( void * zaxisptr, FILE * fp );
+static int    zaxisGetPackSize ( void * zaxisptr, void *context);
+static void   zaxisPack        ( void * zaxisptr, void * buffer, int size, int *pos, void *context);
+static int    zaxisTxCode      ( void );
 
-UINT32 get_SUINT32(unsigned char *x)
-{
-  /* IsBigendian returns 1 for big endian byte order */
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-
-  if ( IsBigendian() )
-    return((UINT32)(((UINT32)x[3]<<24)+((UINT32)x[2]<<16)+((UINT32)x[1]<< 8)+ (UINT32)x[0]));
-  else
-    return((UINT32)(((UINT32)x[0]<<24)+((UINT32)x[1]<<16)+((UINT32)x[2]<< 8)+ (UINT32)x[3]));
-}
+const resOps zaxisOps = {
+  (int (*)(void *, void *))zaxisCompareP,
+  zaxisDestroyP,
+  zaxisPrintP,
+  zaxisGetPackSize,
+  zaxisPack,
+  zaxisTxCode
+};
 
+static int  ZAXIS_Debug = 0;   /* If set to 1, debugging */
 
-UINT64 get_UINT64(unsigned char *x)
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit)
 {
-  /* IsBigendian returns 1 for big endian byte order */
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-
-  if ( IsBigendian() )
-    return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
-		    ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
+  if(zaxisType < 0 || zaxisType >= CDI_NumZaxistype)
+    {
+      if(outPositive) *outPositive = 0;
+      if(outName) *outName = NULL;
+      if(outLongName) *outLongName = NULL;
+      if(outStdName) *outStdName = NULL;
+      if(outUnit) *outUnit = NULL;
+    }
   else
-    return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
-		    ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
+    {
+      if(outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
+      if(outName) *outName = ZaxistypeEntry[zaxisType].name;
+      if(outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
+      if(outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
+      if(outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
+    }
 }
 
-
-UINT64 get_SUINT64(unsigned char *x)
+static
+void zaxisDefaultValue(zaxis_t *zaxisptr)
 {
-  /* IsBigendian returns 1 for big endian byte order */
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-
-  if ( IsBigendian() )
-    return((UINT64)(((UINT64)x[7]<<56)+((UINT64)x[6]<<48)+((UINT64)x[5]<<40)+((UINT64)x[4]<<32)+
-		    ((UINT64)x[3]<<24)+((UINT64)x[2]<<16)+((UINT64)x[1]<< 8)+ (UINT64)x[0]));
-  else
-    return((UINT64)(((UINT64)x[0]<<56)+((UINT64)x[1]<<48)+((UINT64)x[2]<<40)+((UINT64)x[3]<<32)+
-		    ((UINT64)x[4]<<24)+((UINT64)x[5]<<16)+((UINT64)x[6]<< 8)+ (UINT64)x[7]));
+  zaxisptr->self        = CDI_UNDEFID;
+  zaxisptr->name[0]     = 0;
+  zaxisptr->longname[0] = 0;
+  zaxisptr->stdname[0]  = 0;
+  zaxisptr->units[0]    = 0;
+  zaxisptr->vals        = NULL;
+  zaxisptr->ubounds     = NULL;
+  zaxisptr->lbounds     = NULL;
+  zaxisptr->weights     = NULL;
+  zaxisptr->type        = CDI_UNDEFID;
+  zaxisptr->ltype       = 0;
+  zaxisptr->ltype2      = -1;
+  zaxisptr->positive    = 0;
+  zaxisptr->direction   = 0;
+  zaxisptr->prec        = 0;
+  zaxisptr->size        = 0;
+  zaxisptr->vctsize     = 0;
+  zaxisptr->vct         = NULL;
+  zaxisptr->number      = 0;
+  zaxisptr->nhlev       = 0;
+  memset(zaxisptr->uuid, 0, CDI_UUID_SIZE);
 }
 
 
-size_t binReadF77Block(int fileID, int byteswap)
+static
+zaxis_t *zaxisNewEntry(int id)
 {
-  unsigned char f77block[4];
-  size_t blocklen = 0;
-
-  if ( fileRead(fileID, f77block, 4) == 4 )
-    {
-      if ( byteswap )
-	blocklen = get_SUINT32(f77block);
-      else
-	blocklen =  get_UINT32(f77block);
-    }
-
-  return (blocklen);
-}
-
+  zaxis_t *zaxisptr = (zaxis_t *)xmalloc(sizeof(zaxis_t));
 
-void binWriteF77Block(int fileID, int byteswap, size_t blocksize)
-{
-  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
-  unsigned char f77block[4];
+  zaxisDefaultValue ( zaxisptr );
 
-  if ( IsBigendian() )
-    {
-      if ( byteswap )
-	{
-	  f77block[0] = (unsigned char) (blocksize);
-	  f77block[1] = (unsigned char) (blocksize >>  8);
-	  f77block[2] = (unsigned char) (blocksize >> 16);
-	  f77block[3] = (unsigned char) (blocksize >> 24);
-	}
-      else
-	{
-	  f77block[3] = (unsigned char) (blocksize);
-	  f77block[2] = (unsigned char) (blocksize >>  8);
-	  f77block[1] = (unsigned char) (blocksize >> 16);
-	  f77block[0] = (unsigned char) (blocksize >> 24);
-	}
-    }
+  if (id == CDI_UNDEFID)
+    zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
   else
     {
-      if ( byteswap )
-	{
-	  f77block[3] = (unsigned char) (blocksize);
-	  f77block[2] = (unsigned char) (blocksize >>  8);
-	  f77block[1] = (unsigned char) (blocksize >> 16);
-	  f77block[0] = (unsigned char) (blocksize >> 24);
-	}
-      else
-	{
-	  f77block[0] = (unsigned char) (blocksize);
-	  f77block[1] = (unsigned char) (blocksize >>  8);
-	  f77block[2] = (unsigned char) (blocksize >> 16);
-	  f77block[3] = (unsigned char) (blocksize >> 24);
-	}
+      zaxisptr->self = id;
+      reshReplace(id, zaxisptr, &zaxisOps);
     }
 
-  if ( fileWrite(fileID, f77block, 4) != 4 )
-    Error("write failed on %s", fileInqName(fileID));
+  return (zaxisptr);
 }
 
-
-int binReadInt32(int fileID, int byteswap, size_t size, INT32 *ptr)
+static
+void zaxisInit(void)
 {
-  if ( sizeof(INT32) == 4 )
-    {
-      fileRead(fileID, (void *) ptr, 4*size);
-      if ( byteswap ) swap4byte(ptr, size);
-    }
-  else
-    {
-      Error("not implemented for %d byte integer", sizeof(INT32));
-    }
-
-  return (0);
-}
+  static int zaxisInitialized = 0;
+  char *env;
 
+  if ( zaxisInitialized ) return;
 
-int binReadInt64(int fileID, int byteswap, size_t size, INT64 *ptr)
-{
-  if ( sizeof(INT64) == 8 )
-    {
-      fileRead(fileID, (void *) ptr, 8*size);
-      if ( byteswap ) swap8byte(ptr, size);
-    }
-  else
-    {
-      Error("not implemented for %d byte integer", sizeof(INT64));
-    }
+  zaxisInitialized = 1;
 
-  return (0);
+  env = getenv("ZAXIS_DEBUG");
+  if ( env ) ZAXIS_Debug = atoi(env);
 }
 
-
-int binReadFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr)
+static
+void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
 {
-  if ( sizeof(FLT32) == 4 )
-    {
-      fileRead(fileID, (void *) ptr, 4*size);
-      if ( byteswap ) swap4byte(ptr, size);
-    }
-  else
-    {
-      Error("not implemented for %d byte float", sizeof(FLT32));
-    }
-
-  return (0);
+  int zaxisID2 = zaxisptr2->self;
+  memcpy(zaxisptr2, zaxisptr1, sizeof(zaxis_t));
+  zaxisptr2->self = zaxisID2;
 }
 
-
-int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr)
+unsigned cdiZaxisCount(void)
 {
-  if ( sizeof(FLT64) == 8 )
-    {
-      fileRead(fileID, (void *) ptr, 8*size);
-      if ( byteswap ) swap8byte(ptr, size);
-    }
-  else
-    {
-      Error("not implemented for %d byte float", sizeof(FLT64));
-    }
-
-  return (0);
+  return reshCountType(&zaxisOps);
 }
 
-
-int binWriteInt32(int fileID, int byteswap, size_t size, INT32 *ptr)
+static int
+zaxisCreate_(int zaxistype, int size, int id)
 {
-  if ( sizeof(INT32) == 4 )
-    {
-      if ( byteswap ) swap4byte(ptr, size);
-      fileWrite(fileID, (void *) ptr, 4*size);
-    }
-  else
-    {
-      Error("not implemented for %d byte integer", sizeof(INT32));
-    }
+  zaxis_t *zaxisptr = zaxisNewEntry(id);
 
-  return (0);
-}
+  xassert(size >= 0);
+  zaxisptr->type = zaxistype;
+  zaxisptr->size = size;
 
+  if ( zaxistype >= CDI_NumZaxistype || zaxistype < 0 )
+    Error("Internal problem! zaxistype > CDI_MaxZaxistype");
 
-int binWriteInt64(int fileID, int byteswap, size_t size, INT64 *ptr)
-{
-  if ( sizeof(INT64) == 8 )
-    {
-      if ( byteswap ) swap8byte(ptr, size);
-      fileWrite(fileID, (void *) ptr, 8*size);
-    }
-  else
-    {
-      Error("not implemented for %d byte integer", sizeof(INT64));
-    }
+  int zaxisID = zaxisptr->self;
+  zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
+  zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
+  zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
 
-  return (0);
-}
+  if ( *ZaxistypeEntry[zaxistype].stdname )
+    strcpy(zaxisptr->stdname, ZaxistypeEntry[zaxistype].stdname);
 
+  zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
 
-int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr)
-{
-  if ( sizeof(FLT32) == 4 )
-    {
-      if ( byteswap ) swap4byte(ptr, size);
-      fileWrite(fileID, (void *) ptr, 4*size);
-    }
-  else
-    {
-      Error("not implemented for %d byte float", sizeof(FLT32));
-    }
+  double *vals = zaxisptr->vals
+    = (double *)xmalloc((size_t)size * sizeof(double));
 
-  return (0);
-}
+  for ( int ilev = 0; ilev < size; ilev++ )
+    vals[ilev] = 0.0;
 
+  return zaxisID;
+}
 
-int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr)
-{
-  if ( sizeof(FLT64) == 8 )
-    {
-      if ( byteswap ) swap8byte(ptr, size);
-      fileWrite(fileID, (void *) ptr, 8*size);
-    }
-  else
-    {
-      Error("not implemented for %d byte float", sizeof(FLT64));
-    }
 
-  return (0);
-}
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ at Function  zaxisCreate
+ at Title     Create a vertical Z-axis
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
+ at Prototype int zaxisCreate(int zaxistype, int size)
+ at Parameter
+    @Item  zaxistype  The type of the Z-axis, one of the set of predefined CDI Z-axis types.
+                      The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
+                      @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
+                      @func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
+                      @func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
+                      @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
+    @Item  size       Number of levels.
 
+ at Description
+The function @func{zaxisCreate} creates a vertical Z-axis.
 
+ at Result
+ at func{zaxisCreate} returns an identifier to the Z-axis.
 
-const char *cdfLibraryVersion(void)
+ at Example
+Here is an example using @func{zaxisCreate} to create a pressure level Z-axis:
+
+ at Source
+   ...
+#define  nlev    5
+   ...
+double levs[nlev] = {101300, 92500, 85000, 50000, 20000};
+int zaxisID;
+   ...
+zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev);
+zaxisDefLevels(zaxisID, levs);
+   ...
+ at EndSource
+ at EndFunction
+*/
+int zaxisCreate(int zaxistype, int size)
 {
-#if  defined  (HAVE_LIBNETCDF)
-  return (nc_inq_libvers());
-#else
-  return ("library undefined");
-#endif
-}
+  if ( CDI_Debug )
+    Message("zaxistype: %d size: %d ", zaxistype, size);
 
-#if  defined(HAVE_LIBHDF5)
-#if defined(__cplusplus)
-extern "C" {
-#endif
-  int H5get_libversion(unsigned *, unsigned *, unsigned *);
-#if defined(__cplusplus)
+  zaxisInit ();
+  return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
 }
-#endif
-#endif
 
-const char *hdfLibraryVersion(void)
+
+static void zaxisDestroyKernel( zaxis_t * zaxisptr )
 {
-#if  defined(HAVE_LIBHDF5)
-  static char hdf_libvers[256];
-  unsigned majnum, minnum, relnum;
+  int id;
 
-  H5get_libversion(&majnum, &minnum, &relnum);
+  xassert ( zaxisptr );
 
-  sprintf(hdf_libvers, "%u.%u.%u", majnum, minnum, relnum);
+  id = zaxisptr->self;
 
-  return (hdf_libvers);
-#else
-  return ("library undefined");
-#endif
-}
+  if ( zaxisptr->vals )    free ( zaxisptr->vals );
+  if ( zaxisptr->lbounds ) free ( zaxisptr->lbounds );
+  if ( zaxisptr->ubounds ) free ( zaxisptr->ubounds );
+  if ( zaxisptr->weights ) free ( zaxisptr->weights );
+  if ( zaxisptr->vct )     free ( zaxisptr->vct );
 
+  free ( zaxisptr );
 
-int CDF_Debug   = 0;    /* If set to 1, debugging           */
+  reshRemove ( id, &zaxisOps );
+}
 
+/*
+ at Function  zaxisDestroy
+ at Title     Destroy a vertical Z-axis
 
-void cdfDebug(int debug)
+ at Prototype void zaxisDestroy(int zaxisID)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+
+ at EndFunction
+*/
+void zaxisDestroy(int zaxisID)
 {
-  CDF_Debug = debug;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  if ( CDF_Debug )
-    Message("debug level %d", debug);
+  zaxisDestroyKernel ( zaxisptr );
 }
 
-#if  defined  (HAVE_LIBNETCDF)
+
 static
-void cdfComment(int ncid)
+void zaxisDestroyP ( void * zaxisptr )
 {
-  static char comment[256] = "Climate Data Interface version ";
-  static int init = 0;
-
-  if ( ! init )
-    {
-      init = 1;
-      const char *libvers = cdiLibraryVersion();
-      const char *blank = strchr(libvers, ' ');
-      size_t size = blank ? (size_t)(blank - libvers) : 0;
-
-      if ( size == 0 || ! isdigit((int) *libvers) )
-	strcat(comment, "??");
-      else
-	strncat(comment, libvers, size);
-      strcat(comment, " (https://code.zmaw.de/projects/cdi)");
-    }
-
-  cdf_put_att_text(ncid, NC_GLOBAL, "CDI", strlen(comment), comment);
-  cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.4");
+  zaxisDestroyKernel (( zaxis_t * ) zaxisptr );
 }
-#endif
 
-int cdfOpenFile(const char *filename, const char *mode, int *filetype)
+
+char *zaxisNamePtr(int zaxistype)
 {
-  int ncid = -1;
-#if  defined  (HAVE_LIBNETCDF)
-  int fmode = tolower(*mode);
-  int writemode = NC_CLOBBER;
-  int readmode = NC_NOWRITE;
-  int status;
+  char *name;
 
-  if ( filename == NULL )
-    ncid = CDI_EINVAL;
+  if ( zaxistype >= 0 && zaxistype < CDI_NumZaxistype )
+    name = ZaxistypeEntry[zaxistype].longname;
   else
-    {
-      switch (fmode)
-	{
-	case 'r':
-	  status = cdf_open(filename, readmode, &ncid);
-	  if ( status > 0 && ncid < 0 ) ncid = CDI_ESYSTEM;
-#if  defined  (HAVE_NETCDF4)
-	  else
-	    {
-	      int format;
-	      (void) nc_inq_format(ncid, &format);
-	      if ( format == NC_FORMAT_NETCDF4_CLASSIC )
-		{
-		  *filetype = FILETYPE_NC4C;
-		}
-	    }
-#endif
-	  break;
-	case 'w':
-#if  defined  (NC_64BIT_OFFSET)
-	  if      ( *filetype == FILETYPE_NC2  ) writemode |= NC_64BIT_OFFSET;
-#endif
-#if  defined  (HAVE_NETCDF4)
-	  if      ( *filetype == FILETYPE_NC4  ) writemode |= NC_NETCDF4;
-	  else if ( *filetype == FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
-#endif
-	  cdf_create(filename, writemode, &ncid);
-	  cdfComment(ncid);
-	  break;
-	case 'a':
-	  cdf_open(filename, NC_WRITE, &ncid);
-	  break;
-	default:
-	  ncid = CDI_EINVAL;
-	}
-    }
-#endif
+    name = ZaxistypeEntry[ZAXIS_GENERIC].longname;
 
-  return (ncid);
+  return (name);
 }
 
 
-int cdfOpen(const char *filename, const char *mode)
+void zaxisName(int zaxistype, char *zaxisname)
 {
-  int fileID = 0;
-  int filetype = FILETYPE_NC;
-
-  if ( CDF_Debug )
-    Message("Open %s with mode %c", filename, *mode);
-
-  fileID = cdfOpenFile(filename, mode, &filetype);
-
-  if ( CDF_Debug )
-    Message("File %s opened with id %d", filename, fileID);
-
-  return (fileID);
+  strcpy(zaxisname, zaxisNamePtr(zaxistype));
 }
 
+/*
+ at Function  zaxisDefName
+ at Title     Define the name of a Z-axis
 
-int cdfOpen64(const char *filename, const char *mode)
-{
-  int fileID = -1;
-  int open_file = TRUE;
-  int filetype = FILETYPE_NC2;
-
-  if ( CDF_Debug )
-    Message("Open %s with mode %c", filename, *mode);
+ at Prototype void zaxisDefName(int zaxisID, const char *name)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  name     Name of the Z-axis.
 
-#if  defined  (HAVE_LIBNETCDF)
-#if  ! defined  (NC_64BIT_OFFSET)
-  open_file = FALSE;
-#endif
-#endif
+ at Description
+The function @func{zaxisDefName} defines the name of a Z-axis.
 
-  if ( open_file )
-    {
-      fileID = cdfOpenFile(filename, mode, &filetype);
+ at EndFunction
+*/
+void zaxisDefName(int zaxisID, const char *name)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-      if ( CDF_Debug )
-	Message("File %s opened with id %d", filename, fileID);
-    }
-  else
+  if ( name )
     {
-      fileID = CDI_ELIBNAVAIL;
+      strncpy(zaxisptr->name, name, CDI_MAX_NAME - 1);
+      zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
-
-  return (fileID);
 }
 
+/*
+ at Function  zaxisDefLongname
+ at Title     Define the longname of a Z-axis
 
-int cdf4Open(const char *filename, const char *mode, int *filetype)
-{
-  int fileID = -1;
-  int open_file = FALSE;
-
-  if ( CDF_Debug )
-    Message("Open %s with mode %c", filename, *mode);
+ at Prototype void zaxisDefLongname(int zaxisID, const char *longname)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  longname Longname of the Z-axis.
 
-#if  defined  (HAVE_NETCDF4)
-  open_file = TRUE;
-#endif
+ at Description
+The function @func{zaxisDefLongname} defines the longname of a Z-axis.
 
-  if ( open_file )
-    {
-      fileID = cdfOpenFile(filename, mode, filetype);
+ at EndFunction
+*/
+void zaxisDefLongname(int zaxisID, const char *longname)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-      if ( CDF_Debug )
-	Message("File %s opened with id %d", filename, fileID);
-    }
-  else
+  if ( longname )
     {
-      fileID = CDI_ELIBNAVAIL;
+      strncpy(zaxisptr->longname, longname, CDI_MAX_NAME - 1);
+      zaxisptr->longname[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
-
-  return (fileID);
 }
 
+/*
+ at Function  zaxisDefUnits
+ at Title     Define the units of a Z-axis
 
-void cdfCloseFile(int fileID)
-{
-#if  defined  (HAVE_LIBNETCDF)
-  cdf_close(fileID);
-#endif
-}
+ at Prototype void zaxisDefUnits(int zaxisID, const char *units)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  units    Units of the Z-axis.
 
-void cdfClose(int fileID)
+ at Description
+The function @func{zaxisDefUnits} defines the units of a Z-axis.
+
+ at EndFunction
+*/
+void zaxisDefUnits(int zaxisID, const char *units)
 {
-  cdfCloseFile(fileID);
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if ( units )
+    {
+      strncpy(zaxisptr->units, units, CDI_MAX_NAME - 1);
+      zaxisptr->units[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
+
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
+ at Function  zaxisInqName
+ at Title     Get the name of a Z-axis
 
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
-#endif
+ at Prototype void zaxisInqName(int zaxisID, char *name)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  name     Name of the Z-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
+ at Description
+The function @func{zaxisInqName} returns the name of a Z-axis.
 
+ at Result
+ at func{zaxisInqName} returns the name of the Z-axis to the parameter name.
 
-static int nNamespaces = 1;
-static int activeNamespace = 0;
+ at EndFunction
+*/
+void zaxisInqName(int zaxisID, char *name)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  strcpy(name, zaxisptr->name);
+}
 
-#ifdef HAVE_LIBNETCDF
-#define CDI_NETCDF_SWITCHES                     \
-  { .func = (void (*)()) nc__create },          \
-  { .func = (void (*)()) cdf_def_var_serial },  \
-  { .func = (void (*)()) cdfDefTimestep },      \
-  { .func = (void (*)()) cdfDefVars }
+/*
+ at Function  zaxisInqLongname
+ at Title     Get the longname of a Z-axis
 
-#else
-#define CDI_NETCDF_SWITCHES
-#endif
+ at Prototype void zaxisInqLongname(int zaxisID, char *longname)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  longname Longname of the Z-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-#define defaultSwitches {                                   \
-    { .func = (void (*)()) cdiAbortC_serial },              \
-    { .func = (void (*)()) cdiWarning },                    \
-    { .func = (void (*)()) serializeGetSizeInCore },        \
-    { .func = (void (*)()) serializePackInCore },           \
-    { .func = (void (*)()) serializeUnpackInCore },         \
-    { .func = (void (*)()) fileOpen_serial },               \
-    { .func = (void (*)()) fileWrite },                     \
-    { .func = (void (*)()) fileClose_serial },              \
-    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },  \
-    { .func = (void (*)()) cdiStreamDefVlist_ },            \
-    { .func = (void (*)()) cdiStreamWriteVar_ },            \
-    { .func = (void (*)()) cdiStreamwriteVarChunk_ },       \
-    { .func = (void (*)()) 0 },                             \
-    { .func = (void (*)()) 0 },                             \
-    { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
-    { .func = (void (*)()) cdiStreamDefTimestep_ }, \
-    { .func = (void (*)()) cdiStreamSync_ },                \
-    CDI_NETCDF_SWITCHES                        \
-    }
+ at Description
+The function @func{zaxisInqLongname} returns the longname of a Z-axis.
 
-#if defined (SX)
-static const union namespaceSwitchValue
-  defaultSwitches_[NUM_NAMESPACE_SWITCH] = defaultSwitches;
-#endif
+ at Result
+ at func{zaxisInqLongname} returns the longname of the Z-axis to the parameter longname.
 
-struct Namespace
+ at EndFunction
+*/
+void zaxisInqLongname(int zaxisID, char *longname)
 {
-  statusCode resStage;
-  union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
-} initialNamespace = {
-  .resStage = STAGE_DEFINITION,
-  .switches = defaultSwitches
-};
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  strcpy(longname, zaxisptr->longname);
+}
 
-struct Namespace *namespaces = &initialNamespace;
+/*
+ at Function  zaxisInqUnits
+ at Title     Get the units of a Z-axis
 
-static int namespacesSize = 1;
+ at Prototype void zaxisInqUnits(int zaxisID, char *units)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  units    Units of the Z-axis. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
-#if  defined  (HAVE_LIBPTHREAD)
-#  include <pthread.h>
+ at Description
+The function @func{zaxisInqUnits} returns the units of a Z-axis.
 
-static pthread_once_t  namespaceOnce = PTHREAD_ONCE_INIT;
-static pthread_mutex_t namespaceMutex;
+ at Result
+ at func{zaxisInqUnits} returns the units of the Z-axis to the parameter units.
 
-static void
-namespaceInitialize(void)
+ at EndFunction
+*/
+void zaxisInqUnits(int zaxisID, char *units)
 {
-  pthread_mutexattr_t ma;
-  pthread_mutexattr_init(&ma);
-  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
-  pthread_mutex_init(&namespaceMutex, &ma);
-  pthread_mutexattr_destroy(&ma);
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  strcpy(units, zaxisptr->units);
 }
 
-#  define NAMESPACE_LOCK()         pthread_mutex_lock(&namespaceMutex)
-#  define NAMESPACE_UNLOCK()       pthread_mutex_unlock(&namespaceMutex)
-#  define NAMESPACE_INIT()         pthread_once(&namespaceOnce, \
-                                                namespaceInitialize)
 
+void zaxisInqStdname(int zaxisID, char *stdname)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  strcpy(stdname, zaxisptr->stdname);
+}
 
-#else
 
-#  define NAMESPACE_INIT() do { } while (0)
-#  define NAMESPACE_LOCK()
-#  define NAMESPACE_UNLOCK()
+void zaxisDefPrec(int zaxisID, int prec)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-#endif
+  if (zaxisptr->prec != prec)
+    {
+      zaxisptr->prec = prec;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
+}
 
 
-enum {
-  intbits = sizeof(int) * CHAR_BIT,
-  nspbits = 4,
-  idxbits = intbits - nspbits,
-  nspmask = (( 1 << nspbits ) - 1) << idxbits,
-  idxmask = ( 1 << idxbits ) - 1,
-};
+int zaxisInqPrec(int zaxisID)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-enum {
-  NUM_NAMESPACES = 1 << nspbits,
-  NUM_IDX = 1 << idxbits,
-};
+  return (zaxisptr->prec);
+}
 
 
-int namespaceIdxEncode ( namespaceTuple_t tin )
+void zaxisDefPositive(int zaxisID, int positive)
 {
-  xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
-  return ( tin.nsp << idxbits ) + tin.idx;
-}
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-int namespaceIdxEncode2 ( int nsp, int idx )
-{
-  xassert(nsp < NUM_NAMESPACES && idx < NUM_IDX);
-  return ( nsp << idxbits ) + idx;
+  if (zaxisptr->positive != positive)
+    {
+      zaxisptr->positive = (unsigned char)positive;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 
-namespaceTuple_t namespaceResHDecode ( int resH )
+int zaxisInqPositive(int zaxisID)
 {
-  namespaceTuple_t tin;
-
-  tin.idx = resH & idxmask;
-  tin.nsp = (int)(((unsigned)( resH & nspmask )) >> idxbits);
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  return tin;
+  return (zaxisptr->positive);
 }
 
-int
-namespaceNew()
+
+void zaxisDefLtype(int zaxisID, int ltype)
 {
-  int newNamespaceID = -1;
-  NAMESPACE_INIT();
-  NAMESPACE_LOCK();
-  if (namespacesSize > nNamespaces)
-    {
-      /* namespace is already available and only needs reinitialization */
-      for (int i = 0; i < namespacesSize; ++i)
-        if (namespaces[i].resStage == STAGE_UNUSED)
-          {
-            newNamespaceID = i;
-            break;
-          }
-    }
-  else if (namespacesSize == 1)
-    {
-      /* make room for additional namespace */
-      struct Namespace *newNameSpaces
-        = (struct Namespace *)xmalloc(((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
-      memcpy(newNameSpaces, namespaces, sizeof (namespaces[0]));
-      namespaces = newNameSpaces;
-      ++namespacesSize;
-      newNamespaceID = 1;
-    }
-  else if (namespacesSize < NUM_NAMESPACES)
-    {
-      /* make room for additional namespace */
-      newNamespaceID = namespacesSize;
-      namespaces
-        = (struct Namespace *)xrealloc(namespaces, ((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
-      ++namespacesSize;
-    }
-  else /* implicit: namespacesSize >= NUM_NAMESPACES */
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if (zaxisptr->ltype != ltype)
     {
-      NAMESPACE_UNLOCK();
-      return -1;
+      zaxisptr->ltype = ltype;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
-  xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
-  ++nNamespaces;
-  namespaces[newNamespaceID].resStage = STAGE_DEFINITION;
-#if defined (SX)
-  memcpy(namespaces[newNamespaceID].switches,
-         defaultSwitches_,
-         sizeof (namespaces[newNamespaceID].switches));
-#else
-  memcpy(namespaces[newNamespaceID].switches,
-         (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
-         sizeof (namespaces[newNamespaceID].switches));
-#endif
-  reshListCreate(newNamespaceID);
-  NAMESPACE_UNLOCK();
-  return newNamespaceID;
 }
 
-void
-namespaceDelete(int namespaceID)
-{
-  NAMESPACE_INIT();
-  NAMESPACE_LOCK();
-  xassert(namespaceID < namespacesSize && nNamespaces);
-  reshListDestruct(namespaceID);
-  namespaces[namespaceID].resStage = STAGE_UNUSED;
-  --nNamespaces;
-  NAMESPACE_UNLOCK();
-}
 
-int namespaceGetNumber ()
+int zaxisInqLtype(int zaxisID)
 {
-  return nNamespaces;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  return (zaxisptr->ltype);
 }
 
 
-void namespaceSetActive ( int nId )
+void zaxisDefLtype2(int zaxisID, int ltype2)
 {
-  xassert(nId < namespacesSize && nId >= 0
-          && namespaces[nId].resStage != STAGE_UNUSED);
-  activeNamespace = nId;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if (zaxisptr->ltype2 != ltype2)
+    {
+      zaxisptr->ltype2 = ltype2;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 
-int namespaceGetActive ()
+int zaxisInqLtype2(int zaxisID)
 {
-  return activeNamespace;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  return (zaxisptr->ltype2);
 }
 
-int namespaceAdaptKey ( int originResH, int originNamespace )
-{
-  namespaceTuple_t tin;
-  int nsp;
+/*
+ at Function  zaxisDefLevels
+ at Title     Define the levels of a Z-axis
 
-  if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
+ at Prototype void zaxisDefLevels(int zaxisID, const double *levels)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  levels   All levels of the Z-axis.
 
-  tin.idx = originResH & idxmask;
-  tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
+ at Description
+The function @func{zaxisDefLevels} defines the levels of a Z-axis.
 
-  xassert ( tin.nsp == originNamespace );
+ at EndFunction
+*/
+void zaxisDefLevels(int zaxisID, const double *levels)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  nsp = namespaceGetActive ();
+  int size = zaxisptr->size;
 
-  return namespaceIdxEncode2 ( nsp, tin.idx );
-}
+  double *vals = zaxisptr->vals;
 
+  for (int ilev = 0; ilev < size; ilev++ )
+    vals[ilev] = levels[ilev];
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+}
 
-int namespaceAdaptKey2 ( int originResH )
-{
-  namespaceTuple_t tin;
-  int nsp;
+/*
+ at Function  zaxisDefLevel
+ at Title     Define one level of a Z-axis
 
-  if ( originResH == CDI_UNDEFID ) return CDI_UNDEFID;
+ at Prototype void zaxisDefLevel(int zaxisID, int levelID, double level)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  levelID  Level identifier.
+    @Item  level    Level.
 
-  tin.idx = originResH & idxmask;
-  tin.nsp = (int)(((unsigned)( originResH & nspmask )) >> idxbits);
+ at Description
+The function @func{zaxisDefLevel} defines one level of a Z-axis.
 
-  nsp = namespaceGetActive ();
+ at EndFunction
+*/
+void zaxisDefLevel(int zaxisID, int levelID, double level)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  return namespaceIdxEncode2 ( nsp, tin.idx );
+  if ( levelID >= 0 && levelID < zaxisptr->size )
+    zaxisptr->vals[levelID] = level;
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
 
-void namespaceDefResStatus ( statusCode argResStatus )
+void zaxisDefNlevRef(int zaxisID, const int nhlev)
 {
-  int nsp = namespaceGetActive ();
-  namespaces[nsp].resStage = argResStatus;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if (zaxisptr->nhlev != nhlev)
+    {
+      zaxisptr->nhlev = nhlev;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 
-statusCode namespaceInqResStatus ( void )
+int zaxisInqNlevRef(int zaxisID)
 {
-  int nsp = namespaceGetActive ();
-  return namespaces[nsp].resStage;
-}
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-void namespaceSwitchSet(enum namespaceSwitch sw, union namespaceSwitchValue value)
-{
-  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
-  int nsp = namespaceGetActive();
-  namespaces[nsp].switches[sw] = value;
+  return (zaxisptr->nhlev);
 }
 
-union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
-{
-  xassert(sw > NSSWITCH_NO_SUCH_SWITCH && sw < NUM_NAMESPACE_SWITCH);
-  int nsp = namespaceGetActive();
-  return namespaces[nsp].switches[sw];
-}
+/*
+ at Function  zaxisDefNumber
+ at Title     Define the reference number for a generalized Z-axis
 
-void cdiReset(void)
+ at Prototype void zaxisDefNumber(int zaxisID, const int number)
+ at Parameter
+    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  number      Reference number for a generalized Z-axis.
+
+ at Description
+The function @func{zaxisDefNumber} defines the reference number for a generalized Z-axis.
+
+ at EndFunction
+*/
+void zaxisDefNumber(int zaxisID, const int number)
 {
-  NAMESPACE_INIT();
-  NAMESPACE_LOCK();
-  for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
-    if (namespaces[namespaceID].resStage != STAGE_UNUSED)
-      namespaceDelete(namespaceID);
-  if (namespaces != &initialNamespace)
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if (zaxisptr->number != number)
     {
-      free(namespaces);
-      namespaces = &initialNamespace;
+      zaxisptr->number = number;
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
-  namespacesSize = 1;
-  nNamespaces = 1;
-  activeNamespace = 0;
-  NAMESPACE_UNLOCK();
 }
 
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
+ at Function  zaxisInqNumber
+ at Title     Get the reference number to a generalized Z-axis
 
+ at Prototype int zaxisInqNumber(int zaxisID)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
-int
-serializeGetSize(int count, int datatype, void *context)
-{
-  int (*serialize_get_size_p)(int count, int datatype, void *context)
-    = (int (*)(int, int, void *))
-    namespaceSwitchGet(NSSWITCH_SERIALIZE_GET_SIZE).func;
-  return serialize_get_size_p(count, datatype, context);
-}
+ at Description
+The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
 
-void serializePack(const void *data, int count, int datatype,
-                   void *buf, int buf_size, int *position, void *context)
+ at Result
+ at func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
+ at EndFunction
+*/
+int zaxisInqNumber(int zaxisID)
 {
-  void (*serialize_pack_p)(const void *data, int count, int datatype,
-                           void *buf, int buf_size, int *position, void *context)
-    = (void (*)(const void *, int, int, void *, int, int *, void *))
-    namespaceSwitchGet(NSSWITCH_SERIALIZE_PACK).func;
-  serialize_pack_p(data, count, datatype, buf, buf_size, position, context);
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  return (zaxisptr->number);
 }
 
-void serializeUnpack(const void *buf, int buf_size, int *position,
-                     void *data, int count, int datatype, void *context)
+/*
+ at Function  zaxisDefUUID
+ at Title     Define the UUID for a genralized Z-axis
+
+ at Prototype void zaxisDefUUID(int zaxisID, const char *uuid)
+ at Parameter
+    @Item  zaxisID     Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  uuid        UUID for a generalized Z-axis.
+
+ at Description
+The function @func{zaxisDefUUID} defines the UUID for a generalized  Z-axis.
+
+ at EndFunction
+*/
+void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
 {
-  void (*serialize_unpack_p)(const void *buf, int buf_size, int *position,
-                             void *data, int count, int datatype, void *context)
-    = (void (*)(const void *, int, int *, void *, int, int, void *))
-    namespaceSwitchGet(NSSWITCH_SERIALIZE_UNPACK).func;
-  serialize_unpack_p(buf, buf_size, position, data, count, datatype, context);
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  memcpy(zaxisptr->uuid, uuid, CDI_UUID_SIZE);
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
+/*
+ at Function  zaxisInqUUID
+ at Title     Get the uuid to a generalized Z-axis
+
+ at Prototype void zaxisInqUUID(int zaxisID, char *uuid)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item uuid A user supplied buffer of at least 16 bytes.
 
+ at Description
+The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
 
-int
-serializeGetSizeInCore(int count, int datatype, void *context)
+ at Result
+ at func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
+ at EndFunction
+*/
+void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
 {
-  int elemSize;
-  (void)context;
-  switch (datatype)
-  {
-  case DATATYPE_INT8:
-    elemSize = sizeof (int8_t);
-    break;
-  case DATATYPE_INT16:
-    elemSize = sizeof (int16_t);
-    break;
-  case DATATYPE_UINT32:
-    elemSize = sizeof (uint32_t);
-    break;
-  case DATATYPE_INT:
-    elemSize = sizeof (int);
-    break;
-  case DATATYPE_FLT:
-  case DATATYPE_FLT64:
-    elemSize = sizeof (double);
-    break;
-  case DATATYPE_TXT:
-  case DATATYPE_UCHAR:
-    elemSize = 1;
-    break;
-  case DATATYPE_LONG:
-    elemSize = sizeof (long);
-    break;
-  default:
-    xabort("Unexpected datatype");
-  }
-  return count * elemSize;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  memcpy(uuid, zaxisptr->uuid, CDI_UUID_SIZE);
 }
 
-void serializePackInCore(const void *data, int count, int datatype,
-                         void *buf, int buf_size, int *position, void *context)
+/*
+ at Function  zaxisInqLevel
+ at Title     Get one level of a Z-axis
+
+ at Prototype double zaxisInqLevel(int zaxisID, int levelID)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  levelID  Level index (range: 0 to nlevel-1).
+
+ at Description
+The function @func{zaxisInqLevel} returns one level of a Z-axis.
+
+ at Result
+ at func{zaxisInqLevel} returns the level of a Z-axis.
+ at EndFunction
+*/
+double zaxisInqLevel(int zaxisID, int levelID)
 {
-  int size = serializeGetSize(count, datatype, context);
-  int pos = *position;
-  xassert(INT_MAX - pos >= size && buf_size - pos >= size);
-  memcpy((unsigned char *)buf + pos, data, (size_t)size);
-  pos += size;
-  *position = pos;
+  double level = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if ( levelID >= 0 && levelID < zaxisptr->size )
+    level = zaxisptr->vals[levelID];
+
+  return (level);
 }
 
-void serializeUnpackInCore(const void *buf, int buf_size, int *position,
-                           void *data, int count, int datatype, void *context)
+double zaxisInqLbound(int zaxisID, int index)
 {
-  int size = serializeGetSize(count, datatype, context);
-  int pos = *position;
-  xassert(INT_MAX - pos >= size && buf_size - pos >= size);
-  memcpy(data, (unsigned char *)buf + pos, (size_t)size);
-  pos += size;
-  *position = pos;
-}
-#if defined (HAVE_CONFIG_H)
-#endif
+  double level = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
-#endif
+  if ( zaxisptr->lbounds )
+    if ( index >= 0 && index < zaxisptr->size )
+      level = zaxisptr->lbounds[index];
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
+  return (level);
+}
 
-#if defined (HAVE_EXECINFO_H)
-#include <execinfo.h>
-#endif
 
-static
-void show_stackframe()
+double zaxisInqUbound(int zaxisID, int index)
 {
-#if defined HAVE_EXECINFO_H && defined backtrace_size_t && defined HAVE_BACKTRACE
-  void *trace[16];
-  backtrace_size_t trace_size = backtrace(trace, 16);
-  char **messages = backtrace_symbols(trace, trace_size);
+  double level = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  fprintf(stderr, "[bt] Execution path:\n");
-  if ( messages ) {
-    for ( backtrace_size_t i = 0; i < trace_size; ++i )
-      fprintf(stderr, "[bt] %s\n", messages[i]);
-    free(messages);
-  }
-#endif
+  if ( zaxisptr->ubounds )
+    if ( index >= 0 && index < zaxisptr->size )
+      level = zaxisptr->ubounds[index];
+
+  return (level);
 }
 
 
-enum { MIN_LIST_SIZE = 128 };
+const double *zaxisInqLevelsPtr(int zaxisID)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return ( zaxisptr->vals );
+}
 
-static void listInitialize(void);
+/*
+ at Function  zaxisInqLevels
+ at Title     Get all levels of a Z-axis
 
-typedef struct listElem {
-  union
-  {
-    /* free-list management data */
-    struct
-    {
-      int next, prev;
-    } free;
-    /* holding an actual value */
-    struct
-    {
-      const resOps *ops;
-      void         *val;//ptr
-    } v;
-  } res;
-  int           status;
-} listElem_t;
+ at Prototype void zaxisInqLevels(int zaxisID, double *levels)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item  levels   Pointer to the location into which the levels are read.
+                    The caller must allocate space for the returned values.
 
-struct resHList_t
-{
-  int size, freeHead, hasDefaultRes;
-  listElem_t *resources;
-};
+ at Description
+The function @func{zaxisInqLevels} returns all levels of a Z-axis.
 
-static struct resHList_t *resHList;
+ at Result
+ at func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
+ at EndFunction
+*/
+void zaxisInqLevels(int zaxisID, double *levels)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  int size = zaxisptr->size;
+  for (int i = 0; i < size; i++ )
+    levels[i] =  zaxisptr->vals[i];
+}
 
-static int resHListSize = 0;
 
-#if  defined  (HAVE_LIBPTHREAD)
-#  include <pthread.h>
+int zaxisInqLbounds(int zaxisID, double *lbounds)
+{
+  int size = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-static pthread_once_t  listInitThread = PTHREAD_ONCE_INIT;
-static pthread_mutex_t listMutex;
+  if ( zaxisptr->lbounds )
+    {
+      size = zaxisptr->size;
 
-#  define LIST_LOCK()         pthread_mutex_lock(&listMutex)
-#  define LIST_UNLOCK()       pthread_mutex_unlock(&listMutex)
-#  define LIST_INIT(init0)         do {                         \
-    pthread_once(&listInitThread, listInitialize);              \
-    pthread_mutex_lock(&listMutex);                             \
-    if ((init0) && (!resHList || !resHList[0].resources))       \
-      reshListCreate(0);                                        \
-    pthread_mutex_unlock(&listMutex);                           \
-  } while (0)
+      if ( lbounds )
+        for (int i = 0; i < size; i++ )
+          lbounds[i] =  zaxisptr->lbounds[i];
+    }
 
+  return (size);
+}
 
 
-#else
+int zaxisInqUbounds(int zaxisID, double *ubounds)
+{
+  int size = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-static int listInit = 0;
+  if ( zaxisptr->ubounds )
+    {
+      size = zaxisptr->size;
 
-#  define LIST_LOCK()
-#  define LIST_UNLOCK()
-#  define LIST_INIT(init0)        do {                          \
-  if ( !listInit )                                              \
-    {                                                           \
-      listInitialize();                                         \
-      if ((init0) && (!resHList || !resHList[0].resources))     \
-        reshListCreate(0);                                      \
-      listInit = 1;                                             \
-    }                                                           \
-  } while(0)
+      if ( ubounds )
+        for (int i = 0; i < size; i++ )
+          ubounds[i] =  zaxisptr->ubounds[i];
+    }
 
-#endif
+  return (size);
+}
 
-/**************************************************************/
 
-static void
-listInitResources(int nsp)
+int zaxisInqWeights(int zaxisID, double *weights)
 {
-  xassert(nsp < resHListSize && nsp >= 0);
-  int size = resHList[nsp].size = MIN_LIST_SIZE;
-  xassert(resHList[nsp].resources == NULL);
-  resHList[nsp].resources = (listElem_t*) xcalloc(MIN_LIST_SIZE, sizeof(listElem_t));
-  listElem_t *p = resHList[nsp].resources;
+  int size = 0;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  for (int i = 0; i < size; i++ )
+  if ( zaxisptr->weights )
     {
-      p[i].res.free.next = i + 1;
-      p[i].res.free.prev = i - 1;
-      p[i].status = RESH_UNUSED;
+      size = zaxisptr->size;
+
+      if ( weights )
+        for ( int i = 0; i < size; i++ )
+          weights[i] =  zaxisptr->weights[i];
     }
 
-  p[size-1].res.free.next = -1;
-  resHList[nsp].freeHead = 0;
-  int oldNsp = namespaceGetActive();
-  namespaceSetActive(nsp);
-  instituteDefaultEntries();
-  modelDefaultEntries();
-  namespaceSetActive(oldNsp);
+  return (size);
 }
 
-static inline void
-reshListClearEntry(int i)
+
+int zaxisInqLevelID(int zaxisID, double level)
 {
-  resHList[i].size = 0;
-  resHList[i].resources = NULL;
-  resHList[i].freeHead = -1;
+  int levelID = CDI_UNDEFID;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  int size = zaxisptr->size;
+  for ( int i = 0; i < size; i++ )
+    if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
+      {
+        levelID = i;
+        break;
+      }
+
+  return (levelID);
+}
+
+/*
+ at Function  zaxisInqType
+ at Title     Get the type of a Z-axis
+
+ at Prototype int zaxisInqType(int zaxisID)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+
+ at Description
+The function @func{zaxisInqType} returns the type of a Z-axis.
+
+ at Result
+ at func{zaxisInqType} returns the type of the Z-axis,
+one of the set of predefined CDI Z-axis types.
+The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
+ at func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+ at func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+ at func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+ at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
+ at func{ZAXIS_LAKE_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM}, @func{ZAXIS_SEDIMENT_BOTTOM_TA},
+ at func{ZAXIS_SEDIMENT_BOTTOM_TW}, @func{ZAXIS_MIX_LAYER},
+ at func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
+
+ at EndFunction
+*/
+int zaxisInqType(int zaxisID)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return (zaxisptr->type);
 }
 
-void
-reshListCreate(int namespaceID)
+/*
+ at Function  zaxisInqSize
+ at Title     Get the size of a Z-axis
+
+ at Prototype int zaxisInqSize(int zaxisID)
+ at Parameter
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+
+ at Description
+The function @func{zaxisInqSize} returns the size of a Z-axis.
+
+ at Result
+ at func{zaxisInqSize} returns the number of levels of a Z-axis.
+
+ at EndFunction
+*/
+int zaxisInqSize(int zaxisID)
 {
-  LIST_INIT(namespaceID != 0);
-  LIST_LOCK();
-  if (resHListSize <= namespaceID)
-    {
-      resHList = (struct resHList_t *)xrealloc(resHList, (size_t)(namespaceID + 1) * sizeof (resHList[0]));
-      for (int i = resHListSize; i <= namespaceID; ++i)
-        reshListClearEntry(i);
-      resHListSize = namespaceID + 1;
-    }
-  listInitResources(namespaceID);
-  LIST_UNLOCK();
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return (zaxisptr->size);
 }
 
 
-/**************************************************************/
-
-void
-reshListDestruct(int namespaceID)
+void cdiCheckZaxis(int zaxisID)
 {
-  LIST_LOCK();
-  xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
-  int callerNamespaceID = namespaceGetActive();
-  namespaceSetActive(namespaceID);
-  if (resHList[namespaceID].resources)
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
     {
-      for ( int j = 0; j < resHList[namespaceID].size; j++ )
+      int size = zaxisptr->size;
+      if ( size > 1 )
         {
-          listElem_t *listElem = resHList[namespaceID].resources + j;
-          if (listElem->status & RESH_IN_USE_BIT)
-            listElem->res.v.ops->valDestroy(listElem->res.v.val);
+          /* check direction */
+          if ( ! zaxisptr->direction )
+            {
+              int ups = 0, downs = 0;
+              for ( int i = 1; i < size; i++ )
+                {
+                  ups += (zaxisptr->vals[i] > zaxisptr->vals[i-1]);
+                  downs += (zaxisptr->vals[i] < zaxisptr->vals[i-1]);
+                }
+              if ( ups == size-1 )
+                {
+                  zaxisptr->direction = LevelUp;
+                }
+              else if ( downs == size-1 )
+                {
+                  zaxisptr->direction = LevelDown;
+                }
+              else /* !zaxisptr->direction */
+                {
+                  Warning("Direction undefined for zaxisID %d", zaxisID);
+                }
+            }
         }
-      free(resHList[namespaceID].resources);
-      resHList[namespaceID].resources = NULL;
-      reshListClearEntry(namespaceID);
     }
-  if (resHList[callerNamespaceID].resources)
-    namespaceSetActive(callerNamespaceID);
-  LIST_UNLOCK();
 }
 
 
-static void listDestroy ( void )
+void zaxisDefVct(int zaxisID, int size, const double *vct)
 {
-  LIST_LOCK();
-  for (int i = resHListSize; i > 0; --i)
-    if (resHList[i-1].resources)
-      namespaceDelete(i-1);
-  resHListSize = 0;
-  free(resHList);
-  resHList = NULL;
-  cdiReset();
-  LIST_UNLOCK();
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  if ( zaxisptr->vct == 0 )
+    {
+      zaxisptr->vctsize = size;
+      zaxisptr->vct = (double *)xmalloc((size_t)size * sizeof (double));
+      memcpy(zaxisptr->vct, vct, (size_t)size * sizeof (double));
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
+  else
+    if ( zaxisptr->vctsize != size )
+      Warning("VCT was already defined");
 }
 
-/**************************************************************/
 
-static
-void listInitialize ( void )
+void zaxisInqVct(int zaxisID, double *vct)
 {
-#if  defined  (HAVE_LIBPTHREAD)
-  pthread_mutexattr_t ma;
-  pthread_mutexattr_init(&ma);
-  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
-  /* initialize global API mutex lock */
-  pthread_mutex_init ( &listMutex, &ma);
-  pthread_mutexattr_destroy(&ma);
-#endif
-  /* file is special and has its own table, which needs to be
-   * created, before we register the listDestroy exit handler */
-  {
-    int null_id;
-    null_id = fileOpen_serial("/dev/null", "r");
-    if (null_id != -1)
-      fileClose_serial(null_id);
-  }
-  atexit ( listDestroy );
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  memcpy(vct, zaxisptr->vct, (size_t)zaxisptr->vctsize * sizeof (double));
 }
 
-/**************************************************************/
 
-static
-void listSizeExtend()
+int zaxisInqVctSize(int zaxisID)
 {
-  int nsp = namespaceGetActive ();
-  int oldSize = resHList[nsp].size;
-  size_t newListSize = (size_t)oldSize + MIN_LIST_SIZE;
-
-  resHList[nsp].resources = (listElem_t*) xrealloc(resHList[nsp].resources,
-                                                   newListSize * sizeof(listElem_t));
-
-  listElem_t *r = resHList[nsp].resources;
-  for (size_t i = (size_t)oldSize; i < newListSize; ++i)
-    {
-      r[i].res.free.next = (int)i + 1;
-      r[i].res.free.prev = (int)i - 1;
-      r[i].status = RESH_UNUSED;
-    }
-
-  if (resHList[nsp].freeHead != -1)
-    r[resHList[nsp].freeHead].res.free.prev = (int)newListSize - 1;
-  r[newListSize-1].res.free.next = resHList[nsp].freeHead;
-  r[oldSize].res.free.prev = -1;
-  resHList[nsp].freeHead = oldSize;
-  resHList[nsp].size = (int)newListSize;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return (zaxisptr->vctsize);
 }
 
-/**************************************************************/
 
-static void
-reshPut_(int nsp, int entry, void *p, const resOps *ops)
+const double *zaxisInqVctPtr(int zaxisID)
 {
-  listElem_t *newListElem = resHList[nsp].resources + entry;
-  int next = newListElem->res.free.next,
-    prev = newListElem->res.free.prev;
-  if (next != -1)
-    resHList[nsp].resources[next].res.free.prev = prev;
-  if (prev != -1)
-    resHList[nsp].resources[prev].res.free.next = next;
-  else
-    resHList[nsp].freeHead = next;
-  newListElem->res.v.val = p;
-  newListElem->res.v.ops = ops;
-  newListElem->status = RESH_DESYNC_IN_USE;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  return (zaxisptr->vct);
 }
 
-int reshPut ( void *p, const resOps *ops )
-{
-  xassert ( p && ops );
-
-  LIST_INIT(1);
 
-  LIST_LOCK();
+void zaxisDefLbounds(int zaxisID, const double *lbounds)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  int nsp = namespaceGetActive ();
+  size_t size = (size_t)zaxisptr->size;
 
-  if ( resHList[nsp].freeHead == -1) listSizeExtend();
-  int entry = resHList[nsp].freeHead;
-  cdiResH resH = namespaceIdxEncode2(nsp, entry);
-  reshPut_(nsp, entry, p, ops);
+  if ( CDI_Debug )
+    if ( zaxisptr->lbounds != NULL )
+      Warning("Lower bounds already defined for zaxisID = %d", zaxisID);
 
-  LIST_UNLOCK();
+  if ( zaxisptr->lbounds == NULL )
+    zaxisptr->lbounds = (double *)xmalloc(size*sizeof(double));
 
-  return resH;
+  memcpy(zaxisptr->lbounds, lbounds, size*sizeof(double));
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
-/**************************************************************/
-
-static void
-reshRemove_(int nsp, int idx)
-{
-  int curFree = resHList[nsp].freeHead;
-  listElem_t *r = resHList[nsp].resources;
-  r[idx].res.free.next = curFree;
-  r[idx].res.free.prev = -1;
-  if (curFree != -1)
-    r[curFree].res.free.prev = idx;
-  r[idx].status = RESH_DESYNC_DELETED;
-  resHList[nsp].freeHead = idx;
-}
 
-void reshDestroy(cdiResH resH)
+void zaxisDefUbounds(int zaxisID, const double *ubounds)
 {
-  int nsp;
-  namespaceTuple_t nspT;
-
-  LIST_LOCK();
-
-  nsp = namespaceGetActive ();
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  nspT = namespaceResHDecode ( resH );
+  size_t size = (size_t)zaxisptr->size;
 
-  xassert ( nspT.nsp == nsp
-            && nspT.idx >= 0
-            && nspT.idx < resHList[nsp].size
-            && resHList[nsp].resources[nspT.idx].res.v.ops);
+  if ( CDI_Debug )
+    if ( zaxisptr->ubounds != NULL )
+      Warning("Upper bounds already defined for zaxisID = %d", zaxisID);
 
-  if (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
-    reshRemove_(nsp, nspT.idx);
+  if ( zaxisptr->ubounds == NULL )
+    zaxisptr->ubounds = (double *)xmalloc(size*sizeof(double));
 
-  LIST_UNLOCK();
+  memcpy(zaxisptr->ubounds, ubounds, size*sizeof(double));
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
-void reshRemove ( cdiResH resH, const resOps * ops )
+
+void zaxisDefWeights(int zaxisID, const double *weights)
 {
-  int nsp;
-  namespaceTuple_t nspT;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  LIST_LOCK();
+  size_t size = (size_t)zaxisptr->size;
 
-  nsp = namespaceGetActive ();
+  if ( CDI_Debug )
+    if ( zaxisptr->weights != NULL )
+      Warning("Weights already defined for zaxisID = %d", zaxisID);
 
-  nspT = namespaceResHDecode ( resH );
+  if ( zaxisptr->weights == NULL )
+    zaxisptr->weights = (double *)xmalloc(size*sizeof(double));
 
-  xassert ( nspT.nsp == nsp
-            && nspT.idx >= 0
-            && nspT.idx < resHList[nsp].size
-            && (resHList[nsp].resources[nspT.idx].status & RESH_IN_USE_BIT)
-            && resHList[nsp].resources[nspT.idx].res.v.ops
-            && resHList[nsp].resources[nspT.idx].res.v.ops == ops );
+  memcpy(zaxisptr->weights, weights, size*sizeof(double));
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+}
 
-  reshRemove_(nsp, nspT.idx);
 
-  LIST_UNLOCK();
+void zaxisChangeType(int zaxisID, int zaxistype)
+{
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+  zaxisptr->type = zaxistype;
 }
 
-/**************************************************************/
 
-void reshReplace(cdiResH resH, void *p, const resOps *ops)
+void zaxisResize(int zaxisID, int size)
 {
-  xassert(p && ops);
-  LIST_INIT(1);
-  LIST_LOCK();
-  int nsp = namespaceGetActive();
-  namespaceTuple_t nspT = namespaceResHDecode(resH);
-  while (resHList[nsp].size <= nspT.idx)
-    listSizeExtend();
-  listElem_t *q = resHList[nsp].resources + nspT.idx;
-  if (q->status & RESH_IN_USE_BIT)
-    {
-      q->res.v.ops->valDestroy(q->res.v.val);
-      reshRemove_(nsp, nspT.idx);
-    }
-  reshPut_(nsp, nspT.idx, p, ops);
-  LIST_UNLOCK();
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
+
+  xassert(size >= 0);
+
+  zaxisptr->size = size;
+
+  if ( zaxisptr->vals )
+    zaxisptr->vals = (double *)xrealloc(zaxisptr->vals, (size_t)size * sizeof(double));
 }
 
 
-static listElem_t *
-reshGetElem(const char *caller, const char* expressionString, cdiResH resH, const resOps *ops)
+int zaxisDuplicate(int zaxisID)
 {
-  listElem_t *listElem;
-  int nsp;
-  namespaceTuple_t nspT;
-  xassert ( ops );
+  int zaxisIDnew;
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  LIST_INIT(1);
+  int zaxistype = zaxisInqType(zaxisID);
+  int zaxissize = zaxisInqSize(zaxisID);
 
-  LIST_LOCK();
+  zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
+  zaxis_t *zaxisptrnew = reshGetVal(zaxisIDnew, &zaxisOps);
 
-  nsp = namespaceGetActive ();
+  zaxis_copy(zaxisptrnew, zaxisptr);
 
-  nspT = namespaceResHDecode ( resH );
-  assert(nspT.idx >= 0);
+  strcpy(zaxisptrnew->name, zaxisptr->name);
+  strcpy(zaxisptrnew->longname, zaxisptr->longname);
+  strcpy(zaxisptrnew->units, zaxisptr->units);
 
-  if (nspT.nsp == nsp &&
-      nspT.idx < resHList[nsp].size)
+  if ( zaxisptr->vals != NULL )
     {
-      listElem = resHList[nsp].resources + nspT.idx;
-      LIST_UNLOCK();
+      size_t size = (size_t)zaxissize;
+
+      zaxisptrnew->vals = (double *)xmalloc(size * sizeof (double));
+      memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
     }
-  else
+
+  if ( zaxisptr->lbounds )
     {
-      LIST_UNLOCK();
-      show_stackframe();
+      size_t size = (size_t)zaxissize;
 
-      if ( resH == CDI_UNDEFID )
-        {
-          xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is CDI_UNDEFID (= %d).\n\tThis is most likely the result of a failed earlier call. Please check the IDs returned by CDI.", expressionString, caller, resH);
-        }
-      else
-        {
-          xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: the value is garbage (= %d, which resolves to namespace = %d, index = %d).\n\tThis is either the result of using an uninitialized variable,\n\tof using a value as an ID that is not an ID,\n\tor of using an ID after it has been invalidated.", expressionString, caller, resH, nspT.nsp, nspT.idx);
-        }
+      zaxisptrnew->lbounds = (double *)xmalloc(size * sizeof (double));
+      memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
     }
 
-  if ( !(listElem && listElem->res.v.ops == ops) )
+  if ( zaxisptr->ubounds )
     {
-      show_stackframe();
+      size_t size = (size_t)zaxissize;
 
-      xabortC(caller, "Error while trying to resolve the ID \"%s\" in `%s()`: list element not found. The failed ID is %d", expressionString, caller, (int)resH);
+      zaxisptrnew->ubounds = (double *)xmalloc(size * sizeof (double));
+      memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
     }
 
-  return listElem;
-}
+  if ( zaxisptr->vct != NULL )
+    {
+      size_t size = (size_t)zaxisptr->vctsize;
 
+      if ( size )
+        {
+          zaxisptrnew->vctsize = (int)size;
+          zaxisptrnew->vct = (double *)xmalloc(size * sizeof (double));
+          memcpy(zaxisptrnew->vct, zaxisptr->vct, size * sizeof (double));
+        }
+    }
 
-void *reshGetValue(const char * caller, const char* expressionString, cdiResH resH, const resOps * ops)
-{
-  return reshGetElem(caller, expressionString, resH, ops)->res.v.val;
+  return (zaxisIDnew);
 }
 
-/**************************************************************/
 
-void reshGetResHListOfType ( int c, int * resHs, const resOps * ops )
+void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
 {
-  int i, j = 0, nsp;
-
-  xassert ( resHs && ops );
+  unsigned char uuid[CDI_UUID_SIZE];
+  int levelID;
+  int nbyte;
+  double level;
 
-  LIST_INIT(1);
+  xassert ( zaxisptr );
 
-  LIST_LOCK();
+  int zaxisID = zaxisptr->self;
 
-  nsp = namespaceGetActive ();
+  int type    = zaxisptr->type;
+  int nlevels = zaxisptr->size;
 
-  for ( i = 0; i < resHList[nsp].size && j < c; i++ )
-    if ((resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
-        && resHList[nsp].resources[i].res.v.ops == ops)
-      resHs[j++] = namespaceIdxEncode2(nsp, i);
+  int nbyte0 = 0;
+  fprintf(fp, "#\n");
+  fprintf(fp, "# zaxisID %d\n", index);
+  fprintf(fp, "#\n");
+  fprintf(fp, "zaxistype = %s\n", zaxisNamePtr(type));
+  fprintf(fp, "size      = %d\n", nlevels);
+  if ( zaxisptr->name[0]     ) fprintf(fp, "name      = %s\n", zaxisptr->name);
+  if ( zaxisptr->longname[0] ) fprintf(fp, "longname  = %s\n", zaxisptr->longname);
+  if ( zaxisptr->units[0]    ) fprintf(fp, "units     = %s\n", zaxisptr->units);
 
-  LIST_UNLOCK();
-}
+  nbyte0 = fprintf(fp, "levels    = ");
+  nbyte = nbyte0;
+  for ( levelID = 0; levelID < nlevels; levelID++ )
+    {
+      if ( nbyte > 80 )
+	{
+	  fprintf(fp, "\n");
+	  fprintf(fp, "%*s", nbyte0, "");
+	  nbyte = nbyte0;
+	}
+      level = zaxisInqLevel(zaxisID, levelID);
+      nbyte += fprintf(fp, "%.9g ", level);
+    }
+  fprintf(fp, "\n");
 
-enum cdiApplyRet
-cdiResHApply(enum cdiApplyRet (*func)(int id, void *res, const resOps *p,
-                                      void *data), void *data)
-{
-  xassert(func);
+  if ( zaxisptr->lbounds && zaxisptr->ubounds )
+    {
+      double level1, level2;
+      nbyte = nbyte0;
+      nbyte0 = fprintf(fp, "bounds    = ");
+      for ( levelID = 0; levelID < nlevels; levelID++ )
+	{
+	  if ( nbyte > 80 )
+	    {
+	      fprintf(fp, "\n");
+	      fprintf(fp, "%*s", nbyte0, "");
+	      nbyte = nbyte0;
+	    }
+	  level1 = zaxisInqLbound(zaxisID, levelID);
+	  level2 = zaxisInqUbound(zaxisID, levelID);
+	  nbyte += fprintf(fp, "%.9g-%.9g ", level1, level2);
+	}
+      fprintf(fp, "\n");
+    }
 
-  LIST_INIT(1);
+  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+    {
+      int i;
+      int vctsize;
+      const double *vct;
 
-  LIST_LOCK();
+      vctsize = zaxisptr->vctsize;
+      vct     = zaxisptr->vct;
+      fprintf(fp, "vctsize   = %d\n", vctsize);
+      if ( vctsize )
+        {
+          nbyte0 = fprintf(fp, "vct       = ");
+          nbyte = nbyte0;
+          for ( i = 0; i < vctsize; i++ )
+            {
+              if ( nbyte > 70 || i == vctsize/2 )
+                {
+                  fprintf(fp, "\n%*s", nbyte0, "");
+                  nbyte = nbyte0;
+                }
+              nbyte += fprintf(fp, "%.9g ", vct[i]);
+            }
+          fprintf(fp, "\n");
+          /*
+          nbyte0 = fprintf(fp, "vct_b     = ");
+          nbyte  = nbyte0;
+          for ( i = 0; i < vctsize/2; i++ )
+            {
+              if ( nbyte > 70 )
+                {
+                  fprintf(fp, "\n%*s", nbyte0, "");
+                  nbyte = nbyte0;
+                }
+              nbyte += fprintf(fp, "%.9g ", vct[vctsize/2+i]);
+            }
+          fprintf(fp, "\n");
+          */
+        }
+    }
 
-  int nsp = namespaceGetActive ();
-  enum cdiApplyRet ret = CDI_APPLY_GO_ON;
-  for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
-    if (resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
-      ret = func(namespaceIdxEncode2(nsp, i),
-                 resHList[nsp].resources[i].res.v.val,
-                 resHList[nsp].resources[i].res.v.ops, data);
-  LIST_UNLOCK();
-  return ret;
+  if ( type == ZAXIS_REFERENCE )
+    {
+      const unsigned char *d;
+      zaxisInqUUID(zaxisID, uuid);
+      d = uuid;
+      fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+              d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+              d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+    }
 }
 
 
-enum cdiApplyRet
-cdiResHFilterApply(const resOps *p,
-                   enum cdiApplyRet (*func)(int id, void *res, void *data),
-                   void *data)
+void zaxisPrint ( int zaxisID, int index )
 {
-  xassert(p && func);
-
-  LIST_INIT(1);
-
-  LIST_LOCK();
+  zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  int nsp = namespaceGetActive ();
-  enum cdiApplyRet ret = CDI_APPLY_GO_ON;
-  listElem_t *r = resHList[nsp].resources;
-  for (int i = 0; i < resHList[nsp].size && ret > 0; ++i)
-    if ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == p)
-      ret = func(namespaceIdxEncode2(nsp, i), r[i].res.v.val,
-                 data);
-  LIST_UNLOCK();
-  return ret;
+  zaxisPrintKernel ( zaxisptr, index, stdout );
 }
 
 
+static
+void zaxisPrintP ( void * voidptr, FILE * fp )
+{
+  zaxis_t *zaxisptr = ( zaxis_t * ) voidptr;
 
+  xassert ( zaxisptr );
+
+  zaxisPrintKernel(zaxisptr, zaxisptr->self, fp);
+}
 
-/**************************************************************/
 
-int reshCountType ( const resOps * ops )
+static int
+zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
 {
-  int i, nsp, countType = 0;
+  enum {
+    differ = 1,
+  };
+  int diff = 0;
+  xassert(z1 && z2);
+
+  diff |= (z1->type != z2->type)
+    | (z1->ltype != z2->ltype)
+    | (z1->direction != z2->direction)
+    | (z1->prec != z2->prec)
+    | (z1->size != z2->size)
+    | (z1->vctsize != z2->vctsize)
+    | (z1->positive != z2->positive);
 
-  xassert ( ops );
+  if (diff)
+    return differ;
+  int size = z1->size;
+  int anyPresent = 0;
+  int present = (z1->vals != NULL);
+  diff |= (present ^ (z2->vals != NULL));
+  anyPresent |= present;
+  if (!diff && present)
+    {
+      const double *p = z1->vals, *q = z2->vals;
+      for (int i = 0; i < size; i++)
+        diff |= IS_NOT_EQUAL(p[i], q[i]);
+    }
 
-  LIST_INIT(1);
+  present = (z1->lbounds != NULL);
+  diff |= (present ^ (z2->lbounds != NULL));
+  anyPresent |= present;
+  if (!diff && present)
+    {
+      const double *p = z1->lbounds, *q = z2->lbounds;
+      for (int i = 0; i < size; i++)
+        diff |= IS_NOT_EQUAL(p[i], q[i]);
+    }
 
-  LIST_LOCK();
+  present = (z1->ubounds != NULL);
+  diff |= (present ^ (z2->ubounds != NULL));
+  anyPresent |= present;
+  if (!diff && present)
+    {
+      const double *p = z1->ubounds, *q = z2->ubounds;
+      for (int i = 0; i < size; ++i)
+        diff |= IS_NOT_EQUAL(p[i], q[i]);
+    }
 
-  nsp = namespaceGetActive ();
+  present = (z1->weights != NULL);
+  diff |= (present ^ (z2->weights != NULL));
+  anyPresent |= present;
+  if (!diff && present)
+    {
+      const double *p = z1->weights, *q = z2->weights;
+      for (int i = 0; i < size; ++i)
+        diff |= IS_NOT_EQUAL(p[i], q[i]);
+    }
 
-  listElem_t *r = resHList[nsp].resources;
-  for ( i = 0; i < resHList[nsp].size; i++ )
-    countType += ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == ops);
+  present = (z1->vct != NULL);
+  diff |= (present ^ (z2->vct != NULL));
+  if (!diff && present)
+    {
+      int vctsize = z1->vctsize;
+      xassert(vctsize);
+      const double *p = z1->vct, *q = z2->vct;
+      for (int i = 0; i < vctsize; ++i)
+        diff |= IS_NOT_EQUAL(p[i], q[i]);
+    }
 
-  LIST_UNLOCK();
+  if (anyPresent)
+    xassert(size);
 
-  return countType;
+  diff |= strcmp(z1->name, z2->name)
+    | strcmp(z1->longname, z2->longname)
+    | strcmp(z1->stdname, z2->stdname)
+    | strcmp(z1->units, z2->units)
+    | memcmp(z1->uuid, z2->uuid, CDI_UUID_SIZE);
+  return diff != 0;
 }
 
-/**************************************************************/
-
-int
-reshResourceGetPackSize_intern(int resH, const resOps *ops, void *context, const char* caller, const char* expressionString)
-{
-  listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
-  return curr->res.v.ops->valGetPackSize(curr->res.v.val, context);
-}
 
-void
-reshPackResource_intern(int resH, const resOps *ops, void *buf, int buf_size, int *position, void *context,
-                        const char* caller, const char* expressionString)
+static int
+zaxisTxCode ( void )
 {
-  listElem_t *curr = reshGetElem(caller, expressionString, resH, ops);
-  curr->res.v.ops->valPack(curr->res.v.val, buf, buf_size, position, context);
+  return ZAXIS;
 }
 
-enum {
-  resHPackHeaderNInt = 2,
-  resHDeleteNInt = 2,
+enum { zaxisNint     = 8,
+       vals     = 1 << 0,
+       lbounds  = 1 << 1,
+       ubounds  = 1 << 2,
+       weights  = 1 << 3,
+       vct      = 1 << 4,
+       zaxisHasUUIDFlag = 1 << 5,
 };
 
-static int getPackBufferSize(void *context)
-{
-  int intpacksize, packBufferSize = 0;
-
-  int nsp = namespaceGetActive ();
-
-  /* pack start marker, namespace and sererator marker */
-  packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, DATATYPE_INT, context));
+#define ZAXIS_STR_SERIALIZE { zaxisP->name, zaxisP->longname, \
+      zaxisP->stdname, zaxisP->units }
 
-  /* pack resources, type marker and seperator marker */
-  listElem_t *r = resHList[nsp].resources;
-  for ( int i = 0; i < resHList[nsp].size; i++)
-    if (r[i].status & RESH_SYNC_BIT)
-      {
-        if (r[i].status == RESH_DESYNC_DELETED)
-          {
-            packBufferSize += resHDeleteNInt * intpacksize;
-          }
-        else if (r[i].status == RESH_DESYNC_IN_USE)
-          {
-            xassert ( r[i].res.v.ops );
-            /* packed resource plus 1 int for type */
-            packBufferSize +=
-              r[i].res.v.ops->valGetPackSize(r[i].res.v.val, context)
-              + intpacksize;
-          }
-      }
-  /* end marker */
-  packBufferSize += intpacksize;
+static
+int zaxisGetMemberMask ( zaxis_t * zaxisP )
+{
+  int memberMask = 0;
 
-  return packBufferSize;
+  if ( zaxisP->vals )      memberMask |= vals;
+  if ( zaxisP->lbounds )   memberMask |= lbounds;
+  if ( zaxisP->ubounds )   memberMask |= ubounds;
+  if ( zaxisP->weights )   memberMask |= weights;
+  if ( zaxisP->vct )       memberMask |= vct;
+  if (!cdiUUIDIsNull(zaxisP->uuid)) memberMask |= zaxisHasUUIDFlag;
+  return memberMask;
 }
 
-/**************************************************************/
-
-void reshPackBufferDestroy ( char ** buffer )
+static int
+zaxisGetPackSize(void * voidP, void *context)
 {
-  if ( buffer ) free ( *buffer );
-}
+  zaxis_t * zaxisP = ( zaxis_t * ) voidP;
+  int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
-/**************************************************************/
+  if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
+    xassert(zaxisP->size);
 
-void reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
-{
-  int i, packBufferPos = 0;
-  int end = END;
+  if ( zaxisP->vals )
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
-  xassert ( packBuffer );
+  if ( zaxisP->lbounds )
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
-  LIST_LOCK();
+  if ( zaxisP->ubounds )
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
-  int nsp = namespaceGetActive ();
+  if ( zaxisP->weights )
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
-  int pBSize = *packBufferSize = getPackBufferSize(context);
-  char *pB = *packBuffer = (char *)xcalloc(1, (size_t)pBSize);
+  if ( zaxisP->vct )
+    {
+      xassert ( zaxisP->vctsize );
+      packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
+    }
 
   {
-    int header[resHPackHeaderNInt] = { START, nsp };
-    serializePack(header, resHPackHeaderNInt,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+    const char *strTab[] = ZAXIS_STR_SERIALIZE;
+    size_t numStr = sizeof (strTab) / sizeof (strTab[0]);
+    packBufferSize
+      += serializeStrTabGetPackSize(strTab, (int)numStr, context);
   }
 
-  listElem_t *r = resHList[nsp].resources;
-  for ( i = 0; i < resHList[nsp].size; i++ )
-    if (r[i].status & RESH_SYNC_BIT)
-      {
-        if (r[i].status == RESH_DESYNC_DELETED)
-          {
-            int temp[resHDeleteNInt]
-              = { RESH_DELETE, namespaceIdxEncode2(nsp, i) };
-            serializePack(temp, resHDeleteNInt, DATATYPE_INT,
-                          pB, pBSize, &packBufferPos, context);
-          }
-        else
-          {
-            listElem_t * curr = r + i;
-            xassert ( curr->res.v.ops );
-            int type = curr->res.v.ops->valTxCode();
-            if ( ! type ) continue;
-            serializePack(&type, 1, DATATYPE_INT, pB,
-                          pBSize, &packBufferPos, context);
-            curr->res.v.ops->valPack(curr->res.v.val,
-                                     pB, pBSize, &packBufferPos, context);
-          }
-        r[i].status &= ~RESH_SYNC_BIT;
-      }
+  packBufferSize += serializeGetSize(1, DATATYPE_UCHAR, context);
 
-  LIST_UNLOCK();
+  if (!cdiUUIDIsNull(zaxisP->uuid))
+    packBufferSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
-  serializePack(&end, 1,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+  return packBufferSize;
 }
 
-/**************************************************************/
-
-/* for thread safety this feature would have to be integrated in reshPut */
 
-void reshSetStatus ( cdiResH resH, const resOps * ops, int status )
+void
+zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
+            int * unpackBufferPos, int originNamespace, void *context,
+            int force_id)
 {
-  int nsp;
-  namespaceTuple_t nspT;
-  listElem_t * listElem;
-
-  xassert(ops && (status & RESH_IN_USE_BIT));
-
-  LIST_INIT(1);
-
-  LIST_LOCK();
-
-  nsp = namespaceGetActive ();
-
-  nspT = namespaceResHDecode ( resH );
-
-  xassert ( nspT.nsp == nsp &&
-            nspT.idx >= 0 &&
-            nspT.idx < resHList[nsp].size );
+  int intBuffer[zaxisNint], memberMask;
+  uint32_t d;
 
-  listElem = resHList[nsp].resources + nspT.idx;
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  intBuffer, zaxisNint, DATATYPE_INT, context);
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert ( listElem &&
-            listElem->res.v.ops == ops );
+  xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
 
-  listElem->status = status;
+  zaxisInit();
 
-  LIST_UNLOCK();
-}
+  zaxis_t *zaxisP
+    = zaxisNewEntry(force_id ? namespaceAdaptKey(intBuffer[0], originNamespace)
+                    : CDI_UNDEFID);
 
-/**************************************************************/
+  zaxisP->prec      = intBuffer[1];
+  zaxisP->type      = intBuffer[2];
+  zaxisP->ltype     = intBuffer[3];
+  zaxisP->size      = intBuffer[4];
+  zaxisP->direction = intBuffer[5];
+  zaxisP->vctsize   = intBuffer[6];
+  memberMask        = intBuffer[7];
 
-int reshGetStatus ( cdiResH resH, const resOps * ops )
-{
-  int nsp;
-  namespaceTuple_t nspT;
+  if (memberMask & vals)
+    {
+      int size = zaxisP->size;
+      xassert(size >= 0);
 
-  xassert ( ops );
+      zaxisP->vals = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      zaxisP->vals, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
+    }
 
-  LIST_INIT(1);
+  if (memberMask & lbounds)
+    {
+      int size = zaxisP->size;
+      xassert(size >= 0);
 
-  LIST_LOCK();
+      zaxisP->lbounds = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      zaxisP->lbounds, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
+    }
 
-  nsp = namespaceGetActive ();
+  if (memberMask & ubounds)
+    {
+      int size = zaxisP->size;
+      xassert(size >= 0);
 
-  nspT = namespaceResHDecode ( resH );
+      zaxisP->ubounds = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      zaxisP->ubounds, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
+    }
 
-  xassert ( nspT.nsp == nsp &&
-            nspT.idx >= 0 &&
-            nspT.idx < resHList[nsp].size );
+  if (memberMask & weights)
+    {
+      int size = zaxisP->size;
+      xassert(size >= 0);
 
-  listElem_t *listElem = resHList[nsp].resources + nspT.idx;
+      zaxisP->weights = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      zaxisP->weights, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
+    }
 
-  const resOps *elemOps = listElem->res.v.ops;
+  if ( memberMask & vct )
+    {
+      int size = zaxisP->vctsize;
+      xassert(size >= 0);
 
-  LIST_UNLOCK();
+      zaxisP->vct = (double *)xmalloc((size_t)size * sizeof (double));
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      zaxisP->vct, size, DATATYPE_FLT64, context);
+      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
+    }
 
-  xassert(listElem && elemOps == ops);
+  {
+    char *strTab[] = ZAXIS_STR_SERIALIZE;
+    int numStr = sizeof (strTab) / sizeof (strTab[0]);
+    serializeStrTabUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                          strTab, numStr, context);
+  }
 
-  return listElem->status;
-}
+  serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                  &zaxisP->positive, 1, DATATYPE_UCHAR, context);
 
-/**************************************************************/
+  if (memberMask & zaxisHasUUIDFlag)
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
-void reshLock ()
-{
-  LIST_LOCK();
 }
 
-/**************************************************************/
-
-void reshUnlock ()
+static void
+zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
+          int * packBufferPos, void *context)
 {
-  LIST_UNLOCK();
-}
+  zaxis_t   * zaxisP = ( zaxis_t * ) voidP;
+  int intBuffer[zaxisNint];
+  int memberMask;
+  uint32_t d;
 
-/**************************************************************/
+  intBuffer[0]  = zaxisP->self;
+  intBuffer[1]  = zaxisP->prec;
+  intBuffer[2]  = zaxisP->type;
+  intBuffer[3]  = zaxisP->ltype;
+  intBuffer[4]  = zaxisP->size;
+  intBuffer[5]  = zaxisP->direction;
+  intBuffer[6]  = zaxisP->vctsize;
+  intBuffer[7]  = memberMask = zaxisGetMemberMask ( zaxisP );
 
-int reshListCompare ( int nsp0, int nsp1 )
-{
-  LIST_INIT(1);
-  LIST_LOCK();
+  serializePack(intBuffer, zaxisNint, DATATYPE_INT,
+                packBuffer, packBufferSize, packBufferPos, context);
+  d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
+                packBuffer, packBufferSize, packBufferPos, context);
 
-  xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
-          nsp0 >= 0 && nsp1 >= 0);
 
-  int valCompare = 0;
-  int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
-    ? resHList[nsp0].size : resHList[nsp1].size;
-  listElem_t *resources0 = resHList[nsp0].resources,
-    *resources1 = resHList[nsp1].resources;
-  for (i = 0; i < listSizeMin; i++)
+  if ( memberMask & vals )
     {
-      int occupied0 = (resources0[i].status & RESH_IN_USE_BIT) != 0,
-        occupied1 = (resources1[i].status & RESH_IN_USE_BIT) != 0;
-      /* occupation mismatch ? */
-      int diff = occupied0 ^ occupied1;
-      valCompare |= (diff << cdiResHListOccupationMismatch);
-      if (!diff && occupied0)
-        {
-          /* both occupied, do resource types match? */
-          diff = (resources0[i].res.v.ops != resources1[i].res.v.ops
-                  || resources0[i].res.v.ops == NULL);
-          valCompare |= (diff << cdiResHListResourceTypeMismatch);
-          if (!diff)
-            {
-              /* types match, does content match also? */
-              diff
-                = resources0[i].res.v.ops->valCompare(resources0[i].res.v.val,
-                                                      resources1[i].res.v.val);
-              valCompare |= (diff << cdiResHListResourceContentMismatch);
-            }
-        }
+      xassert(zaxisP->size);
+      serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
     }
-  /* find resources in nsp 0 beyond end of nsp 1 */
-  for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
-    valCompare |= (((resources0[j].status & RESH_IN_USE_BIT) != 0)
-                   << cdiResHListOccupationMismatch);
-  /* find resources in nsp 1 beyond end of nsp 0 */
-  for (; i < resHList[nsp1].size; ++i)
-    valCompare |= (((resources1[i].status & RESH_IN_USE_BIT) != 0)
-                   << cdiResHListOccupationMismatch);
 
-  LIST_UNLOCK();
+  if (memberMask & lbounds)
+    {
+      xassert(zaxisP->size);
+      serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  return valCompare;
-}
+  if (memberMask & ubounds)
+    {
+      xassert(zaxisP->size);
 
-/**************************************************************/
+      serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-void reshListPrint(FILE *fp)
-{
-  int i, j, temp;
-  listElem_t * curr;
+  if (memberMask & weights)
+    {
+      xassert(zaxisP->size);
 
-  LIST_INIT(1);
+      serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
+  if (memberMask & vct)
+    {
+      xassert(zaxisP->vctsize);
 
-  temp = namespaceGetActive ();
+      serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
+                    packBuffer, packBufferSize, packBufferPos, context);
+      d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
+      serializePack(&d, 1, DATATYPE_UINT32,
+                    packBuffer, packBufferSize, packBufferPos, context);
+    }
 
-  fprintf ( fp, "\n\n##########################################\n#\n#  print " \
-            "global resource list \n#\n" );
+  {
+    const char *strTab[] = ZAXIS_STR_SERIALIZE;
+    int numStr = sizeof (strTab) / sizeof (strTab[0]);
+    serializeStrTabPack(strTab, numStr,
+                        packBuffer, packBufferSize, packBufferPos, context);
+  }
 
-  for ( i = 0; i < namespaceGetNumber (); i++ )
-    {
-      namespaceSetActive ( i );
+  serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
+                packBuffer, packBufferSize, packBufferPos, context);
 
-      fprintf ( fp, "\n" );
-      fprintf ( fp, "##################################\n" );
-      fprintf ( fp, "#\n" );
-      fprintf ( fp, "# namespace=%d\n", i );
-      fprintf ( fp, "#\n" );
-      fprintf ( fp, "##################################\n\n" );
+  if (memberMask & zaxisHasUUIDFlag)
+    serializePack(zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
+                  packBuffer, packBufferSize, packBufferPos, context);
 
-      fprintf ( fp, "resHList[%d].size=%d\n", i, resHList[i].size );
+}
 
-      for ( j = 0; j < resHList[i].size; j++ )
-        {
-          curr = resHList[i].resources + j;
-          if (!(curr->status & RESH_IN_USE_BIT))
-            {
-              curr->res.v.ops->valPrint(curr->res.v.val, fp);
-              fprintf ( fp, "\n" );
-            }
-        }
-    }
-  fprintf ( fp, "#\n#  end global resource list" \
-            "\n#\n##########################################\n\n" );
 
-  namespaceSetActive ( temp );
+void cdiZaxisGetIndexList(unsigned nzaxis, int zaxisResHs[nzaxis])
+{
+  reshGetResHListOfType(nzaxis, zaxisResHs, &zaxisOps);
 }
 
+#undef ZAXIS_STR_SERIALIZE
 
 /*
  * Local Variables:
@@ -63965,7 +66738,7 @@ void reshListPrint(FILE *fp)
  * require-trailing-newline: t
  * End:
  */
-   static const char cdi_libvers[] = "1.6.7" " of ""Dec 10 2014"" ""16:20:02";
+   static const char cdi_libvers[] = "1.6.9" " of ""Apr 27 2015"" ""08:19:12";
 const char *cdiLibraryVersion(void)
 {
   return (cdi_libvers);
@@ -64058,7 +66831,7 @@ only C calling FORTRAN subroutines will work using K&R style.*/
 
 /* Remainder of cfortran.h depends on the Fortran compiler. */
 
-#if defined(CLIPPERFortran) || defined(pgiFortran)
+#if (defined(CLIPPERFortran) || defined(pgiFortran)) && !defined(f2cFortran)
 #define f2cFortran
 #endif
 
@@ -66462,6 +69235,12 @@ string. */
 /*  number of unsigned char needed to store UUID  */
 
 
+/*  Structs that are used to return data to the user  */
+
+
+/*  Opaque types  */
+
+
 /*  CDI control routines  */
 
 FCALLSCSUB0 (cdiReset, CDIRESET, cdireset)
@@ -66520,8 +69299,6 @@ FCALLSCFUN1 (INT, streamInqCompLevel, STREAMINQCOMPLEVEL, streaminqcomplevel, IN
 FCALLSCFUN2 (INT, streamDefTimestep, STREAMDEFTIMESTEP, streamdeftimestep, INT, INT)
 FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT, INT)
 FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
-FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
-FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
 FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
 
 /*  STREAM var I/O routines  */
@@ -66545,6 +69322,9 @@ FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, PF
 FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, PDOUBLE, PINT)
 FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
 
+/*  File driven I/O (may yield better performance than using the streamXXX functions)  */
+
+
 /*  VLIST routines  */
 
 FCALLSCFUN0 (INT, vlistCreate, VLISTCREATE, vlistcreate)
@@ -66683,7 +69463,7 @@ FCALLSCSUB2 (gridDefMaskGME, GRIDDEFMASKGME, griddefmaskgme, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, PINT)
 FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, PINT)
-FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
+FCALLSCSUB3 (gridPrint, GRIDPRINT, gridprint, INT, INT, INT)
 FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
 FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
 FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
@@ -66775,7 +69555,6 @@ FCALLSCSUB2 (gridDefXbounds, GRIDDEFXBOUNDS, griddefxbounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqXbounds, GRIDINQXBOUNDS, gridinqxbounds, INT, PDOUBLE)
 FCALLSCSUB2 (gridDefYbounds, GRIDDEFYBOUNDS, griddefybounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqYbounds, GRIDINQYBOUNDS, gridinqybounds, INT, PDOUBLE)
-FCALLSCSUB3 (gridDefRowlon, GRIDDEFROWLON, griddefrowlon, INT, INT, INTV)
 FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, PINT)
 FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
 FCALLSCSUB2 (gridDefComplexPacking, GRIDDEFCOMPLEXPACKING, griddefcomplexpacking, INT, INT)
@@ -66790,7 +69569,7 @@ FCALLSCFUN1 (INT, zaxisInqType, ZAXISINQTYPE, zaxisinqtype, INT)
 FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
 FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
 FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
-FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
+FCALLSCSUB2 (zaxisPrint, ZAXISPRINT, zaxisprint, INT, INT)
 FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, PDOUBLE)
 FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
@@ -66863,7 +69642,6 @@ FCALLSCFUN1 (DOUBLE, taxisInqForecastPeriod, TAXISINQFORECASTPERIOD, taxisinqfor
 FCALLSCSUB2 (taxisDefNumavg, TAXISDEFNUMAVG, taxisdefnumavg, INT, INT)
 FCALLSCFUN1 (INT, taxisInqType, TAXISINQTYPE, taxisinqtype, INT)
 FCALLSCFUN1 (INT, taxisInqNumavg, TAXISINQNUMAVG, taxisinqnumavg, INT)
-FCALLSCFUN1 (STRING, tunitNamePtr, TUNITNAMEPTR, tunitnameptr, INT)
 
 /*  Institut routines  */
 
@@ -66873,7 +69651,6 @@ FCALLSCFUN0 (INT, institutInqNumber, INSTITUTINQNUMBER, institutinqnumber)
 FCALLSCFUN1 (INT, institutInqCenter, INSTITUTINQCENTER, institutinqcenter, INT)
 FCALLSCFUN1 (INT, institutInqSubcenter, INSTITUTINQSUBCENTER, institutinqsubcenter, INT)
 FCALLSCFUN1 (STRING, institutInqNamePtr, INSTITUTINQNAMEPTR, institutinqnameptr, INT)
-FCALLSCFUN1 (STRING, institutInqLongnamePtr, INSTITUTINQLONGNAMEPTR, institutinqlongnameptr, INT)
 
 /*  Model routines  */
 
@@ -66889,7 +69666,6 @@ FCALLSCSUB2 (tableWriteC, TABLEWRITEC, tablewritec, STRING, INT)
 FCALLSCSUB2 (tableWrite, TABLEWRITE, tablewrite, STRING, INT)
 FCALLSCFUN1 (INT, tableRead, TABLEREAD, tableread, STRING)
 FCALLSCFUN3 (INT, tableDef, TABLEDEF, tabledef, INT, INT, STRING)
-FCALLSCFUN1 (STRING, tableInqNamePtr, TABLEINQNAMEPTR, tableinqnameptr, INT)
 FCALLSCSUB5 (tableDefEntry, TABLEDEFENTRY, tabledefentry, INT, INT, STRING, STRING, STRING)
 FCALLSCFUN3 (INT, tableInq, TABLEINQ, tableinq, INT, INT, STRING)
 FCALLSCFUN0 (INT, tableInqNumber, TABLEINQNUMBER, tableinqnumber)
diff --git a/libcdi/src/cfortran.h b/libcdi/src/cfortran.h
index 59a26d3..a6316f8 100644
--- a/libcdi/src/cfortran.h
+++ b/libcdi/src/cfortran.h
@@ -80,7 +80,7 @@ only C calling FORTRAN subroutines will work using K&R style.*/
 
 /* Remainder of cfortran.h depends on the Fortran compiler. */
 
-#if defined(CLIPPERFortran) || defined(pgiFortran)
+#if (defined(CLIPPERFortran) || defined(pgiFortran)) && !defined(f2cFortran)
 #define f2cFortran
 #endif
 
diff --git a/libcdi/src/cgribexlib.c b/libcdi/src/cgribexlib.c
index 12a5fd1..b152910 100644
--- a/libcdi/src/cgribexlib.c
+++ b/libcdi/src/cgribexlib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2014-12-03, do not edit */
+/* Automatically generated by m214003 at 2015-04-22, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.7.0" */
+/* CGRIBEXLIB_VERSION="1.7.2" */
 
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
 #pragma GCC diagnostic push
@@ -133,7 +133,7 @@
 
 double intpow2(int x);
 
-int gribrec_len(int b1, int b2, int b3);
+int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
 int correct_bdslen(int bdslen, long recsize, long gribpos);
 
 /* CDI converter routines */
@@ -678,12 +678,22 @@ gcc -g -Wall -O3 -march=native -std=c99 -DTEST_MINMAXVAL -fopenmp -DOMP_SIMD min
   simd    : fmin: -500000  fmax: 499999  time:   3.10s # omp simd in gcc 4.9
   avx     : fmin: -500000  fmax: 499999  time:   2.84s
 
-icc -g -Wall -O3 -march=native -std=c99 -vec-report=1 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
  result on thunder5 (icc 14.0.2):
   orig    : fmin: -500000  fmax: 499999  time:   2.83s
   simd    : fmin: -500000  fmax: 499999  time:   2.83s
   avx     : fmin: -500000  fmax: 499999  time:   2.92s
 
+icc -g -Wall -O3 -march=native -std=c99 -qopt-report=5 -DTEST_MINMAXVAL -openmp -DOMP_SIMD minmax_val.c
+ result on hama (icc 15.0.1):
+ float:
+  minmax_val: fmin: -500000  fmax: 499999  time:   0.60s
+ double:
+  minmax_val: fmin: -500000  fmax: 499999  time:   3.06s
+  orig      : fmin: -500000  fmax: 499999  time:   2.66s
+  simd      : fmin: -500000  fmax: 499999  time:   6.65s
+  avx       : fmin: -500000  fmax: 499999  time:   3.11s
+
 xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_MINMAXVAL minmax_val.c
  result on blizzard (xlc 12):
   orig    : fmin: -500000  fmax: 499999  time:   7.26s
@@ -977,6 +987,8 @@ void pwr6_minmax_val_double_unrolled6(const double *restrict data, long idatasiz
 #if defined(TEST_MINMAXVAL) && defined(__GNUC__)
 static
 void minmax_val_double_orig(const double *restrict data, long idatasize, double *fmin, double *fmax) __attribute__ ((noinline));
+static
+void minmax_val_double_simd(const double *restrict data, long idatasize, double *fmin, double *fmax) __attribute__ ((noinline));
 #endif
 
 #if defined(GNUC_PUSH_POP)
@@ -1041,10 +1053,8 @@ void minmax_val_float(const float *restrict data, long idatasize, float *fmin, f
 // TEST
 #if defined(OMP_SIMD)
 
-//#pragma omp declare reduction(xmin : double : omp_out = omp:in > omp_out ? omp_out : omp_in)
-// initializer( omp_priv = { largenumber })
-//#pragma omp declare reduction(xmax : double : omp_out = omp:in < omp_out ? omp_out : omp_in)
-// initializer( omp_priv = { -largenumber })
+//#pragma omp declare reduction(xmin : double : omp_out = omp_in > omp_out ? omp_out : omp_in) initializer( omp_priv = { 1.e300 })
+//#pragma omp declare reduction(xmax : double : omp_out = omp_in < omp_out ? omp_out : omp_in) initializer( omp_priv = { -1.e300 })
 
 #if defined(GNUC_PUSH_POP)
 #pragma GCC push_options
@@ -1254,7 +1264,7 @@ int main(void)
     for ( int i = 0; i < NRUN; ++i )
       {
 	fmin = fmax = data_dp[0];
-	avx_minmax_double_val(data_dp, datasize, &fmin, &fmax);
+	avx_minmax_val_double(data_dp, datasize, &fmin, &fmax);
       }
     t_end = dtime();
     printf("avx       : fmin: %ld  fmax: %ld  time: %6.2fs\n", (long)fmin, (long) fmax, t_end-t_begin);
@@ -1404,7 +1414,7 @@ void avx_encode_array_2byte_double(size_t datasize,
 
   for (i = 0; i < (datasize-residual); i += 16)
     {
-      (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
+      (void) _mm_prefetch((const char*)(dval+8), _MM_HINT_NTA);
       //_____________________________________________________________________________
 
       d0 = _mm256_loadu_pd (dval);
@@ -1431,7 +1441,7 @@ void avx_encode_array_2byte_double(size_t datasize,
 
       //_____________________________________________________________________________
 
-      (void) _mm_prefetch(dval+16, _MM_HINT_NTA);
+      (void) _mm_prefetch((const char*)(dval+16), _MM_HINT_NTA);
 
       //_____________________________________________________________________________
       
@@ -1479,6 +1489,8 @@ void avx_encode_array_2byte_double(size_t datasize,
   return;
 }
 
+#define grib_encode_array_2byte_double avx_encode_array_2byte_double
+
 #elif defined _ENABLE_SSE4_1
 
 static
@@ -1608,6 +1620,12 @@ void sse41_encode_array_2byte_double(size_t datasize,
   return;
 }
 
+#define grib_encode_array_2byte_double sse41_encode_array_2byte_double
+
+#else
+
+#define grib_encode_array_2byte_double encode_array_2byte_double
+
 #endif // SIMD variants
 
 
@@ -2438,42 +2456,48 @@ int gribTimeIsFC(int *isec1)
 void gribDateTime(int *isec1, int *date, int *time)
 {
   static int lprint = TRUE;
-  int ryear, rmonth, rday, rhour, rminute, second;
   int julday, secofday;
   int64_t addsec = 0;
   int64_t time_period = 0;
-  int century;
   extern int grib_calendar;
 
-  century = ISEC1_Century;
-  if ( century < 0 ) century = -century;
-  century -= 1;
+  int century = ISEC1_Century;
+  int ryear   = ISEC1_Year;
 
-  ryear   = ISEC1_Year;
-
-  /* if ( century != 0 ) */
+  if ( century == -255 && ryear == 127 )
     {
-      if ( ryear == 100 )
-	{
-	  ryear = 0;
-	  century += 1;
-	}
+      century = 0;
+      ryear = 0;
+    }
+  else
+    {
+      if ( century < 0 ) century = -century;
+      century -= 1;
 
-      if ( ryear != 255 )
-	{
-	  ryear = century*100 + ryear;
-	  if ( ISEC1_Century < 0 ) ryear = -ryear;
-	}
-      else
-	ryear = 1;
+      /* if ( century != 0 ) */
+      {
+        if ( ryear == 100 )
+          {
+            ryear = 0;
+            century += 1;
+          }
+
+        if ( ryear != 255 )
+          {
+            ryear = century*100 + ryear;
+            if ( ISEC1_Century < 0 ) ryear = -ryear;
+          }
+        else
+          ryear = 1;
+      }
     }
 
-  rmonth  = ISEC1_Month;
-  rday    = ISEC1_Day;
+  int rmonth  = ISEC1_Month;
+  int rday    = ISEC1_Day;
 
-  rhour   = ISEC1_Hour;
-  rminute = ISEC1_Minute;
-  second  = 0;
+  int rhour   = ISEC1_Hour;
+  int rminute = ISEC1_Minute;
+  int second  = 0;
 
   /* printf("ref %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute); */
 
@@ -4236,9 +4260,7 @@ void gribPrintSec4Wave(int *isec4)
 
 int gribOpen(const char *filename, const char *mode)
 {
-  int fileID;
-
-  fileID = fileOpen(filename, mode);
+  int fileID = fileOpen(filename, mode);
 
 #if defined (__sun)
   if ( fileID != FILE_UNDEFID && tolower(*mode) == 'r' )
@@ -4247,7 +4269,7 @@ int gribOpen(const char *filename, const char *mode)
     }
 #endif
 
-  return (fileID);  
+  return fileID;  
 }
 
 
@@ -4259,17 +4281,16 @@ void gribClose(int fileID)
 
 off_t gribGetPos(int fileID)
 {
-  return (fileGetPos(fileID));
+  return fileGetPos(fileID);
 }
 
 
 int gribCheckFiletype(int fileID)
 {
-  int ierr;
   int found = 0;
   char buffer[4];
 
-  if ( fileRead(fileID, buffer, 4) != 4 ) return(found);
+  if ( fileRead(fileID, buffer, 4) != 4 ) return found;
 
   if ( memcmp(buffer, "GRIB", 4) == 0 )
     {
@@ -4279,8 +4300,7 @@ int gribCheckFiletype(int fileID)
   else
     {
       long offset;
-
-      ierr = gribFileSeek(fileID, &offset);
+      int ierr = gribFileSeek(fileID, &offset);
       fileRewind(fileID);
       if ( !ierr )
 	{
@@ -4289,25 +4309,23 @@ int gribCheckFiletype(int fileID)
 	}
     }
 
-  return (found);
+  return found;
 }
 
 
 int gribCheckSeek(int fileID, long *offset, int *version)
 {
-  int ierr;
-  char buffer[4];
-
-  ierr = gribFileSeek(fileID, offset);
+  int ierr = gribFileSeek(fileID, offset);
 
   *version = -1;
   if ( !ierr )
     {
-      if ( fileRead(fileID, buffer, 4) == 4 )
+      char buffer[4];
+     if ( fileRead(fileID, buffer, 4) == 4 )
 	*version = buffer[3];
     }
 
-  return (ierr);
+  return ierr;
 }
 
 
@@ -4319,11 +4337,10 @@ int gribFileSeekOld(int fileID, long *offset)
   unsigned char buffer[4096];
   int retry = 4096;
   int i;
-  void *fileptr;
 
   *offset = 0;
 
-  fileptr = filePtr(fileID);
+  void *fileptr = filePtr(fileID);
 
   ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[0] = ch;
   ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[1] = ch;
@@ -4358,10 +4375,9 @@ int gribFileSeekOld(int fileID, long *offset)
       buffer[3] = buffer[i+3];
     }
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  return (1);
+  return 1;
 }
 
 
@@ -4372,11 +4388,10 @@ int gribFileSeek(int fileID, long *offset)
   long code = 0;
   int ch;
   int retry = 4096*4096;
-  void *fileptr;
 
   *offset = 0;
 
-  fileptr = filePtr(fileID);
+  void *fileptr = filePtr(fileID);
 
   while ( retry-- )
     {
@@ -4395,10 +4410,9 @@ int gribFileSeek(int fileID, long *offset)
       (*offset)++;
     }
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  return (1);
+  return 1;
 }
 
 
@@ -4412,12 +4426,11 @@ int gribFileSeekTest(int fileID, long *offset)
   const int buffersize = 8;
   unsigned char buffer[8];
   int retry = 4096*4096;
-  void *fileptr;
   int nread = 0;
 
   *offset = 0;
 
-  fileptr = filePtr(fileID);
+  void *fileptr = filePtr(fileID);
 
   while ( retry-- )
     {
@@ -4445,43 +4458,24 @@ int gribFileSeekTest(int fileID, long *offset)
       (*offset)++;
     }
 
-  if ( CGRIBEX_Debug )
-    Message("record offset = %d", (int) *offset);
+  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
 
-  return (1);
+  return 1;
 }
 
 
 int gribReadSize(int fileID)
 {
-  int gribversion, gribsize;
-  int b1, b2, b3;
-  off_t pos;
-  void *fileptr;
-  /*
-  const int buffersize = 4;
-  unsigned char buffer[4];
-  */
-  fileptr = filePtr(fileID);
+  void *fileptr = filePtr(fileID);
+  off_t pos = fileGetPos(fileID); 
 
-  pos = fileGetPos(fileID); 
-  /* bug: order of functions calls!
-     gribsize = (filePtrGetc(fileptr) << 16) + (filePtrGetc(fileptr) << 8) + filePtrGetc(fileptr);
-  */
-  b1 = filePtrGetc(fileptr);
-  b2 = filePtrGetc(fileptr);
-  b3 = filePtrGetc(fileptr);
-  // gribsize = (b1 << 16) + (b2 << 8) + b3;
-  gribsize = gribrec_len(b1, b2, b3);
+  unsigned b1 = (unsigned) filePtrGetc(fileptr);
+  unsigned b2 = (unsigned) filePtrGetc(fileptr);
+  unsigned b3 = (unsigned) filePtrGetc(fileptr);
 
-  gribversion = filePtrGetc(fileptr);
-  /*
-  filePtrRead(fileptr, buffer, buffersize);
-
-  gribsize = (buffer[0] << 16) + (buffer[1] << 8) + buffer[2];
+  int gribsize = gribrec_len(b1, b2, b3);
+  int gribversion = filePtrGetc(fileptr);
 
-  gribversion = buffer[3];
-  */
   if ( gribsize == 24 )
     {
       if ( gribversion != 1 && gribversion != 2 ) gribversion = 0;
@@ -4589,84 +4583,70 @@ int gribReadSize(int fileID)
 
   fileSetPos(fileID, pos, SEEK_SET);
 
-  return (gribsize);
+  return gribsize;
 }
 
 
 int gribGetSize(int fileID)
 {
-  int recsize;
   long offset;
-  int ierr;
-
-  ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
+  int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
   if ( ierr > 0 )
     {
       Warning("GRIB record not found!");
       return (0);
     }
 
-  if ( ierr == -1 )
-    return (0);
-  else if ( ierr == 1 )
-    return (0);
+  if      ( ierr == -1 ) return 0;
+  else if ( ierr ==  1 ) return 0;
 
-  recsize = gribReadSize(fileID);
+  int recSize = gribReadSize(fileID);
 
-  if ( CGRIBEX_Debug ) Message("recsize = %d", recsize);
+  if ( CGRIBEX_Debug ) Message("recsize = %d", recSize);
 
   fileSetPos(fileID, (off_t) -4, SEEK_CUR);
 
-  return (recsize);
+  return recSize;
 }
 
 
 int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
 {
   long offset;
-  int ierr = 0;
-  size_t nread, recsize, recsize0;
-
-  ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
+  int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
   if ( ierr > 0 )
     {
       Warning("GRIB record not found!");
       return (-2);
     }
 
-  if ( ierr == -1 )
-    {
-      *buffersize = 0;
-      return (-1);
-    }
-  else if ( ierr == 1 )
+  if      ( ierr == -1 ) { *buffersize = 0; return -1; }
+  else if ( ierr ==  1 ) { *buffersize = 0; return -2; }
+
+  size_t recSize  = gribReadSize(fileID);
+  size_t readSize = recSize;
+
+  if ( readSize > *buffersize )
     {
-      *buffersize = 0;
-      return (-2);
+      readSize = *buffersize;
+      ierr = -3;          // Tell the caller that the buffer was insufficient.
     }
 
-  recsize = gribReadSize(fileID);
+  *buffersize = recSize;  // Inform the caller about the record size.
 
+  // Write the stuff to the buffer that has already been read in gribFileSeek().
   buffer[0] = 'G';
   buffer[1] = 'R';
   buffer[2] = 'I';
   buffer[3] = 'B';
 
-  recsize0 = recsize;
-
-  if ( recsize > *buffersize )
-    {
-      recsize = *buffersize;
-      ierr = -3;
-    }
-
-  *buffersize = recsize0;
+  readSize -= 4;
+  // Read the rest of the record into the buffer.
+  size_t nread = fileRead(fileID, &buffer[4], readSize);
 
-  nread = fileRead(fileID, &buffer[4], recsize-4);
+  if ( nread != readSize ) ierr = 1;
 
-  if ( nread != recsize-4 ) ierr = 1;
-
-  return (ierr);
+  return ierr;
 }
 
 
@@ -4674,30 +4654,31 @@ int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
 {
   int  nwrite = 0;
 
-  if( (nwrite = fileWrite(fileID, buffer, buffersize)) != (int) buffersize )
+  if ( (nwrite = fileWrite(fileID, buffer, buffersize)) != (int) buffersize )
     {
       perror(__func__);
       nwrite = -1;
     }
 
-  return ((int) nwrite);
+  return nwrite;
 }
 
 
-int gribrec_len(int b1, int b2, int b3)
+int gribrec_len(unsigned b1, unsigned b2, unsigned b3)
 {
-  int gribsize;
-
-  gribsize = (1-(int) ((unsigned) (b1&128) >> 6)) * (int) (((b1&127) << 16)+(b2<<8) + b3);
   /*
-    If count is negative, have to rescale by factor of -120.
+    If bit 7 of b1 is set, we have to rescale by factor of 120.
     This is a fixup to get round the restriction on product lengths
     due to the count being only 24 bits. It is only possible because
     the (default) rounding for GRIB products is 120 bytes.
   */
-  if ( gribsize < 0 ) gribsize *= (-120);
+  int needRescaling = b1 & (1 << 7);
+  
+  int gribsize = (((b1&127) << 16)+(b2<<8) + b3);
+
+  if ( needRescaling ) gribsize *= 120;
 
-  return (gribsize);
+  return gribsize;
 }
 
 #include <stdlib.h>
@@ -6961,6 +6942,10 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   }
 
 #else
+  
+  UNUSED(sbuf);
+  UNUSED(sbufsize);
+
   if ( libszwarn )
     {
       Warning("Compression disabled, szlib or libaec not available!");
@@ -7230,6 +7215,12 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
     */
   }
 #else
+  UNUSED(bds_nbits);
+  UNUSED(sourceLen);
+  UNUSED(source);
+  UNUSED(bdsLen);
+  UNUSED(dest);
+  
   if ( libszwarn )
     {
       Warning("Decompression disabled, szlib or libaec not available!");
@@ -12165,14 +12156,8 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
 
       if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-          avx_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#elif defined _ENABLE_SSE4_1
-          sse41_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#else
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-#endif
+      	{
+          grib_encode_array_2byte_double(datasize, lGrib, (const double * restrict) data, zref, factor, &z);
         }
       else
         {
@@ -12642,14 +12627,8 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
 
       if ( sizeof(T) == sizeof(double) )
-      	{ 
-#if defined _ENABLE_AVX
-          avx_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#elif defined _ENABLE_SSE4_1
-          sse41_encode_array_2byte_double(datasize, lGrib, data, zref, factor, &z);
-#else
-          TEMPLATE(encode_array_2byte,T)(datasize, lGrib, data, zref, factor, &z);
-#endif
+      	{
+          grib_encode_array_2byte_double(datasize, lGrib, (const double * restrict) data, zref, factor, &z);
         }
       else
         {
@@ -14224,7 +14203,7 @@ void encode_dummy(void)
   (void) encode_array_unrolled_double(0, 0, 0, NULL, NULL, 0, 0, NULL);
   (void) encode_array_unrolled_float(0, 0, 0, NULL, NULL, 0, 0, NULL);
 }
-static const char grb_libvers[] = "1.7.0" " of ""Dec  3 2014"" ""08:52:12";
+static const char grb_libvers[] = "1.7.2" " of ""Apr 22 2015"" ""13:44:04";
 const char *
 cgribexLibraryVersion(void)
 {
diff --git a/libcdi/src/config.h.in b/libcdi/src/config.h.in
index 0c6aa67..25182f7 100644
--- a/libcdi/src/config.h.in
+++ b/libcdi/src/config.h.in
@@ -260,3 +260,17 @@
 
 /* Defined to return type of backtrace(). */
 #undef backtrace_size_t
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+   __restrict__, even though the corresponding Sun C compiler ends up with
+   "#define restrict _Restrict" or "#define restrict __restrict__" in the
+   previous line.  Perhaps some future version of Sun C++ will work with
+   restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif
diff --git a/libcdi/tests/create_uuid.h b/libcdi/src/create_uuid.h
similarity index 100%
rename from libcdi/tests/create_uuid.h
rename to libcdi/src/create_uuid.h
diff --git a/libcdi/src/dmemory.c b/libcdi/src/dmemory.c
index b1a8ebb..3adb757 100644
--- a/libcdi/src/dmemory.c
+++ b/libcdi/src/dmemory.c
@@ -1,4 +1,4 @@
-#if  defined  (HAVE_CONFIG_H)
+#if  defined(HAVE_CONFIG_H)
 #  include "config.h"
 #endif
 
@@ -11,18 +11,24 @@
 
 #include "error.h"
 
-#if ! defined (HAVE_CONFIG_H)
-#if ! defined (HAVE_MALLOC_H)
-#  if defined (SX)
-#    define  HAVE_MALLOC_H
-#  endif
-#endif
+#if !defined(HAVE_CONFIG_H) && !defined(HAVE_MALLOC_H) && defined(SX)
+#  define  HAVE_MALLOC_H
 #endif
 
-#if  defined  (HAVE_MALLOC_H)
-#    include <malloc.h>
+#if  defined(HAVE_MALLOC_H)
+#  include <malloc.h>
 #endif
 
+//There is no point in avoiding to include our own header, it is likely to be included before this file in the backed cdilib.c.
+//As such, we may as well always include it and let the compiler check our function signatures.
+#include "dmemory.h"
+
+//However, we need to avoid clobbering our own `malloc()` calls, so we ensure that our own malloc calls cannot be interpreted as macro calls.
+#define protected_realloc (realloc)
+#define protected_calloc (calloc)
+#define protected_malloc (malloc)
+#define protected_free (free)
+
 
 #define  MALLOC_FUNC   0
 #define  CALLOC_FUNC   1
@@ -269,7 +275,7 @@ int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
     {
       memTableSize = 8;
       memSize  = memTableSize * sizeof(MemTable_t);
-      memTable = (MemTable_t *) malloc(memSize);
+      memTable = (MemTable_t *) protected_malloc(memSize);
       if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
 
       for(size_t i = 0; i < memTableSize; i++)
@@ -290,7 +296,7 @@ int memListNewEntry(int mtype, void *ptr, size_t size, size_t nobj,
     {
       memTableSize = 2*memTableSize;
       memSize  = memTableSize*sizeof(MemTable_t);
-      memTable = (MemTable_t*) realloc(memTable, memSize);
+      memTable = (MemTable_t*) protected_realloc(memTable, memSize);
       if( memTable == NULL ) memError(__func__, __FILE__, __LINE__, memSize);
 
       for (size_t i = memID; i < memTableSize; i++)
@@ -414,7 +420,7 @@ void *Calloc(const char *caller, const char *file, int line, size_t nobjs, size_
 
   if ( nobjs*size > 0 )
     {
-      ptr = calloc(nobjs, size);
+      ptr = protected_calloc(nobjs, size);
 
       if ( MEM_Debug )
 	{
@@ -444,7 +450,7 @@ void *Malloc(const char *caller, const char *file, int line, size_t size)
 
   if ( size > 0 )
     {
-      ptr = malloc(size);
+      ptr = protected_malloc(size);
 
       if ( MEM_Debug )
 	{
@@ -474,7 +480,7 @@ void *Realloc(const char *caller, const char *file, int line, void *ptrold, size
 
   if ( size > 0 )
     {
-      ptr = realloc(ptrold, size);
+      ptr = protected_realloc(ptrold, size);
 
       if ( MEM_Debug )
 	{
@@ -521,36 +527,33 @@ void Free(const char *caller, const char *file, int line, void *ptr)
 	}
     }
 
-  free(ptr);
+  protected_free(ptr);
 }
 
 void *cdiXmalloc(size_t size, const char *filename, const char *functionname,
                  int line)
 {
-  void *value = malloc(size);
+  void *value = protected_malloc(size);
   if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "malloc failed: %s",
-             strerror(errno));
+    cdiAbort(filename, functionname, line, "malloc failed: %s", strerror(errno));
   return value;
 }
 
 void *cdiXcalloc(size_t nmemb, size_t size, const char *filename,
                  const char *functionname, int line)
 {
-  void *value = calloc(nmemb, size);
+  void *value = protected_calloc(nmemb, size);
   if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "calloc failed: %s",
-             strerror(errno) );
+    cdiAbort(filename, functionname, line, "calloc failed: %s", strerror(errno) );
   return value;
 }
 
 void *cdiXrealloc(void *p, size_t size, const char *functionname,
                   const char *filename, int line)
 {
-  void *value = realloc(p, size);
+  void *value = protected_realloc(p, size);
   if (size == 0 || value != NULL) ; else
-    cdiAbort(filename, functionname, line, "realloc failed: %s",
-             strerror(errno));
+    cdiAbort(filename, functionname, line, "realloc failed: %s", strerror(errno));
   return value;
 }
 
diff --git a/libcdi/src/dmemory.h b/libcdi/src/dmemory.h
index 52795f4..dced537 100644
--- a/libcdi/src/dmemory.h
+++ b/libcdi/src/dmemory.h
@@ -1,7 +1,11 @@
 #ifndef _DMEMORY_H
 #define _DMEMORY_H
 
+//Ensure that all standard headers that may declare malloc() and friends are already included so that our macros won't clobber their definitions.
 #include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+    #include <malloc.h>
+#endif
 
 /*
  * if DEBUG_MEMORY is defined setenv MEMORY_DEBUG to debug memory
diff --git a/libcdi/src/error.h b/libcdi/src/error.h
index 86dc559..77ea2b5 100644
--- a/libcdi/src/error.h
+++ b/libcdi/src/error.h
@@ -57,7 +57,7 @@ void cdiAbortC(const char *caller, const char *filename,
 
 #define xassert(arg) do {                       \
     if ((arg)) { } else {                       \
-      xabort("assertion failed");}              \
+      xabort("assertion `" #arg "` failed");}   \
   } while(0)
 
 void
diff --git a/libcdi/src/gribapi.h b/libcdi/src/gribapi.h
index 264ff60..ab11feb 100644
--- a/libcdi/src/gribapi.h
+++ b/libcdi/src/gribapi.h
@@ -2,8 +2,14 @@
 #define _GRIBAPI_H
 
 #ifdef HAVE_LIBGRIB_API
-#  include "error.h"
-#  include <grib_api.h>
+#include <grib_api.h>
+#ifndef  _ERROR_H
+#include "error.h"
+#endif
+#endif
+
+#ifndef  _CDI_INT_H
+#include "cdi_int.h"
 #endif
 
 #define  GRIBAPI_MISSVAL  -9.E33
@@ -50,13 +56,14 @@
 const char *gribapiLibraryVersionString(void);
 void gribContainersNew(stream_t * streamptr);
 void gribContainersDelete(stream_t * streamptr);
+
 #ifdef HAVE_LIBGRIB_API
 static inline void *gribHandleNew(int editionNumber)
 {
-  void *gh =
-    (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
+  void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
 
   if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
+
   return gh;
 }
 
diff --git a/libcdi/src/gribapi_utilities.c b/libcdi/src/gribapi_utilities.c
new file mode 100644
index 0000000..408ce3a
--- /dev/null
+++ b/libcdi/src/gribapi_utilities.c
@@ -0,0 +1,711 @@
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+static int dummy;
+
+#ifdef HAVE_LIBGRIB_API
+
+#include "gribapi_utilities.h"
+
+#include "cdi.h"
+#include "dmemory.h"
+#include "error.h"
+#include "gribapi.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <assert.h>
+#include <time.h>
+
+#define FAIL_ON_GRIB_ERROR(function, gribHandle, key, ...) do\
+{\
+  int errorCode = function(gribHandle, key, __VA_ARGS__);\
+  if(errorCode)\
+    {\
+      fprintf(stderr, "%s:%d: Error in function `%s`: `%s` returned error code %d for key \"%s\"", __FILE__, __LINE__, __func__, #function, errorCode, key);\
+      exit(errorCode);\
+    }\
+} while(0)
+
+//A simple wrapper for grib_get_string() that returns a newly allocated string.
+char* gribCopyString(grib_handle* gribHandle, const char* key)
+{
+  size_t length;
+  if(grib_get_length(gribHandle, key, &length)) return NULL;
+  char* result = xmalloc(length);
+  if(!grib_get_string(gribHandle, key, result, &length)) return result;
+  free(result);
+  return NULL;
+}
+
+//A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
+//Returns true if the key exists and the value is equal to the given string.
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue)
+{
+  size_t expectedLength = strlen(expectedValue) + 1, length;
+  if(grib_get_length(gribHandle, key, &length)) return false;
+  if(length != expectedLength) return false;
+  char value[length];
+  if(grib_get_string(gribHandle, key, value, &length)) return false;
+  return !strcmp(value, expectedValue);
+}
+
+//A simple wrapper for grib_get_long() for the usecase that the result is only compared to a given constant value.
+//Returns true if the key exists and the value is equal to the given one.
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue)
+{
+  long value;
+  if(grib_get_long(gribHandle, key, &value)) return false;
+  return value == expectedValue;
+}
+
+//A simple wrapper for grib_get_long() for the usecase that failure to fetch the value is fatal.
+long gribGetLong(grib_handle* gh, const char* key)
+{
+  long result;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, key, &result);
+  return result;
+}
+
+//A simple wrapper for grib_get_long() for the usecase that a default value is used in the case that the operation fails.
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
+{
+  long result;
+  if(grib_get_long(gribHandle, key, &result)) return defaultValue;
+  if(result == GRIB_MISSING_LONG) return defaultValue;
+  return result;
+}
+
+//A simple wrapper for grib_get_double() for the usecase that failure to fetch the value is fatal.
+double gribGetDouble(grib_handle* gh, const char* key)
+{
+  double result;
+  FAIL_ON_GRIB_ERROR(grib_get_double, gh, key, &result);
+  return result;
+}
+
+//A sample wrapper for grib_get_double() for the usecase that a default value is used in the case that the operation fails.
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
+{
+  double result;
+  if(grib_get_double(gribHandle, key, &result)) return defaultValue;
+  if(IS_EQUAL(result, GRIB_MISSING_DOUBLE)) return defaultValue;
+  return result;
+}
+
+//A simple wrapper for grib_get_size() for the usecase that failure to fetch the value is fatal.
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key)
+{
+  size_t result;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gribHandle, key, &result);
+  return result;
+}
+
+//A simple wrapper for grib_get_double_array() for the usecase that failure to fetch the data is fatal.
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_double_array, gribHandle, key, array, &valueCount);
+}
+
+//A simple wrapper for grib_get_long_array() for the usecase that failure to fetch the data is fatal.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_long_array, gribHandle, key, array, &valueCount);
+}
+
+
+//We need the edition number so frequently, that it's convenient to give it its own function.
+long gribEditionNumber(grib_handle* gh)
+{
+  return gribGetLong(gh, "editionNumber");
+}
+
+//This return value of this should be passed to a call to resetTz(), it is a malloc'ed string with the content of the TZ environment variable before the call (or NULL if that was not set).
+static char* setUtc()
+{
+  char* temp = getenv("TZ"), *result = NULL;
+  if(temp) result = myStrDup(temp);
+  setenv("TZ", "UTC", 1);
+  return result;
+}
+
+//Undoes the effect of setUtc(), pass to it the return value of the corresponding setUtc() call, it will free the string.
+static void resetTz(char* savedTz)
+{
+  if(savedTz)
+    {
+      setenv("TZ", savedTz, 1);
+      free(savedTz);
+    }
+  else
+    {
+      unsetenv("TZ");
+    }
+}
+
+//This function uses the system functions to normalize the date representation according to the gregorian calendar.
+//Returns zero on success.
+static int normalizeDays(struct tm* me)
+{
+  char* savedTz = setUtc();     //Ensure that mktime() does not interprete the date according to our local time zone.
+
+  int result = mktime(me) == (time_t)-1;        //This does all the heavy lifting.
+
+  resetTz(savedTz);
+  return result;
+}
+
+//Returns zero on success.
+static int addSecondsToDate(struct tm* me, long long amount)
+{
+  //It is irrelevant here whether days are zero or one based, the correction would have be undone again so that it is effectless.
+  long long seconds = ((me->tm_mday*24ll + me->tm_hour)*60 + me->tm_min)*60 + me->tm_sec;    //The portion of the date that uses fixed increments.
+  seconds += amount;
+  me->tm_mday = seconds/24/60/60;
+  seconds -= me->tm_mday*24*60*60;
+  me->tm_hour = seconds/60/60;
+  seconds -= me->tm_hour*60*60;
+  me->tm_min = seconds/60;
+  seconds -= me->tm_min*60;
+  me->tm_sec = seconds;
+  return normalizeDays(me);
+}
+
+static void addMonthsToDate(struct tm* me, long long amount)
+{
+  long long months = me->tm_year*12ll + me->tm_mon;
+  months += amount;
+  me->tm_year = months/12;
+  months -= me->tm_year*12;
+  me->tm_mon = months;
+}
+
+//unit is a value according to code table 4.4 of the GRIB2 specification, returns non-zero on error
+static int addToDate(struct tm* me, long long amount, long unit)
+{
+  switch(unit)
+    {
+      case 0: return addSecondsToDate(me,       60*amount);   // minute
+      case 1: return addSecondsToDate(me,    60*60*amount);   // hour
+      case 2: return addSecondsToDate(me, 24*60*60*amount);   // day
+
+      case 3: addMonthsToDate(me,        amount); return 0;   // month
+      case 4: addMonthsToDate(me,     12*amount); return 0;   // year
+      case 5: addMonthsToDate(me,  10*12*amount); return 0;   // decade
+      case 6: addMonthsToDate(me,  30*12*amount); return 0;   // normal
+      case 7: addMonthsToDate(me, 100*12*amount); return 0;   // century
+
+      case 10: return addSecondsToDate(me,  3*60*60*amount);  // eighth of a day
+      case 11: return addSecondsToDate(me,  6*60*60*amount);  // quarter day
+      case 12: return addSecondsToDate(me, 12*60*60*amount);  // half day
+      case 13: return addSecondsToDate(me,          amount);  // second
+
+      default: return 1;        //reserved, unknown, or missing
+    }
+}
+
+static char* makeDateString(struct tm* me)
+{
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec);
+}
+
+//FIXME: This ignores any calendar definition that might be present.
+//XXX: Identification templates are not implemented in grib_api-1.12.3, so even if I implemented the other calendars now, it wouldn't be possible to use them.
+static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecastTime, bool* outHaveTimeRange)
+{
+  switch(gribGetLong(gh, "productDefinitionTemplateNumber"))
+    {
+      case 20: case 30: case 31: case 254: case 311: case 2000:
+        *outHaveForecastTime = false, *outHaveTimeRange = false;
+        return 0;
+
+      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 60: case 1000: case 1002: case 1100: case 40033:
+        *outHaveForecastTime = true, *outHaveTimeRange = false;
+        return 0;
+
+      case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 34: case 42: case 43: case 46: case 47: case 61: case 91: case 1001: case 1101: case 40034:
+        *outHaveForecastTime = true, *outHaveTimeRange = true;
+        return 0;
+
+      default:
+        return 1;
+    }
+}
+
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime)
+{
+  //Get the parts of the reference date.
+  struct tm date = {
+      .tm_mon = gribGetLong(gh, "month") - 1,   //months are zero based in struct tm and one based in GRIB
+      .tm_mday = gribGetLong(gh, "day"),
+      .tm_hour = gribGetLong(gh, "hour"),
+      .tm_min = gribGetLong(gh, "minute")
+  };
+  if(gribEditionNumber(gh) == 1)
+    {
+      date.tm_year = gribGetLong(gh, "yearOfCentury");  //years are -1900 based both in struct tm and GRIB1
+    }
+  else
+    {
+      date.tm_year = gribGetLong(gh, "year") - 1900;   //years are -1900 based in struct tm and zero based in GRIB2
+      date.tm_sec = gribGetLong(gh, "second");
+
+      //Determine whether we have a forecast time and a time range.
+      bool haveForecastTime, haveTimeRange;
+      if(getAvailabilityOfRelativeTimes(gh, &haveForecastTime, &haveTimeRange)) return NULL;
+      if(getEndTime && !haveTimeRange) return NULL;     //tell the caller that the requested time does not exist
+
+      //If we have relative times, apply them to the date
+      if(haveForecastTime)
+        {
+          long offset = gribGetLongDefault(gh, "forecastTime", 0);  //if(stepUnits == indicatorOfUnitOfTimeRange) assert(startStep == forecastTime)
+          long offsetUnit = gribGetLongDefault(gh, "indicatorOfUnitOfTimeRange", 255);
+          if(addToDate(&date, offset, offsetUnit)) return NULL;
+          if(getEndTime)
+            {
+              assert(haveTimeRange);
+              long range = gribGetLongDefault(gh, "lengthOfTimeRange", 0);       //if(stepUnits == indicatorOfUnitForTimeRange) assert(endStep == startStep + lengthOfTimeRange)
+              long rangeUnit = gribGetLongDefault(gh, "indicatorOfUnitForTimeRange", 255);
+              if(addToDate(&date, range, rangeUnit)) return NULL;
+            }
+        }
+    }
+
+  //Bake the date into a string.
+  return makeDateString(&date);
+}
+
+int gribapiTimeIsFC(grib_handle *gh)
+{
+  if(gribEditionNumber(gh) <= 1) return true;
+
+  long sigofrtime;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
+  return sigofrtime != 3;
+}
+
+//Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
+int gribapiGetTsteptype(grib_handle *gh)
+{
+  int tsteptype = TSTEP_INSTANT;
+  static bool lprint = true;
+
+  if ( gribapiTimeIsFC(gh) )
+    {
+      int status;
+      size_t len = 256;
+      char stepType[256];
+
+      status = grib_get_string(gh, "stepType", stepType, &len);
+      if ( status == 0 && len > 1 && len < 256 )
+        {
+          if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
+          else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
+          else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
+          else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
+          else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
+          else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
+          else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
+          else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
+          else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
+          else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
+          else if ( lprint )
+            {
+              Message("Time stepType %s unsupported, set to instant!", stepType);
+              lprint = false;
+            }
+
+          // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
+        }
+    }
+
+  return (tsteptype);
+}
+
+int gribGetDatatype(grib_handle* gribHandle)
+{
+  int datatype;
+  if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
+    {
+      datatype = gribCheckLong(gribHandle, "precision", 1) ? DATATYPE_FLT32 : DATATYPE_FLT64;
+    }
+  else
+    {
+      long bitsPerValue;
+      datatype = (!grib_get_long(gribHandle, "bitsPerValue", &bitsPerValue) && bitsPerValue > 0 && bitsPerValue <= 32) ? (int)bitsPerValue : DATATYPE_PACK;
+    }
+  return datatype;
+}
+
+int gribapiGetParam(grib_handle *gh)
+{
+  long pdis, pcat, pnum;
+  if ( gribEditionNumber(gh) <= 1 )
+    {
+      pdis = 255;
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "table2Version", &pcat);
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "indicatorOfParameter", &pnum);
+    }
+  else
+    {
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "discipline", &pdis);
+      if(grib_get_long(gh, "parameterCategory", &pcat)) pcat = 0;
+      if(grib_get_long(gh, "parameterNumber", &pnum)) pnum = 0;
+    }
+  return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
+}
+
+int gribapiGetGridType(grib_handle *gh)
+{
+  int gridtype = GRID_GENERIC;
+  switch (gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1))
+    {
+      case  GRIB2_GTYPE_LATLON:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GENERIC : GRID_LONLAT;
+        break;
+
+      case  GRIB2_GTYPE_GAUSSIAN:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN;
+        break;
+
+      case GRIB2_GTYPE_LATLON_ROT:   gridtype = GRID_LONLAT; break;
+      case GRIB2_GTYPE_LCC:          gridtype = GRID_LCC; break;
+      case GRIB2_GTYPE_SPECTRAL:     gridtype = GRID_SPECTRAL; break;
+      case GRIB2_GTYPE_GME:          gridtype = GRID_GME; break;
+      case GRIB2_GTYPE_UNSTRUCTURED: gridtype = GRID_UNSTRUCTURED; break;
+    }
+
+  return gridtype;
+}
+
+static
+int gribapiGetIsRotated(grib_handle *gh)
+{
+  return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
+}
+
+//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
+void gribapiGetGrid(grib_handle *gh, grid_t *grid)
+{
+  long editionNumber = gribEditionNumber(gh);
+  int gridtype = gribapiGetGridType(gh);
+  /*
+  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
+    {
+      gridtype = GRID_GAUSSIAN;
+      ISEC2_NumLon = 2*ISEC2_NumLat;
+      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
+    }
+  */
+  memset(grid, 0, sizeof(grid_t));
+
+  size_t datasize;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
+  long numberOfPoints;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
+
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+      {
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlon = (int)lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
+
+        if ( gridtype == GRID_GAUSSIAN )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+            grid->np = (int)lpar;
+          }
+
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
+        grid->xinc  = 0;
+        grid->yinc  = 0;
+        grid->xdef  = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+        if ( gridtype == GRID_LONLAT )
+          FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->yinc);
+
+        if ( grid->xinc < -999 || grid->xinc > 999 ) grid->xinc = 0;
+        if ( grid->yinc < -999 || grid->yinc > 999 ) grid->yinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
+
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_GAUSSIAN_REDUCED:
+      {
+        size_t dummy;
+        long *pl;
+
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        grid->np = (int)lpar;
+
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size   = (int)numberOfPoints;
+
+        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
+        pl          = (long *) malloc((size_t)nlat * sizeof (long));
+        dummy       = (size_t)nlat;
+        FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
+        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
+        for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
+        free(pl);
+
+        grid->ysize  = nlat;
+        grid->xinc   = 0;
+        grid->yinc   = 0;
+        grid->xdef   = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+
+        if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
+
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef  = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_LCC:
+      {
+        int nlon, nlat;
+        long lpar;
+
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
+        nlon = lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
+        nlat = lpar;
+
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+
+        grid->size  = numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
+
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &grid->lcc_xinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &grid->lcc_yinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "LoVInDegrees", &grid->lcc_lonParY);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin1InDegrees", &grid->lcc_lat1);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin2InDegrees", &grid->lcc_lat2);
+
+        if ( editionNumber <= 1 )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "projectionCenterFlag", &lpar);
+            grid->lcc_projflag  = (int) lpar;
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "scanningMode", &lpar);
+            grid->lcc_scanflag  = (int) lpar;
+          }
+
+        grid->xdef   = 0;
+        grid->ydef   = 0;
+
+        break;
+      }
+    case GRID_SPECTRAL:
+      {
+        size_t len = 256;
+        char typeOfPacking[256];
+        FAIL_ON_GRIB_ERROR(grib_get_string, gh, "packingType", typeOfPacking, &len);
+        grid->lcomplex = 0;
+        if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
+
+        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
+        grid->size  = (int)datasize;
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        grid->trunc = (int)lpar;
+
+        break;
+      }
+    case GRID_GME:
+      {
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        long lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
+
+        break;
+      }
+    case GRID_UNSTRUCTURED:
+      {
+        unsigned char uuid[CDI_UUID_SIZE];
+        /*
+        char reference_link[8192];
+        size_t len = sizeof(reference_link);
+        reference_link[0] = 0;
+        */
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+            grid->size  = (int)numberOfPoints;
+        long lpar;
+        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+          {
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            grid->number   = (int)lpar;
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
+              grid->position = (int)lpar;
+            /*
+            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+              {
+                if ( strncmp(reference_link, "file://", 7) == 0 )
+                  grid->reference = strdupx(reference_link);
+              }
+            */
+            size_t len = (size_t)CDI_UUID_SIZE;
+            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
+              {
+                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
+              }
+          }
+        break;
+      }
+    case GRID_GENERIC:
+      {
+        int nlon = 0, nlat = 0;
+        long lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+
+        if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
+          {
+            grid->xsize = nlon;
+            grid->ysize = nlat;
+          }
+        else
+          {
+            grid->xsize = 0;
+            grid->ysize = 0;
+          }
+
+        break;
+      }
+    default:
+      {
+        Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+        break;
+      }
+    }
+
+  grid->isRotated = FALSE;
+  if ( gribapiGetIsRotated(gh) )
+    {
+      grid->isRotated = TRUE;
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "angleOfRotation", &grid->angle);
+      /* change from south to north pole */
+      grid->ypole = -grid->ypole;
+      grid->xpole =  grid->xpole - 180;
+    }
+
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  grid->type  = gridtype;
+}
+#endif
diff --git a/libcdi/src/gribapi_utilities.h b/libcdi/src/gribapi_utilities.h
new file mode 100644
index 0000000..6c76723
--- /dev/null
+++ b/libcdi/src/gribapi_utilities.h
@@ -0,0 +1,37 @@
+#ifndef INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+#define INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+
+#ifdef HAVE_LIBGRIB_API
+
+#include "grid.h"
+
+#include <grib_api.h>
+
+#include <stdbool.h>
+
+char* gribCopyString(grib_handle* gribHandle, const char* key);
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue);
+
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue);
+long gribGetLong(grib_handle* gh, const char* key);
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue);
+
+double gribGetDouble(grib_handle* gh, const char* key);
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue);
+
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key);
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array);       //The caller is responsible to ensure a sufficiently large buffer.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array);   //The caller is responsible to ensure a sufficiently large buffer.
+
+long gribEditionNumber(grib_handle* gh);
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime);     //For statistical fields, setting getEndTime produces the time of the end of the integration period, otherwise the time of the start of the integration period is returned. Returns NULL if getEndTime is set and the field does not have an integration period.
+int gribapiTimeIsFC(grib_handle *gh);
+int gribapiGetTsteptype(grib_handle *gh);
+int gribGetDatatype(grib_handle* gribHandle);
+int gribapiGetParam(grib_handle *gh);
+int gribapiGetGridType(grib_handle *gh);
+void gribapiGetGrid(grib_handle *gh, grid_t *grid);
+
+#endif
+
+#endif
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index 704348d..3c5acdd 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -56,7 +56,7 @@ static void   gridPack        ( void * gridptr, void * buff, int size,
 				int *position, void *context);
 static int    gridTxCode      ( void );
 
-static const resOps gridOps = {
+const resOps gridOps = {
   gridCompareP,
   gridDestroyP,
   gridPrintP,
@@ -201,9 +201,9 @@ void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
   gridptr2->self = gridID2;
 }
 
-int gridSize(void)
+unsigned cdiGridCount(void)
 {
-  return reshCountType ( &gridOps );
+  return reshCountType(&gridOps);
 }
 
 // used also in CDO
@@ -999,11 +999,12 @@ void gridDefXsize(int gridID, int xsize)
 {
   grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( xsize > gridInqSize(gridID) )
-    Error("xsize %d is greater then gridsize %d", xsize, gridInqSize(gridID));
+  int gridSize = gridInqSize(gridID);
+  if ( xsize > gridSize )
+    Error("xsize %d is greater then gridsize %d", xsize, gridSize);
 
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridInqSize(gridID) )
-    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridInqSize(gridID));
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridSize )
+    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
 
   if (gridptr->xsize != xsize)
     {
@@ -1013,10 +1014,10 @@ void gridDefXsize(int gridID, int xsize)
 
   if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
     {
-      long gridsize = gridptr->xsize*gridptr->ysize;
-      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
+      long axisproduct = gridptr->xsize*gridptr->ysize;
+      if ( axisproduct > 0 && axisproduct != gridSize )
         Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
+              gridptr->xsize, gridptr->ysize, gridSize);
     }
 }
 
@@ -1099,11 +1100,13 @@ void gridDefYsize(int gridID, int ysize)
 {
   grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( ysize > gridInqSize(gridID) )
-    Error("ysize %d is greater then gridsize %d", ysize, gridInqSize(gridID));
+  int gridSize = gridInqSize(gridID);
 
-  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridInqSize(gridID) )
-    Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridInqSize(gridID));
+  if ( ysize > gridSize )
+    Error("ysize %d is greater then gridsize %d", ysize, gridSize);
+
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridSize )
+    Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridSize);
 
   if (gridptr->ysize != ysize)
     {
@@ -1113,10 +1116,10 @@ void gridDefYsize(int gridID, int ysize)
 
   if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
     {
-      long gridsize = gridptr->xsize*gridptr->ysize;
-      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
+      long axisproduct = gridptr->xsize*gridptr->ysize;
+      if ( axisproduct > 0 && axisproduct != gridSize )
         Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
+              gridptr->xsize, gridptr->ysize, gridSize);
     }
 }
 
@@ -3020,14 +3023,11 @@ const double *gridInqYboundsPtr(int gridID)
 }
 
 
-void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
+void gridPrintKernel(grid_t * gridptr, int index, int opt, FILE *fp)
 {
-  int type;
-  int gridsize, xsize, ysize, xdim, ydim;
-  int trunc;
-  int nbyte0, nbyte;
-  int i;
-  int nvertex, iv;
+  int xdim, ydim;
+  int nbyte;
+  int i, iv;
   unsigned char uuidOfHGrid[CDI_UUID_SIZE];
   int gridID = gridptr->self;
   const double *area    = gridInqAreaPtr(gridID);
@@ -3036,16 +3036,16 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
   const double *xbounds = gridInqXboundsPtr(gridID);
   const double *ybounds = gridInqYboundsPtr(gridID);
 
-  type     = gridInqType(gridID);
-  trunc    = gridInqTrunc(gridID);
-  gridsize = gridInqSize(gridID);
-  xsize    = gridInqXsize(gridID);
-  ysize    = gridInqYsize(gridID);
-  nvertex  = gridInqNvertex(gridID);
+  int type     = gridInqType(gridID);
+  int trunc    = gridInqTrunc(gridID);
+  int gridsize = gridInqSize(gridID);
+  int xsize    = gridInqXsize(gridID);
+  int ysize    = gridInqYsize(gridID);
+  int nvertex  = gridInqNvertex(gridID);
 
-  nbyte0 = 0;
+  int nbyte0 = 0;
   fprintf(fp, "#\n");
-  fprintf(fp, "# gridID %d\n", gridID);
+  fprintf(fp, "# gridID %d\n", index);
   fprintf(fp, "#\n");
   fprintf(fp, "gridtype  = %s\n", gridNamePtr(type));
   fprintf(fp, "gridsize  = %d\n", gridsize);
@@ -3152,7 +3152,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 	  {
 	    if ( xsize > 0 ) fprintf(fp, "xnpole    = %g\n", gridptr->xpole);
 	    if ( ysize > 0 ) fprintf(fp, "ynpole    = %g\n", gridptr->ypole);
-	    if ( gridptr->angle > 0 ) fprintf(fp, "angle     = %g\n", gridptr->angle);
+	    if ( IS_NOT_EQUAL(gridptr->angle, 0) ) fprintf(fp, "angle     = %g\n", gridptr->angle);
  	  }
 
 	if ( xvals )
@@ -3364,11 +3364,11 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
     }
 }
 
-void gridPrint ( int gridID, int opt )
+void gridPrint ( int gridID, int index, int opt )
 {
   grid_t *gridptr = gridID2Ptr(gridID);
 
-  gridPrintKernel ( gridptr, opt, stdout );
+  gridPrintKernel ( gridptr, index, opt, stdout );
 }
 
 
@@ -3380,7 +3380,7 @@ void gridPrintP ( void * voidptr, FILE * fp )
 
   xassert ( gridptr );
 
-  gridPrintKernel ( gridptr , 0, fp );
+  gridPrintKernel ( gridptr , gridptr->self, 0, fp );
 
   fprintf ( fp, "precision = %d\n", gridptr->prec);
   fprintf ( fp, "nd        = %d\n", gridptr->nd );
@@ -3860,9 +3860,9 @@ void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
 }
 
 
-void gridGetIndexList ( int ngrids, int * gridIndexList )
+void cdiGridGetIndexList(unsigned ngrids, int * gridIndexList)
 {
-  reshGetResHListOfType ( ngrids, gridIndexList, &gridOps );
+  reshGetResHListOfType(ngrids, gridIndexList, &gridOps);
 }
 
 
diff --git a/libcdi/src/grid.h b/libcdi/src/grid.h
index b859434..cd30879 100644
--- a/libcdi/src/grid.h
+++ b/libcdi/src/grid.h
@@ -2,6 +2,9 @@
 #define _GRID_H
 
 #include "cdi.h"
+#ifndef RESOURCE_HANDLE_H
+#include "resource_handle.h"
+#endif
 
 typedef unsigned char mask_t;
 
@@ -76,7 +79,7 @@ grid_t;
 void grid_init(grid_t *gridptr);
 void grid_free(grid_t *gridptr);
 
-int gridSize(void);
+unsigned cdiGridCount(void);
 
 const double *gridInqXvalsPtr(int gridID);
 const double *gridInqYvalsPtr(int gridID);
@@ -88,13 +91,15 @@ const double *gridInqAreaPtr(int gridID);
 int gridCompare(int gridID, const grid_t *grid);
 int gridGenerate(const grid_t *grid);
 
-void gridGetIndexList( int, int * );
+void cdiGridGetIndexList(unsigned, int * );
 
 void
 gridUnpack(char * unpackBuffer, int unpackBufferSize,
            int * unpackBufferPos, int originNamespace, void *context,
            int force_id);
 
+extern const resOps gridOps;
+
 #endif
 /*
  * Local Variables:
diff --git a/libcdi/src/input_file.c b/libcdi/src/input_file.c
new file mode 100644
index 0000000..5d1e36f
--- /dev/null
+++ b/libcdi/src/input_file.c
@@ -0,0 +1,141 @@
+#include "input_file.h"
+
+#include "cdi.h"
+#include "dmemory.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+static void cdiInputFile_destruct(CdiInputFile* me);
+
+//For an explanation of the condestruct() pattern, see the comment in iterator_grib.c
+//path != NULL -> construction
+//path = NULL -> destruction
+static CdiInputFile* cdiInputFile_condestruct(CdiInputFile* me, const char* path)
+{
+  #define super() (&me->super)
+  if(!path) goto destruct;
+  cdiRefObject_construct(super());
+  me->path = myStrDup(path);
+  if(!me->path) goto destructSuper;
+  do
+    {
+      me->fileDescriptor = open(me->path, O_RDONLY);
+    }
+  while(me->fileDescriptor == -1 && (errno == EINTR || errno == EAGAIN));
+  if(me->fileDescriptor == -1) goto freePath;
+  //construction successfull, now we can set our own destructor
+  super()->destructor = (void(*)(CdiReferencedObject*))cdiInputFile_destruct;
+  goto success;
+
+// ^        constructor code       ^
+// |                               |
+// v destructor/error-cleanup code v
+
+destruct:
+  close(me->fileDescriptor);
+freePath:
+  free(me->path);
+destructSuper:
+  cdiRefObject_destruct(super());
+  me = NULL;
+
+success:
+  return me;
+  #undef super
+}
+
+static CdiInputFile** openFileList = NULL;
+static size_t openFileCount = 0, openFileListSize = 0;
+static pthread_mutex_t openFileListLock = PTHREAD_MUTEX_INITIALIZER;
+
+//This either returns a new object, or retains and returns a preexisting open file.
+CdiInputFile* cdiInputFile_make(const char* path)
+{
+  CdiInputFile* result = NULL;
+  xassert(path);
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
+    {
+      //Check the list of open files for the given path.
+      for(size_t i = openFileCount; i-- && !result; )
+        {
+          if(!strcmp(path, openFileList[i]->path)) result = openFileList[i];
+        }
+      //If no open file was found, we open one, otherwise we just retain the existing one one more time.
+      if(result)
+        {
+          cdiRefObject_retain(&result->super);
+        }
+      else
+        {
+          result = xmalloc(sizeof(*result));
+          if(!cdiInputFile_condestruct(result, path))
+            {
+              //An error occured during construction, avoid a memory leak.
+              free(result);
+              result = NULL;
+            }
+          else
+            {
+              //Add the new file to the list of open files.
+              if(openFileCount == openFileListSize)
+                {
+                  openFileListSize *= 2;
+                  if(openFileListSize < 16) openFileListSize = 16;
+                  openFileList = xrealloc(openFileList, openFileListSize);
+                }
+              xassert(openFileCount < openFileListSize);
+              openFileList[openFileCount++] = result;
+            }
+        }
+    }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  return result;
+}
+
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer)
+{
+  char* byteBuffer = buffer;
+  size_t trash;
+  if(!outActualReadSize) outActualReadSize = &trash;
+  *outActualReadSize = 0;
+  while(readSize)
+    {
+      ssize_t bytesRead = pread(me->fileDescriptor, byteBuffer, readSize, readPosition);
+      if(bytesRead == -1) return (errno == EINVAL) ?  CDI_EINVAL : CDI_ESYSTEM;
+      if(bytesRead == 0) return CDI_EEOF;
+      byteBuffer += bytesRead;
+      readPosition += bytesRead;
+      readSize -= bytesRead;
+      *outActualReadSize += bytesRead;
+    }
+  return CDI_NOERR;
+}
+
+char* cdiInputFile_copyPath(const CdiInputFile* me)
+{
+  return myStrDup(me->path);
+}
+
+void cdiInputFile_destruct(CdiInputFile* me)
+{
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
+    {
+      //Find the position of me in the list of open files.
+      ssize_t position;
+      for(position = openFileCount; position--; ) if(openFileList[position] == me) break;
+      xassert(position != -1);
+      //Remove me from the list
+      openFileList[position] = openFileList[--openFileCount];
+    }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  cdiInputFile_condestruct(me, NULL);
+}
diff --git a/libcdi/src/input_file.h b/libcdi/src/input_file.h
new file mode 100644
index 0000000..ab3c8d3
--- /dev/null
+++ b/libcdi/src/input_file.h
@@ -0,0 +1,27 @@
+#ifndef INCLUDE_GUARD_CDI_GRIB_FILE_H
+#define INCLUDE_GUARD_CDI_GRIB_FILE_H
+
+#include "referenceCounting.h"
+
+/*
+CdiInputFile is a file abstraction that allows accessing an input file through any number of channels:
+It is reference counted, so that it is closed at the right place,
+and it is stateless, so that accesses from different callers cannot interfere with each other.
+Once the reference counting code is threadsafe, CdiInputFile will also be threadsafe.
+*/
+typedef struct CdiInputFile {
+  //public:
+    CdiReferencedObject super;
+
+  //private:
+    char* path;
+    int fileDescriptor;
+} CdiInputFile;
+
+//Final class, the constructor is private and not defined here.
+CdiInputFile* cdiInputFile_make(const char* path);   //The caller is responsible to call cdiRefObject_release() on the returned object.
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer);       //Returns one of CDI_EINVAL, CDI_ESYSTEM, CDI_EEOF, OR CDI_NOERR.
+char* cdiInputFile_copyPath(const CdiInputFile* me);    //Returns a malloc'ed string, don't forget to free() it.
+//Destructor is private as well.
+
+#endif
diff --git a/libcdi/src/institution.c b/libcdi/src/institution.c
index fcbef8d..b4cdadb 100644
--- a/libcdi/src/institution.c
+++ b/libcdi/src/institution.c
@@ -88,12 +88,6 @@ void instituteDefaultEntries ( void )
 }
 
 
-int instituteCount ( void )
-{
-  return reshCountType ( &instituteOps );
-}
-
-
 static int
 instituteCompareKernel(institute_t *  ip1, institute_t * ip2)
 {
@@ -238,7 +232,7 @@ const char *institutInqNamePtr(int instID)
 }
 
 
-char *institutInqLongnamePtr(int instID)
+const char *institutInqLongnamePtr(int instID)
 {
   institute_t * instituteptr = NULL;
 
diff --git a/libcdi/src/iterator.c b/libcdi/src/iterator.c
new file mode 100644
index 0000000..2b431fd
--- /dev/null
+++ b/libcdi/src/iterator.c
@@ -0,0 +1,965 @@
+#include "cdi.h"
+#include "iterator.h"
+#include "iterator_fallback.h"
+#include "iterator_grib.h"
+#include "cdi_int.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <assert.h>
+#include <ctype.h>
+
+const char* const kUnexpectedFileTypeMessage = "Internal error: Unexpected file type encountered in iterator.\nThis is either due to an illegal memory access by the application or an internal logical error in CDI (unlikely, but possible).";
+const char* const kAdvancedString = "advanced";
+const char* const kUnadvancedString = "unadvanced";
+
+//Returns a static string.
+static const char* fileType2String(int fileType)
+{
+  switch(fileType)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB: return "CDI::Iterator::GRIB1";
+        case FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
+      #endif
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC: return "CDI::Iterator::NetCDF";
+        case FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
+        case FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
+        case FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV: return "CDI::Iterator::SRV";
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT: return "CDI::Iterator::EXT";
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG: return "CDI::Iterator::IEG";
+      #endif
+
+      default: return NULL;
+    }
+}
+
+static int string2FileType(const char* fileType, const char** outRestString)
+{
+  //This first part unconditionally checks all known type strings, and only if the given string matches one of these strings, we use fileType2string() to check whether support for this type has been compiled in. This is to avoid throwing "invalid type string" errors when we just have a library version mismatch.
+  #define check(givenString, typeString, typeConstant) do \
+    { \
+      if(givenString == strstr(givenString, typeString)) \
+        { \
+          if(outRestString) *outRestString = givenString + strlen(typeString); \
+          if(fileType2String(typeConstant)) return typeConstant; \
+          Error("Support for " typeString " not compiled in. Please check that the result of `cdiIterator_serialize()` is only passed to a `cdiIterator_deserialize()` implementation of the same CDI library version."); \
+          return FILETYPE_UNDEF; \
+        } \
+    } while(0)
+  check(fileType, "CDI::Iterator::GRIB1", FILETYPE_GRB);
+  check(fileType, "CDI::Iterator::GRIB2", FILETYPE_GRB2);
+  check(fileType, "CDI::Iterator::NetCDF", FILETYPE_NC);
+  check(fileType, "CDI::Iterator::NetCDF2", FILETYPE_NC2);
+  check(fileType, "CDI::Iterator::NetCDF4", FILETYPE_NC4);
+  check(fileType, "CDI::Iterator::NetCDF4C", FILETYPE_NC4C);
+  check(fileType, "CDI::Iterator::SRV", FILETYPE_SRV);
+  check(fileType, "CDI::Iterator::EXT", FILETYPE_EXT);
+  check(fileType, "CDI::Iterator::IEG", FILETYPE_IEG);
+  #undef check
+
+  //If this point is reached, the given string does not seem to be produced by a cdiIterator_serialize() call.
+  Error("The string \"%s\" does not start with a valid iterator type. Please check the source of this string.", fileType);
+  *outRestString = fileType;
+  return FILETYPE_UNDEF;
+}
+
+/**
+ at Function cdiIterator_new
+ at Title Create an iterator for an input file
+
+ at Prototype CdiIterator* cdiIterator_new(const char* path)
+ at Parameter
+    @item path Path to the file that is to be read.
+
+ at Result An iterator for the given file.
+
+ at Description
+    Combined allocator and constructor for CdiIterator.
+
+    The returned iterator does not point to the first field yet,
+    it must first be advanced once before the first field can be introspected.
+    This design decision has two benefits: 1. Empty files require no special
+    cases, 2. Users can start a while(!cdiIterator_nextField(iterator)) loop
+    right after the call to cdiIterator_new().
+*/
+CdiIterator* cdiIterator_new(const char* path)
+{
+  int trash;
+  int filetype = cdiGetFiletype(path, &trash);
+  switch(filetype)
+    {
+      case FILETYPE_UNDEF:
+        Warning("Can't open file \"%s\": unknown format\n", path);
+        return NULL;
+
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_new(path, filetype);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_new(path, filetype);
+
+      default:
+        Warning("the file \"%s\" is of type %s, but support for this format is not compiled in!", path, strfiletype(filetype));
+        return NULL;
+    }
+}
+
+void baseIterConstruct(CdiIterator* me, int filetype)
+{
+  me->filetype = filetype;
+  me->isAdvanced = false;
+}
+
+const char* baseIter_constructFromString(CdiIterator* me, const char* description)
+{
+  const char* result = description;
+  me->filetype = string2FileType(result, &result);
+  assert(me->filetype != FILETYPE_UNDEF && "Please report this error.");        //This condition should have been checked for in a calling function.
+  for(; *result && isspace(*result); result++);
+  if(result == strstr(result, kAdvancedString))
+    {
+      me->isAdvanced = true;
+      result += strlen(kAdvancedString);
+    }
+  else if(result == strstr(result, kUnadvancedString))
+    {
+      me->isAdvanced = false;
+      result += strlen(kUnadvancedString);
+    }
+  else
+    {
+      Error("Invalid iterator description string \"%s\". Please check the origin of this string.", description);
+      return NULL;
+    }
+  return result;
+}
+
+#define sanityCheck(me) do { \
+    if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+    if(!me->isAdvanced) xabort("Calling %s is not allowed without calling cdiIterator_nextField() first.", __func__); \
+} while(0)
+
+/**
+ at Function cdiIterator_clone
+ at Title Make a copy of an iterator
+
+ at Prototype CdiIterator* cdiIterator_clone(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to copy.
+
+ at Result The clone.
+
+ at Description
+    Clones the given iterator. Make sure to call cdiIterator_delete() on both
+    the copy and the original.
+
+    This is not a cheap operation: Depending on the type of the file, it will
+    either make a copy of the current field in memory (GRIB files), or reopen
+    the file (all other file types). Use it sparingly. And if you do, try to
+    avoid keeping too many clones around: their memory footprint is
+    significant.
+*/
+CdiIterator* cdiIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_clone(me)->super;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_clone(me)->super;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+ at Function cdiGribIterator_clone
+ at Title Gain access to GRIB specific functionality
+
+ at Prototype CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A clone that allows access to GRIB specific functionality, or NULL if the underlying file is not a GRIB file.
+
+ at Description
+    Clones the given iterator iff the underlying file is a GRIB file, the returned iterator allows access to GRIB specific functionality.
+    Make sure to check that the return value is not NULL, and to call cdiGribIterator_delete() on the copy.
+
+    This is not a cheap operation: It will make a copy of the current field in memory. Use it sparingly. And if you do, try to avoid keeping too many clones around, their memory footprint is significant.
+*/
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_makeClone(me);
+      #endif
+
+      default:
+        return NULL;
+    }
+}
+
+/**
+ at Function cdiIterator_serialize
+ at Title Serialize an iterator for sending it to another process
+
+ at Prototype char* cdiIterator_serialize(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string that contains the full description of the iterator.
+
+ at Description
+    Make sure to call free() on the resulting string.
+*/
+char* cdiIterator_serialize(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+  char* subclassDescription = NULL;
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          subclassDescription = cdiGribIterator_serialize(me);
+          break;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          subclassDescription = cdiFallbackIterator_serialize(me);
+          break;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+
+  char* result = myAsprintf("%s %s %s", fileType2String(me->filetype), (me->isAdvanced ? kAdvancedString : kUnadvancedString), subclassDescription);
+  free(subclassDescription);
+  return result;
+}
+
+/**
+ at Function cdiIterator_deserialize
+ at Title Recreate an iterator from its textual description
+
+ at Prototype CdiIterator* cdiIterator_deserialize(const char* description)
+ at Parameter
+    @item description The result of a call to cdiIterator_serialize().
+
+ at Result A clone of the original iterator.
+
+ at Description
+    A pair of cdiIterator_serialize() and cdiIterator_deserialize() is functionally equivalent to a call to cdiIterator_clone()
+
+    This function will reread the current field from disk, so don't expect immediate return.
+*/
+//This only checks the type of the iterator and calls the corresponding subclass function,
+//the real deserialization is done in baseIter_constructFromString().
+CdiIterator* cdiIterator_deserialize(const char* description)
+{
+  switch(string2FileType(description, NULL))
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_deserialize(description)->super;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_deserialize(description)->super;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+
+/**
+ at Function cdiIterator_print
+ at Title Print a textual description of the iterator to a stream
+
+ at Prototype void cdiIterator_print(CdiIterator* iterator, FILE* stream);
+ at Parameter
+    @item iterator The iterator to print.
+    @item stream The stream to print to.
+
+ at Description
+    Use for debugging output.
+*/
+void cdiIterator_print(CdiIterator* me, FILE* stream)
+{
+  char* description = cdiIterator_serialize(me);
+  fprintf(stream, "%s\n", description);
+  free(description);
+}
+
+
+/**
+ at Function cdiIterator_nextField
+ at Title Advance an iterator to the next field in the file
+
+ at Prototype int cdiIterator_nextField(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result An error code. May be one of:
+  * CDI_NOERR: The iterator has successfully been advanced to the next field.
+  * CDI_EEOF: No more fields to read in this file.
+
+ at Description
+    One call to cdiIterator_nextField() is required before the metadata of the first field can be examined.
+    Usually, it will be used directly as the condition for a while() loop.
+*/
+int cdiIterator_nextField(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  me->isAdvanced = true;
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_nextField(me);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_nextField(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
+    }
+}
+
+static char* cdiIterator_inqTime(CdiIterator* me, bool getEndTime)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_inqTime(me, getEndTime);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_inqTime(me, getEndTime);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+ at Function cdiIterator_inqStartTime
+ at Title Get the start time of a measurement
+
+ at Prototype char* cdiIterator_inqStartTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string containing the (start) time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+
+ at Description
+The returned time is either the time of the data (fields defined at a time point),
+or the start time of an integration time range (statistical fields).
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqStartTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, false);
+}
+
+/**
+ at Function cdiIterator_inqEndTime
+ at Title Get the end time of a measurement
+
+ at Prototype char* cdiIterator_inqEndTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string containing the end time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm", or NULL if no such time is defined.
+
+ at Description
+The returned time is the end time of an integration period if such a time exists (statistical fields).
+Otherwise, NULL is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqEndTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, true);
+}
+
+/**
+ at Function cdiIterator_inqVTime
+ at Title Get the validity time of the current field
+
+ at Prototype char* cdiIterator_inqVTime(CdiIterator* me)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+
+ at Description
+The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
+That is, if the field is a time point, its time is returned,
+if it is a statistical field with an integration period, the end time of the integration period is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqVTime(CdiIterator* me)
+{
+  char* result = cdiIterator_inqEndTime(me);
+  return (result) ? result : cdiIterator_inqStartTime(me);
+}
+
+/**
+ at Function cdiIterator_inqLevelType
+ at Title Get the type of a level
+
+ at Prototype int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName = NULL, char** outLongName = NULL, char** outStdName = NULL, char** outUnit = NULL)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outName Will be set to a malloc()'ed string with the name of the level if not NULL.
+    @item outLongName Will be set to a malloc()'ed string with the long name of the level if not NULL.
+    @item outStdName Will be set to a malloc()'ed string with the standard name of the level if not NULL.
+    @item outUnit Will be set to a malloc()'ed string with the unit of the level if not NULL.
+
+ at Result An integer indicating the type of the level.
+
+ at Description
+Find out some basic information about the given level, the levelSelector selects the function of the requested level.
+If the requested level does not exist, this returns CDI_UNDEFID.
+*/
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_UNDEFID;
+    }
+}
+
+/**
+ at Function cdiIterator_inqLevel
+ at Title Get the value of the z-coordinate
+
+ at Prototype void cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2 = NULL)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outValue1 For "normal" levels this returns the value, for hybrid levels the first coordinate, for generalized levels the level number.
+    @item outValue2 Zero for "normal" levels, for hybrid levels, this returns the second coordinate, for generalized levels the level count.
+
+ at Result An error code.
+
+ at Description
+Returns the value of the z-coordinate, whatever that may be.
+*/
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
+    }
+}
+
+/**
+ at Function cdiIterator_inqLevelUuid
+ at Title Get the UUID of the z-axis used by this field
+
+ at Prototype int cdiIterator_inqLevelUuid(CdiIterator* me, int levelSelector, unsigned char (*outUuid)[16])
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item outVgridNumber The number of the associated vertical grid description.
+    @item outLevelCount The number of levels in the associated vertical grid description.
+    @item outUuid A pointer to a user supplied buffer of 16 bytes to store the UUID in.
+
+ at Result An error code.
+
+ at Description
+Returns identifying information for the external z-axis description. May only be called for generalized levels.
+*/
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_ELIBNAVAIL;
+    }
+}
+
+/**
+ at Function cdiIterator_inqParam
+ at Title Get discipline, category, and number
+
+ at Prototype CdiParam cdiIterator_inqParam(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A struct containing the requested information.
+
+ at Description
+    Simple metadata inspection function.
+*/
+CdiParam cdiIterator_inqParam(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->param;
+}
+
+/**
+ at Function cdiIterator_inqDatatype
+ at Title Get the datatype of the current field
+
+ at Prototype int cdiIterator_inqDatatype(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result The datatype that is used to store this field on disk.
+
+ at Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqDatatype(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->datatype;
+}
+
+/**
+ at Function cdiIterator_inqTsteptype
+ at Title Get the timestep type
+
+ at Prototype int cdiIterator_inqTsteptype(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result The timestep type.
+
+ at Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqTsteptype(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->timesteptype;
+}
+
+/**
+ at Function cdiIterator_inqVariableName
+ at Title Get the variable name of the current field
+
+ at Prototype char* cdiIterator_inqVariableName(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A pointer to a C-string containing the name. The storage for this string is allocated with malloc(), and it is the responsibility of the caller to free() it.
+
+ at Description
+    Allocates a buffer to hold the string, copies the current variable name into this buffer, and returns the buffer.
+    The caller is responsible to make the corresponding free() call.
+*/
+char* cdiIterator_inqVariableName(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_copyVariableName(me);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_copyVariableName(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+ at Function cdiIterator_inqGridId
+ at Title Get the ID of the current grid
+
+ at Prototype int cdiIterator_inqGridId(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Result A gridId that can be used for further introspection.
+
+ at Description
+    This provides access to the grid related metadata.
+    The resulting ID is only valid until the next time cdiIterator_nextField() is called.
+*/
+int cdiIterator_inqGridId(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->gridId;
+}
+
+/**
+ at Function cdiIterator_readField
+ at Title Read the whole field into a double buffer
+
+ at Prototype void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+
+ at Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+{
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readField(me, buffer, nmiss);
+	  return;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readField(me, buffer, nmiss);
+          return;
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+/**
+ at Function cdiIterator_readFieldF
+ at Title Read the whole field into a double buffer
+
+ at Prototype void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+ at Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+
+ at Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+{
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readFieldF(me, buffer, nmiss);
+	  return;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readFieldF(me, buffer, nmiss);
+          return; 
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+/**
+ at Function cdiIterator_delete
+ at Title Destroy an iterator
+
+ at Prototype void cdiIterator_delete(CdiIterator* iterator)
+ at Parameter
+    @item iterator The iterator to operate on.
+
+ at Description
+    Combined destructor & deallocator.
+*/
+void cdiIterator_delete(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB_API
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_delete((CdiGribIterator*)me);
+          break;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_delete(me);
+          break;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+void baseIterDestruct(CdiIterator* me) { /*currently empty, but that's no reason not to call it*/ }
diff --git a/libcdi/src/iterator.h b/libcdi/src/iterator.h
new file mode 100644
index 0000000..a65ef37
--- /dev/null
+++ b/libcdi/src/iterator.h
@@ -0,0 +1,48 @@
+/*
+ * This file is for the use of iterator.c and the CdiIterator subclasses only.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_INT_H
+#define INCLUDE_GUARD_CDI_ITERATOR_INT_H
+
+#include "cdi.h"
+
+#include <stdbool.h>
+
+/*
+class CdiIterator
+
+An iterator is an object that identifies the position of one record in a file, where a record is defined as the data belonging to one level, timestep, and variable.
+Using iterators to read a file can be significantly faster than using streams, because they can avoid building an index of the file.
+For file formats like grib that do not provide an index within the file, this makes the difference between reading the file once or reading the file twice.
+
+CdiIterator is an abstract base class. Which derived class is used depends on the type of the file. The class hierarchy currently looks like this:
+
+    CdiIterator <|--+-- CdiFallbackIterator
+                    |
+                    +-- CdiGribIterator
+
+The fallback implementation currently uses the stream interface of CDI under the hood to provide full functionality for all filetypes for which no iterator implementation exists yet.
+*/
+//TODO[NH]: Debug messages, print function.
+
+struct CdiIterator {
+  int filetype;      //This is used to dispatch calls to the correct subclass.
+  bool isAdvanced;    //Used to catch inquiries before the first call to CdiIteratorNextField(). //XXX: Advanced is probably not a good word (initialized?)
+
+  //The metadata that can be accessed by the inquiry calls.
+  //While theoretically redundant, these fields allow the handling of most inquiry calls within the base class.
+  //Only the name is excempted because it needs an allocation.
+  //These fields are set by the subclasses in the xxxIterNextField() method.
+  int datatype, timesteptype;
+  int gridId;
+  CdiParam param;
+
+  //The status information for reading/advancing is added in the subclasses.
+};
+
+void baseIterConstruct(CdiIterator* me, int filetype);
+const char* baseIter_constructFromString(CdiIterator* me, const char* description);     //Returns a pointer past the end of the parsed portion of the description string.
+void baseIterDestruct(CdiIterator* me);
+
+#endif
diff --git a/libcdi/src/iterator_fallback.c b/libcdi/src/iterator_fallback.c
new file mode 100644
index 0000000..be0b6cf
--- /dev/null
+++ b/libcdi/src/iterator_fallback.c
@@ -0,0 +1,285 @@
+#include "iterator_fallback.h"
+
+#include "cdi.h"
+#include "cdi_int.h"
+#include "dmemory.h"
+#include "proprietarySystemWorkarounds.h"
+#include "vlist.h"      //Required for vlist_t, which we require because there is no safe function available to access a variable name.
+
+#include <assert.h>
+#include <stdlib.h>
+
+//For more information on the condestruct() pattern, see comment in src/iterator_grib.c
+static CdiFallbackIterator* cdiFallbackIterator_condestruct(CdiFallbackIterator* me, const char* path, int filetype)
+{
+  if(me) goto destruct;
+
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(&me->super, filetype);
+
+  me->streamId = streamOpenRead(path);
+  if(me->streamId == CDI_UNDEFID) goto destructSuper;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
+  me->variableCount = vlistNvars(me->vlistId);
+  if(me->variableCount <= 0) goto closeStream;
+  me->curLevelCount = -1;        //Will be set in cdiFallbackIterator_nextField()
+
+  //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
+  me->curTimestep = 0;
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  me->curVariable = 0;
+  me->curLevel = -1;
+  me->path = myStrDup(path);
+  if(!me->path) goto closeStream;
+
+  return me;
+
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
+
+destruct:
+  free(me->path);
+closeStream:
+  streamClose(me->streamId);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+  return NULL;
+}
+
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype)
+{
+  return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
+}
+
+//Fetches the info that is published by the variables in the base class from the current field.
+static void fetchSuperInfo(CdiFallbackIterator* me)
+{
+  me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
+  me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
+  me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
+  int param = vlistInqVarParam(me->vlistId, me->curVariable);
+  cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
+}
+
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+
+  //Make another stream for this file. This yields an unadvanced iterator.
+  CdiFallbackIterator* clone = cdiFallbackIterator_condestruct(NULL, me->path, me->super.filetype);
+  if(!clone) return NULL;
+
+  //Point the clone to the same position in the file.
+  clone->variableCount = me->variableCount;
+  clone->curVariable = me->curVariable;
+  clone->curLevelCount = me->curLevelCount;
+  clone->curLevel = me->curLevel;
+  clone->curTimestep = me->curTimestep;
+
+  clone->super.isAdvanced = super->isAdvanced;
+  if(super->isAdvanced) fetchSuperInfo(clone);
+
+  return clone;
+}
+
+char* cdiFallbackIterator_serialize(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+
+  char* escapedPath = cdiEscapeSpaces(me->path);
+  char* result = myAsprintf("%s %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curTimestep);
+  free(escapedPath);
+  return result;
+}
+
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* description)
+{
+  CdiFallbackIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
+
+  description = baseIter_constructFromString(&me->super, description);
+
+  while(*description == ' ') description++;
+  me->path = cdiUnescapeSpaces(description, &description);
+  if(!me->path) goto destructSuper;
+
+  me->streamId = streamOpenRead(me->path);
+  if(me->streamId == CDI_UNDEFID) goto freePath;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
+
+  //This reads one variable from the description string, does error checking, and advances the given string pointer.
+  #define decodeValue(variable, description) do \
+    { \
+      const char* savedStart = description; \
+      long long decodedValue = strtoll(description, (char**)&description, 0);   /*The cast is a workaround for the wrong signature of strtoll().*/ \
+      variable = (int)decodedValue; \
+      if(savedStart == description) goto closeStream; \
+      if((long long)decodedValue != (long long)variable) goto closeStream; \
+    } while(0)
+  decodeValue(me->variableCount, description);
+  decodeValue(me->curVariable, description);
+  decodeValue(me->curLevelCount, description);
+  decodeValue(me->curLevel, description);
+  decodeValue(me->curTimestep, description);
+  #undef decodeValue
+
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  if(me->super.isAdvanced) fetchSuperInfo(me);
+
+  return me;
+
+closeStream:
+  streamClose(me->streamId);
+freePath:
+  free(me->path);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
+
+static int advance(CdiFallbackIterator* me)
+{
+  me->curLevel++;
+  if(me->curLevel == me->curLevelCount)
+    {
+      me->curLevel = 0;
+      me->curVariable++;
+      if(me->curVariable == me->variableCount)
+        {
+          me->curVariable = 0;
+          me->curTimestep++;
+          if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiFallbackIterator_nextField(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int result = advance(me);
+  if(result) return result;
+
+  if(!me->curLevel)
+    { //Fetch the information that may have changed (we are processing a new variable/timestep if this point is reached).
+      fetchSuperInfo(me);
+      me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
+    }
+  return CDI_NOERR;
+}
+
+char* cdiFallbackIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  if(getEndTime) return NULL;   //The stream interface does not export the start/end times of statistical fields, so we treat all data as point of time data, returning the validity time as the start time.
+  int taxisId = vlistInqTaxis(me->vlistId);
+  int date = taxisInqVdate(taxisId);
+  int time = taxisInqVtime(taxisId);
+  int year, month, day, hour, minute, second;
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", year, month, day, hour, minute, second);
+}
+
+int cdiFallbackIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  #define copyString(outPointer, function) do \
+    { \
+      if(outPointer) \
+        { \
+          char tempBuffer[CDI_MAX_NAME]; \
+          function(zaxisId, tempBuffer); \
+          *outPointer = myStrDup(tempBuffer); \
+        } \
+    } \
+  while(0)
+  copyString(outName, zaxisInqName);    //FIXME: zaxisInqName is unsafe.
+  copyString(outLongName, zaxisInqLongname);    //FIXME: zaxisInqLongname is unsafe.
+  copyString(outStdName, zaxisInqStdname);    //FIXME: zaxisInqStdname is unsafe.
+  copyString(outUnit, zaxisInqUnits);    //FIXME: zaxisInqUnits is unsafe.
+  #undef copyString
+  return zaxisInqLtype(zaxisId);
+}
+
+int cdiFallbackIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+
+  //handle NULL pointers once and for all
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+
+  //get the level value
+  if(levelSelector)
+    {
+      *outValue1 = (zaxisInqLbounds(zaxisId, NULL))
+                 ? zaxisInqLbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
+    }
+  else
+    {
+      *outValue1 = (zaxisInqUbounds(zaxisId, NULL))
+                 ? zaxisInqUbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
+    }
+  *outValue2 = 0.0;
+
+  //if this is a hybrid zaxis, lookup the coordinates in the vertical coordinate table
+  ssize_t intLevel = (ssize_t)(2**outValue1);
+  if(0 <= intLevel && intLevel < zaxisInqVctSize(zaxisId) - 1)
+    {
+      const double* coordinateTable = zaxisInqVctPtr(zaxisId);
+      *outValue1 = coordinateTable[intLevel];
+      *outValue2 = coordinateTable[intLevel + 1];
+    }
+  return CDI_NOERR;
+}
+
+int cdiFallbackIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  if(zaxisInqLtype(zaxisId) != ZAXIS_HYBRID) return CDI_EINVAL;
+  if(outVgridNumber) *outVgridNumber = zaxisInqNumber(zaxisId);
+  if(outLevelCount) *outLevelCount = zaxisInqNlevRef(zaxisId);
+  if(outUuid) zaxisInqUUID(zaxisId, *outUuid);
+  return CDI_NOERR;
+}
+
+char* cdiFallbackIterator_copyVariableName(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  return vlistCopyVarName(me->vlistId, me->curVariable);
+}
+
+void cdiFallbackIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
+}
+
+void cdiFallbackIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
+}
+
+void cdiFallbackIterator_delete(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  cdiFallbackIterator_condestruct(me, NULL, 0);
+}
diff --git a/libcdi/src/iterator_fallback.h b/libcdi/src/iterator_fallback.h
new file mode 100644
index 0000000..1128746
--- /dev/null
+++ b/libcdi/src/iterator_fallback.h
@@ -0,0 +1,41 @@
+/*
+ * A fallback implementation of the iterator interface that opens a stream under the hood.
+ *
+ * This implementation is mainly available to provide iterator access to file formats that don't support iterator access natively,
+ * nevertheless, it allows the file to dictate the order in which data is read, possibly providing performance benefits.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+#define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+
+#include "iterator.h"
+
+typedef struct CdiFallbackIterator {
+  CdiIterator super;
+  int streamId, vlistId;
+  char* path;   //needed for clone() & serialize()
+
+  int variableCount, curVariable;
+  int curLevelCount, curLevel;
+  int curTimestep;
+} CdiFallbackIterator;
+
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype);
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* me);
+char* cdiFallbackIterator_serialize(CdiIterator* me);
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* me);
+
+int cdiFallbackIterator_nextField(CdiIterator* me);
+
+char* cdiFallbackIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiFallbackIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiFallbackIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiFallbackIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiFallbackIterator_copyVariableName(CdiIterator* me);
+
+void cdiFallbackIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiFallbackIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
+
+void cdiFallbackIterator_delete(CdiIterator* super);
+
+#endif
diff --git a/libcdi/src/iterator_grib.c b/libcdi/src/iterator_grib.c
new file mode 100644
index 0000000..02daeca
--- /dev/null
+++ b/libcdi/src/iterator_grib.c
@@ -0,0 +1,815 @@
+#include "iterator_grib.h"
+
+#include "cdi_int.h"
+#include "cgribex.h"
+#include "dmemory.h"
+#include "error.h"
+#include "gribapi.h"
+#include "gribapi_utilities.h"
+#include "proprietarySystemWorkarounds.h"
+#include "stream_grb.h"
+#include "zaxis.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#ifdef HAVE_LIBGRIB_API
+
+//Since the error handling in constructors is usually very closely related to the workings of a destructor,
+//this function combines both functions in one, using a centralized exit.
+//The mode of operation depends on whether me is a NULL pointer on entry:
+//If it is NULL, a new object is allocated and constructed, which is returned if construction is successful.
+//If a non-NULL pointer is passed in, the object is destructed and NULL is returned. In this case, the other arguments are ignored.
+static CdiGribIterator* cdiGribIterator_condestruct(CdiGribIterator* me, const char* path, int filetype)
+{
+  #define super() (&me->super)
+  if(me) goto destruct;
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(super(), filetype);
+
+  me->file = cdiInputFile_make(path);
+  if(!me->file) goto destructSuper;
+  me->fileOffset = 0;
+  me->gribHandle = NULL;
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->super.gridId = CDI_UNDEFID;
+
+  goto success;
+
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
+
+destruct:
+  if(me->super.gridId != CDI_UNDEFID) gridDestroy(me->super.gridId);
+  if(me->gribHandle) grib_handle_delete(me->gribHandle);
+  free(me->gribBuffer);
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(super());
+  free(me);
+  me = NULL;
+
+success:
+  return me;
+  #undef super
+}
+
+CdiIterator* cdiGribIterator_new(const char* path, int filetype)
+{
+  return &cdiGribIterator_condestruct(NULL, path, filetype)->super;
+}
+
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  //Allocate memory and copy data. (operations that may fail)
+  CdiGribIterator* result = xmalloc(sizeof(*result));
+  if(!result) goto fail;
+  *result = (CdiGribIterator)
+    {
+      .file = me->file,
+      .fileOffset = me->fileOffset,
+      .gribBuffer = NULL,
+      .bufferSize = me->bufferSize,
+      .curRecordSize = me->curRecordSize,
+      .gribHandle = NULL
+    };
+  if(me->gribBuffer)
+    {
+      result->gribBuffer = xmalloc(me->bufferSize);
+      if(!result->gribBuffer) goto freeResult;
+      memcpy(result->gribBuffer, me->gribBuffer, me->curRecordSize);
+    }
+  if(me->gribHandle)
+    {
+      result->gribHandle = grib_handle_new_from_message(NULL, result->gribBuffer, result->curRecordSize);
+      if(!result->gribHandle) goto freeBuffer;
+    }
+  if(super->gridId != CDI_UNDEFID)
+    {
+      result->super.gridId = gridDuplicate(super->gridId);
+      if(result->super.gridId == CDI_UNDEFID) goto deleteGribHandle;
+    }
+
+  //Finish construction. (operations that cannot fail)
+  baseIterConstruct(&result->super, super->filetype);
+  result->super.datatype = super->datatype;
+  result->super.timesteptype = super->timesteptype;
+  result->super.param = super->param;
+  cdiRefObject_retain(&result->file->super);
+
+  return result;
+
+  //Error handling.
+deleteGribHandle:
+  if(result->gribHandle) grib_handle_delete(result->gribHandle);
+freeBuffer:
+  free(result->gribBuffer);
+freeResult:
+  free(result);
+fail:
+  return NULL;
+}
+
+char* cdiGribIterator_serialize(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  char* path = cdiInputFile_copyPath(me->file);
+  char* escapedPath = cdiEscapeSpaces(path);
+  free(path);
+  char* result = myAsprintf("%s %zu", escapedPath, me->fileOffset);
+  free(escapedPath);
+  return result;
+}
+
+
+CdiGribIterator* cdiGribIterator_deserialize(const char* description)
+{
+  char* path;
+  CdiGribIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
+
+  description = baseIter_constructFromString(&me->super, description);
+
+  while(*description == ' ') description++;
+  path = cdiUnescapeSpaces(description, &description);
+  if(!path) goto destructSuper;
+
+  me->file = cdiInputFile_make(path);
+  free(path);
+  if(!me->file) goto destructSuper;
+
+  {
+    const char* savedStart = description;
+    long long decodedOffset = strtoll(description, (char**)&description, 0);    //The cast is a workaround for the wrong signature of strtoll() (it should have been `long long strtoll(const char*, const char**, int)`, not `long long strtoll(const char*, char**, int)`.
+    me->fileOffset = (off_t)decodedOffset;
+    if(savedStart == description) goto closeFile;
+    if((unsigned long long)decodedOffset > (unsigned long long)me->fileOffset) goto closeFile;
+  }
+
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->gribHandle = NULL;
+  me->super.gridId = CDI_UNDEFID;
+  if(me->super.isAdvanced && cdiGribIterator_nextField(&me->super)) goto closeFile;
+
+  return me;
+
+
+closeFile:
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
+#endif
+
+#ifdef HAVE_LIBGRIB_API
+static void cdiGribIterator_ensureBuffer(CdiGribIterator* me, size_t requiredSize)
+{
+  if(me->bufferSize < requiredSize)
+    {
+      me->bufferSize *= 2;
+      if(me->bufferSize < requiredSize) me->bufferSize = requiredSize;
+      me->gribBuffer = xrealloc(me->gribBuffer, me->bufferSize);
+    }
+}
+
+static bool isGrib1DualLevel(int levelType)
+{
+  switch(levelType)
+    {
+      case 101: case 104: case 106: case 108: case 110: case 112:
+      case 114: case 116: case 120: case 121: case 128: case 141:   //This is the complete list after grib_api-1.12.3/definitions/grib1/sections.1.def:106-117:, the code in cdi/src/stream_gribapi.c:grib1GetLevel() seems to be incomplete.
+        return true;
+      default:
+        return false;
+    }
+}
+
+static const unsigned char* positionOfGribMarker(const unsigned char* data, size_t size)
+{
+  for(const unsigned char* currentPosition = data, *end = data + size; currentPosition < end; currentPosition++)
+    {
+      currentPosition = memchr(currentPosition, 'G', size - (currentPosition - data) - 3);      //-3 to ensure that we don't overrun the buffer during the strncmp() call.
+      if(!currentPosition) return NULL;
+      if(!strncmp((const char*)currentPosition, "GRIB", 4)) return currentPosition;
+    }
+  return NULL;
+}
+
+//This clobbers the contents of the gribBuffer!
+//Returns the file offset of the next 'GRIB' marker.
+static ssize_t scanToGribMarker(CdiGribIterator* me)
+{
+  cdiGribIterator_ensureBuffer(me, 8*1024);
+  const size_t kMaxScanSize = 16*1024*1024;
+  for(size_t scannedBytes = 0, scanSize; scannedBytes < kMaxScanSize; scannedBytes += scanSize)
+    {
+      //Load a chunk of data into our buffer.
+      scanSize = me->bufferSize;
+      if(scannedBytes + scanSize > kMaxScanSize) scanSize = kMaxScanSize - scannedBytes;
+      assert(scanSize <= me->bufferSize);
+      int status = cdiInputFile_read(me->file, me->fileOffset + scannedBytes, scanSize, &scanSize, me->gribBuffer);
+      if(status != CDI_NOERR && status != CDI_EEOF) return status;
+
+      const unsigned char* startPosition = positionOfGribMarker(me->gribBuffer, scanSize);
+      if(startPosition)
+        {
+          return me->fileOffset + scannedBytes + (startPosition - me->gribBuffer);
+        }
+
+      //Get the offset for the next iteration if there is a next iteration.
+      scanSize -= 3;        //so that we won't miss a 'GRIB' sequence that happens to be cut off
+      scannedBytes += scanSize;
+      scannedBytes &= ~0xf; //make 16 bytes aligned
+    }
+  return -1;
+}
+
+static unsigned decode24(void* beData)
+{
+  unsigned char* bytes = beData;
+  return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
+}
+
+static uint64_t decode64(void* beData)
+{
+  unsigned char* bytes = beData;
+  uint64_t result = 0;
+  for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
+  return result;
+}
+
+//Determine the size of the GRIB record that begins at the given file offset.
+static int getRecordSize(CdiGribIterator* me, off_t gribFileOffset, size_t* outRecordSize)
+{
+  char buffer[16];
+  size_t readSize;
+  int status = cdiInputFile_read(me->file, gribFileOffset, sizeof(buffer), &readSize, buffer);
+  if(status != CDI_NOERR && status != CDI_EEOF) return status;
+  if(readSize < sizeof(buffer)) return CDI_EEOF;
+  *outRecordSize = 0;
+  switch(buffer[7])
+    {
+      case 1:
+        *outRecordSize = decode24(&buffer[4]);
+        if(*outRecordSize & (1 << 23))
+          {
+            *outRecordSize = 120*(*outRecordSize & ((1 << 23) - 1));    //Rescaling for long records.
+            //The corresponding code in cgribexlib.c:4532-4570: is much more complicated
+            //due to the fact that it subtracts the padding bytes that are inserted after section 4.
+            //However, we are only interested in the total size of data we need to read here,
+            //so we can ignore the presence of some padding bytes.
+          }
+        return CDI_NOERR;
+
+      case 2:
+        *outRecordSize =  decode64(&buffer[8]);
+        return CDI_NOERR;
+
+      default:
+        return CDI_EUFTYPE;
+    }
+}
+
+#if 0
+static void hexdump(void* data, size_t size)
+{
+  unsigned char* charData = data;
+  for(size_t offset = 0; offset < size; )
+    {
+      printf("%016zx:", offset);
+      for(size_t i = 0; i < 64 && offset < size; i++, offset++)
+        {
+          if((i & 63) && !(i & 15)) printf(" |");
+          if((i & 15) && !(i & 3)) printf("  ");
+          printf(" %02x", charData[offset]);
+        }
+      printf("\n");
+    }
+}
+#endif
+
+//Read a record into memory and wrap it in a grib_handle.
+//XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this [...]
+static int readMessage(CdiGribIterator* me)
+{
+  //Destroy the old grib_handle.
+  if(me->gribHandle) grib_handle_delete(me->gribHandle), me->gribHandle = NULL;
+  me->fileOffset += me->curRecordSize;
+
+  //Find the next record and determine its size.
+  ssize_t gribFileOffset = scanToGribMarker(me);
+  int result = CDI_EEOF;
+  if(gribFileOffset < 0) goto fail;
+  result = getRecordSize(me, gribFileOffset, &me->curRecordSize);
+  if(result) goto fail;
+
+  //Load the whole record into our buffer and create a grib_handle for it.
+  cdiGribIterator_ensureBuffer(me, me->curRecordSize);
+  result = cdiInputFile_read(me->file, gribFileOffset, me->curRecordSize, NULL, me->gribBuffer);
+  if(result) goto fail;
+  me->gribHandle = grib_handle_new_from_message(NULL, me->gribBuffer, me->curRecordSize);
+  result = CDI_EUFSTRUCT;
+  if(!me->gribHandle) goto fail;
+
+  return CDI_NOERR;
+
+fail:
+  me->curRecordSize = 0;        //This ensures that we won't jump to an uncontrolled file position if cdiGribIterator_nextField() is called another time after it has returned an error.
+  return result;
+}
+
+int cdiGribIterator_nextField(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
+
+  //Get the next GRIB message into our buffer.
+  int result = readMessage(me);
+  if(result) return result;
+
+  //Get the metadata that's published as variables in the base class.
+  super->datatype = gribGetDatatype(me->gribHandle);
+  super->timesteptype = gribapiGetTsteptype(me->gribHandle);
+  cdiDecodeParam(gribapiGetParam(me->gribHandle), &super->param.number, &super->param.category, &super->param.discipline);
+  grid_t grid;
+  gribapiGetGrid(me->gribHandle, &grid);
+  super->gridId = gridGenerate(&grid);
+
+  return CDI_NOERR;
+}
+
+char* cdiGribIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribMakeTimeString(me->gribHandle, getEndTime);
+}
+
+int cdiGribIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  //First determine the zaxis type corresponding to the given level.
+  int zaxisType = ZAXIS_GENERIC;
+  if(gribEditionNumber(me->gribHandle) <= 1)
+    {
+      int levelType = gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", 255);
+      if(levelSelector && !isGrib1DualLevel(levelType)) levelType = 255;
+      zaxisType = grib1ltypeToZaxisType(levelType);
+    }
+  else
+    {
+      int levelType = gribGetLongDefault(me->gribHandle, levelSelector ? "typeOfSecondFixedSurface" : "typeOfFirstFixedSurface", 255);
+      zaxisType = grib2ltypeToZaxisType(levelType);
+    }
+
+  //Then lookup the requested names.
+  const char* name, *longName, *stdName, *unit;
+  zaxisGetTypeDescription(zaxisType, NULL, &name, &longName, &stdName, &unit);
+  if(outName) *outName = myStrDup(name);
+  if(outLongName) *outLongName = myStrDup(longName);
+  if(outStdName) *outStdName = myStrDup(stdName);
+  if(outUnit) *outUnit = myStrDup(unit);
+
+  return zaxisType;
+}
+
+static double logicalLevelValue2(long gribType, long storedValue, long power)
+{
+  double factor = 1;
+  while(power--) factor *= 10;      //this is precise up to factor == 22.
+  switch(gribType)
+    {
+      case GRIB2_LTYPE_LANDDEPTH:
+      case GRIB2_LTYPE_ISOBARIC:
+      case GRIB2_LTYPE_SIGMA:
+        return storedValue*(1000/factor);      //The evaluation order allows the factors of ten to cancel out before rounding.
+
+      case 255:
+        return 0;
+
+      default:
+        return storedValue/factor;
+    }
+}
+
+//The output values must be preinitialized, this function does not always write them.
+static int readLevel2(grib_handle* gribHandle, const char* levelTypeKey, const char* powerKey, const char* valueKey, double* outValue1, double* outValue2)
+{
+  assert(levelTypeKey && powerKey && valueKey && outValue1 && outValue2);
+
+  long levelType = gribGetLongDefault(gribHandle, levelTypeKey, 255);   //1 byte
+  switch(levelType)
+    {
+      case 255: break;
+
+      case 105: case 113:
+        {
+          unsigned long value = (unsigned long)gribGetLongDefault(gribHandle, valueKey, 0);
+          unsigned long coordinateCount = (unsigned long)gribGetLongDefault(gribHandle, "numberOfCoordinatesValues", 0);
+          if(value >= coordinateCount/2)
+            {
+              Error("Invalid level coordinate: Level has the hybrid coordinate index %lu, but only %lu coordinate pairs are present.", value, coordinateCount/2);
+              return CDI_EUFSTRUCT;
+            }
+          int status;
+          //XXX: I'm not 100% sure about how the coordinate pairs are stored in the file.
+          //     I'm assuming an array of pairs due to the example code in grib_api-1.12.3/examples/F90/set_pv.f90, but that may be wrong.
+          if((status = grib_get_double_element(gribHandle, "pv", value*2    , outValue1))) return status;
+          if((status = grib_get_double_element(gribHandle, "pv", value*2 + 1, outValue2))) return status;
+          break;
+        }
+
+      default:
+        {
+          long power = gribGetLongDefault(gribHandle, powerKey, 0);  //1 byte
+          if(power == 255) power = 0;
+          long value = gribGetLongDefault(gribHandle, valueKey, 0);   //4 bytes
+          *outValue1 = logicalLevelValue2(levelType, value, power);
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiGribIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+  *outValue1 = *outValue2 = 0;
+
+  if(gribEditionNumber(me->gribHandle) > 1)
+    {
+      if(levelSelector)
+        {
+          return readLevel2(me->gribHandle, "typeOfFirstFixedSurface", "scaleFactorOfFirstFixedSurface", "scaledValueOfFirstFixedSurface", outValue1, outValue2);
+        }
+      else
+        {
+          return readLevel2(me->gribHandle, "typeOfSecondFixedSurface", "scaleFactorOfSecondFixedSurface", "scaledValueOfSecondFixedSurface", outValue1, outValue2);
+        }
+    }
+  else
+    {
+      long levelType = (uint8_t)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", -1);    //1 byte
+      if(levelType == 255)
+        {}
+      else if(isGrib1DualLevel(levelType))
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0);
+        }
+      else if(levelType == 100)
+        {
+          *outValue1 = 100*gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+      else
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiGribIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  if(outVgridNumber)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "numberOfVGridUsed", &temp)) return CDI_EINVAL;
+      *outVgridNumber = (int)temp;
+    }
+  if(outLevelCount)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "nlev", &temp)) return CDI_EINVAL;
+      *outLevelCount = (int)temp;
+    }
+  if(outUuid)
+    {
+      size_t size = sizeof(*outUuid);
+      if(grib_get_bytes(me->gribHandle, "uuidOfVGrid", *outUuid, &size)) return CDI_EINVAL;
+      if(size != sizeof(*outUuid)) return CDI_EUFSTRUCT;
+    }
+
+  return CDI_NOERR;
+}
+
+char* cdiGribIterator_copyVariableName(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribCopyString(me->gribHandle, "shortName");
+}
+
+void cdiGribIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  gribGetDoubleArray(me->gribHandle, "values", buffer);
+  long gridType = gribGetLong(me->gribHandle, "gridDefinitionTemplateNumber");
+  if(nmiss)
+    {
+      *nmiss = (gridType >= 50 && gridType <= 53) ? 0 : (int)gribGetLong(me->gribHandle, "numberOfMissing");        //The condition excludes harmonic data.
+    }
+}
+
+void cdiGribIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  size_t valueCount = gribGetArraySize(me->gribHandle, "values");
+  double* temp = malloc(valueCount*sizeof(*temp));
+  cdiGribIterator_readField(super, temp, nmiss);
+  for(size_t i = valueCount; i--; ) buffer[i] = temp[i];
+  free(temp);
+}
+
+/**
+ at Function cdiGribIterator_delete
+ at Title Dispose off a CdiGribIterator instance.
+
+ at Prototype void cdiGribIterator_delete(CdiGribIterator* me)
+ at Parameter
+    @item me The iterator to delete.
+
+ at Description
+    Combined destructor and deallocator. Make sure to match every call to cdiGribIterator_clone() with a call to this function.
+*/
+void cdiGribIterator_delete(CdiGribIterator* me)
+{
+  if(me) cdiGribIterator_condestruct(me, NULL, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// callthroughs to provide direct access to the grib keys //////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ at Function cdiGribIterator_inqEdition
+ at Title Get the version of the GRIB standard that is used
+
+ at Prototype int cdiGribIterator_inqEdition(CdiGribIterator* me)
+ at Parameter
+    @item me The iterator to operate on.
+
+ at Result The GRIB version.
+
+ at Description
+    Returns the version of the file format.
+*/
+int cdiGribIterator_inqEdition(CdiGribIterator* me)
+{
+  return gribEditionNumber(me->gribHandle);
+}
+
+/**
+ at Function cdiGribIterator_getLong
+ at Title Access to grib_get_long()
+
+ at Prototype int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_long().
+*/
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+{
+  return grib_get_long(me->gribHandle, key, result);
+}
+
+/**
+ at Function cdiGribIterator_getLength
+ at Title Access to grib_get_length()
+
+ at Prototype int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_length().
+*/
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
+{
+  return grib_get_length(me->gribHandle, key, result);
+}
+
+/**
+ at Function cdiGribIterator_getString
+ at Title Access to grib_get_string()
+
+ at Prototype int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_string().
+*/
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+{
+  return grib_get_string(me->gribHandle, key, result, length);
+}
+
+/**
+ at Function cdiGribIterator_inqLongValue
+ at Title Get the value of a GRIB-API key as a long
+
+ at Prototype long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+ at Result The value of the key.
+
+ at Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetLong(me->gribHandle, key);
+}
+
+/**
+ at Function cdiGribIterator_inqLongDefaultValue
+ at Title Get the value of a GRIB-API key as a long
+
+ at Prototype long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
+
+ at Result The value of the key or the given default value.
+
+ at Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+{
+  return gribGetLongDefault(me->gribHandle, key, defaultValue);
+}
+
+/**
+ at Function cdiGribIterator_inqStringValue
+ at Title Safely retrieve a GRIB-API key with a string value
+
+ at Prototype char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+ at Result A malloc'ed string or NULL.
+
+ at Description
+    This will first call grib_get_length() to inquire the actual size of the string,
+    allocate memory accordingly, call grib_get_string(), and return the pointer to the new string.
+    Returns NULL on failure.
+*/
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
+{
+  return gribCopyString(me->gribHandle, key);
+}
+
+/**
+ at Function cdiGribIterator_getDouble
+ at Title Access to grib_get_double()
+
+ at Prototype int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_double().
+*/
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+{
+  return grib_get_double(me->gribHandle, key, result);
+}
+
+/**
+ at Function cdiGribIterator_getSize
+ at Title Access to grib_get_size()
+
+ at Prototype int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_size().
+*/
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+{
+  return grib_get_size(me->gribHandle, key, result);
+}
+
+/**
+ at Function cdiGribIterator_getLongArray
+ at Title Access to grib_get_long_array()
+
+ at Prototype int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_long_array().
+*/
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+{
+  return grib_get_long_array(me->gribHandle, key, result, size);
+}
+
+/**
+ at Function cdiGribIterator_getDoubleArray
+ at Title Access to grib_get_double_array()
+
+ at Prototype int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+ at Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+ at Result An error code.
+
+ at Description
+    Callthrough to grib_get_double_array().
+*/
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+{
+  return grib_get_double_array(me->gribHandle, key, result, size);
+}
+
+/**
+ at Function cdiGribIterator_inqDoubleValue
+ at Title Get the value of a GRIB-API key as a double
+
+ at Prototype double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+ at Result The value of the key.
+
+ at Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetDouble(me->gribHandle, key);
+}
+
+/**
+ at Function cdiGribIterator_inqDoubleDefaultValue
+ at Title Get the value of a GRIB-API key as a double
+
+ at Prototype double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+ at Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
+
+ at Result The value of the key or the given default value.
+
+ at Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+{
+  return gribGetDoubleDefault(me->gribHandle, key, defaultValue);
+}
+
+#endif
diff --git a/libcdi/src/iterator_grib.h b/libcdi/src/iterator_grib.h
new file mode 100644
index 0000000..2847f72
--- /dev/null
+++ b/libcdi/src/iterator_grib.h
@@ -0,0 +1,48 @@
+/*
+ * An implementation of the iterator interface for GRIB files.
+ * Since GRIB files do not contain an index, this avoids scanning the entire file to generate an in-memory index as streamOpenRead() does.
+ * Consequently, using this interface is much more efficient for GRIB files.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+#define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+
+#include "iterator.h"
+#include "input_file.h"
+
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#endif
+
+typedef struct recordList recordList;
+struct CdiGribIterator {
+  CdiIterator super;
+
+  CdiInputFile* file;
+  off_t fileOffset;
+  unsigned char* gribBuffer;
+  size_t bufferSize, curRecordSize;
+#ifdef HAVE_LIBGRIB_API
+  grib_handle* gribHandle;
+#else
+  void* gribHandle;
+#endif
+};
+
+CdiIterator* cdiGribIterator_new(const char* path, int filetype);
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* me);
+char* cdiGribIterator_serialize(CdiIterator* me);
+CdiGribIterator* cdiGribIterator_deserialize(const char* me);
+
+int cdiGribIterator_nextField(CdiIterator* me);
+
+char* cdiGribIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiGribIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiGribIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiGribIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiGribIterator_copyVariableName(CdiIterator* me);
+
+void cdiGribIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiGribIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
+
+#endif
diff --git a/libcdi/src/mo_cdi.f90 b/libcdi/src/mo_cdi.f90
index f2fe49e..1036158 100644
--- a/libcdi/src/mo_cdi.f90
+++ b/libcdi/src/mo_cdi.f90
@@ -1,3742 +1,7918 @@
+! >>> Warning: This is a generated file. If you modify it, you get what you deserve. <<<
+!
+! Generated by "../../../../libcdi/interfaces/f2003/bindGen.rb" from input file "../../../../libcdi/src/cdi.h".
 
 module mo_cdi
-      use, intrinsic :: iso_c_binding
-
-      implicit none
-
-      private
-  
-      integer, parameter :: CDI_MAX_NAME = 256
-      integer, parameter :: CDI_UNDEFID = -1
-      integer, parameter :: CDI_GLOBAL = -1
-      integer, parameter :: CDI_BIGENDIAN = 0
-      integer, parameter :: CDI_LITTLEENDIAN = 1
-      integer, parameter :: CDI_REAL = 1
-      integer, parameter :: CDI_COMP = 2
-      integer, parameter :: CDI_BOTH = 3
-      integer, parameter :: CDI_ESYSTEM = -10
-      integer, parameter :: CDI_EINVAL = -20
-      integer, parameter :: CDI_EUFTYPE = -21
-      integer, parameter :: CDI_ELIBNAVAIL = -22
-      integer, parameter :: CDI_EUFSTRUCT = -23
-      integer, parameter :: CDI_EUNC4 = -24
-      integer, parameter :: CDI_ELIMIT = -99
-      integer, parameter :: FILETYPE_UNDEF = -1
-      integer, parameter :: FILETYPE_GRB = 1
-      integer, parameter :: FILETYPE_GRB2 = 2
-      integer, parameter :: FILETYPE_NC = 3
-      integer, parameter :: FILETYPE_NC2 = 4
-      integer, parameter :: FILETYPE_NC4 = 5
-      integer, parameter :: FILETYPE_NC4C = 6
-      integer, parameter :: FILETYPE_SRV = 7
-      integer, parameter :: FILETYPE_EXT = 8
-      integer, parameter :: FILETYPE_IEG = 9
-      integer, parameter :: COMPRESS_NONE = 0
-      integer, parameter :: COMPRESS_SZIP = 1
-      integer, parameter :: COMPRESS_GZIP = 2
-      integer, parameter :: COMPRESS_BZIP2 = 3
-      integer, parameter :: COMPRESS_ZIP = 4
-      integer, parameter :: COMPRESS_JPEG = 5
-      integer, parameter :: DATATYPE_PACK = 0
-      integer, parameter :: DATATYPE_PACK1 = 1
-      integer, parameter :: DATATYPE_PACK2 = 2
-      integer, parameter :: DATATYPE_PACK3 = 3
-      integer, parameter :: DATATYPE_PACK4 = 4
-      integer, parameter :: DATATYPE_PACK5 = 5
-      integer, parameter :: DATATYPE_PACK6 = 6
-      integer, parameter :: DATATYPE_PACK7 = 7
-      integer, parameter :: DATATYPE_PACK8 = 8
-      integer, parameter :: DATATYPE_PACK9 = 9
-      integer, parameter :: DATATYPE_PACK10 = 10
-      integer, parameter :: DATATYPE_PACK11 = 11
-      integer, parameter :: DATATYPE_PACK12 = 12
-      integer, parameter :: DATATYPE_PACK13 = 13
-      integer, parameter :: DATATYPE_PACK14 = 14
-      integer, parameter :: DATATYPE_PACK15 = 15
-      integer, parameter :: DATATYPE_PACK16 = 16
-      integer, parameter :: DATATYPE_PACK17 = 17
-      integer, parameter :: DATATYPE_PACK18 = 18
-      integer, parameter :: DATATYPE_PACK19 = 19
-      integer, parameter :: DATATYPE_PACK20 = 20
-      integer, parameter :: DATATYPE_PACK21 = 21
-      integer, parameter :: DATATYPE_PACK22 = 22
-      integer, parameter :: DATATYPE_PACK23 = 23
-      integer, parameter :: DATATYPE_PACK24 = 24
-      integer, parameter :: DATATYPE_PACK25 = 25
-      integer, parameter :: DATATYPE_PACK26 = 26
-      integer, parameter :: DATATYPE_PACK27 = 27
-      integer, parameter :: DATATYPE_PACK28 = 28
-      integer, parameter :: DATATYPE_PACK29 = 29
-      integer, parameter :: DATATYPE_PACK30 = 30
-      integer, parameter :: DATATYPE_PACK31 = 31
-      integer, parameter :: DATATYPE_PACK32 = 32
-      integer, parameter :: DATATYPE_CPX32 = 64
-      integer, parameter :: DATATYPE_CPX64 = 128
-      integer, parameter :: DATATYPE_FLT32 = 132
-      integer, parameter :: DATATYPE_FLT64 = 164
-      integer, parameter :: DATATYPE_INT8 = 208
-      integer, parameter :: DATATYPE_INT16 = 216
-      integer, parameter :: DATATYPE_INT32 = 232
-      integer, parameter :: DATATYPE_UINT8 = 308
-      integer, parameter :: DATATYPE_UINT16 = 316
-      integer, parameter :: DATATYPE_UINT32 = 332
-      integer, parameter :: DATATYPE_INT = 251
-      integer, parameter :: DATATYPE_FLT = 252
-      integer, parameter :: DATATYPE_TXT = 253
-      integer, parameter :: DATATYPE_CPX = 254
-      integer, parameter :: DATATYPE_UCHAR = 255
-      integer, parameter :: DATATYPE_LONG = 256
-      integer, parameter :: CHUNK_AUTO = 1
-      integer, parameter :: CHUNK_GRID = 2
-      integer, parameter :: CHUNK_LINES = 3
-      integer, parameter :: GRID_GENERIC = 1
-      integer, parameter :: GRID_GAUSSIAN = 2
-      integer, parameter :: GRID_GAUSSIAN_REDUCED = 3
-      integer, parameter :: GRID_LONLAT = 4
-      integer, parameter :: GRID_SPECTRAL = 5
-      integer, parameter :: GRID_FOURIER = 6
-      integer, parameter :: GRID_GME = 7
-      integer, parameter :: GRID_TRAJECTORY = 8
-      integer, parameter :: GRID_UNSTRUCTURED = 9
-      integer, parameter :: GRID_CURVILINEAR = 10
-      integer, parameter :: GRID_LCC = 11
-      integer, parameter :: GRID_LCC2 = 12
-      integer, parameter :: GRID_LAEA = 13
-      integer, parameter :: GRID_SINUSOIDAL = 14
-      integer, parameter :: GRID_PROJECTION = 15
-      integer, parameter :: ZAXIS_SURFACE = 0
-      integer, parameter :: ZAXIS_GENERIC = 1
-      integer, parameter :: ZAXIS_HYBRID = 2
-      integer, parameter :: ZAXIS_HYBRID_HALF = 3
-      integer, parameter :: ZAXIS_PRESSURE = 4
-      integer, parameter :: ZAXIS_HEIGHT = 5
-      integer, parameter :: ZAXIS_DEPTH_BELOW_SEA = 6
-      integer, parameter :: ZAXIS_DEPTH_BELOW_LAND = 7
-      integer, parameter :: ZAXIS_ISENTROPIC = 8
-      integer, parameter :: ZAXIS_TRAJECTORY = 9
-      integer, parameter :: ZAXIS_ALTITUDE = 10
-      integer, parameter :: ZAXIS_SIGMA = 11
-      integer, parameter :: ZAXIS_MEANSEA = 12
-      integer, parameter :: ZAXIS_TOA = 13
-      integer, parameter :: ZAXIS_SEA_BOTTOM = 14
-      integer, parameter :: ZAXIS_ATMOSPHERE = 15
-      integer, parameter :: ZAXIS_CLOUD_BASE = 16
-      integer, parameter :: ZAXIS_CLOUD_TOP = 17
-      integer, parameter :: ZAXIS_ISOTHERM_ZERO = 18
-      integer, parameter :: ZAXIS_SNOW = 19
-      integer, parameter :: ZAXIS_LAKE_BOTTOM = 20
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM = 21
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM_TA = 22
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM_TW = 23
-      integer, parameter :: ZAXIS_MIX_LAYER = 24
-      integer, parameter :: ZAXIS_REFERENCE = 25
-      integer, parameter :: TIME_CONSTANT = 0
-      integer, parameter :: TIME_VARIABLE = 1
-      integer, parameter :: TSTEP_CONSTANT = 0
-      integer, parameter :: TSTEP_INSTANT = 1
-      integer, parameter :: TSTEP_AVG = 2
-      integer, parameter :: TSTEP_ACCUM = 3
-      integer, parameter :: TSTEP_MAX = 4
-      integer, parameter :: TSTEP_MIN = 5
-      integer, parameter :: TSTEP_DIFF = 6
-      integer, parameter :: TSTEP_RMS = 7
-      integer, parameter :: TSTEP_SD = 8
-      integer, parameter :: TSTEP_COV = 9
-      integer, parameter :: TSTEP_RATIO = 10
-      integer, parameter :: TSTEP_RANGE = 11
-      integer, parameter :: TSTEP_INSTANT2 = 12
-      integer, parameter :: TSTEP_INSTANT3 = 13
-      integer, parameter :: TAXIS_ABSOLUTE = 1
-      integer, parameter :: TAXIS_RELATIVE = 2
-      integer, parameter :: TAXIS_FORECAST = 3
-      integer, parameter :: TUNIT_SECOND = 1
-      integer, parameter :: TUNIT_MINUTE = 2
-      integer, parameter :: TUNIT_QUARTER = 3
-      integer, parameter :: TUNIT_30MINUTES = 4
-      integer, parameter :: TUNIT_HOUR = 5
-      integer, parameter :: TUNIT_3HOURS = 6
-      integer, parameter :: TUNIT_6HOURS = 7
-      integer, parameter :: TUNIT_12HOURS = 8
-      integer, parameter :: TUNIT_DAY = 9
-      integer, parameter :: TUNIT_MONTH = 10
-      integer, parameter :: TUNIT_YEAR = 11
-      integer, parameter :: CALENDAR_STANDARD = 0
-      integer, parameter :: CALENDAR_PROLEPTIC = 1
-      integer, parameter :: CALENDAR_360DAYS = 2
-      integer, parameter :: CALENDAR_365DAYS = 3
-      integer, parameter :: CALENDAR_366DAYS = 4
-      integer, parameter :: CALENDAR_NONE = 5
-      integer, parameter :: CDI_UUID_SIZE = 16
-      interface
-        function strlen(s) bind(c,name='strlen')
-          import :: c_ptr,c_size_t
-          type(c_ptr), value :: s
-          integer(kind=c_size_t) :: strlen
-        end function strlen
-      end interface
-      interface
-        function getchar() bind(c,name='getchar')
-          import :: c_int
-          integer(kind=c_int) :: getchar
-        end function getchar
-      end interface
-      interface
-        function getchar_unlocked() bind(c,name='getchar_unlocked')
-          import :: c_int
-          integer(kind=c_int) :: getchar_unlocked
-        end function getchar_unlocked
-      end interface
-      interface
-        subroutine cdiReset() bind(c,name='cdiReset')
-        end subroutine cdiReset
-      end interface
-      interface
-        subroutine cdiDebug(debug) bind(c,name='cdiDebug')
-          import :: c_int
-          integer(kind=c_int), value :: debug
-        end subroutine cdiDebug
-      end interface
-      interface
-        subroutine cdiPrintVersion() bind(c,name='cdiPrintVersion')
-        end subroutine cdiPrintVersion
-      end interface
-      interface
-        function cdiHaveFiletype(filetype) bind(c,name='cdiHaveFiletype')
-          import :: c_int
-          integer(kind=c_int), value :: filetype
-          integer(kind=c_int) :: cdiHaveFiletype
-        end function cdiHaveFiletype
-      end interface
-      interface
-        subroutine cdiDefMissval(missval) bind(c,name='cdiDefMissval')
-          import :: c_double
-          real(kind=c_double), value :: missval
-        end subroutine cdiDefMissval
-      end interface
-      interface
-        function cdiInqMissval() bind(c,name='cdiInqMissval')
-          import :: c_double
-          real(kind=c_double) :: cdiInqMissval
-        end function cdiInqMissval
-      end interface
-      interface
-        subroutine cdiDefGlobal(string,val) bind(c,name='cdiDefGlobal')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: string
-          integer(kind=c_int), value :: val
-        end subroutine cdiDefGlobal
-      end interface
-      interface
-        function namespaceNew() bind(c,name='namespaceNew')
-          import :: c_int
-          integer(kind=c_int) :: namespaceNew
-        end function namespaceNew
-      end interface
-      interface
-        subroutine namespaceSetActive(namespaceID) bind(c,name='namespaceSetActive')
-          import :: c_int
-          integer(kind=c_int), value :: namespaceID
-        end subroutine namespaceSetActive
-      end interface
-      interface
-        subroutine namespaceDelete(namespaceID) bind(c,name='namespaceDelete')
-          import :: c_int
-          integer(kind=c_int), value :: namespaceID
-        end subroutine namespaceDelete
-      end interface
-      interface
-        subroutine cdiParamToString(param,paramstr,maxlen) bind(c,name='cdiParamToString')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: param
-          character(kind=c_char), dimension(*) :: paramstr
-          integer(kind=c_int), value :: maxlen
-        end subroutine cdiParamToString
-      end interface
-      interface
-        subroutine cdiDecodeParam(param,pnum,pcat,pdis) bind(c,name='cdiDecodeParam')
-          import :: c_int
-          integer(kind=c_int), value :: param
-          integer(kind=c_int), intent(out) :: pnum
-          integer(kind=c_int), intent(out) :: pcat
-          integer(kind=c_int), intent(out) :: pdis
-        end subroutine cdiDecodeParam
-      end interface
-      interface
-        function cdiEncodeParam(pnum,pcat,pdis) bind(c,name='cdiEncodeParam')
-          import :: c_int
-          integer(kind=c_int), value :: pnum
-          integer(kind=c_int), value :: pcat
-          integer(kind=c_int), value :: pdis
-          integer(kind=c_int) :: cdiEncodeParam
-        end function cdiEncodeParam
-      end interface
-      interface
-        subroutine cdiDecodeDate(date,year,month,day) bind(c,name='cdiDecodeDate')
-          import :: c_int
-          integer(kind=c_int), value :: date
-          integer(kind=c_int), intent(out) :: year
-          integer(kind=c_int), intent(out) :: month
-          integer(kind=c_int), intent(out) :: day
-        end subroutine cdiDecodeDate
-      end interface
-      interface
-        function cdiEncodeDate(year,month,day) bind(c,name='cdiEncodeDate')
-          import :: c_int
-          integer(kind=c_int), value :: year
-          integer(kind=c_int), value :: month
-          integer(kind=c_int), value :: day
-          integer(kind=c_int) :: cdiEncodeDate
-        end function cdiEncodeDate
-      end interface
-      interface
-        subroutine cdiDecodeTime(time,hour,minute,second) bind(c,name='cdiDecodeTime')
-          import :: c_int
-          integer(kind=c_int), value :: time
-          integer(kind=c_int), intent(out) :: hour
-          integer(kind=c_int), intent(out) :: minute
-          integer(kind=c_int), intent(out) :: second
-        end subroutine cdiDecodeTime
-      end interface
-      interface
-        function cdiEncodeTime(hour,minute,second) bind(c,name='cdiEncodeTime')
-          import :: c_int
-          integer(kind=c_int), value :: hour
-          integer(kind=c_int), value :: minute
-          integer(kind=c_int), value :: second
-          integer(kind=c_int) :: cdiEncodeTime
-        end function cdiEncodeTime
-      end interface
-      interface
-        function cdiGetFiletype(path,byteorder) bind(c,name='cdiGetFiletype')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int), intent(out) :: byteorder
-          integer(kind=c_int) :: cdiGetFiletype
-        end function cdiGetFiletype
-      end interface
-      interface
-        function streamOpenRead(path) bind(c,name='streamOpenRead')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int) :: streamOpenRead
-        end function streamOpenRead
-      end interface
-      interface
-        function streamOpenWrite(path,filetype) bind(c,name='streamOpenWrite')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int), value :: filetype
-          integer(kind=c_int) :: streamOpenWrite
-        end function streamOpenWrite
-      end interface
-      interface
-        function streamOpenAppend(path) bind(c,name='streamOpenAppend')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int) :: streamOpenAppend
-        end function streamOpenAppend
-      end interface
-      interface
-        subroutine streamClose(streamID) bind(c,name='streamClose')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-        end subroutine streamClose
-      end interface
-      interface
-        subroutine streamSync(streamID) bind(c,name='streamSync')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-        end subroutine streamSync
-      end interface
-      interface
-        subroutine streamDefVlist(streamID,vlistID) bind(c,name='streamDefVlist')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: vlistID
-        end subroutine streamDefVlist
-      end interface
-      interface
-        function streamInqVlist(streamID) bind(c,name='streamInqVlist')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqVlist
-        end function streamInqVlist
-      end interface
-      interface
-        function streamInqVlistIDorig(streamID) bind(c,name='streamInqVlistIDorig')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqVlistIDorig
-        end function streamInqVlistIDorig
-      end interface
-      interface
-        function streamInqFiletype(streamID) bind(c,name='streamInqFiletype')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqFiletype
-        end function streamInqFiletype
-      end interface
-      interface
-        subroutine streamDefByteorder(streamID,byteorder) bind(c,name='streamDefByteorder')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: byteorder
-        end subroutine streamDefByteorder
-      end interface
-      interface
-        function streamInqByteorder(streamID) bind(c,name='streamInqByteorder')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqByteorder
-        end function streamInqByteorder
-      end interface
-      interface
-        subroutine streamDefCompType(streamID,comptype) bind(c,name='streamDefCompType')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: comptype
-        end subroutine streamDefCompType
-      end interface
-      interface
-        function streamInqCompType(streamID) bind(c,name='streamInqCompType')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCompType
-        end function streamInqCompType
-      end interface
-      interface
-        subroutine streamDefCompLevel(streamID,complevel) bind(c,name='streamDefCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: complevel
-        end subroutine streamDefCompLevel
-      end interface
-      interface
-        function streamInqCompLevel(streamID) bind(c,name='streamInqCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCompLevel
-        end function streamInqCompLevel
-      end interface
-      interface
-        function streamDefTimestep(streamID,tsID) bind(c,name='streamDefTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: tsID
-          integer(kind=c_int) :: streamDefTimestep
-        end function streamDefTimestep
-      end interface
-      interface
-        function streamInqTimestep(streamID,tsID) bind(c,name='streamInqTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: tsID
-          integer(kind=c_int) :: streamInqTimestep
-        end function streamInqTimestep
-      end interface
-      interface
-        function streamInqCurTimestepID(streamID) bind(c,name='streamInqCurTimestepID')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCurTimestepID
-        end function streamInqCurTimestepID
-      end interface
-      interface
-        function streamInqNvars(streamID) bind(c,name='streamInqNvars')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqNvars
-        end function streamInqNvars
-      end interface
-      interface
-        subroutine streamWriteVar(streamID,varID,data_vec,nmiss) bind(c,name='streamWriteVar')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVar
-      end interface
-      interface
-        subroutine streamWriteVarF(streamID,varID,data_vec,nmiss) bind(c,name='streamWriteVarF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarF
-      end interface
-      interface
-        subroutine streamReadVar(streamID,varID,data_vec,nmiss) bind(c,name='streamReadVar')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVar
-      end interface
-      interface
-        subroutine streamReadVarF(streamID,varID,data_vec,nmiss) bind(c,name='streamReadVarF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_float), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarF
-      end interface
-      interface
-        subroutine streamWriteVarSlice(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamWriteVarSlice')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarSlice
-      end interface
-      interface
-        subroutine streamWriteVarSliceF(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamWriteVarSliceF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarSliceF
-      end interface
-      interface
-        subroutine streamReadVarSlice(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamReadVarSlice')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarSlice
-      end interface
-      interface
-        subroutine streamReadVarSliceF(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamReadVarSliceF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_float), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarSliceF
-      end interface
-      interface
-        subroutine streamDefRecord(streamID,varID,levelID) bind(c,name='streamDefRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-        end subroutine streamDefRecord
-      end interface
-      interface
-        subroutine streamInqRecord(streamID,varID,levelID) bind(c,name='streamInqRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), intent(out) :: varID
-          integer(kind=c_int), intent(out) :: levelID
-        end subroutine streamInqRecord
-      end interface
-      interface
-        subroutine streamWriteRecord(streamID,data_vec,nmiss) bind(c,name='streamWriteRecord')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteRecord
-      end interface
-      interface
-        subroutine streamWriteRecordF(streamID,data_vec,nmiss) bind(c,name='streamWriteRecordF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteRecordF
-      end interface
-      interface
-        subroutine streamReadRecord(streamID,data_vec,nmiss) bind(c,name='streamReadRecord')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadRecord
-      end interface
-      interface
-        subroutine streamCopyRecord(streamIDdest,streamIDsrc) bind(c,name='streamCopyRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamIDdest
-          integer(kind=c_int), value :: streamIDsrc
-        end subroutine streamCopyRecord
-      end interface
-      interface
-        function vlistCreate() bind(c,name='vlistCreate')
-          import :: c_int
-          integer(kind=c_int) :: vlistCreate
-        end function vlistCreate
-      end interface
-      interface
-        subroutine vlistDestroy(vlistID) bind(c,name='vlistDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistDestroy
-      end interface
-      interface
-        function vlistDuplicate(vlistID) bind(c,name='vlistDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistDuplicate
-        end function vlistDuplicate
-      end interface
-      interface
-        subroutine vlistCopy(vlistID2,vlistID1) bind(c,name='vlistCopy')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCopy
-      end interface
-      interface
-        subroutine vlistCopyFlag(vlistID2,vlistID1) bind(c,name='vlistCopyFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCopyFlag
-      end interface
-      interface
-        subroutine vlistClearFlag(vlistID) bind(c,name='vlistClearFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistClearFlag
-      end interface
-      interface
-        subroutine vlistCat(vlistID2,vlistID1) bind(c,name='vlistCat')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCat
-      end interface
-      interface
-        subroutine vlistMerge(vlistID2,vlistID1) bind(c,name='vlistMerge')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistMerge
-      end interface
-      interface
-        subroutine vlistPrint(vlistID) bind(c,name='vlistPrint')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistPrint
-      end interface
-      interface
-        function vlistNumber(vlistID) bind(c,name='vlistNumber')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNumber
-        end function vlistNumber
-      end interface
-      interface
-        function vlistNvars(vlistID) bind(c,name='vlistNvars')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNvars
-        end function vlistNvars
-      end interface
-      interface
-        function vlistNgrids(vlistID) bind(c,name='vlistNgrids')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNgrids
-        end function vlistNgrids
-      end interface
-      interface
-        function vlistNzaxis(vlistID) bind(c,name='vlistNzaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNzaxis
-        end function vlistNzaxis
-      end interface
-      interface
-        subroutine vlistDefNtsteps(vlistID,nts) bind(c,name='vlistDefNtsteps')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: nts
-        end subroutine vlistDefNtsteps
-      end interface
-      interface
-        function vlistNtsteps(vlistID) bind(c,name='vlistNtsteps')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNtsteps
-        end function vlistNtsteps
-      end interface
-      interface
-        function vlistGridsizeMax(vlistID) bind(c,name='vlistGridsizeMax')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistGridsizeMax
-        end function vlistGridsizeMax
-      end interface
-      interface
-        function vlistGrid(vlistID,index) bind(c,name='vlistGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int) :: vlistGrid
-        end function vlistGrid
-      end interface
-      interface
-        function vlistGridIndex(vlistID,gridID) bind(c,name='vlistGridIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: vlistGridIndex
-        end function vlistGridIndex
-      end interface
-      interface
-        subroutine vlistChangeGridIndex(vlistID,index,gridID) bind(c,name='vlistChangeGridIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int), value :: gridID
-        end subroutine vlistChangeGridIndex
-      end interface
-      interface
-        subroutine vlistChangeGrid(vlistID,gridID1,gridID2) bind(c,name='vlistChangeGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID1
-          integer(kind=c_int), value :: gridID2
-        end subroutine vlistChangeGrid
-      end interface
-      interface
-        function vlistZaxis(vlistID,index) bind(c,name='vlistZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int) :: vlistZaxis
-        end function vlistZaxis
-      end interface
-      interface
-        function vlistZaxisIndex(vlistID,zaxisID) bind(c,name='vlistZaxisIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: vlistZaxisIndex
-        end function vlistZaxisIndex
-      end interface
-      interface
-        subroutine vlistChangeZaxisIndex(vlistID,index,zaxisID) bind(c,name='vlistChangeZaxisIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int), value :: zaxisID
-        end subroutine vlistChangeZaxisIndex
-      end interface
-      interface
-        subroutine vlistChangeZaxis(vlistID,zaxisID1,zaxisID2) bind(c,name='vlistChangeZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: zaxisID1
-          integer(kind=c_int), value :: zaxisID2
-        end subroutine vlistChangeZaxis
-      end interface
-      interface
-        function vlistNrecs(vlistID) bind(c,name='vlistNrecs')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNrecs
-        end function vlistNrecs
-      end interface
-      interface
-        subroutine vlistDefTaxis(vlistID,taxisID) bind(c,name='vlistDefTaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: taxisID
-        end subroutine vlistDefTaxis
-      end interface
-      interface
-        function vlistInqTaxis(vlistID) bind(c,name='vlistInqTaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqTaxis
-        end function vlistInqTaxis
-      end interface
-      interface
-        subroutine vlistDefTable(vlistID,tableID) bind(c,name='vlistDefTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: tableID
-        end subroutine vlistDefTable
-      end interface
-      interface
-        function vlistInqTable(vlistID) bind(c,name='vlistInqTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqTable
-        end function vlistInqTable
-      end interface
-      interface
-        subroutine vlistDefInstitut(vlistID,instID) bind(c,name='vlistDefInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: instID
-        end subroutine vlistDefInstitut
-      end interface
-      interface
-        function vlistInqInstitut(vlistID) bind(c,name='vlistInqInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqInstitut
-        end function vlistInqInstitut
-      end interface
-      interface
-        subroutine vlistDefModel(vlistID,modelID) bind(c,name='vlistDefModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: modelID
-        end subroutine vlistDefModel
-      end interface
-      interface
-        function vlistInqModel(vlistID) bind(c,name='vlistInqModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqModel
-        end function vlistInqModel
-      end interface
-      interface
-        function vlistDefVar(vlistID,gridID,zaxisID,tsteptype) bind(c,name='vlistDefVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: tsteptype
-          integer(kind=c_int) :: vlistDefVar
-        end function vlistDefVar
-      end interface
-      interface
-        subroutine vlistChangeVarGrid(vlistID,varID,gridID) bind(c,name='vlistChangeVarGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: gridID
-        end subroutine vlistChangeVarGrid
-      end interface
-      interface
-        subroutine vlistChangeVarZaxis(vlistID,varID,zaxisID) bind(c,name='vlistChangeVarZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: zaxisID
-        end subroutine vlistChangeVarZaxis
-      end interface
-      interface
-        subroutine vlistInqVar(vlistID,varID,gridID,zaxisID,tsteptype) bind(c,name='vlistInqVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: gridID
-          integer(kind=c_int), intent(out) :: zaxisID
-          integer(kind=c_int), intent(out) :: tsteptype
-        end subroutine vlistInqVar
-      end interface
-      interface
-        function vlistInqVarGrid(vlistID,varID) bind(c,name='vlistInqVarGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarGrid
-        end function vlistInqVarGrid
-      end interface
-      interface
-        function vlistInqVarZaxis(vlistID,varID) bind(c,name='vlistInqVarZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarZaxis
-        end function vlistInqVarZaxis
-      end interface
-      interface
-        function vlistInqVarID(vlistID,code) bind(c,name='vlistInqVarID')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: code
-          integer(kind=c_int) :: vlistInqVarID
-        end function vlistInqVarID
-      end interface
-      interface
-        subroutine vlistDefVarTsteptype(vlistID,varID,tsteptype) bind(c,name='vlistDefVarTsteptype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: tsteptype
-        end subroutine vlistDefVarTsteptype
-      end interface
-      interface
-        function vlistInqVarTsteptype(vlistID,varID) bind(c,name='vlistInqVarTsteptype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTsteptype
-        end function vlistInqVarTsteptype
-      end interface
-      interface
-        subroutine vlistDefVarCompType(vlistID,varID,comptype) bind(c,name='vlistDefVarCompType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: comptype
-        end subroutine vlistDefVarCompType
-      end interface
-      interface
-        function vlistInqVarCompType(vlistID,varID) bind(c,name='vlistInqVarCompType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCompType
-        end function vlistInqVarCompType
-      end interface
-      interface
-        subroutine vlistDefVarCompLevel(vlistID,varID,complevel) bind(c,name='vlistDefVarCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: complevel
-        end subroutine vlistDefVarCompLevel
-      end interface
-      interface
-        function vlistInqVarCompLevel(vlistID,varID) bind(c,name='vlistInqVarCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCompLevel
-        end function vlistInqVarCompLevel
-      end interface
-      interface
-        subroutine vlistDefVarParam(vlistID,varID,param) bind(c,name='vlistDefVarParam')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: param
-        end subroutine vlistDefVarParam
-      end interface
-      interface
-        function vlistInqVarParam(vlistID,varID) bind(c,name='vlistInqVarParam')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarParam
-        end function vlistInqVarParam
-      end interface
-      interface
-        subroutine vlistDefVarCode(vlistID,varID,code) bind(c,name='vlistDefVarCode')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: code
-        end subroutine vlistDefVarCode
-      end interface
-      interface
-        function vlistInqVarCode(vlistID,varID) bind(c,name='vlistInqVarCode')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCode
-        end function vlistInqVarCode
-      end interface
-      interface
-        subroutine vlistDefVarDatatype(vlistID,varID,datatype) bind(c,name='vlistDefVarDatatype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: datatype
-        end subroutine vlistDefVarDatatype
-      end interface
-      interface
-        function vlistInqVarDatatype(vlistID,varID) bind(c,name='vlistInqVarDatatype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarDatatype
-        end function vlistInqVarDatatype
-      end interface
-      interface
-        subroutine vlistDefVarChunkType(vlistID,varID,chunktype) bind(c,name='vlistDefVarChunkType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: chunktype
-        end subroutine vlistDefVarChunkType
-      end interface
-      interface
-        function vlistInqVarChunkType(vlistID,varID) bind(c,name='vlistInqVarChunkType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarChunkType
-        end function vlistInqVarChunkType
-      end interface
-      interface
-        subroutine vlistDefVarXYZ(vlistID,varID,xyz) bind(c,name='vlistDefVarXYZ')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: xyz
-        end subroutine vlistDefVarXYZ
-      end interface
-      interface
-        function vlistInqVarXYZ(vlistID,varID) bind(c,name='vlistInqVarXYZ')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarXYZ
-        end function vlistInqVarXYZ
-      end interface
-      interface
-        function vlistInqVarNumber(vlistID,varID) bind(c,name='vlistInqVarNumber')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarNumber
-        end function vlistInqVarNumber
-      end interface
-      interface
-        subroutine vlistDefVarInstitut(vlistID,varID,instID) bind(c,name='vlistDefVarInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: instID
-        end subroutine vlistDefVarInstitut
-      end interface
-      interface
-        function vlistInqVarInstitut(vlistID,varID) bind(c,name='vlistInqVarInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarInstitut
-        end function vlistInqVarInstitut
-      end interface
-      interface
-        subroutine vlistDefVarModel(vlistID,varID,modelID) bind(c,name='vlistDefVarModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: modelID
-        end subroutine vlistDefVarModel
-      end interface
-      interface
-        function vlistInqVarModel(vlistID,varID) bind(c,name='vlistInqVarModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarModel
-        end function vlistInqVarModel
-      end interface
-      interface
-        subroutine vlistDefVarTable(vlistID,varID,tableID) bind(c,name='vlistDefVarTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: tableID
-        end subroutine vlistDefVarTable
-      end interface
-      interface
-        function vlistInqVarTable(vlistID,varID) bind(c,name='vlistInqVarTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTable
-        end function vlistInqVarTable
-      end interface
-      interface
-        subroutine vlistDefVarName(vlistID,varID,name) bind(c,name='vlistDefVarName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine vlistDefVarName
-      end interface
-      interface
-        subroutine vlistInqVarName(vlistID,varID,name) bind(c,name='vlistInqVarName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine vlistInqVarName
-      end interface
-      interface
-        subroutine vlistDefVarStdname(vlistID,varID,stdname) bind(c,name='vlistDefVarStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine vlistDefVarStdname
-      end interface
-      interface
-        subroutine vlistInqVarStdname(vlistID,varID,stdname) bind(c,name='vlistInqVarStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine vlistInqVarStdname
-      end interface
-      interface
-        subroutine vlistDefVarLongname(vlistID,varID,longname) bind(c,name='vlistDefVarLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine vlistDefVarLongname
-      end interface
-      interface
-        subroutine vlistInqVarLongname(vlistID,varID,longname) bind(c,name='vlistInqVarLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine vlistInqVarLongname
-      end interface
-      interface
-        subroutine vlistDefVarUnits(vlistID,varID,units) bind(c,name='vlistDefVarUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine vlistDefVarUnits
-      end interface
-      interface
-        subroutine vlistInqVarUnits(vlistID,varID,units) bind(c,name='vlistInqVarUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine vlistInqVarUnits
-      end interface
-      interface
-        subroutine vlistDefVarMissval(vlistID,varID,missval) bind(c,name='vlistDefVarMissval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: missval
-        end subroutine vlistDefVarMissval
-      end interface
-      interface
-        function vlistInqVarMissval(vlistID,varID) bind(c,name='vlistInqVarMissval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarMissval
-        end function vlistInqVarMissval
-      end interface
-      interface
-        subroutine vlistDefVarExtra(vlistID,varID,extra) bind(c,name='vlistDefVarExtra')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: extra
-        end subroutine vlistDefVarExtra
-      end interface
-      interface
-        subroutine vlistInqVarExtra(vlistID,varID,extra) bind(c,name='vlistInqVarExtra')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: extra
-        end subroutine vlistInqVarExtra
-      end interface
-      interface
-        subroutine vlistDefVarScalefactor(vlistID,varID,scalefactor) bind(c,name='vlistDefVarScalefactor')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: scalefactor
-        end subroutine vlistDefVarScalefactor
-      end interface
-      interface
-        function vlistInqVarScalefactor(vlistID,varID) bind(c,name='vlistInqVarScalefactor')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarScalefactor
-        end function vlistInqVarScalefactor
-      end interface
-      interface
-        subroutine vlistDefVarAddoffset(vlistID,varID,addoffset) bind(c,name='vlistDefVarAddoffset')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: addoffset
-        end subroutine vlistDefVarAddoffset
-      end interface
-      interface
-        function vlistInqVarAddoffset(vlistID,varID) bind(c,name='vlistInqVarAddoffset')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarAddoffset
-        end function vlistInqVarAddoffset
-      end interface
-      interface
-        subroutine vlistDefVarTimave(vlistID,varID,timave) bind(c,name='vlistDefVarTimave')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: timave
-        end subroutine vlistDefVarTimave
-      end interface
-      interface
-        function vlistInqVarTimave(vlistID,varID) bind(c,name='vlistInqVarTimave')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTimave
-        end function vlistInqVarTimave
-      end interface
-      interface
-        subroutine vlistDefVarTimaccu(vlistID,varID,timaccu) bind(c,name='vlistDefVarTimaccu')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: timaccu
-        end subroutine vlistDefVarTimaccu
-      end interface
-      interface
-        function vlistInqVarTimaccu(vlistID,varID) bind(c,name='vlistInqVarTimaccu')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTimaccu
-        end function vlistInqVarTimaccu
-      end interface
-      interface
-        subroutine vlistDefVarTypeOfGeneratingProcess(vlistID,varID,typeOfGeneratingProcess) bind(c,&
-       name='vlistDefVarTypeOfGeneratingProcess')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: typeOfGeneratingProcess
-        end subroutine vlistDefVarTypeOfGeneratingProcess
-      end interface
-      interface
-        function vlistInqVarTypeOfGeneratingProcess(vlistID,varID) bind(c,name='vlistInqVarTypeOfGeneratingProcess')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTypeOfGeneratingProcess
-        end function vlistInqVarTypeOfGeneratingProcess
-      end interface
-      interface
-        subroutine vlistDefVarProductDefinitionTemplate(vlistID,varID,productDefinitionTemplate) bind(c,&
-       name='vlistDefVarProductDefinitionTemplate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: productDefinitionTemplate
-        end subroutine vlistDefVarProductDefinitionTemplate
-      end interface
-      interface
-        function vlistInqVarProductDefinitionTemplate(vlistID,varID) bind(c,name='vlistInqVarProductDefinitionTemplate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarProductDefinitionTemplate
-        end function vlistInqVarProductDefinitionTemplate
-      end interface
-      interface
-        function vlistInqVarSize(vlistID,varID) bind(c,name='vlistInqVarSize')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarSize
-        end function vlistInqVarSize
-      end interface
-      interface
-        subroutine vlistDefIndex(vlistID,varID,levID,index) bind(c,name='vlistDefIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int), value :: index
-        end subroutine vlistDefIndex
-      end interface
-      interface
-        function vlistInqIndex(vlistID,varID,levID) bind(c,name='vlistInqIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int) :: vlistInqIndex
-        end function vlistInqIndex
-      end interface
-      interface
-        subroutine vlistDefFlag(vlistID,varID,levID,flag) bind(c,name='vlistDefFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int), value :: flag
-        end subroutine vlistDefFlag
-      end interface
-      interface
-        function vlistInqFlag(vlistID,varID,levID) bind(c,name='vlistInqFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int) :: vlistInqFlag
-        end function vlistInqFlag
-      end interface
-      interface
-        function vlistFindVar(vlistID,fvarID) bind(c,name='vlistFindVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: fvarID
-          integer(kind=c_int) :: vlistFindVar
-        end function vlistFindVar
-      end interface
-      interface
-        function vlistFindLevel(vlistID,fvarID,flevelID) bind(c,name='vlistFindLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: fvarID
-          integer(kind=c_int), value :: flevelID
-          integer(kind=c_int) :: vlistFindLevel
-        end function vlistFindLevel
-      end interface
-      interface
-        function vlistMergedVar(vlistID,varID) bind(c,name='vlistMergedVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistMergedVar
-        end function vlistMergedVar
-      end interface
-      interface
-        function vlistMergedLevel(vlistID,varID,levelID) bind(c,name='vlistMergedLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          integer(kind=c_int) :: vlistMergedLevel
-        end function vlistMergedLevel
-      end interface
-      interface
-        subroutine vlistDefVarEnsemble(vlistID,varID,ensID,ensCount,forecast_type) bind(c,name='vlistDefVarEnsemble')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: ensID
-          integer(kind=c_int), value :: ensCount
-          integer(kind=c_int), value :: forecast_type
-        end subroutine vlistDefVarEnsemble
-      end interface
-      interface
-        function vlistInqVarEnsemble(vlistID,varID,ensID,ensCount,forecast_type) bind(c,name='vlistInqVarEnsemble')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: ensID
-          integer(kind=c_int), intent(out) :: ensCount
-          integer(kind=c_int), intent(out) :: forecast_type
-          integer(kind=c_int) :: vlistInqVarEnsemble
-        end function vlistInqVarEnsemble
-      end interface
-      interface
-        subroutine cdiClearAdditionalKeys() bind(c,name='cdiClearAdditionalKeys')
-        end subroutine cdiClearAdditionalKeys
-      end interface
-      interface
-        subroutine cdiDefAdditionalKey(string) bind(c,name='cdiDefAdditionalKey')
-          import :: c_char
-          character(kind=c_char), dimension(*) :: string
-        end subroutine cdiDefAdditionalKey
-      end interface
-      interface
-        subroutine vlistDefVarIntKey(vlistID,varID,name,value) bind(c,name='vlistDefVarIntKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: value
-        end subroutine vlistDefVarIntKey
-      end interface
-      interface
-        subroutine vlistDefVarDblKey(vlistID,varID,name,value) bind(c,name='vlistDefVarDblKey')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          real(kind=c_double), value :: value
-        end subroutine vlistDefVarDblKey
-      end interface
-      interface
-        function vlistHasVarKey(vlistID,varID,name) bind(c,name='vlistHasVarKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistHasVarKey
-        end function vlistHasVarKey
-      end interface
-      interface
-        function vlistInqVarDblKey(vlistID,varID,name) bind(c,name='vlistInqVarDblKey')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          real(kind=c_double) :: vlistInqVarDblKey
-        end function vlistInqVarDblKey
-      end interface
-      interface
-        function vlistInqVarIntKey(vlistID,varID,name) bind(c,name='vlistInqVarIntKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistInqVarIntKey
-        end function vlistInqVarIntKey
-      end interface
-      interface
-        function vlistInqNatts(vlistID,varID,nattsp) bind(c,name='vlistInqNatts')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: nattsp
-          integer(kind=c_int) :: vlistInqNatts
-        end function vlistInqNatts
-      end interface
-      interface
-        function vlistInqAtt(vlistID,varID,attrnum,name,typep,lenp) bind(c,name='vlistInqAtt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: attrnum
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), intent(out) :: typep
-          integer(kind=c_int), intent(out) :: lenp
-          integer(kind=c_int) :: vlistInqAtt
-        end function vlistInqAtt
-      end interface
-      interface
-        function vlistDelAtt(vlistID,varID,name) bind(c,name='vlistDelAtt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistDelAtt
-        end function vlistDelAtt
-      end interface
-      interface
-        function vlistDefAttInt(vlistID,varID,name,type,len,ip_vec) bind(c,name='vlistDefAttInt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: type
-          integer(kind=c_int), value :: len
-          integer(kind=c_int), intent(in), dimension(*) :: ip_vec
-          integer(kind=c_int) :: vlistDefAttInt
-        end function vlistDefAttInt
-      end interface
-      interface
-        function vlistDefAttFlt(vlistID,varID,name,type,len,dp_vec) bind(c,name='vlistDefAttFlt')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: type
-          integer(kind=c_int), value :: len
-          real(kind=c_double), intent(in), dimension(*) :: dp_vec
-          integer(kind=c_int) :: vlistDefAttFlt
-        end function vlistDefAttFlt
-      end interface
-      interface
-        function vlistDefAttTxt(vlistID,varID,name,len,tp_cbuf) bind(c,name='vlistDefAttTxt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: len
-          character(kind=c_char), dimension(*) :: tp_cbuf
-          integer(kind=c_int) :: vlistDefAttTxt
-        end function vlistDefAttTxt
-      end interface
-      interface
-        function vlistInqAttInt(vlistID,varID,name,mlen,ip_vec) bind(c,name='vlistInqAttInt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          integer(kind=c_int), intent(out), dimension(*) :: ip_vec
-          integer(kind=c_int) :: vlistInqAttInt
-        end function vlistInqAttInt
-      end interface
-      interface
-        function vlistInqAttFlt(vlistID,varID,name,mlen,dp_vec) bind(c,name='vlistInqAttFlt')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          real(kind=c_double), intent(out), dimension(*) :: dp_vec
-          integer(kind=c_int) :: vlistInqAttFlt
-        end function vlistInqAttFlt
-      end interface
-      interface
-        function vlistInqAttTxt(vlistID,varID,name,mlen,tp_cbuf) bind(c,name='vlistInqAttTxt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          character(kind=c_char), dimension(*) :: tp_cbuf
-          integer(kind=c_int) :: vlistInqAttTxt
-        end function vlistInqAttTxt
-      end interface
-      interface
-        subroutine gridName(gridtype,gridnamev) bind(c,name='gridName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridtype
-          character(kind=c_char), dimension(*) :: gridnamev
-        end subroutine gridName
-      end interface
-      interface
-        subroutine gridCompress(gridID) bind(c,name='gridCompress')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-        end subroutine gridCompress
-      end interface
-      interface
-        subroutine gridDefMaskGME(gridID,mask_vec) bind(c,name='gridDefMaskGME')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(in), dimension(*) :: mask_vec
-        end subroutine gridDefMaskGME
-      end interface
-      interface
-        function gridInqMaskGME(gridID,mask_vec) bind(c,name='gridInqMaskGME')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: mask_vec
-          integer(kind=c_int) :: gridInqMaskGME
-        end function gridInqMaskGME
-      end interface
-      interface
-        subroutine gridDefMask(gridID,mask_vec) bind(c,name='gridDefMask')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(in), dimension(*) :: mask_vec
-        end subroutine gridDefMask
-      end interface
-      interface
-        function gridInqMask(gridID,mask_vec) bind(c,name='gridInqMask')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: mask_vec
-          integer(kind=c_int) :: gridInqMask
-        end function gridInqMask
-      end interface
-      interface
-        subroutine gridPrint(gridID,opt) bind(c,name='gridPrint')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: opt
-        end subroutine gridPrint
-      end interface
-      interface
-        function gridCreate(gridtype,size) bind(c,name='gridCreate')
-          import :: c_int
-          integer(kind=c_int), value :: gridtype
-          integer(kind=c_int), value :: size
-          integer(kind=c_int) :: gridCreate
-        end function gridCreate
-      end interface
-      interface
-        subroutine gridDestroy(gridID) bind(c,name='gridDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-        end subroutine gridDestroy
-      end interface
-      interface
-        function gridDuplicate(gridID) bind(c,name='gridDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridDuplicate
-        end function gridDuplicate
-      end interface
-      interface
-        function gridInqType(gridID) bind(c,name='gridInqType')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqType
-        end function gridInqType
-      end interface
-      interface
-        function gridInqSize(gridID) bind(c,name='gridInqSize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqSize
-        end function gridInqSize
-      end interface
-      interface
-        subroutine gridDefXsize(gridID,xsize) bind(c,name='gridDefXsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: xsize
-        end subroutine gridDefXsize
-      end interface
-      interface
-        function gridInqXsize(gridID) bind(c,name='gridInqXsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqXsize
-        end function gridInqXsize
-      end interface
-      interface
-        subroutine gridDefYsize(gridID,ysize) bind(c,name='gridDefYsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ysize
-        end subroutine gridDefYsize
-      end interface
-      interface
-        function gridInqYsize(gridID) bind(c,name='gridInqYsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqYsize
-        end function gridInqYsize
-      end interface
-      interface
-        subroutine gridDefNP(gridID,np) bind(c,name='gridDefNP')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: np
-        end subroutine gridDefNP
-      end interface
-      interface
-        function gridInqNP(gridID) bind(c,name='gridInqNP')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNP
-        end function gridInqNP
-      end interface
-      interface
-        subroutine gridDefXvals(gridID,xvals_vec) bind(c,name='gridDefXvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: xvals_vec
-        end subroutine gridDefXvals
-      end interface
-      interface
-        function gridInqXvals(gridID,xvals_vec) bind(c,name='gridInqXvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: xvals_vec
-          integer(kind=c_int) :: gridInqXvals
-        end function gridInqXvals
-      end interface
-      interface
-        subroutine gridDefYvals(gridID,yvals_vec) bind(c,name='gridDefYvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: yvals_vec
-        end subroutine gridDefYvals
-      end interface
-      interface
-        function gridInqYvals(gridID,yvals_vec) bind(c,name='gridInqYvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: yvals_vec
-          integer(kind=c_int) :: gridInqYvals
-        end function gridInqYvals
-      end interface
-      interface
-        subroutine gridDefXname(gridID,xname) bind(c,name='gridDefXname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xname
-        end subroutine gridDefXname
-      end interface
-      interface
-        subroutine gridInqXname(gridID,xname) bind(c,name='gridInqXname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xname
-        end subroutine gridInqXname
-      end interface
-      interface
-        subroutine gridDefXlongname(gridID,xlongname) bind(c,name='gridDefXlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xlongname
-        end subroutine gridDefXlongname
-      end interface
-      interface
-        subroutine gridInqXlongname(gridID,xlongname) bind(c,name='gridInqXlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xlongname
-        end subroutine gridInqXlongname
-      end interface
-      interface
-        subroutine gridDefXunits(gridID,xunits) bind(c,name='gridDefXunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xunits
-        end subroutine gridDefXunits
-      end interface
-      interface
-        subroutine gridInqXunits(gridID,xunits) bind(c,name='gridInqXunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xunits
-        end subroutine gridInqXunits
-      end interface
-      interface
-        subroutine gridDefYname(gridID,yname) bind(c,name='gridDefYname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yname
-        end subroutine gridDefYname
-      end interface
-      interface
-        subroutine gridInqYname(gridID,yname) bind(c,name='gridInqYname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yname
-        end subroutine gridInqYname
-      end interface
-      interface
-        subroutine gridDefYlongname(gridID,ylongname) bind(c,name='gridDefYlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ylongname
-        end subroutine gridDefYlongname
-      end interface
-      interface
-        subroutine gridInqYlongname(gridID,ylongname) bind(c,name='gridInqYlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ylongname
-        end subroutine gridInqYlongname
-      end interface
-      interface
-        subroutine gridDefYunits(gridID,yunits) bind(c,name='gridDefYunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yunits
-        end subroutine gridDefYunits
-      end interface
-      interface
-        subroutine gridInqYunits(gridID,yunits) bind(c,name='gridInqYunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yunits
-        end subroutine gridInqYunits
-      end interface
-      interface
-        subroutine gridInqXstdname(gridID,xstdname) bind(c,name='gridInqXstdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xstdname
-        end subroutine gridInqXstdname
-      end interface
-      interface
-        subroutine gridInqYstdname(gridID,ystdname) bind(c,name='gridInqYstdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ystdname
-        end subroutine gridInqYstdname
-      end interface
-      interface
-        subroutine gridDefPrec(gridID,prec) bind(c,name='gridDefPrec')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: prec
-        end subroutine gridDefPrec
-      end interface
-      interface
-        function gridInqPrec(gridID) bind(c,name='gridInqPrec')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqPrec
-        end function gridInqPrec
-      end interface
-      interface
-        function gridInqXval(gridID,index) bind(c,name='gridInqXval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: gridInqXval
-        end function gridInqXval
-      end interface
-      interface
-        function gridInqYval(gridID,index) bind(c,name='gridInqYval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: gridInqYval
-        end function gridInqYval
-      end interface
-      interface
-        function gridInqXinc(gridID) bind(c,name='gridInqXinc')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqXinc
-        end function gridInqXinc
-      end interface
-      interface
-        function gridInqYinc(gridID) bind(c,name='gridInqYinc')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqYinc
-        end function gridInqYinc
-      end interface
-      interface
-        function gridIsCircular(gridID) bind(c,name='gridIsCircular')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridIsCircular
-        end function gridIsCircular
-      end interface
-      interface
-        function gridIsRotated(gridID) bind(c,name='gridIsRotated')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridIsRotated
-        end function gridIsRotated
-      end interface
-      interface
-        subroutine gridDefXpole(gridID,xpole) bind(c,name='gridDefXpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: xpole
-        end subroutine gridDefXpole
-      end interface
-      interface
-        function gridInqXpole(gridID) bind(c,name='gridInqXpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqXpole
-        end function gridInqXpole
-      end interface
-      interface
-        subroutine gridDefYpole(gridID,ypole) bind(c,name='gridDefYpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: ypole
-        end subroutine gridDefYpole
-      end interface
-      interface
-        function gridInqYpole(gridID) bind(c,name='gridInqYpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqYpole
-        end function gridInqYpole
-      end interface
-      interface
-        subroutine gridDefAngle(gridID,angle) bind(c,name='gridDefAngle')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: angle
-        end subroutine gridDefAngle
-      end interface
-      interface
-        function gridInqAngle(gridID) bind(c,name='gridInqAngle')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqAngle
-        end function gridInqAngle
-      end interface
-      interface
-        function gridInqTrunc(gridID) bind(c,name='gridInqTrunc')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqTrunc
-        end function gridInqTrunc
-      end interface
-      interface
-        subroutine gridDefTrunc(gridID,trunc) bind(c,name='gridDefTrunc')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: trunc
-        end subroutine gridDefTrunc
-      end interface
-      interface
-        subroutine gridDefGMEnd(gridID,nd) bind(c,name='gridDefGMEnd')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nd
-        end subroutine gridDefGMEnd
-      end interface
-      interface
-        function gridInqGMEnd(gridID) bind(c,name='gridInqGMEnd')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEnd
-        end function gridInqGMEnd
-      end interface
-      interface
-        subroutine gridDefGMEni(gridID,ni) bind(c,name='gridDefGMEni')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni
-        end subroutine gridDefGMEni
-      end interface
-      interface
-        function gridInqGMEni(gridID) bind(c,name='gridInqGMEni')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni
-        end function gridInqGMEni
-      end interface
-      interface
-        subroutine gridDefGMEni2(gridID,ni2) bind(c,name='gridDefGMEni2')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni2
-        end subroutine gridDefGMEni2
-      end interface
-      interface
-        function gridInqGMEni2(gridID) bind(c,name='gridInqGMEni2')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni2
-        end function gridInqGMEni2
-      end interface
-      interface
-        subroutine gridDefGMEni3(gridID,ni3) bind(c,name='gridDefGMEni3')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni3
-        end subroutine gridDefGMEni3
-      end interface
-      interface
-        function gridInqGMEni3(gridID) bind(c,name='gridInqGMEni3')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni3
-        end function gridInqGMEni3
-      end interface
-      interface
-        subroutine gridDefNumber(gridID,number) bind(c,name='gridDefNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: number
-        end subroutine gridDefNumber
-      end interface
-      interface
-        function gridInqNumber(gridID) bind(c,name='gridInqNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNumber
-        end function gridInqNumber
-      end interface
-      interface
-        subroutine gridDefPosition(gridID,position) bind(c,name='gridDefPosition')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: position
-        end subroutine gridDefPosition
-      end interface
-      interface
-        function gridInqPosition(gridID) bind(c,name='gridInqPosition')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqPosition
-        end function gridInqPosition
-      end interface
-      interface
-        subroutine gridDefReference(gridID,reference) bind(c,name='gridDefReference')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: reference
-        end subroutine gridDefReference
-      end interface
-      interface
-        function gridInqReference(gridID,reference) bind(c,name='gridInqReference')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: reference
-          integer(kind=c_int) :: gridInqReference
-        end function gridInqReference
-      end interface
-      interface
-        subroutine gridDefUUID(gridID,uuid) bind(c,name='gridDefUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_signed_char), intent(in), dimension(16) :: uuid
-        end subroutine gridDefUUID
-      end interface
-      interface
-        subroutine gridInqUUID(gridID,uuid) bind(c,name='gridInqUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_signed_char), intent(out), dimension(16) :: uuid
-        end subroutine gridInqUUID
-      end interface
-      interface
-        subroutine gridDefLCC(gridID,originLon,originLat,lonParY,lat1,lat2,xinc,yinc,projflag,scanflag) bind(c,name='gridDefLCC')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: originLon
-          real(kind=c_double), value :: originLat
-          real(kind=c_double), value :: lonParY
-          real(kind=c_double), value :: lat1
-          real(kind=c_double), value :: lat2
-          real(kind=c_double), value :: xinc
-          real(kind=c_double), value :: yinc
-          integer(kind=c_int), value :: projflag
-          integer(kind=c_int), value :: scanflag
-        end subroutine gridDefLCC
-      end interface
-      interface
-        subroutine gridInqLCC(gridID,originLon,originLat,lonParY,lat1,lat2,xinc,yinc,projflag,scanflag) bind(c,name='gridInqLCC')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: originLon
-          real(kind=c_double), intent(out) :: originLat
-          real(kind=c_double), intent(out) :: lonParY
-          real(kind=c_double), intent(out) :: lat1
-          real(kind=c_double), intent(out) :: lat2
-          real(kind=c_double), intent(out) :: xinc
-          real(kind=c_double), intent(out) :: yinc
-          integer(kind=c_int), intent(out) :: projflag
-          integer(kind=c_int), intent(out) :: scanflag
-        end subroutine gridInqLCC
-      end interface
-      interface
-        subroutine gridDefLcc2(gridID,earth_radius,lon_0,lat_0,lat_1,lat_2) bind(c,name='gridDefLcc2')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: earth_radius
-          real(kind=c_double), value :: lon_0
-          real(kind=c_double), value :: lat_0
-          real(kind=c_double), value :: lat_1
-          real(kind=c_double), value :: lat_2
-        end subroutine gridDefLcc2
-      end interface
-      interface
-        subroutine gridInqLcc2(gridID,earth_radius,lon_0,lat_0,lat_1,lat_2) bind(c,name='gridInqLcc2')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: earth_radius
-          real(kind=c_double), intent(out) :: lon_0
-          real(kind=c_double), intent(out) :: lat_0
-          real(kind=c_double), intent(out) :: lat_1
-          real(kind=c_double), intent(out) :: lat_2
-        end subroutine gridInqLcc2
-      end interface
-      interface
-        subroutine gridDefLaea(gridID,earth_radius,lon_0,lat_0) bind(c,name='gridDefLaea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: earth_radius
-          real(kind=c_double), value :: lon_0
-          real(kind=c_double), value :: lat_0
-        end subroutine gridDefLaea
-      end interface
-      interface
-        subroutine gridInqLaea(gridID,earth_radius,lon_0,lat_0) bind(c,name='gridInqLaea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: earth_radius
-          real(kind=c_double), intent(out) :: lon_0
-          real(kind=c_double), intent(out) :: lat_0
-        end subroutine gridInqLaea
-      end interface
-      interface
-        subroutine gridDefArea(gridID,area_vec) bind(c,name='gridDefArea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: area_vec
-        end subroutine gridDefArea
-      end interface
-      interface
-        subroutine gridInqArea(gridID,area_vec) bind(c,name='gridInqArea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: area_vec
-        end subroutine gridInqArea
-      end interface
-      interface
-        function gridHasArea(gridID) bind(c,name='gridHasArea')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridHasArea
-        end function gridHasArea
-      end interface
-      interface
-        subroutine gridDefNvertex(gridID,nvertex) bind(c,name='gridDefNvertex')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nvertex
-        end subroutine gridDefNvertex
-      end interface
-      interface
-        function gridInqNvertex(gridID) bind(c,name='gridInqNvertex')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNvertex
-        end function gridInqNvertex
-      end interface
-      interface
-        subroutine gridDefXbounds(gridID,xbounds_vec) bind(c,name='gridDefXbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: xbounds_vec
-        end subroutine gridDefXbounds
-      end interface
-      interface
-        function gridInqXbounds(gridID,xbounds_vec) bind(c,name='gridInqXbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: xbounds_vec
-          integer(kind=c_int) :: gridInqXbounds
-        end function gridInqXbounds
-      end interface
-      interface
-        subroutine gridDefYbounds(gridID,ybounds_vec) bind(c,name='gridDefYbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: ybounds_vec
-        end subroutine gridDefYbounds
-      end interface
-      interface
-        function gridInqYbounds(gridID,ybounds_vec) bind(c,name='gridInqYbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: ybounds_vec
-          integer(kind=c_int) :: gridInqYbounds
-        end function gridInqYbounds
-      end interface
-      interface
-        subroutine gridDefRowlon(gridID,nrowlon,rowlon_vec) bind(c,name='gridDefRowlon')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nrowlon
-          integer(kind=c_int), intent(in), dimension(*) :: rowlon_vec
-        end subroutine gridDefRowlon
-      end interface
-      interface
-        subroutine gridInqRowlon(gridID,rowlon_vec) bind(c,name='gridInqRowlon')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: rowlon_vec
-        end subroutine gridInqRowlon
-      end interface
-      interface
-        subroutine gridChangeType(gridID,gridtype) bind(c,name='gridChangeType')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: gridtype
-        end subroutine gridChangeType
-      end interface
-      interface
-        subroutine gridDefComplexPacking(gridID,lpack) bind(c,name='gridDefComplexPacking')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: lpack
-        end subroutine gridDefComplexPacking
-      end interface
-      interface
-        function gridInqComplexPacking(gridID) bind(c,name='gridInqComplexPacking')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqComplexPacking
-        end function gridInqComplexPacking
-      end interface
-      interface
-        subroutine zaxisName(zaxistype,zaxisnamev) bind(c,name='zaxisName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxistype
-          character(kind=c_char), dimension(*) :: zaxisnamev
-        end subroutine zaxisName
-      end interface
-      interface
-        function zaxisCreate(zaxistype,size) bind(c,name='zaxisCreate')
-          import :: c_int
-          integer(kind=c_int), value :: zaxistype
-          integer(kind=c_int), value :: size
-          integer(kind=c_int) :: zaxisCreate
-        end function zaxisCreate
-      end interface
-      interface
-        subroutine zaxisDestroy(zaxisID) bind(c,name='zaxisDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-        end subroutine zaxisDestroy
-      end interface
-      interface
-        function zaxisInqType(zaxisID) bind(c,name='zaxisInqType')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqType
-        end function zaxisInqType
-      end interface
-      interface
-        function zaxisInqSize(zaxisID) bind(c,name='zaxisInqSize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqSize
-        end function zaxisInqSize
-      end interface
-      interface
-        function zaxisDuplicate(zaxisID) bind(c,name='zaxisDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisDuplicate
-        end function zaxisDuplicate
-      end interface
-      interface
-        subroutine zaxisResize(zaxisID,size) bind(c,name='zaxisResize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: size
-        end subroutine zaxisResize
-      end interface
-      interface
-        subroutine zaxisPrint(zaxisID) bind(c,name='zaxisPrint')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-        end subroutine zaxisPrint
-      end interface
-      interface
-        subroutine zaxisDefLevels(zaxisID,levels_vec) bind(c,name='zaxisDefLevels')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: levels_vec
-        end subroutine zaxisDefLevels
-      end interface
-      interface
-        subroutine zaxisInqLevels(zaxisID,levels_vec) bind(c,name='zaxisInqLevels')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: levels_vec
-        end subroutine zaxisInqLevels
-      end interface
-      interface
-        subroutine zaxisDefLevel(zaxisID,levelID,levels) bind(c,name='zaxisDefLevel')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), value :: levels
-        end subroutine zaxisDefLevel
-      end interface
-      interface
-        function zaxisInqLevel(zaxisID,levelID) bind(c,name='zaxisInqLevel')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double) :: zaxisInqLevel
-        end function zaxisInqLevel
-      end interface
-      interface
-        subroutine zaxisDefNlevRef(gridID,nhlev) bind(c,name='zaxisDefNlevRef')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nhlev
-        end subroutine zaxisDefNlevRef
-      end interface
-      interface
-        function zaxisInqNlevRef(gridID) bind(c,name='zaxisInqNlevRef')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: zaxisInqNlevRef
-        end function zaxisInqNlevRef
-      end interface
-      interface
-        subroutine zaxisDefNumber(gridID,number) bind(c,name='zaxisDefNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: number
-        end subroutine zaxisDefNumber
-      end interface
-      interface
-        function zaxisInqNumber(gridID) bind(c,name='zaxisInqNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: zaxisInqNumber
-        end function zaxisInqNumber
-      end interface
-      interface
-        subroutine zaxisDefUUID(zaxisID,uuid) bind(c,name='zaxisDefUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_signed_char), intent(in), dimension(16) :: uuid
-        end subroutine zaxisDefUUID
-      end interface
-      interface
-        subroutine zaxisInqUUID(zaxisID,uuid) bind(c,name='zaxisInqUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_signed_char), intent(out), dimension(16) :: uuid
-        end subroutine zaxisInqUUID
-      end interface
-      interface
-        subroutine zaxisDefName(zaxisID,name) bind(c,name='zaxisDefName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine zaxisDefName
-      end interface
-      interface
-        subroutine zaxisInqName(zaxisID,name) bind(c,name='zaxisInqName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine zaxisInqName
-      end interface
-      interface
-        subroutine zaxisDefLongname(zaxisID,longname) bind(c,name='zaxisDefLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine zaxisDefLongname
-      end interface
-      interface
-        subroutine zaxisInqLongname(zaxisID,longname) bind(c,name='zaxisInqLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine zaxisInqLongname
-      end interface
-      interface
-        subroutine zaxisDefUnits(zaxisID,units) bind(c,name='zaxisDefUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine zaxisDefUnits
-      end interface
-      interface
-        subroutine zaxisInqUnits(zaxisID,units) bind(c,name='zaxisInqUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine zaxisInqUnits
-      end interface
-      interface
-        subroutine zaxisInqStdname(zaxisID,stdname) bind(c,name='zaxisInqStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine zaxisInqStdname
-      end interface
-      interface
-        subroutine zaxisDefPrec(zaxisID,prec) bind(c,name='zaxisDefPrec')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: prec
-        end subroutine zaxisDefPrec
-      end interface
-      interface
-        function zaxisInqPrec(zaxisID) bind(c,name='zaxisInqPrec')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqPrec
-        end function zaxisInqPrec
-      end interface
-      interface
-        subroutine zaxisDefPositive(zaxisID,positive) bind(c,name='zaxisDefPositive')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: positive
-        end subroutine zaxisDefPositive
-      end interface
-      interface
-        function zaxisInqPositive(zaxisID) bind(c,name='zaxisInqPositive')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqPositive
-        end function zaxisInqPositive
-      end interface
-      interface
-        subroutine zaxisDefLtype(zaxisID,ltype) bind(c,name='zaxisDefLtype')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: ltype
-        end subroutine zaxisDefLtype
-      end interface
-      interface
-        function zaxisInqLtype(zaxisID) bind(c,name='zaxisInqLtype')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqLtype
-        end function zaxisInqLtype
-      end interface
-      interface
-        function zaxisInqLevelsPtr(zaxisID) bind(c,name='zaxisInqLevelsPtr')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double) :: zaxisInqLevelsPtr
-        end function zaxisInqLevelsPtr
-      end interface
-      interface
-        subroutine zaxisDefVct(zaxisID,size,vct_vec) bind(c,name='zaxisDefVct')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: size
-          real(kind=c_double), intent(in), dimension(*) :: vct_vec
-        end subroutine zaxisDefVct
-      end interface
-      interface
-        subroutine zaxisInqVct(zaxisID,vct_vec) bind(c,name='zaxisInqVct')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: vct_vec
-        end subroutine zaxisInqVct
-      end interface
-      interface
-        function zaxisInqVctSize(zaxisID) bind(c,name='zaxisInqVctSize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqVctSize
-        end function zaxisInqVctSize
-      end interface
-      interface
-        function zaxisInqVctPtr(zaxisID) bind(c,name='zaxisInqVctPtr')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double) :: zaxisInqVctPtr
-        end function zaxisInqVctPtr
-      end interface
-      interface
-        subroutine zaxisDefLbounds(zaxisID,lbounds_vec) bind(c,name='zaxisDefLbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: lbounds_vec
-        end subroutine zaxisDefLbounds
-      end interface
-      interface
-        function zaxisInqLbounds(zaxisID,lbounds_vec) bind(c,name='zaxisInqLbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: lbounds_vec
-          integer(kind=c_int) :: zaxisInqLbounds
-        end function zaxisInqLbounds
-      end interface
-      interface
-        function zaxisInqLbound(zaxisID,index) bind(c,name='zaxisInqLbound')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: zaxisInqLbound
-        end function zaxisInqLbound
-      end interface
-      interface
-        subroutine zaxisDefUbounds(zaxisID,ubounds_vec) bind(c,name='zaxisDefUbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: ubounds_vec
-        end subroutine zaxisDefUbounds
-      end interface
-      interface
-        function zaxisInqUbounds(zaxisID,ubounds_vec) bind(c,name='zaxisInqUbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: ubounds_vec
-          integer(kind=c_int) :: zaxisInqUbounds
-        end function zaxisInqUbounds
-      end interface
-      interface
-        function zaxisInqUbound(zaxisID,index) bind(c,name='zaxisInqUbound')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: zaxisInqUbound
-        end function zaxisInqUbound
-      end interface
-      interface
-        subroutine zaxisDefWeights(zaxisID,weights_vec) bind(c,name='zaxisDefWeights')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: weights_vec
-        end subroutine zaxisDefWeights
-      end interface
-      interface
-        function zaxisInqWeights(zaxisID,weights_vec) bind(c,name='zaxisInqWeights')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: weights_vec
-          integer(kind=c_int) :: zaxisInqWeights
-        end function zaxisInqWeights
-      end interface
-      interface
-        subroutine zaxisChangeType(zaxisID,zaxistype) bind(c,name='zaxisChangeType')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: zaxistype
-        end subroutine zaxisChangeType
-      end interface
-      interface
-        function taxisCreate(timetype) bind(c,name='taxisCreate')
-          import :: c_int
-          integer(kind=c_int), value :: timetype
-          integer(kind=c_int) :: taxisCreate
-        end function taxisCreate
-      end interface
-      interface
-        subroutine taxisDestroy(taxisID) bind(c,name='taxisDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-        end subroutine taxisDestroy
-      end interface
-      interface
-        function taxisDuplicate(taxisID) bind(c,name='taxisDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisDuplicate
-        end function taxisDuplicate
-      end interface
-      interface
-        subroutine taxisCopyTimestep(taxisIDdes,taxisIDsrc) bind(c,name='taxisCopyTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: taxisIDdes
-          integer(kind=c_int), value :: taxisIDsrc
-        end subroutine taxisCopyTimestep
-      end interface
-      interface
-        subroutine taxisDefType(taxisID,type) bind(c,name='taxisDefType')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: type
-        end subroutine taxisDefType
-      end interface
-      interface
-        subroutine taxisDefVdate(taxisID,date) bind(c,name='taxisDefVdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefVdate
-      end interface
-      interface
-        subroutine taxisDefVtime(taxisID,time) bind(c,name='taxisDefVtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefVtime
-      end interface
-      interface
-        function taxisInqVdate(taxisID) bind(c,name='taxisInqVdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqVdate
-        end function taxisInqVdate
-      end interface
-      interface
-        function taxisInqVtime(taxisID) bind(c,name='taxisInqVtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqVtime
-        end function taxisInqVtime
-      end interface
-      interface
-        subroutine taxisDefRdate(taxisID,date) bind(c,name='taxisDefRdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefRdate
-      end interface
-      interface
-        subroutine taxisDefRtime(taxisID,time) bind(c,name='taxisDefRtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefRtime
-      end interface
-      interface
-        function taxisInqRdate(taxisID) bind(c,name='taxisInqRdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqRdate
-        end function taxisInqRdate
-      end interface
-      interface
-        function taxisInqRtime(taxisID) bind(c,name='taxisInqRtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqRtime
-        end function taxisInqRtime
-      end interface
-      interface
-        subroutine taxisDefFdate(taxisID,date) bind(c,name='taxisDefFdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefFdate
-      end interface
-      interface
-        subroutine taxisDefFtime(taxisID,time) bind(c,name='taxisDefFtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefFtime
-      end interface
-      interface
-        function taxisInqFdate(taxisID) bind(c,name='taxisInqFdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqFdate
-        end function taxisInqFdate
-      end interface
-      interface
-        function taxisInqFtime(taxisID) bind(c,name='taxisInqFtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqFtime
-        end function taxisInqFtime
-      end interface
-      interface
-        function taxisHasBounds(taxisID) bind(c,name='taxisHasBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisHasBounds
-        end function taxisHasBounds
-      end interface
-      interface
-        subroutine taxisDeleteBounds(taxisID) bind(c,name='taxisDeleteBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-        end subroutine taxisDeleteBounds
-      end interface
-      interface
-        subroutine taxisDefVdateBounds(taxisID,vdate_lb,vdate_ub) bind(c,name='taxisDefVdateBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: vdate_lb
-          integer(kind=c_int), value :: vdate_ub
-        end subroutine taxisDefVdateBounds
-      end interface
-      interface
-        subroutine taxisDefVtimeBounds(taxisID,vtime_lb,vtime_ub) bind(c,name='taxisDefVtimeBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: vtime_lb
-          integer(kind=c_int), value :: vtime_ub
-        end subroutine taxisDefVtimeBounds
-      end interface
-      interface
-        subroutine taxisInqVdateBounds(taxisID,vdate_lb,vdate_ub) bind(c,name='taxisInqVdateBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), intent(out) :: vdate_lb
-          integer(kind=c_int), intent(out) :: vdate_ub
-        end subroutine taxisInqVdateBounds
-      end interface
-      interface
-        subroutine taxisInqVtimeBounds(taxisID,vtime_lb,vtime_ub) bind(c,name='taxisInqVtimeBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), intent(out) :: vtime_lb
-          integer(kind=c_int), intent(out) :: vtime_ub
-        end subroutine taxisInqVtimeBounds
-      end interface
-      interface
-        subroutine taxisDefCalendar(taxisID,calendar) bind(c,name='taxisDefCalendar')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: calendar
-        end subroutine taxisDefCalendar
-      end interface
-      interface
-        function taxisInqCalendar(taxisID) bind(c,name='taxisInqCalendar')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqCalendar
-        end function taxisInqCalendar
-      end interface
-      interface
-        subroutine taxisDefTunit(taxisID,tunit) bind(c,name='taxisDefTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: tunit
-        end subroutine taxisDefTunit
-      end interface
-      interface
-        function taxisInqTunit(taxisID) bind(c,name='taxisInqTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqTunit
-        end function taxisInqTunit
-      end interface
-      interface
-        subroutine taxisDefForecastTunit(taxisID,tunit) bind(c,name='taxisDefForecastTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: tunit
-        end subroutine taxisDefForecastTunit
-      end interface
-      interface
-        function taxisInqForecastTunit(taxisID) bind(c,name='taxisInqForecastTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqForecastTunit
-        end function taxisInqForecastTunit
-      end interface
-      interface
-        subroutine taxisDefForecastPeriod(taxisID,fc_period) bind(c,name='taxisDefForecastPeriod')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: taxisID
-          real(kind=c_double), value :: fc_period
-        end subroutine taxisDefForecastPeriod
-      end interface
-      interface
-        function taxisInqForecastPeriod(taxisID) bind(c,name='taxisInqForecastPeriod')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: taxisID
-          real(kind=c_double) :: taxisInqForecastPeriod
-        end function taxisInqForecastPeriod
-      end interface
-      interface
-        subroutine taxisDefNumavg(taxisID,numavg) bind(c,name='taxisDefNumavg')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: numavg
-        end subroutine taxisDefNumavg
-      end interface
-      interface
-        function taxisInqType(taxisID) bind(c,name='taxisInqType')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqType
-        end function taxisInqType
-      end interface
-      interface
-        function taxisInqNumavg(taxisID) bind(c,name='taxisInqNumavg')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqNumavg
-        end function taxisInqNumavg
-      end interface
-      interface
-        function institutDef(center,subcenter,name,longname) bind(c,name='institutDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: center
-          integer(kind=c_int), value :: subcenter
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: institutDef
-        end function institutDef
-      end interface
-      interface
-        function institutInq(center,subcenter,name,longname) bind(c,name='institutInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: center
-          integer(kind=c_int), value :: subcenter
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: institutInq
-        end function institutInq
-      end interface
-      interface
-        function institutInqNumber() bind(c,name='institutInqNumber')
-          import :: c_int
-          integer(kind=c_int) :: institutInqNumber
-        end function institutInqNumber
-      end interface
-      interface
-        function institutInqCenter(instID) bind(c,name='institutInqCenter')
-          import :: c_int
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int) :: institutInqCenter
-        end function institutInqCenter
-      end interface
-      interface
-        function institutInqSubcenter(instID) bind(c,name='institutInqSubcenter')
-          import :: c_int
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int) :: institutInqSubcenter
-        end function institutInqSubcenter
-      end interface
-      interface
-        function modelDef(instID,modelgribID,name) bind(c,name='modelDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int), value :: modelgribID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: modelDef
-        end function modelDef
-      end interface
-      interface
-        function modelInq(instID,modelgribID,name) bind(c,name='modelInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int), value :: modelgribID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: modelInq
-        end function modelInq
-      end interface
-      interface
-        function modelInqInstitut(modelID) bind(c,name='modelInqInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int) :: modelInqInstitut
-        end function modelInqInstitut
-      end interface
-      interface
-        function modelInqGribID(modelID) bind(c,name='modelInqGribID')
-          import :: c_int
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int) :: modelInqGribID
-        end function modelInqGribID
-      end interface
-      interface
-        subroutine tableWriteC(filename,tableID) bind(c,name='tableWriteC')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: filename
-          integer(kind=c_int), value :: tableID
-        end subroutine tableWriteC
-      end interface
-      interface
-        subroutine tableWrite(filename,tableID) bind(c,name='tableWrite')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: filename
-          integer(kind=c_int), value :: tableID
-        end subroutine tableWrite
-      end interface
-      interface
-        function tableRead(tablefile) bind(c,name='tableRead')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: tablefile
-          integer(kind=c_int) :: tableRead
-        end function tableRead
-      end interface
-      interface
-        function tableDef(modelID,tablenum,tablename) bind(c,name='tableDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int), value :: tablenum
-          character(kind=c_char), dimension(*) :: tablename
-          integer(kind=c_int) :: tableDef
-        end function tableDef
-      end interface
-      interface
-        subroutine tableDefEntry(tableID,code,name,longname,units) bind(c,name='tableDefEntry')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          character(kind=c_char), dimension(*) :: units
-        end subroutine tableDefEntry
-      end interface
-      interface
-        function tableInq(modelID,tablenum,tablename) bind(c,name='tableInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int), value :: tablenum
-          character(kind=c_char), dimension(*) :: tablename
-          integer(kind=c_int) :: tableInq
-        end function tableInq
-      end interface
-      interface
-        function tableInqNumber() bind(c,name='tableInqNumber')
-          import :: c_int
-          integer(kind=c_int) :: tableInqNumber
-        end function tableInqNumber
-      end interface
-      interface
-        function tableInqNum(tableID) bind(c,name='tableInqNum')
-          import :: c_int
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int) :: tableInqNum
-        end function tableInqNum
-      end interface
-      interface
-        function tableInqModel(tableID) bind(c,name='tableInqModel')
-          import :: c_int
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int) :: tableInqModel
-        end function tableInqModel
-      end interface
-      interface
-        subroutine tableInqPar(tableID,code,name,longname,units) bind(c,name='tableInqPar')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          character(kind=c_char), dimension(*) :: units
-        end subroutine tableInqPar
-      end interface
-      interface
-        function tableInqParCode(tableID,name,code) bind(c,name='tableInqParCode')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), intent(out) :: code
-          integer(kind=c_int) :: tableInqParCode
-        end function tableInqParCode
-      end interface
-      interface
-        function tableInqParName(tableID,code,name) bind(c,name='tableInqParName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: tableInqParName
-        end function tableInqParName
-      end interface
-      interface
-        function tableInqParLongname(tableID,code,longname) bind(c,name='tableInqParLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: tableInqParLongname
-        end function tableInqParLongname
-      end interface
-      interface
-        function tableInqParUnits(tableID,code,units) bind(c,name='tableInqParUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: units
-          integer(kind=c_int) :: tableInqParUnits
-        end function tableInqParUnits
-      end interface
-      interface
-        subroutine streamDefHistory(streamID,size,history) bind(c,name='streamDefHistory')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: size
-          character(kind=c_char), dimension(*) :: history
-        end subroutine streamDefHistory
-      end interface
-      interface
-        function streamInqHistorySize(streamID) bind(c,name='streamInqHistorySize')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqHistorySize
-        end function streamInqHistorySize
-      end interface
-      interface
-        subroutine streamInqHistoryString(streamID,history) bind(c,name='streamInqHistoryString')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: streamID
-          character(kind=c_char), dimension(*) :: history
-        end subroutine streamInqHistoryString
-      end interface
-      interface
-        subroutine gribapiLibraryVersion(major_version,minor_version,revision_version) bind(c,name='gribapiLibraryVersion')
-          import :: c_int
-          integer(kind=c_int), intent(out) :: major_version
-          integer(kind=c_int), intent(out) :: minor_version
-          integer(kind=c_int), intent(out) :: revision_version
-        end subroutine gribapiLibraryVersion
-      end interface
-
-      public :: strlen
-      public :: getchar
-      public :: getchar_unlocked
-      public :: cdiReset
-      public :: cdiStringError
-      public :: cdiDebug
-      public :: cdiLibraryVersion
-      public :: cdiPrintVersion
-      public :: cdiHaveFiletype
-      public :: cdiDefMissval
-      public :: cdiInqMissval
-      public :: cdiDefGlobal
-      public :: namespaceNew
-      public :: namespaceSetActive
-      public :: namespaceDelete
-      public :: cdiParamToString
-      public :: cdiDecodeParam
-      public :: cdiEncodeParam
-      public :: cdiDecodeDate
-      public :: cdiEncodeDate
-      public :: cdiDecodeTime
-      public :: cdiEncodeTime
-      public :: cdiGetFiletype
-      public :: streamOpenRead
-      public :: streamOpenWrite
-      public :: streamOpenAppend
-      public :: streamClose
-      public :: streamSync
-      public :: streamDefVlist
-      public :: streamInqVlist
-      public :: streamInqVlistIDorig
-      public :: streamInqFiletype
-      public :: streamDefByteorder
-      public :: streamInqByteorder
-      public :: streamDefCompType
-      public :: streamInqCompType
-      public :: streamDefCompLevel
-      public :: streamInqCompLevel
-      public :: streamDefTimestep
-      public :: streamInqTimestep
-      public :: streamInqCurTimestepID
-      public :: streamFilename
-      public :: streamFilesuffix
-      public :: streamInqNvars
-      public :: streamWriteVar
-      public :: streamWriteVarF
-      public :: streamReadVar
-      public :: streamReadVarF
-      public :: streamWriteVarSlice
-      public :: streamWriteVarSliceF
-      public :: streamReadVarSlice
-      public :: streamReadVarSliceF
-      public :: streamDefRecord
-      public :: streamInqRecord
-      public :: streamWriteRecord
-      public :: streamWriteRecordF
-      public :: streamReadRecord
-      public :: streamCopyRecord
-      public :: vlistCreate
-      public :: vlistDestroy
-      public :: vlistDuplicate
-      public :: vlistCopy
-      public :: vlistCopyFlag
-      public :: vlistClearFlag
-      public :: vlistCat
-      public :: vlistMerge
-      public :: vlistPrint
-      public :: vlistNumber
-      public :: vlistNvars
-      public :: vlistNgrids
-      public :: vlistNzaxis
-      public :: vlistDefNtsteps
-      public :: vlistNtsteps
-      public :: vlistGridsizeMax
-      public :: vlistGrid
-      public :: vlistGridIndex
-      public :: vlistChangeGridIndex
-      public :: vlistChangeGrid
-      public :: vlistZaxis
-      public :: vlistZaxisIndex
-      public :: vlistChangeZaxisIndex
-      public :: vlistChangeZaxis
-      public :: vlistNrecs
-      public :: vlistDefTaxis
-      public :: vlistInqTaxis
-      public :: vlistDefTable
-      public :: vlistInqTable
-      public :: vlistDefInstitut
-      public :: vlistInqInstitut
-      public :: vlistDefModel
-      public :: vlistInqModel
-      public :: vlistDefVar
-      public :: vlistChangeVarGrid
-      public :: vlistChangeVarZaxis
-      public :: vlistInqVar
-      public :: vlistInqVarGrid
-      public :: vlistInqVarZaxis
-      public :: vlistInqVarID
-      public :: vlistDefVarTsteptype
-      public :: vlistInqVarTsteptype
-      public :: vlistDefVarCompType
-      public :: vlistInqVarCompType
-      public :: vlistDefVarCompLevel
-      public :: vlistInqVarCompLevel
-      public :: vlistDefVarParam
-      public :: vlistInqVarParam
-      public :: vlistDefVarCode
-      public :: vlistInqVarCode
-      public :: vlistDefVarDatatype
-      public :: vlistInqVarDatatype
-      public :: vlistDefVarChunkType
-      public :: vlistInqVarChunkType
-      public :: vlistDefVarXYZ
-      public :: vlistInqVarXYZ
-      public :: vlistInqVarNumber
-      public :: vlistDefVarInstitut
-      public :: vlistInqVarInstitut
-      public :: vlistDefVarModel
-      public :: vlistInqVarModel
-      public :: vlistDefVarTable
-      public :: vlistInqVarTable
-      public :: vlistDefVarName
-      public :: vlistInqVarName
-      public :: vlistDefVarStdname
-      public :: vlistInqVarStdname
-      public :: vlistDefVarLongname
-      public :: vlistInqVarLongname
-      public :: vlistDefVarUnits
-      public :: vlistInqVarUnits
-      public :: vlistDefVarMissval
-      public :: vlistInqVarMissval
-      public :: vlistDefVarExtra
-      public :: vlistInqVarExtra
-      public :: vlistDefVarScalefactor
-      public :: vlistInqVarScalefactor
-      public :: vlistDefVarAddoffset
-      public :: vlistInqVarAddoffset
-      public :: vlistDefVarTimave
-      public :: vlistInqVarTimave
-      public :: vlistDefVarTimaccu
-      public :: vlistInqVarTimaccu
-      public :: vlistDefVarTypeOfGeneratingProcess
-      public :: vlistInqVarTypeOfGeneratingProcess
-      public :: vlistDefVarProductDefinitionTemplate
-      public :: vlistInqVarProductDefinitionTemplate
-      public :: vlistInqVarSize
-      public :: vlistDefIndex
-      public :: vlistInqIndex
-      public :: vlistDefFlag
-      public :: vlistInqFlag
-      public :: vlistFindVar
-      public :: vlistFindLevel
-      public :: vlistMergedVar
-      public :: vlistMergedLevel
-      public :: vlistDefVarEnsemble
-      public :: vlistInqVarEnsemble
-      public :: cdiClearAdditionalKeys
-      public :: cdiDefAdditionalKey
-      public :: vlistDefVarIntKey
-      public :: vlistDefVarDblKey
-      public :: vlistHasVarKey
-      public :: vlistInqVarDblKey
-      public :: vlistInqVarIntKey
-      public :: vlistInqNatts
-      public :: vlistInqAtt
-      public :: vlistDelAtt
-      public :: vlistDefAttInt
-      public :: vlistDefAttFlt
-      public :: vlistDefAttTxt
-      public :: vlistInqAttInt
-      public :: vlistInqAttFlt
-      public :: vlistInqAttTxt
-      public :: gridName
-      public :: gridNamePtr
-      public :: gridCompress
-      public :: gridDefMaskGME
-      public :: gridInqMaskGME
-      public :: gridDefMask
-      public :: gridInqMask
-      public :: gridPrint
-      public :: gridCreate
-      public :: gridDestroy
-      public :: gridDuplicate
-      public :: gridInqType
-      public :: gridInqSize
-      public :: gridDefXsize
-      public :: gridInqXsize
-      public :: gridDefYsize
-      public :: gridInqYsize
-      public :: gridDefNP
-      public :: gridInqNP
-      public :: gridDefXvals
-      public :: gridInqXvals
-      public :: gridDefYvals
-      public :: gridInqYvals
-      public :: gridDefXname
-      public :: gridInqXname
-      public :: gridDefXlongname
-      public :: gridInqXlongname
-      public :: gridDefXunits
-      public :: gridInqXunits
-      public :: gridDefYname
-      public :: gridInqYname
-      public :: gridDefYlongname
-      public :: gridInqYlongname
-      public :: gridDefYunits
-      public :: gridInqYunits
-      public :: gridInqXstdname
-      public :: gridInqYstdname
-      public :: gridDefPrec
-      public :: gridInqPrec
-      public :: gridInqXval
-      public :: gridInqYval
-      public :: gridInqXinc
-      public :: gridInqYinc
-      public :: gridIsCircular
-      public :: gridIsRotated
-      public :: gridDefXpole
-      public :: gridInqXpole
-      public :: gridDefYpole
-      public :: gridInqYpole
-      public :: gridDefAngle
-      public :: gridInqAngle
-      public :: gridInqTrunc
-      public :: gridDefTrunc
-      public :: gridDefGMEnd
-      public :: gridInqGMEnd
-      public :: gridDefGMEni
-      public :: gridInqGMEni
-      public :: gridDefGMEni2
-      public :: gridInqGMEni2
-      public :: gridDefGMEni3
-      public :: gridInqGMEni3
-      public :: gridDefNumber
-      public :: gridInqNumber
-      public :: gridDefPosition
-      public :: gridInqPosition
-      public :: gridDefReference
-      public :: gridInqReference
-      public :: gridDefUUID
-      public :: gridInqUUID
-      public :: gridDefLCC
-      public :: gridInqLCC
-      public :: gridDefLcc2
-      public :: gridInqLcc2
-      public :: gridDefLaea
-      public :: gridInqLaea
-      public :: gridDefArea
-      public :: gridInqArea
-      public :: gridHasArea
-      public :: gridDefNvertex
-      public :: gridInqNvertex
-      public :: gridDefXbounds
-      public :: gridInqXbounds
-      public :: gridDefYbounds
-      public :: gridInqYbounds
-      public :: gridDefRowlon
-      public :: gridInqRowlon
-      public :: gridChangeType
-      public :: gridDefComplexPacking
-      public :: gridInqComplexPacking
-      public :: zaxisName
-      public :: zaxisCreate
-      public :: zaxisDestroy
-      public :: zaxisInqType
-      public :: zaxisInqSize
-      public :: zaxisDuplicate
-      public :: zaxisResize
-      public :: zaxisPrint
-      public :: zaxisDefLevels
-      public :: zaxisInqLevels
-      public :: zaxisDefLevel
-      public :: zaxisInqLevel
-      public :: zaxisDefNlevRef
-      public :: zaxisInqNlevRef
-      public :: zaxisDefNumber
-      public :: zaxisInqNumber
-      public :: zaxisDefUUID
-      public :: zaxisInqUUID
-      public :: zaxisDefName
-      public :: zaxisInqName
-      public :: zaxisDefLongname
-      public :: zaxisInqLongname
-      public :: zaxisDefUnits
-      public :: zaxisInqUnits
-      public :: zaxisInqStdname
-      public :: zaxisDefPrec
-      public :: zaxisInqPrec
-      public :: zaxisDefPositive
-      public :: zaxisInqPositive
-      public :: zaxisDefLtype
-      public :: zaxisInqLtype
-      public :: zaxisInqLevelsPtr
-      public :: zaxisDefVct
-      public :: zaxisInqVct
-      public :: zaxisInqVctSize
-      public :: zaxisInqVctPtr
-      public :: zaxisDefLbounds
-      public :: zaxisInqLbounds
-      public :: zaxisInqLbound
-      public :: zaxisDefUbounds
-      public :: zaxisInqUbounds
-      public :: zaxisInqUbound
-      public :: zaxisDefWeights
-      public :: zaxisInqWeights
-      public :: zaxisChangeType
-      public :: taxisCreate
-      public :: taxisDestroy
-      public :: taxisDuplicate
-      public :: taxisCopyTimestep
-      public :: taxisDefType
-      public :: taxisDefVdate
-      public :: taxisDefVtime
-      public :: taxisInqVdate
-      public :: taxisInqVtime
-      public :: taxisDefRdate
-      public :: taxisDefRtime
-      public :: taxisInqRdate
-      public :: taxisInqRtime
-      public :: taxisDefFdate
-      public :: taxisDefFtime
-      public :: taxisInqFdate
-      public :: taxisInqFtime
-      public :: taxisHasBounds
-      public :: taxisDeleteBounds
-      public :: taxisDefVdateBounds
-      public :: taxisDefVtimeBounds
-      public :: taxisInqVdateBounds
-      public :: taxisInqVtimeBounds
-      public :: taxisDefCalendar
-      public :: taxisInqCalendar
-      public :: taxisDefTunit
-      public :: taxisInqTunit
-      public :: taxisDefForecastTunit
-      public :: taxisInqForecastTunit
-      public :: taxisDefForecastPeriod
-      public :: taxisInqForecastPeriod
-      public :: taxisDefNumavg
-      public :: taxisInqType
-      public :: taxisInqNumavg
-      public :: tunitNamePtr
-      public :: institutDef
-      public :: institutInq
-      public :: institutInqNumber
-      public :: institutInqCenter
-      public :: institutInqSubcenter
-      public :: institutInqNamePtr
-      public :: institutInqLongnamePtr
-      public :: modelDef
-      public :: modelInq
-      public :: modelInqInstitut
-      public :: modelInqGribID
-      public :: modelInqNamePtr
-      public :: tableWriteC
-      public :: tableWrite
-      public :: tableRead
-      public :: tableDef
-      public :: tableInqNamePtr
-      public :: tableDefEntry
-      public :: tableInq
-      public :: tableInqNumber
-      public :: tableInqNum
-      public :: tableInqModel
-      public :: tableInqPar
-      public :: tableInqParCode
-      public :: tableInqParName
-      public :: tableInqParLongname
-      public :: tableInqParUnits
-      public :: tableInqParNamePtr
-      public :: tableInqParLongnamePtr
-      public :: tableInqParUnitsPtr
-      public :: streamDefHistory
-      public :: streamInqHistorySize
-      public :: streamInqHistoryString
-      public :: gribapiLibraryVersion
-      public :: ctrim
-      public :: c_len
-
-      public :: CDI_MAX_NAME
-      public :: CDI_UNDEFID
-      public :: CDI_GLOBAL
-      public :: CDI_BIGENDIAN
-      public :: CDI_LITTLEENDIAN
-      public :: CDI_REAL
-      public :: CDI_COMP
-      public :: CDI_BOTH
-      public :: CDI_ESYSTEM
-      public :: CDI_EINVAL
-      public :: CDI_EUFTYPE
-      public :: CDI_ELIBNAVAIL
-      public :: CDI_EUFSTRUCT
-      public :: CDI_EUNC4
-      public :: CDI_ELIMIT
-      public :: FILETYPE_UNDEF
-      public :: FILETYPE_GRB
-      public :: FILETYPE_GRB2
-      public :: FILETYPE_NC
-      public :: FILETYPE_NC2
-      public :: FILETYPE_NC4
-      public :: FILETYPE_NC4C
-      public :: FILETYPE_SRV
-      public :: FILETYPE_EXT
-      public :: FILETYPE_IEG
-      public :: COMPRESS_NONE
-      public :: COMPRESS_SZIP
-      public :: COMPRESS_GZIP
-      public :: COMPRESS_BZIP2
-      public :: COMPRESS_ZIP
-      public :: COMPRESS_JPEG
-      public :: DATATYPE_PACK
-      public :: DATATYPE_PACK1
-      public :: DATATYPE_PACK2
-      public :: DATATYPE_PACK3
-      public :: DATATYPE_PACK4
-      public :: DATATYPE_PACK5
-      public :: DATATYPE_PACK6
-      public :: DATATYPE_PACK7
-      public :: DATATYPE_PACK8
-      public :: DATATYPE_PACK9
-      public :: DATATYPE_PACK10
-      public :: DATATYPE_PACK11
-      public :: DATATYPE_PACK12
-      public :: DATATYPE_PACK13
-      public :: DATATYPE_PACK14
-      public :: DATATYPE_PACK15
-      public :: DATATYPE_PACK16
-      public :: DATATYPE_PACK17
-      public :: DATATYPE_PACK18
-      public :: DATATYPE_PACK19
-      public :: DATATYPE_PACK20
-      public :: DATATYPE_PACK21
-      public :: DATATYPE_PACK22
-      public :: DATATYPE_PACK23
-      public :: DATATYPE_PACK24
-      public :: DATATYPE_PACK25
-      public :: DATATYPE_PACK26
-      public :: DATATYPE_PACK27
-      public :: DATATYPE_PACK28
-      public :: DATATYPE_PACK29
-      public :: DATATYPE_PACK30
-      public :: DATATYPE_PACK31
-      public :: DATATYPE_PACK32
-      public :: DATATYPE_CPX32
-      public :: DATATYPE_CPX64
-      public :: DATATYPE_FLT32
-      public :: DATATYPE_FLT64
-      public :: DATATYPE_INT8
-      public :: DATATYPE_INT16
-      public :: DATATYPE_INT32
-      public :: DATATYPE_UINT8
-      public :: DATATYPE_UINT16
-      public :: DATATYPE_UINT32
-      public :: DATATYPE_INT
-      public :: DATATYPE_FLT
-      public :: DATATYPE_TXT
-      public :: DATATYPE_CPX
-      public :: DATATYPE_UCHAR
-      public :: DATATYPE_LONG
-      public :: CHUNK_AUTO
-      public :: CHUNK_GRID
-      public :: CHUNK_LINES
-      public :: GRID_GENERIC
-      public :: GRID_GAUSSIAN
-      public :: GRID_GAUSSIAN_REDUCED
-      public :: GRID_LONLAT
-      public :: GRID_SPECTRAL
-      public :: GRID_FOURIER
-      public :: GRID_GME
-      public :: GRID_TRAJECTORY
-      public :: GRID_UNSTRUCTURED
-      public :: GRID_CURVILINEAR
-      public :: GRID_LCC
-      public :: GRID_LCC2
-      public :: GRID_LAEA
-      public :: GRID_SINUSOIDAL
-      public :: GRID_PROJECTION
-      public :: ZAXIS_SURFACE
-      public :: ZAXIS_GENERIC
-      public :: ZAXIS_HYBRID
-      public :: ZAXIS_HYBRID_HALF
-      public :: ZAXIS_PRESSURE
-      public :: ZAXIS_HEIGHT
-      public :: ZAXIS_DEPTH_BELOW_SEA
-      public :: ZAXIS_DEPTH_BELOW_LAND
-      public :: ZAXIS_ISENTROPIC
-      public :: ZAXIS_TRAJECTORY
-      public :: ZAXIS_ALTITUDE
-      public :: ZAXIS_SIGMA
-      public :: ZAXIS_MEANSEA
-      public :: ZAXIS_TOA
-      public :: ZAXIS_SEA_BOTTOM
-      public :: ZAXIS_ATMOSPHERE
-      public :: ZAXIS_CLOUD_BASE
-      public :: ZAXIS_CLOUD_TOP
-      public :: ZAXIS_ISOTHERM_ZERO
-      public :: ZAXIS_SNOW
-      public :: ZAXIS_LAKE_BOTTOM
-      public :: ZAXIS_SEDIMENT_BOTTOM
-      public :: ZAXIS_SEDIMENT_BOTTOM_TA
-      public :: ZAXIS_SEDIMENT_BOTTOM_TW
-      public :: ZAXIS_MIX_LAYER
-      public :: ZAXIS_REFERENCE
-      public :: TIME_CONSTANT
-      public :: TIME_VARIABLE
-      public :: TSTEP_CONSTANT
-      public :: TSTEP_INSTANT
-      public :: TSTEP_AVG
-      public :: TSTEP_ACCUM
-      public :: TSTEP_MAX
-      public :: TSTEP_MIN
-      public :: TSTEP_DIFF
-      public :: TSTEP_RMS
-      public :: TSTEP_SD
-      public :: TSTEP_COV
-      public :: TSTEP_RATIO
-      public :: TSTEP_RANGE
-      public :: TSTEP_INSTANT2
-      public :: TSTEP_INSTANT3
-      public :: TAXIS_ABSOLUTE
-      public :: TAXIS_RELATIVE
-      public :: TAXIS_FORECAST
-      public :: TUNIT_SECOND
-      public :: TUNIT_MINUTE
-      public :: TUNIT_QUARTER
-      public :: TUNIT_30MINUTES
-      public :: TUNIT_HOUR
-      public :: TUNIT_3HOURS
-      public :: TUNIT_6HOURS
-      public :: TUNIT_12HOURS
-      public :: TUNIT_DAY
-      public :: TUNIT_MONTH
-      public :: TUNIT_YEAR
-      public :: CALENDAR_STANDARD
-      public :: CALENDAR_PROLEPTIC
-      public :: CALENDAR_360DAYS
-      public :: CALENDAR_365DAYS
-      public :: CALENDAR_366DAYS
-      public :: CALENDAR_NONE
-      public :: CDI_UUID_SIZE
+	use iso_c_binding
+	implicit none
+	private
+
+	public ctrim
+	public c_len
+
+	interface
+		integer(c_size_t) function lib_strlen(charPtr) bind(c, name = "strlen")
+			import c_size_t, c_ptr
+			type(c_ptr), value :: charPtr
+		end function lib_strlen
+
+		subroutine lib_free(pointer) bind(c, name = "free")
+			import c_ptr
+			type(c_ptr), value :: pointer
+		end subroutine lib_free
+	end interface
+
+	integer(c_int), public, parameter :: CDI_MAX_NAME = 256
+	integer(c_int), public, parameter :: CDI_UNDEFID = -1
+	integer(c_int), public, parameter :: CDI_GLOBAL = -1
+	integer(c_int), public, parameter :: CDI_BIGENDIAN = 0
+	integer(c_int), public, parameter :: CDI_LITTLEENDIAN = 1
+	integer(c_int), public, parameter :: CDI_REAL = 1
+	integer(c_int), public, parameter :: CDI_COMP = 2
+	integer(c_int), public, parameter :: CDI_BOTH = 3
+	integer(c_int), public, parameter :: CDI_NOERR = 0
+	integer(c_int), public, parameter :: CDI_EEOF = -1
+	integer(c_int), public, parameter :: CDI_ESYSTEM = -10
+	integer(c_int), public, parameter :: CDI_EINVAL = -20
+	integer(c_int), public, parameter :: CDI_EUFTYPE = -21
+	integer(c_int), public, parameter :: CDI_ELIBNAVAIL = -22
+	integer(c_int), public, parameter :: CDI_EUFSTRUCT = -23
+	integer(c_int), public, parameter :: CDI_EUNC4 = -24
+	integer(c_int), public, parameter :: CDI_ELIMIT = -99
+	integer(c_int), public, parameter :: FILETYPE_UNDEF = -1
+	integer(c_int), public, parameter :: FILETYPE_GRB = 1
+	integer(c_int), public, parameter :: FILETYPE_GRB2 = 2
+	integer(c_int), public, parameter :: FILETYPE_NC = 3
+	integer(c_int), public, parameter :: FILETYPE_NC2 = 4
+	integer(c_int), public, parameter :: FILETYPE_NC4 = 5
+	integer(c_int), public, parameter :: FILETYPE_NC4C = 6
+	integer(c_int), public, parameter :: FILETYPE_SRV = 7
+	integer(c_int), public, parameter :: FILETYPE_EXT = 8
+	integer(c_int), public, parameter :: FILETYPE_IEG = 9
+	integer(c_int), public, parameter :: COMPRESS_NONE = 0
+	integer(c_int), public, parameter :: COMPRESS_SZIP = 1
+	integer(c_int), public, parameter :: COMPRESS_GZIP = 2
+	integer(c_int), public, parameter :: COMPRESS_BZIP2 = 3
+	integer(c_int), public, parameter :: COMPRESS_ZIP = 4
+	integer(c_int), public, parameter :: COMPRESS_JPEG = 5
+	integer(c_int), public, parameter :: DATATYPE_PACK = 0
+	integer(c_int), public, parameter :: DATATYPE_PACK1 = 1
+	integer(c_int), public, parameter :: DATATYPE_PACK2 = 2
+	integer(c_int), public, parameter :: DATATYPE_PACK3 = 3
+	integer(c_int), public, parameter :: DATATYPE_PACK4 = 4
+	integer(c_int), public, parameter :: DATATYPE_PACK5 = 5
+	integer(c_int), public, parameter :: DATATYPE_PACK6 = 6
+	integer(c_int), public, parameter :: DATATYPE_PACK7 = 7
+	integer(c_int), public, parameter :: DATATYPE_PACK8 = 8
+	integer(c_int), public, parameter :: DATATYPE_PACK9 = 9
+	integer(c_int), public, parameter :: DATATYPE_PACK10 = 10
+	integer(c_int), public, parameter :: DATATYPE_PACK11 = 11
+	integer(c_int), public, parameter :: DATATYPE_PACK12 = 12
+	integer(c_int), public, parameter :: DATATYPE_PACK13 = 13
+	integer(c_int), public, parameter :: DATATYPE_PACK14 = 14
+	integer(c_int), public, parameter :: DATATYPE_PACK15 = 15
+	integer(c_int), public, parameter :: DATATYPE_PACK16 = 16
+	integer(c_int), public, parameter :: DATATYPE_PACK17 = 17
+	integer(c_int), public, parameter :: DATATYPE_PACK18 = 18
+	integer(c_int), public, parameter :: DATATYPE_PACK19 = 19
+	integer(c_int), public, parameter :: DATATYPE_PACK20 = 20
+	integer(c_int), public, parameter :: DATATYPE_PACK21 = 21
+	integer(c_int), public, parameter :: DATATYPE_PACK22 = 22
+	integer(c_int), public, parameter :: DATATYPE_PACK23 = 23
+	integer(c_int), public, parameter :: DATATYPE_PACK24 = 24
+	integer(c_int), public, parameter :: DATATYPE_PACK25 = 25
+	integer(c_int), public, parameter :: DATATYPE_PACK26 = 26
+	integer(c_int), public, parameter :: DATATYPE_PACK27 = 27
+	integer(c_int), public, parameter :: DATATYPE_PACK28 = 28
+	integer(c_int), public, parameter :: DATATYPE_PACK29 = 29
+	integer(c_int), public, parameter :: DATATYPE_PACK30 = 30
+	integer(c_int), public, parameter :: DATATYPE_PACK31 = 31
+	integer(c_int), public, parameter :: DATATYPE_PACK32 = 32
+	integer(c_int), public, parameter :: DATATYPE_CPX32 = 64
+	integer(c_int), public, parameter :: DATATYPE_CPX64 = 128
+	integer(c_int), public, parameter :: DATATYPE_FLT32 = 132
+	integer(c_int), public, parameter :: DATATYPE_FLT64 = 164
+	integer(c_int), public, parameter :: DATATYPE_INT8 = 208
+	integer(c_int), public, parameter :: DATATYPE_INT16 = 216
+	integer(c_int), public, parameter :: DATATYPE_INT32 = 232
+	integer(c_int), public, parameter :: DATATYPE_UINT8 = 308
+	integer(c_int), public, parameter :: DATATYPE_UINT16 = 316
+	integer(c_int), public, parameter :: DATATYPE_UINT32 = 332
+	integer(c_int), public, parameter :: DATATYPE_INT = 251
+	integer(c_int), public, parameter :: DATATYPE_FLT = 252
+	integer(c_int), public, parameter :: DATATYPE_TXT = 253
+	integer(c_int), public, parameter :: DATATYPE_CPX = 254
+	integer(c_int), public, parameter :: DATATYPE_UCHAR = 255
+	integer(c_int), public, parameter :: DATATYPE_LONG = 256
+	integer(c_int), public, parameter :: CHUNK_AUTO = 1
+	integer(c_int), public, parameter :: CHUNK_GRID = 2
+	integer(c_int), public, parameter :: CHUNK_LINES = 3
+	integer(c_int), public, parameter :: GRID_GENERIC = 1
+	integer(c_int), public, parameter :: GRID_GAUSSIAN = 2
+	integer(c_int), public, parameter :: GRID_GAUSSIAN_REDUCED = 3
+	integer(c_int), public, parameter :: GRID_LONLAT = 4
+	integer(c_int), public, parameter :: GRID_SPECTRAL = 5
+	integer(c_int), public, parameter :: GRID_FOURIER = 6
+	integer(c_int), public, parameter :: GRID_GME = 7
+	integer(c_int), public, parameter :: GRID_TRAJECTORY = 8
+	integer(c_int), public, parameter :: GRID_UNSTRUCTURED = 9
+	integer(c_int), public, parameter :: GRID_CURVILINEAR = 10
+	integer(c_int), public, parameter :: GRID_LCC = 11
+	integer(c_int), public, parameter :: GRID_LCC2 = 12
+	integer(c_int), public, parameter :: GRID_LAEA = 13
+	integer(c_int), public, parameter :: GRID_SINUSOIDAL = 14
+	integer(c_int), public, parameter :: GRID_PROJECTION = 15
+	integer(c_int), public, parameter :: ZAXIS_SURFACE = 0
+	integer(c_int), public, parameter :: ZAXIS_GENERIC = 1
+	integer(c_int), public, parameter :: ZAXIS_HYBRID = 2
+	integer(c_int), public, parameter :: ZAXIS_HYBRID_HALF = 3
+	integer(c_int), public, parameter :: ZAXIS_PRESSURE = 4
+	integer(c_int), public, parameter :: ZAXIS_HEIGHT = 5
+	integer(c_int), public, parameter :: ZAXIS_DEPTH_BELOW_SEA = 6
+	integer(c_int), public, parameter :: ZAXIS_DEPTH_BELOW_LAND = 7
+	integer(c_int), public, parameter :: ZAXIS_ISENTROPIC = 8
+	integer(c_int), public, parameter :: ZAXIS_TRAJECTORY = 9
+	integer(c_int), public, parameter :: ZAXIS_ALTITUDE = 10
+	integer(c_int), public, parameter :: ZAXIS_SIGMA = 11
+	integer(c_int), public, parameter :: ZAXIS_MEANSEA = 12
+	integer(c_int), public, parameter :: ZAXIS_TOA = 13
+	integer(c_int), public, parameter :: ZAXIS_SEA_BOTTOM = 14
+	integer(c_int), public, parameter :: ZAXIS_ATMOSPHERE = 15
+	integer(c_int), public, parameter :: ZAXIS_CLOUD_BASE = 16
+	integer(c_int), public, parameter :: ZAXIS_CLOUD_TOP = 17
+	integer(c_int), public, parameter :: ZAXIS_ISOTHERM_ZERO = 18
+	integer(c_int), public, parameter :: ZAXIS_SNOW = 19
+	integer(c_int), public, parameter :: ZAXIS_LAKE_BOTTOM = 20
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM = 21
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM_TA = 22
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM_TW = 23
+	integer(c_int), public, parameter :: ZAXIS_MIX_LAYER = 24
+	integer(c_int), public, parameter :: ZAXIS_REFERENCE = 25
+	integer(c_int), public, parameter :: TIME_CONSTANT = 0
+	integer(c_int), public, parameter :: TIME_VARIABLE = 1
+	integer(c_int), public, parameter :: TSTEP_CONSTANT = 0
+	integer(c_int), public, parameter :: TSTEP_INSTANT = 1
+	integer(c_int), public, parameter :: TSTEP_AVG = 2
+	integer(c_int), public, parameter :: TSTEP_ACCUM = 3
+	integer(c_int), public, parameter :: TSTEP_MAX = 4
+	integer(c_int), public, parameter :: TSTEP_MIN = 5
+	integer(c_int), public, parameter :: TSTEP_DIFF = 6
+	integer(c_int), public, parameter :: TSTEP_RMS = 7
+	integer(c_int), public, parameter :: TSTEP_SD = 8
+	integer(c_int), public, parameter :: TSTEP_COV = 9
+	integer(c_int), public, parameter :: TSTEP_RATIO = 10
+	integer(c_int), public, parameter :: TSTEP_RANGE = 11
+	integer(c_int), public, parameter :: TSTEP_INSTANT2 = 12
+	integer(c_int), public, parameter :: TSTEP_INSTANT3 = 13
+	integer(c_int), public, parameter :: TAXIS_ABSOLUTE = 1
+	integer(c_int), public, parameter :: TAXIS_RELATIVE = 2
+	integer(c_int), public, parameter :: TAXIS_FORECAST = 3
+	integer(c_int), public, parameter :: TUNIT_SECOND = 1
+	integer(c_int), public, parameter :: TUNIT_MINUTE = 2
+	integer(c_int), public, parameter :: TUNIT_QUARTER = 3
+	integer(c_int), public, parameter :: TUNIT_30MINUTES = 4
+	integer(c_int), public, parameter :: TUNIT_HOUR = 5
+	integer(c_int), public, parameter :: TUNIT_3HOURS = 6
+	integer(c_int), public, parameter :: TUNIT_6HOURS = 7
+	integer(c_int), public, parameter :: TUNIT_12HOURS = 8
+	integer(c_int), public, parameter :: TUNIT_DAY = 9
+	integer(c_int), public, parameter :: TUNIT_MONTH = 10
+	integer(c_int), public, parameter :: TUNIT_YEAR = 11
+	integer(c_int), public, parameter :: CALENDAR_STANDARD = 0
+	integer(c_int), public, parameter :: CALENDAR_PROLEPTIC = 1
+	integer(c_int), public, parameter :: CALENDAR_360DAYS = 2
+	integer(c_int), public, parameter :: CALENDAR_365DAYS = 3
+	integer(c_int), public, parameter :: CALENDAR_366DAYS = 4
+	integer(c_int), public, parameter :: CALENDAR_NONE = 5
+	integer(c_int), public, parameter :: CDI_UUID_SIZE = 16
+
+	public t_CdiParam
+	type, bind(c) :: t_CdiParam
+		integer(c_int) :: discipline
+		integer(c_int) :: category
+		integer(c_int) :: number
+	end type t_CdiParam
+
+	public t_CdiIterator
+	type t_CdiIterator
+		type(c_ptr) :: ptr
+	end type t_CdiIterator
+
+	public t_CdiGribIterator
+	type t_CdiGribIterator
+		type(c_ptr) :: ptr
+	end type t_CdiGribIterator
+	public cdiReset
+	public cdiStringError
+	public cdiDebug
+	public cdiLibraryVersion
+	public cdiPrintVersion
+	public cdiHaveFiletype
+	public cdiDefMissval
+	public cdiInqMissval
+	public cdiDefGlobal
+	public namespaceNew
+	public namespaceSetActive
+	public namespaceDelete
+	public cdiParamToString
+	public cdiDecodeParam
+	public cdiEncodeParam
+	public cdiDecodeDate
+	public cdiEncodeDate
+	public cdiDecodeTime
+	public cdiEncodeTime
+	public cdiGetFiletype
+	public streamOpenRead
+	public streamOpenWrite
+	public streamOpenAppend
+	public streamClose
+	public streamSync
+	public streamDefVlist
+	public streamInqVlist
+	public streamInqVlistIDorig
+	public streamInqFiletype
+	public streamDefByteorder
+	public streamInqByteorder
+	public streamDefCompType
+	public streamInqCompType
+	public streamDefCompLevel
+	public streamInqCompLevel
+	public streamDefTimestep
+	public streamInqTimestep
+	public streamInqCurTimestepID
+	public streamFilename
+	public streamFilesuffix
+	public streamInqNvars
+	public streamWriteVar
+	public streamWriteVarF
+	public streamReadVar
+	public streamReadVarF
+	public streamWriteVarSlice
+	public streamWriteVarSliceF
+	public streamReadVarSlice
+	public streamReadVarSliceF
+	public streamWriteVarChunk
+	public streamDefRecord
+	public streamInqRecord
+	public streamWriteRecord
+	public streamWriteRecordF
+	public streamReadRecord
+	public streamCopyRecord
+	public cdiIterator_new
+	public cdiIterator_clone
+	public cdiIterator_serialize
+	public cdiIterator_deserialize
+	public cdiIterator_delete
+	public cdiIterator_nextField
+	public cdiIterator_inqStartTime
+	public cdiIterator_inqEndTime
+	public cdiIterator_inqVTime
+	public cdiIterator_inqLevelType
+	public cdiIterator_inqLevel
+	public cdiIterator_inqLevelUuid
+	public cdiIterator_inqParam
+	public cdiIterator_inqDatatype
+	public cdiIterator_inqTsteptype
+	public cdiIterator_inqVariableName
+	public cdiIterator_inqGridId
+	public cdiIterator_readField
+	public cdiIterator_readFieldF
+	public cdiGribIterator_clone
+	public cdiGribIterator_delete
+	public cdiGribIterator_getLong
+	public cdiGribIterator_getDouble
+	public cdiGribIterator_getLength
+	public cdiGribIterator_getString
+	public cdiGribIterator_getSize
+	public cdiGribIterator_getLongArray
+	public cdiGribIterator_getDoubleArray
+	public cdiGribIterator_inqEdition
+	public cdiGribIterator_inqLongValue
+	public cdiGribIterator_inqLongDefaultValue
+	public cdiGribIterator_inqDoubleValue
+	public cdiGribIterator_inqDoubleDefaultValue
+	public cdiGribIterator_inqStringValue
+	public vlistCreate
+	public vlistDestroy
+	public vlistDuplicate
+	public vlistCopy
+	public vlistCopyFlag
+	public vlistClearFlag
+	public vlistCat
+	public vlistMerge
+	public vlistPrint
+	public vlistNumber
+	public vlistNvars
+	public vlistNgrids
+	public vlistNzaxis
+	public vlistDefNtsteps
+	public vlistNtsteps
+	public vlistGridsizeMax
+	public vlistGrid
+	public vlistGridIndex
+	public vlistChangeGridIndex
+	public vlistChangeGrid
+	public vlistZaxis
+	public vlistZaxisIndex
+	public vlistChangeZaxisIndex
+	public vlistChangeZaxis
+	public vlistNrecs
+	public vlistDefTaxis
+	public vlistInqTaxis
+	public vlistDefTable
+	public vlistInqTable
+	public vlistDefInstitut
+	public vlistInqInstitut
+	public vlistDefModel
+	public vlistInqModel
+	public vlistDefVar
+	public vlistChangeVarGrid
+	public vlistChangeVarZaxis
+	public vlistInqVar
+	public vlistInqVarGrid
+	public vlistInqVarZaxis
+	public vlistInqVarID
+	public vlistDefVarTsteptype
+	public vlistInqVarTsteptype
+	public vlistDefVarCompType
+	public vlistInqVarCompType
+	public vlistDefVarCompLevel
+	public vlistInqVarCompLevel
+	public vlistDefVarParam
+	public vlistInqVarParam
+	public vlistDefVarCode
+	public vlistInqVarCode
+	public vlistDefVarDatatype
+	public vlistInqVarDatatype
+	public vlistDefVarChunkType
+	public vlistInqVarChunkType
+	public vlistDefVarXYZ
+	public vlistInqVarXYZ
+	public vlistInqVarNumber
+	public vlistDefVarInstitut
+	public vlistInqVarInstitut
+	public vlistDefVarModel
+	public vlistInqVarModel
+	public vlistDefVarTable
+	public vlistInqVarTable
+	public vlistDefVarName
+	public vlistInqVarName
+	public vlistCopyVarName
+	public vlistDefVarStdname
+	public vlistInqVarStdname
+	public vlistDefVarLongname
+	public vlistInqVarLongname
+	public vlistDefVarUnits
+	public vlistInqVarUnits
+	public vlistDefVarMissval
+	public vlistInqVarMissval
+	public vlistDefVarExtra
+	public vlistInqVarExtra
+	public vlistDefVarScalefactor
+	public vlistInqVarScalefactor
+	public vlistDefVarAddoffset
+	public vlistInqVarAddoffset
+	public vlistDefVarTimave
+	public vlistInqVarTimave
+	public vlistDefVarTimaccu
+	public vlistInqVarTimaccu
+	public vlistDefVarTypeOfGeneratingProcess
+	public vlistInqVarTypeOfGeneratingProcess
+	public vlistDefVarProductDefinitionTemplate
+	public vlistInqVarProductDefinitionTemplate
+	public vlistInqVarSize
+	public vlistDefIndex
+	public vlistInqIndex
+	public vlistDefFlag
+	public vlistInqFlag
+	public vlistFindVar
+	public vlistFindLevel
+	public vlistMergedVar
+	public vlistMergedLevel
+	public vlistDefVarEnsemble
+	public vlistInqVarEnsemble
+	public cdiClearAdditionalKeys
+	public cdiDefAdditionalKey
+	public vlistDefVarIntKey
+	public vlistDefVarDblKey
+	public vlistHasVarKey
+	public vlistInqVarDblKey
+	public vlistInqVarIntKey
+	public vlistInqNatts
+	public vlistInqAtt
+	public vlistDelAtt
+	public vlistDefAttInt
+	public vlistDefAttFlt
+	public vlistDefAttTxt
+	public vlistInqAttInt
+	public vlistInqAttFlt
+	public vlistInqAttTxt
+	public gridName
+	public gridNamePtr
+	public gridCompress
+	public gridDefMaskGME
+	public gridInqMaskGME
+	public gridDefMask
+	public gridInqMask
+	public gridPrint
+	public gridCreate
+	public gridDestroy
+	public gridDuplicate
+	public gridInqType
+	public gridInqSize
+	public gridDefXsize
+	public gridInqXsize
+	public gridDefYsize
+	public gridInqYsize
+	public gridDefNP
+	public gridInqNP
+	public gridDefXvals
+	public gridInqXvals
+	public gridDefYvals
+	public gridInqYvals
+	public gridDefXname
+	public gridInqXname
+	public gridDefXlongname
+	public gridInqXlongname
+	public gridDefXunits
+	public gridInqXunits
+	public gridDefYname
+	public gridInqYname
+	public gridDefYlongname
+	public gridInqYlongname
+	public gridDefYunits
+	public gridInqYunits
+	public gridInqXstdname
+	public gridInqYstdname
+	public gridDefPrec
+	public gridInqPrec
+	public gridInqXval
+	public gridInqYval
+	public gridInqXinc
+	public gridInqYinc
+	public gridIsCircular
+	public gridIsRotated
+	public gridDefXpole
+	public gridInqXpole
+	public gridDefYpole
+	public gridInqYpole
+	public gridDefAngle
+	public gridInqAngle
+	public gridInqTrunc
+	public gridDefTrunc
+	public gridDefGMEnd
+	public gridInqGMEnd
+	public gridDefGMEni
+	public gridInqGMEni
+	public gridDefGMEni2
+	public gridInqGMEni2
+	public gridDefGMEni3
+	public gridInqGMEni3
+	public gridDefNumber
+	public gridInqNumber
+	public gridDefPosition
+	public gridInqPosition
+	public gridDefReference
+	public gridInqReference
+	public gridDefUUID
+	public gridInqUUID
+	public gridDefLCC
+	public gridInqLCC
+	public gridDefLcc2
+	public gridInqLcc2
+	public gridDefLaea
+	public gridInqLaea
+	public gridDefArea
+	public gridInqArea
+	public gridHasArea
+	public gridDefNvertex
+	public gridInqNvertex
+	public gridDefXbounds
+	public gridInqXbounds
+	public gridDefYbounds
+	public gridInqYbounds
+	public gridDefRowlon
+	public gridInqRowlon
+	public gridChangeType
+	public gridDefComplexPacking
+	public gridInqComplexPacking
+	public zaxisName
+	public zaxisCreate
+	public zaxisDestroy
+	public zaxisInqType
+	public zaxisInqSize
+	public zaxisDuplicate
+	public zaxisResize
+	public zaxisPrint
+	public zaxisDefLevels
+	public zaxisInqLevels
+	public zaxisDefLevel
+	public zaxisInqLevel
+	public zaxisDefNlevRef
+	public zaxisInqNlevRef
+	public zaxisDefNumber
+	public zaxisInqNumber
+	public zaxisDefUUID
+	public zaxisInqUUID
+	public zaxisDefName
+	public zaxisInqName
+	public zaxisDefLongname
+	public zaxisInqLongname
+	public zaxisDefUnits
+	public zaxisInqUnits
+	public zaxisInqStdname
+	public zaxisDefPrec
+	public zaxisInqPrec
+	public zaxisDefPositive
+	public zaxisInqPositive
+	public zaxisDefLtype
+	public zaxisInqLtype
+	public zaxisInqLevelsPtr
+	public zaxisDefVct
+	public zaxisInqVct
+	public zaxisInqVctSize
+	public zaxisInqVctPtr
+	public zaxisDefLbounds
+	public zaxisInqLbounds
+	public zaxisInqLbound
+	public zaxisDefUbounds
+	public zaxisInqUbounds
+	public zaxisInqUbound
+	public zaxisDefWeights
+	public zaxisInqWeights
+	public zaxisChangeType
+	public taxisCreate
+	public taxisDestroy
+	public taxisDuplicate
+	public taxisCopyTimestep
+	public taxisDefType
+	public taxisDefVdate
+	public taxisDefVtime
+	public taxisInqVdate
+	public taxisInqVtime
+	public taxisDefRdate
+	public taxisDefRtime
+	public taxisInqRdate
+	public taxisInqRtime
+	public taxisDefFdate
+	public taxisDefFtime
+	public taxisInqFdate
+	public taxisInqFtime
+	public taxisHasBounds
+	public taxisDeleteBounds
+	public taxisDefVdateBounds
+	public taxisDefVtimeBounds
+	public taxisInqVdateBounds
+	public taxisInqVtimeBounds
+	public taxisDefCalendar
+	public taxisInqCalendar
+	public taxisDefTunit
+	public taxisInqTunit
+	public taxisDefForecastTunit
+	public taxisInqForecastTunit
+	public taxisDefForecastPeriod
+	public taxisInqForecastPeriod
+	public taxisDefNumavg
+	public taxisInqType
+	public taxisInqNumavg
+	public tunitNamePtr
+	public institutDef
+	public institutInq
+	public institutInqNumber
+	public institutInqCenter
+	public institutInqSubcenter
+	public institutInqNamePtr
+	public institutInqLongnamePtr
+	public modelDef
+	public modelInq
+	public modelInqInstitut
+	public modelInqGribID
+	public modelInqNamePtr
+	public tableWriteC
+	public tableWrite
+	public tableRead
+	public tableDef
+	public tableInqNamePtr
+	public tableDefEntry
+	public tableInq
+	public tableInqNumber
+	public tableInqNum
+	public tableInqModel
+	public tableInqPar
+	public tableInqParCode
+	public tableInqParName
+	public tableInqParLongname
+	public tableInqParUnits
+	public tableInqParNamePtr
+	public tableInqParLongnamePtr
+	public tableInqParUnitsPtr
+	public streamDefHistory
+	public streamInqHistorySize
+	public streamInqHistoryString
+	public gribapiLibraryVersion
 
 contains
-      function cdiStringError(cdiErrno)
-        integer(kind=c_int), value :: cdiErrno
-        interface
-          function cdiStringError_c(cdiErrno) bind(c,name='cdiStringError')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: cdiErrno
-            type(c_ptr) :: cdiStringError_c
-          end function cdiStringError_c
-        end interface
-        character(len=1, kind=c_char), pointer :: cdiStringError(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = cdiStringError_c(cdiErrno)
-        cdiStringError => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, cdiStringError, slen)
-      end function cdiStringError
-      function cdiLibraryVersion()
-        interface
-          function cdiLibraryVersion_c() bind(c,name='cdiLibraryVersion')
-            import :: c_ptr,c_char
-            type(c_ptr) :: cdiLibraryVersion_c
-          end function cdiLibraryVersion_c
-        end interface
-        character(len=1, kind=c_char), pointer :: cdiLibraryVersion(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = cdiLibraryVersion_c()
-        cdiLibraryVersion => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, cdiLibraryVersion, slen)
-      end function cdiLibraryVersion
-      function streamFilename(streamID)
-        integer(kind=c_int), value :: streamID
-        interface
-          function streamFilename_c(streamID) bind(c,name='streamFilename')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: streamID
-            type(c_ptr) :: streamFilename_c
-          end function streamFilename_c
-        end interface
-        character(len=1, kind=c_char), pointer :: streamFilename(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = streamFilename_c(streamID)
-        streamFilename => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, streamFilename, slen)
-      end function streamFilename
-      function streamFilesuffix(filetype)
-        integer(kind=c_int), value :: filetype
-        interface
-          function streamFilesuffix_c(filetype) bind(c,name='streamFilesuffix')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: filetype
-            type(c_ptr) :: streamFilesuffix_c
-          end function streamFilesuffix_c
-        end interface
-        character(len=1, kind=c_char), pointer :: streamFilesuffix(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = streamFilesuffix_c(filetype)
-        streamFilesuffix => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, streamFilesuffix, slen)
-      end function streamFilesuffix
-      function gridNamePtr(gridtype)
-        integer(kind=c_int), value :: gridtype
-        interface
-          function gridNamePtr_c(gridtype) bind(c,name='gridNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: gridtype
-            type(c_ptr) :: gridNamePtr_c
-          end function gridNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: gridNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = gridNamePtr_c(gridtype)
-        gridNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, gridNamePtr, slen)
-      end function gridNamePtr
-      function tunitNamePtr(tunitID)
-        integer(kind=c_int), value :: tunitID
-        interface
-          function tunitNamePtr_c(tunitID) bind(c,name='tunitNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tunitID
-            type(c_ptr) :: tunitNamePtr_c
-          end function tunitNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tunitNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tunitNamePtr_c(tunitID)
-        tunitNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tunitNamePtr, slen)
-      end function tunitNamePtr
-      function institutInqNamePtr(instID)
-        integer(kind=c_int), value :: instID
-        interface
-          function institutInqNamePtr_c(instID) bind(c,name='institutInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: instID
-            type(c_ptr) :: institutInqNamePtr_c
-          end function institutInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: institutInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = institutInqNamePtr_c(instID)
-        institutInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, institutInqNamePtr, slen)
-      end function institutInqNamePtr
-      function institutInqLongnamePtr(instID)
-        integer(kind=c_int), value :: instID
-        interface
-          function institutInqLongnamePtr_c(instID) bind(c,name='institutInqLongnamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: instID
-            type(c_ptr) :: institutInqLongnamePtr_c
-          end function institutInqLongnamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: institutInqLongnamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = institutInqLongnamePtr_c(instID)
-        institutInqLongnamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, institutInqLongnamePtr, slen)
-      end function institutInqLongnamePtr
-      function modelInqNamePtr(modelID)
-        integer(kind=c_int), value :: modelID
-        interface
-          function modelInqNamePtr_c(modelID) bind(c,name='modelInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: modelID
-            type(c_ptr) :: modelInqNamePtr_c
-          end function modelInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: modelInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = modelInqNamePtr_c(modelID)
-        modelInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, modelInqNamePtr, slen)
-      end function modelInqNamePtr
-      function tableInqNamePtr(tableID)
-        integer(kind=c_int), value :: tableID
-        interface
-          function tableInqNamePtr_c(tableID) bind(c,name='tableInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            type(c_ptr) :: tableInqNamePtr_c
-          end function tableInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqNamePtr_c(tableID)
-        tableInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqNamePtr, slen)
-      end function tableInqNamePtr
-      function tableInqParNamePtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParNamePtr_c(tableID,parID) bind(c,name='tableInqParNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParNamePtr_c
-          end function tableInqParNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParNamePtr_c(tableID,&
-          parID)
-        tableInqParNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParNamePtr, slen)
-      end function tableInqParNamePtr
-      function tableInqParLongnamePtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParLongnamePtr_c(tableID,parID) bind(c,name='tableInqParLongnamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParLongnamePtr_c
-          end function tableInqParLongnamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParLongnamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParLongnamePtr_c(tableID,&
-          parID)
-        tableInqParLongnamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParLongnamePtr, slen)
-      end function tableInqParLongnamePtr
-      function tableInqParUnitsPtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParUnitsPtr_c(tableID,parID) bind(c,name='tableInqParUnitsPtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParUnitsPtr_c
-          end function tableInqParUnitsPtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParUnitsPtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParUnitsPtr_c(tableID,&
-          parID)
-        tableInqParUnitsPtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParUnitsPtr, slen)
-      end function tableInqParUnitsPtr
-
-    subroutine ctrim(str)
-    character(kind=c_char), intent(inout) :: str(:)
-    character(kind=c_char) :: c
-    integer :: i
-
-    do i=1,size(str)
-      c = str(i)
-      if (c == c_null_char) then
-        str(i:size(str)) = ' '
-        exit
-      end if
-    end do
-
-    end subroutine ctrim
-
-    function c_len(s) result(i)
-      character(kind=c_char), intent(in) :: s(:)
-      integer :: i
-      do i = 1, size(s)
-        if (s(i) == c_null_char) then
-          exit
-        end if
-      end do
-      i = i - 1
-    end function
 
+	subroutine ctrim(str)
+		character(kind = c_char, len = *), intent(inout) :: str
+		integer :: i
+
+		do i=1,len(str)
+			if (str(i:i) == c_null_char) then
+				str(i:len(str)) = ' '
+				exit
+			end if
+		end do
+	end subroutine ctrim
+
+	function c_len(s) result(i)
+		character(kind = c_char, len = *), intent(in) :: s
+		integer :: i
+
+		do i = 1, len(s)
+			if (s(i:i) == c_null_char) exit
+		end do
+		i = i - 1
+	end function
+
+	subroutine cdiReset()
+		interface
+			subroutine lib_cdiReset() bind(c, name = 'cdiReset')
+			end subroutine lib_cdiReset
+		end interface
+		call lib_cdiReset()
+	end subroutine cdiReset
+
+	function cdiStringError(cdiErrno_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: cdiErrno_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_cdiStringError(cdiErrno_dummy) bind(c, name = 'cdiStringError')
+				import c_int, c_ptr
+				integer(c_int), value :: cdiErrno_dummy
+			end function lib_cdiStringError
+		end interface
+		result => null()
+		ptr = lib_cdiStringError(cdiErrno_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function cdiStringError
+
+	subroutine cdiDebug(debug_dummy)
+		integer(c_int), value :: debug_dummy
+		interface
+			subroutine lib_cdiDebug(debug_dummy) bind(c, name = 'cdiDebug')
+				import c_int
+				integer(c_int), value :: debug_dummy
+			end subroutine lib_cdiDebug
+		end interface
+		call lib_cdiDebug(debug_dummy)
+	end subroutine cdiDebug
+
+	function cdiLibraryVersion() result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_cdiLibraryVersion() bind(c, name = 'cdiLibraryVersion')
+				import c_ptr
+			end function lib_cdiLibraryVersion
+		end interface
+		result => null()
+		ptr = lib_cdiLibraryVersion()
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function cdiLibraryVersion
+
+	subroutine cdiPrintVersion()
+		interface
+			subroutine lib_cdiPrintVersion() bind(c, name = 'cdiPrintVersion')
+			end subroutine lib_cdiPrintVersion
+		end interface
+		call lib_cdiPrintVersion()
+	end subroutine cdiPrintVersion
+
+	function cdiHaveFiletype(filetype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: filetype_dummy
+		interface
+			integer(c_int) function lib_cdiHaveFiletype(filetype_dummy) bind(c, name = 'cdiHaveFiletype')
+				import c_int
+				integer(c_int), value :: filetype_dummy
+			end function lib_cdiHaveFiletype
+		end interface
+		result = lib_cdiHaveFiletype(filetype_dummy)
+	end function cdiHaveFiletype
+
+	subroutine cdiDefMissval(missval_dummy)
+		real(c_double), value :: missval_dummy
+		interface
+			subroutine lib_cdiDefMissval(missval_dummy) bind(c, name = 'cdiDefMissval')
+				import c_double
+				real(c_double), value :: missval_dummy
+			end subroutine lib_cdiDefMissval
+		end interface
+		call lib_cdiDefMissval(missval_dummy)
+	end subroutine cdiDefMissval
+
+	function cdiInqMissval() result(result)
+		real(c_double) :: result
+		interface
+			real(c_double) function lib_cdiInqMissval() bind(c, name = 'cdiInqMissval')
+				import c_double
+			end function lib_cdiInqMissval
+		end interface
+		result = lib_cdiInqMissval()
+	end function cdiInqMissval
+
+	subroutine cdiDefGlobal(string_dummy, val_dummy)
+		character(kind = c_char, len = *), intent(in) :: string_dummy
+		integer(c_int), value :: val_dummy
+		character(kind = c_char) :: string_temp(len(string_dummy) + 1)
+		integer :: string_i
+		interface
+			subroutine lib_cdiDefGlobal(string_dummy, val_dummy) bind(c, name = 'cdiDefGlobal')
+				import c_char, c_int
+				character(kind = c_char) :: string_dummy(*)
+				integer(c_int), value :: val_dummy
+			end subroutine lib_cdiDefGlobal
+		end interface
+		do string_i = 1, len(string_dummy)
+		string_temp(string_i) = string_dummy(string_i:string_i)
+		end do
+		string_temp(len(string_dummy) + 1) = c_null_char
+		call lib_cdiDefGlobal(string_temp, val_dummy)
+	end subroutine cdiDefGlobal
+
+	function namespaceNew() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_namespaceNew() bind(c, name = 'namespaceNew')
+				import c_int
+			end function lib_namespaceNew
+		end interface
+		result = lib_namespaceNew()
+	end function namespaceNew
+
+	subroutine namespaceSetActive(namespaceID_dummy)
+		integer(c_int), value :: namespaceID_dummy
+		interface
+			subroutine lib_namespaceSetActive(namespaceID_dummy) bind(c, name = 'namespaceSetActive')
+				import c_int
+				integer(c_int), value :: namespaceID_dummy
+			end subroutine lib_namespaceSetActive
+		end interface
+		call lib_namespaceSetActive(namespaceID_dummy)
+	end subroutine namespaceSetActive
+
+	subroutine namespaceDelete(namespaceID_dummy)
+		integer(c_int), value :: namespaceID_dummy
+		interface
+			subroutine lib_namespaceDelete(namespaceID_dummy) bind(c, name = 'namespaceDelete')
+				import c_int
+				integer(c_int), value :: namespaceID_dummy
+			end subroutine lib_namespaceDelete
+		end interface
+		call lib_namespaceDelete(namespaceID_dummy)
+	end subroutine namespaceDelete
+
+	subroutine cdiParamToString(param_dummy, paramstr_dummy, maxlen_dummy)
+		integer(c_int), value :: param_dummy
+		character(kind = c_char, len = *), intent(inout) :: paramstr_dummy
+		integer(c_int), value :: maxlen_dummy
+		character(kind = c_char) :: paramstr_temp(len(paramstr_dummy))
+		integer :: paramstr_i
+		logical :: paramstr_padding = .true.
+		interface
+			subroutine lib_cdiParamToString(param_dummy, paramstr_dummy, maxlen_dummy) bind(c, name = 'cdiParamToString')
+				import c_char, c_int
+				integer(c_int), value :: param_dummy
+				character(kind = c_char) :: paramstr_dummy(*)
+				integer(c_int), value :: maxlen_dummy
+			end subroutine lib_cdiParamToString
+		end interface
+		do paramstr_i = len(paramstr_dummy), 1, -1
+			if(paramstr_dummy(paramstr_i:paramstr_i) /= ' ') paramstr_padding = .false.
+			if(paramstr_padding) then
+				paramstr_temp(paramstr_i) = c_null_char
+			else
+				paramstr_temp(paramstr_i) = paramstr_dummy(paramstr_i:paramstr_i)
+			end if
+		end do
+		call lib_cdiParamToString(param_dummy, paramstr_temp, maxlen_dummy)
+		paramstr_padding = .false.
+		do paramstr_i = 1, len(paramstr_dummy)
+			if(paramstr_temp(paramstr_i) == c_null_char) paramstr_padding = .true.
+			if(paramstr_padding) then
+				paramstr_dummy(paramstr_i:paramstr_i) = ' '
+			else
+				paramstr_dummy(paramstr_i:paramstr_i) = paramstr_temp(paramstr_i)
+			end if
+		end do
+	end subroutine cdiParamToString
+
+	subroutine cdiDecodeParam(param_dummy, pnum, pcat, pdis)
+		integer(c_int), value :: param_dummy
+		integer(c_int), optional, intent(inout) :: pnum
+		integer(c_int), optional, intent(inout) :: pcat
+		integer(c_int), optional, intent(inout) :: pdis
+		integer(c_int), target :: pnum_temp
+		type(c_ptr) :: pnum_ptr
+		integer(c_int), target :: pcat_temp
+		type(c_ptr) :: pcat_ptr
+		integer(c_int), target :: pdis_temp
+		type(c_ptr) :: pdis_ptr
+		interface
+			subroutine lib_cdiDecodeParam(param_dummy, pnum, pcat, pdis) bind(c, name = 'cdiDecodeParam')
+				import c_int, c_ptr
+				integer(c_int), value :: param_dummy
+				type(c_ptr), value :: pnum
+				type(c_ptr), value :: pcat
+				type(c_ptr), value :: pdis
+			end subroutine lib_cdiDecodeParam
+		end interface
+		pnum_ptr = c_null_ptr
+		if(present(pnum)) pnum_ptr = c_loc(pnum_temp)
+		pcat_ptr = c_null_ptr
+		if(present(pcat)) pcat_ptr = c_loc(pcat_temp)
+		pdis_ptr = c_null_ptr
+		if(present(pdis)) pdis_ptr = c_loc(pdis_temp)
+		call lib_cdiDecodeParam(param_dummy, pnum_ptr, pcat_ptr, pdis_ptr)
+		if(present(pnum)) pnum = pnum_temp
+		if(present(pcat)) pcat = pcat_temp
+		if(present(pdis)) pdis = pdis_temp
+	end subroutine cdiDecodeParam
+
+	function cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: pnum_dummy
+		integer(c_int), value :: pcat_dummy
+		integer(c_int), value :: pdis_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy) bind(c, name = 'cdiEncodeParam')
+				import c_int
+				integer(c_int), value :: pnum_dummy
+				integer(c_int), value :: pcat_dummy
+				integer(c_int), value :: pdis_dummy
+			end function lib_cdiEncodeParam
+		end interface
+		result = lib_cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy)
+	end function cdiEncodeParam
+
+	subroutine cdiDecodeDate(date_dummy, year, month, day)
+		integer(c_int), value :: date_dummy
+		integer(c_int), optional, intent(inout) :: year
+		integer(c_int), optional, intent(inout) :: month
+		integer(c_int), optional, intent(inout) :: day
+		integer(c_int), target :: year_temp
+		type(c_ptr) :: year_ptr
+		integer(c_int), target :: month_temp
+		type(c_ptr) :: month_ptr
+		integer(c_int), target :: day_temp
+		type(c_ptr) :: day_ptr
+		interface
+			subroutine lib_cdiDecodeDate(date_dummy, year, month, day) bind(c, name = 'cdiDecodeDate')
+				import c_int, c_ptr
+				integer(c_int), value :: date_dummy
+				type(c_ptr), value :: year
+				type(c_ptr), value :: month
+				type(c_ptr), value :: day
+			end subroutine lib_cdiDecodeDate
+		end interface
+		year_ptr = c_null_ptr
+		if(present(year)) year_ptr = c_loc(year_temp)
+		month_ptr = c_null_ptr
+		if(present(month)) month_ptr = c_loc(month_temp)
+		day_ptr = c_null_ptr
+		if(present(day)) day_ptr = c_loc(day_temp)
+		call lib_cdiDecodeDate(date_dummy, year_ptr, month_ptr, day_ptr)
+		if(present(year)) year = year_temp
+		if(present(month)) month = month_temp
+		if(present(day)) day = day_temp
+	end subroutine cdiDecodeDate
+
+	function cdiEncodeDate(year_dummy, month_dummy, day_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: year_dummy
+		integer(c_int), value :: month_dummy
+		integer(c_int), value :: day_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeDate(year_dummy, month_dummy, day_dummy) bind(c, name = 'cdiEncodeDate')
+				import c_int
+				integer(c_int), value :: year_dummy
+				integer(c_int), value :: month_dummy
+				integer(c_int), value :: day_dummy
+			end function lib_cdiEncodeDate
+		end interface
+		result = lib_cdiEncodeDate(year_dummy, month_dummy, day_dummy)
+	end function cdiEncodeDate
+
+	subroutine cdiDecodeTime(time_dummy, hour, minute, second)
+		integer(c_int), value :: time_dummy
+		integer(c_int), optional, intent(inout) :: hour
+		integer(c_int), optional, intent(inout) :: minute
+		integer(c_int), optional, intent(inout) :: second
+		integer(c_int), target :: hour_temp
+		type(c_ptr) :: hour_ptr
+		integer(c_int), target :: minute_temp
+		type(c_ptr) :: minute_ptr
+		integer(c_int), target :: second_temp
+		type(c_ptr) :: second_ptr
+		interface
+			subroutine lib_cdiDecodeTime(time_dummy, hour, minute, second) bind(c, name = 'cdiDecodeTime')
+				import c_int, c_ptr
+				integer(c_int), value :: time_dummy
+				type(c_ptr), value :: hour
+				type(c_ptr), value :: minute
+				type(c_ptr), value :: second
+			end subroutine lib_cdiDecodeTime
+		end interface
+		hour_ptr = c_null_ptr
+		if(present(hour)) hour_ptr = c_loc(hour_temp)
+		minute_ptr = c_null_ptr
+		if(present(minute)) minute_ptr = c_loc(minute_temp)
+		second_ptr = c_null_ptr
+		if(present(second)) second_ptr = c_loc(second_temp)
+		call lib_cdiDecodeTime(time_dummy, hour_ptr, minute_ptr, second_ptr)
+		if(present(hour)) hour = hour_temp
+		if(present(minute)) minute = minute_temp
+		if(present(second)) second = second_temp
+	end subroutine cdiDecodeTime
+
+	function cdiEncodeTime(hour_dummy, minute_dummy, second_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: hour_dummy
+		integer(c_int), value :: minute_dummy
+		integer(c_int), value :: second_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeTime(hour_dummy, minute_dummy, second_dummy) bind(c, name = 'cdiEncodeTime')
+				import c_int
+				integer(c_int), value :: hour_dummy
+				integer(c_int), value :: minute_dummy
+				integer(c_int), value :: second_dummy
+			end function lib_cdiEncodeTime
+		end interface
+		result = lib_cdiEncodeTime(hour_dummy, minute_dummy, second_dummy)
+	end function cdiEncodeTime
+
+	function cdiGetFiletype(path_dummy, byteorder) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		integer(c_int), optional, intent(inout) :: byteorder
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		integer(c_int), target :: byteorder_temp
+		type(c_ptr) :: byteorder_ptr
+		interface
+			integer(c_int) function lib_cdiGetFiletype(path_dummy, byteorder) bind(c, name = 'cdiGetFiletype')
+				import c_char, c_int, c_ptr
+				character(kind = c_char) :: path_dummy(*)
+				type(c_ptr), value :: byteorder
+			end function lib_cdiGetFiletype
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		byteorder_ptr = c_null_ptr
+		if(present(byteorder)) byteorder_ptr = c_loc(byteorder_temp)
+		result = lib_cdiGetFiletype(path_temp, byteorder_ptr)
+		if(present(byteorder)) byteorder = byteorder_temp
+	end function cdiGetFiletype
+
+	function streamOpenRead(path_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenRead(path_dummy) bind(c, name = 'streamOpenRead')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_streamOpenRead
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenRead(path_temp)
+	end function streamOpenRead
+
+	function streamOpenWrite(path_dummy, filetype_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		integer(c_int), value :: filetype_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenWrite(path_dummy, filetype_dummy) bind(c, name = 'streamOpenWrite')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+				integer(c_int), value :: filetype_dummy
+			end function lib_streamOpenWrite
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenWrite(path_temp, filetype_dummy)
+	end function streamOpenWrite
+
+	function streamOpenAppend(path_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenAppend(path_dummy) bind(c, name = 'streamOpenAppend')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_streamOpenAppend
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenAppend(path_temp)
+	end function streamOpenAppend
+
+	subroutine streamClose(streamID_dummy)
+		integer(c_int), value :: streamID_dummy
+		interface
+			subroutine lib_streamClose(streamID_dummy) bind(c, name = 'streamClose')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end subroutine lib_streamClose
+		end interface
+		call lib_streamClose(streamID_dummy)
+	end subroutine streamClose
+
+	subroutine streamSync(streamID_dummy)
+		integer(c_int), value :: streamID_dummy
+		interface
+			subroutine lib_streamSync(streamID_dummy) bind(c, name = 'streamSync')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end subroutine lib_streamSync
+		end interface
+		call lib_streamSync(streamID_dummy)
+	end subroutine streamSync
+
+	subroutine streamDefVlist(streamID_dummy, vlistID_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_streamDefVlist(streamID_dummy, vlistID_dummy) bind(c, name = 'streamDefVlist')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_streamDefVlist
+		end interface
+		call lib_streamDefVlist(streamID_dummy, vlistID_dummy)
+	end subroutine streamDefVlist
+
+	function streamInqVlist(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqVlist(streamID_dummy) bind(c, name = 'streamInqVlist')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqVlist
+		end interface
+		result = lib_streamInqVlist(streamID_dummy)
+	end function streamInqVlist
+
+	function streamInqVlistIDorig(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqVlistIDorig(streamID_dummy) bind(c, name = 'streamInqVlistIDorig')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqVlistIDorig
+		end interface
+		result = lib_streamInqVlistIDorig(streamID_dummy)
+	end function streamInqVlistIDorig
+
+	function streamInqFiletype(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqFiletype(streamID_dummy) bind(c, name = 'streamInqFiletype')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqFiletype
+		end interface
+		result = lib_streamInqFiletype(streamID_dummy)
+	end function streamInqFiletype
+
+	subroutine streamDefByteorder(streamID_dummy, byteorder_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: byteorder_dummy
+		interface
+			subroutine lib_streamDefByteorder(streamID_dummy, byteorder_dummy) bind(c, name = 'streamDefByteorder')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: byteorder_dummy
+			end subroutine lib_streamDefByteorder
+		end interface
+		call lib_streamDefByteorder(streamID_dummy, byteorder_dummy)
+	end subroutine streamDefByteorder
+
+	function streamInqByteorder(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqByteorder(streamID_dummy) bind(c, name = 'streamInqByteorder')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqByteorder
+		end interface
+		result = lib_streamInqByteorder(streamID_dummy)
+	end function streamInqByteorder
+
+	subroutine streamDefCompType(streamID_dummy, comptype_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: comptype_dummy
+		interface
+			subroutine lib_streamDefCompType(streamID_dummy, comptype_dummy) bind(c, name = 'streamDefCompType')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: comptype_dummy
+			end subroutine lib_streamDefCompType
+		end interface
+		call lib_streamDefCompType(streamID_dummy, comptype_dummy)
+	end subroutine streamDefCompType
+
+	function streamInqCompType(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCompType(streamID_dummy) bind(c, name = 'streamInqCompType')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCompType
+		end interface
+		result = lib_streamInqCompType(streamID_dummy)
+	end function streamInqCompType
+
+	subroutine streamDefCompLevel(streamID_dummy, complevel_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: complevel_dummy
+		interface
+			subroutine lib_streamDefCompLevel(streamID_dummy, complevel_dummy) bind(c, name = 'streamDefCompLevel')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: complevel_dummy
+			end subroutine lib_streamDefCompLevel
+		end interface
+		call lib_streamDefCompLevel(streamID_dummy, complevel_dummy)
+	end subroutine streamDefCompLevel
+
+	function streamInqCompLevel(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCompLevel(streamID_dummy) bind(c, name = 'streamInqCompLevel')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCompLevel
+		end interface
+		result = lib_streamInqCompLevel(streamID_dummy)
+	end function streamInqCompLevel
+
+	function streamDefTimestep(streamID_dummy, tsID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: tsID_dummy
+		interface
+			integer(c_int) function lib_streamDefTimestep(streamID_dummy, tsID_dummy) bind(c, name = 'streamDefTimestep')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: tsID_dummy
+			end function lib_streamDefTimestep
+		end interface
+		result = lib_streamDefTimestep(streamID_dummy, tsID_dummy)
+	end function streamDefTimestep
+
+	function streamInqTimestep(streamID_dummy, tsID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: tsID_dummy
+		interface
+			integer(c_int) function lib_streamInqTimestep(streamID_dummy, tsID_dummy) bind(c, name = 'streamInqTimestep')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: tsID_dummy
+			end function lib_streamInqTimestep
+		end interface
+		result = lib_streamInqTimestep(streamID_dummy, tsID_dummy)
+	end function streamInqTimestep
+
+	function streamInqCurTimestepID(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCurTimestepID(streamID_dummy) bind(c, name = 'streamInqCurTimestepID')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCurTimestepID
+		end interface
+		result = lib_streamInqCurTimestepID(streamID_dummy)
+	end function streamInqCurTimestepID
+
+	function streamFilename(streamID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: streamID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_streamFilename(streamID_dummy) bind(c, name = 'streamFilename')
+				import c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamFilename
+		end interface
+		result => null()
+		ptr = lib_streamFilename(streamID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function streamFilename
+
+	function streamFilesuffix(filetype_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: filetype_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_streamFilesuffix(filetype_dummy) bind(c, name = 'streamFilesuffix')
+				import c_int, c_ptr
+				integer(c_int), value :: filetype_dummy
+			end function lib_streamFilesuffix
+		end interface
+		result => null()
+		ptr = lib_streamFilesuffix(filetype_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function streamFilesuffix
+
+	function streamInqNvars(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqNvars(streamID_dummy) bind(c, name = 'streamInqNvars')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqNvars
+		end interface
+		result = lib_streamInqNvars(streamID_dummy)
+	end function streamInqNvars
+
+	subroutine streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteVar')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVar
+		end interface
+		call lib_streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVar
+
+	subroutine streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteVarF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarF
+		end interface
+		call lib_streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarF
+
+	subroutine streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadVar')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVar
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVar
+
+	subroutine streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadVarF')
+				import c_float, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarF
+
+	subroutine streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'stre&
+			&amWriteVarSlice')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarSlice
+		end interface
+		call lib_streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarSlice
+
+	subroutine streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'str&
+			&eamWriteVarSliceF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarSliceF
+		end interface
+		call lib_streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarSliceF
+
+	subroutine streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadV&
+			&arSlice')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarSlice
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarSlice
+
+	subroutine streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamRead&
+			&VarSliceF')
+				import c_float, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarSliceF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarSliceF
+
+	subroutine streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), intent(in) :: rect_dummy(2, 3)
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamW&
+			&riteVarChunk')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), intent(in) :: rect_dummy(*)
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarChunk
+		end interface
+		call lib_streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarChunk
+
+	subroutine streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			subroutine lib_streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy) bind(c, name = 'streamDefRecord')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+			end subroutine lib_streamDefRecord
+		end interface
+		call lib_streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy)
+	end subroutine streamDefRecord
+
+	subroutine streamInqRecord(streamID_dummy, varID, levelID)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), optional, intent(inout) :: varID
+		integer(c_int), optional, intent(inout) :: levelID
+		integer(c_int), target :: varID_temp
+		type(c_ptr) :: varID_ptr
+		integer(c_int), target :: levelID_temp
+		type(c_ptr) :: levelID_ptr
+		interface
+			subroutine lib_streamInqRecord(streamID_dummy, varID, levelID) bind(c, name = 'streamInqRecord')
+				import c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				type(c_ptr), value :: varID
+				type(c_ptr), value :: levelID
+			end subroutine lib_streamInqRecord
+		end interface
+		varID_ptr = c_null_ptr
+		if(present(varID)) varID_ptr = c_loc(varID_temp)
+		levelID_ptr = c_null_ptr
+		if(present(levelID)) levelID_ptr = c_loc(levelID_temp)
+		call lib_streamInqRecord(streamID_dummy, varID_ptr, levelID_ptr)
+		if(present(varID)) varID = varID_temp
+		if(present(levelID)) levelID = levelID_temp
+	end subroutine streamInqRecord
+
+	subroutine streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteRecord')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteRecord
+		end interface
+		call lib_streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteRecord
+
+	subroutine streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteRecordF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteRecordF
+		end interface
+		call lib_streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteRecordF
+
+	subroutine streamReadRecord(streamID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadRecord(streamID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadRecord')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadRecord
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadRecord(streamID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadRecord
+
+	subroutine streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy)
+		integer(c_int), value :: streamIDdest_dummy
+		integer(c_int), value :: streamIDsrc_dummy
+		interface
+			subroutine lib_streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy) bind(c, name = 'streamCopyRecord')
+				import c_int
+				integer(c_int), value :: streamIDdest_dummy
+				integer(c_int), value :: streamIDsrc_dummy
+			end subroutine lib_streamCopyRecord
+		end interface
+		call lib_streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy)
+	end subroutine streamCopyRecord
+
+	function cdiIterator_new(path_dummy) result(result)
+		type(t_CdiIterator) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			type(c_ptr) function lib_cdiIterator_new(path_dummy) bind(c, name = 'cdiIterator_new')
+				import c_char, c_ptr
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_cdiIterator_new
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result%ptr = lib_cdiIterator_new(path_temp)
+	end function cdiIterator_new
+
+	function cdiIterator_clone(me_dummy) result(result)
+		type(t_CdiIterator) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(c_ptr) function lib_cdiIterator_clone(me_dummy) bind(c, name = 'cdiIterator_clone')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_clone
+		end interface
+		result%ptr = lib_cdiIterator_clone(me_dummy%ptr)
+	end function cdiIterator_clone
+
+	function cdiIterator_serialize(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_serialize(me_dummy) bind(c, name = 'cdiIterator_serialize')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_serialize
+		end interface
+		cString = lib_cdiIterator_serialize(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_serialize
+
+	function cdiIterator_deserialize(description_dummy) result(result)
+		type(t_CdiIterator) :: result
+		character(kind = c_char, len = *), intent(in) :: description_dummy
+		character(kind = c_char) :: description_temp(len(description_dummy) + 1)
+		integer :: description_i
+		interface
+			type(c_ptr) function lib_cdiIterator_deserialize(description_dummy) bind(c, name = 'cdiIterator_deserialize')
+				import c_char, c_ptr
+				character(kind = c_char) :: description_dummy(*)
+			end function lib_cdiIterator_deserialize
+		end interface
+		do description_i = 1, len(description_dummy)
+		description_temp(description_i) = description_dummy(description_i:description_i)
+		end do
+		description_temp(len(description_dummy) + 1) = c_null_char
+		result%ptr = lib_cdiIterator_deserialize(description_temp)
+	end function cdiIterator_deserialize
+
+	subroutine cdiIterator_delete(me_dummy)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			subroutine lib_cdiIterator_delete(me_dummy) bind(c, name = 'cdiIterator_delete')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end subroutine lib_cdiIterator_delete
+		end interface
+		call lib_cdiIterator_delete(me_dummy%ptr)
+	end subroutine cdiIterator_delete
+
+	function cdiIterator_nextField(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_nextField(me_dummy) bind(c, name = 'cdiIterator_nextField')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_nextField
+		end interface
+		result = lib_cdiIterator_nextField(me_dummy%ptr)
+	end function cdiIterator_nextField
+
+	function cdiIterator_inqStartTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqStartTime(me_dummy) bind(c, name = 'cdiIterator_inqStartTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqStartTime
+		end interface
+		cString = lib_cdiIterator_inqStartTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqStartTime
+
+	function cdiIterator_inqEndTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqEndTime(me_dummy) bind(c, name = 'cdiIterator_inqEndTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqEndTime
+		end interface
+		cString = lib_cdiIterator_inqEndTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqEndTime
+
+	function cdiIterator_inqVTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqVTime(me_dummy) bind(c, name = 'cdiIterator_inqVTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqVTime
+		end interface
+		cString = lib_cdiIterator_inqVTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqVTime
+
+	function cdiIterator_inqLevelType(me_dummy, levelSelector_dummy, outName, outLongName, outStdName, outUnit) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), value :: levelSelector_dummy
+		character(kind = c_char), pointer, optional, intent(inout) :: outName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outLongName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outStdName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outUnit(:)
+		type(c_ptr), target :: outName_ptr
+		type(c_ptr) :: outName_handle
+		integer :: outName_shape(1)
+		character(kind = c_char), pointer :: outName_fptr(:)
+		type(c_ptr), target :: outLongName_ptr
+		type(c_ptr) :: outLongName_handle
+		integer :: outLongName_shape(1)
+		character(kind = c_char), pointer :: outLongName_fptr(:)
+		type(c_ptr), target :: outStdName_ptr
+		type(c_ptr) :: outStdName_handle
+		integer :: outStdName_shape(1)
+		character(kind = c_char), pointer :: outStdName_fptr(:)
+		type(c_ptr), target :: outUnit_ptr
+		type(c_ptr) :: outUnit_handle
+		integer :: outUnit_shape(1)
+		character(kind = c_char), pointer :: outUnit_fptr(:)
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevelType(me_dummy, levelSelector_dummy, outName, outLongName, outStdName, outUnit) b&
+			&ind(c, name = 'cdiIterator_inqLevelType')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				integer(c_int), value :: levelSelector_dummy
+				type(c_ptr), value :: outName
+				type(c_ptr), value :: outLongName
+				type(c_ptr), value :: outStdName
+				type(c_ptr), value :: outUnit
+			end function lib_cdiIterator_inqLevelType
+		end interface
+		outName_handle = c_null_ptr
+		if(present(outName)) outName_handle = c_loc(outName_ptr)
+		outLongName_handle = c_null_ptr
+		if(present(outLongName)) outLongName_handle = c_loc(outLongName_ptr)
+		outStdName_handle = c_null_ptr
+		if(present(outStdName)) outStdName_handle = c_loc(outStdName_ptr)
+		outUnit_handle = c_null_ptr
+		if(present(outUnit)) outUnit_handle = c_loc(outUnit_ptr)
+		result = lib_cdiIterator_inqLevelType(me_dummy%ptr, levelSelector_dummy, outName_handle, outLongName_handle, outStdName_handle, o&
+		&utUnit_handle)
+		if(present(outName)) then
+			if(c_associated(outName_ptr)) then
+				outName_shape(1) = int(lib_strlen(outName_ptr))
+				call c_f_pointer(outName_ptr, outName_fptr, outName_shape)
+				allocate(outName(outName_shape(1)))
+				outName = outName_fptr
+				call lib_free(outName_ptr)
+			else
+				outName => null()
+			end if
+		end if
+		if(present(outLongName)) then
+			if(c_associated(outLongName_ptr)) then
+				outLongName_shape(1) = int(lib_strlen(outLongName_ptr))
+				call c_f_pointer(outLongName_ptr, outLongName_fptr, outLongName_shape)
+				allocate(outLongName(outLongName_shape(1)))
+				outLongName = outLongName_fptr
+				call lib_free(outLongName_ptr)
+			else
+				outLongName => null()
+			end if
+		end if
+		if(present(outStdName)) then
+			if(c_associated(outStdName_ptr)) then
+				outStdName_shape(1) = int(lib_strlen(outStdName_ptr))
+				call c_f_pointer(outStdName_ptr, outStdName_fptr, outStdName_shape)
+				allocate(outStdName(outStdName_shape(1)))
+				outStdName = outStdName_fptr
+				call lib_free(outStdName_ptr)
+			else
+				outStdName => null()
+			end if
+		end if
+		if(present(outUnit)) then
+			if(c_associated(outUnit_ptr)) then
+				outUnit_shape(1) = int(lib_strlen(outUnit_ptr))
+				call c_f_pointer(outUnit_ptr, outUnit_fptr, outUnit_shape)
+				allocate(outUnit(outUnit_shape(1)))
+				outUnit = outUnit_fptr
+				call lib_free(outUnit_ptr)
+			else
+				outUnit => null()
+			end if
+		end if
+	end function cdiIterator_inqLevelType
+
+	function cdiIterator_inqLevel(me_dummy, levelSelector_dummy, outValue1, outValue2) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), value :: levelSelector_dummy
+		real(c_double), optional, intent(inout) :: outValue1
+		real(c_double), optional, intent(inout) :: outValue2
+		real(c_double), target :: outValue1_temp
+		type(c_ptr) :: outValue1_ptr
+		real(c_double), target :: outValue2_temp
+		type(c_ptr) :: outValue2_ptr
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevel(me_dummy, levelSelector_dummy, outValue1, outValue2) bind(c, name = 'cdiIterato&
+			&r_inqLevel')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				integer(c_int), value :: levelSelector_dummy
+				type(c_ptr), value :: outValue1
+				type(c_ptr), value :: outValue2
+			end function lib_cdiIterator_inqLevel
+		end interface
+		outValue1_ptr = c_null_ptr
+		if(present(outValue1)) outValue1_ptr = c_loc(outValue1_temp)
+		outValue2_ptr = c_null_ptr
+		if(present(outValue2)) outValue2_ptr = c_loc(outValue2_temp)
+		result = lib_cdiIterator_inqLevel(me_dummy%ptr, levelSelector_dummy, outValue1_ptr, outValue2_ptr)
+		if(present(outValue1)) outValue1 = outValue1_temp
+		if(present(outValue2)) outValue2 = outValue2_temp
+	end function cdiIterator_inqLevel
+
+	function cdiIterator_inqLevelUuid(me_dummy, outVgridNumber, outLevelCount, outUuid) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), optional, intent(inout) :: outVgridNumber
+		integer(c_int), optional, intent(inout) :: outLevelCount
+		character(kind = c_char), optional, intent(inout) :: outUuid(CDI_UUID_SIZE)
+		integer(c_int), target :: outVgridNumber_temp
+		type(c_ptr) :: outVgridNumber_ptr
+		integer(c_int), target :: outLevelCount_temp
+		type(c_ptr) :: outLevelCount_ptr
+		character(kind = c_char), target :: outUuid_temp(CDI_UUID_SIZE)
+		type(c_ptr) :: outUuid_ptr
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevelUuid(me_dummy, outVgridNumber, outLevelCount, outUuid) bind(c, name = 'cdiIterat&
+			&or_inqLevelUuid')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				type(c_ptr), value :: outVgridNumber
+				type(c_ptr), value :: outLevelCount
+				type(c_ptr), value :: outUuid
+			end function lib_cdiIterator_inqLevelUuid
+		end interface
+		outVgridNumber_ptr = c_null_ptr
+		if(present(outVgridNumber)) outVgridNumber_ptr = c_loc(outVgridNumber_temp)
+		outLevelCount_ptr = c_null_ptr
+		if(present(outLevelCount)) outLevelCount_ptr = c_loc(outLevelCount_temp)
+		outUuid_ptr = c_null_ptr
+		if(present(outUuid)) outUuid_ptr = c_loc(outUuid_temp)
+		result = lib_cdiIterator_inqLevelUuid(me_dummy%ptr, outVgridNumber_ptr, outLevelCount_ptr, outUuid_ptr)
+		if(present(outVgridNumber)) outVgridNumber = outVgridNumber_temp
+		if(present(outLevelCount)) outLevelCount = outLevelCount_temp
+		if(present(outUuid)) outUuid = outUuid_temp
+	end function cdiIterator_inqLevelUuid
+
+	function cdiIterator_inqParam(me_dummy) result(result)
+		type(t_CdiParam) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(t_CdiParam) function lib_cdiIterator_inqParam(me_dummy) bind(c, name = 'cdiIterator_inqParam')
+				import c_ptr, t_CdiParam
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqParam
+		end interface
+		result = lib_cdiIterator_inqParam(me_dummy%ptr)
+	end function cdiIterator_inqParam
+
+	function cdiIterator_inqDatatype(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqDatatype(me_dummy) bind(c, name = 'cdiIterator_inqDatatype')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqDatatype
+		end interface
+		result = lib_cdiIterator_inqDatatype(me_dummy%ptr)
+	end function cdiIterator_inqDatatype
+
+	function cdiIterator_inqTsteptype(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqTsteptype(me_dummy) bind(c, name = 'cdiIterator_inqTsteptype')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqTsteptype
+		end interface
+		result = lib_cdiIterator_inqTsteptype(me_dummy%ptr)
+	end function cdiIterator_inqTsteptype
+
+	function cdiIterator_inqVariableName(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqVariableName(me_dummy) bind(c, name = 'cdiIterator_inqVariableName')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqVariableName
+		end interface
+		cString = lib_cdiIterator_inqVariableName(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqVariableName
+
+	function cdiIterator_inqGridId(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqGridId(me_dummy) bind(c, name = 'cdiIterator_inqGridId')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqGridId
+		end interface
+		result = lib_cdiIterator_inqGridId(me_dummy%ptr)
+	end function cdiIterator_inqGridId
+
+	subroutine cdiIterator_readField(me_dummy, data_vec_dummy, nmiss)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_size_t), optional, intent(inout) :: nmiss
+		integer(c_size_t), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_cdiIterator_readField(me_dummy, data_vec_dummy, nmiss) bind(c, name = 'cdiIterator_readField')
+				import c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_cdiIterator_readField
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_cdiIterator_readField(me_dummy%ptr, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine cdiIterator_readField
+
+	subroutine cdiIterator_readFieldF(me_dummy, data_vec_dummy, nmiss)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_size_t), optional, intent(inout) :: nmiss
+		integer(c_size_t), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_cdiIterator_readFieldF(me_dummy, data_vec_dummy, nmiss) bind(c, name = 'cdiIterator_readFieldF')
+				import c_float, c_ptr
+				type(c_ptr), value :: me_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_cdiIterator_readFieldF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_cdiIterator_readFieldF(me_dummy%ptr, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine cdiIterator_readFieldF
+
+	function cdiGribIterator_clone(me_dummy) result(result)
+		type(t_CdiGribIterator) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(c_ptr) function lib_cdiGribIterator_clone(me_dummy) bind(c, name = 'cdiGribIterator_clone')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiGribIterator_clone
+		end interface
+		result%ptr = lib_cdiGribIterator_clone(me_dummy%ptr)
+	end function cdiGribIterator_clone
+
+	subroutine cdiGribIterator_delete(me_dummy)
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		interface
+			subroutine lib_cdiGribIterator_delete(me_dummy) bind(c, name = 'cdiGribIterator_delete')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end subroutine lib_cdiGribIterator_delete
+		end interface
+		call lib_cdiGribIterator_delete(me_dummy%ptr)
+	end subroutine cdiGribIterator_delete
+
+	function cdiGribIterator_getLong(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_long), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLong(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getLong')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getLong
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getLong(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getLong
+
+	function cdiGribIterator_getDouble(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		real(c_double), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getDouble(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getDouble')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getDouble
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getDouble(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getDouble
+
+	function cdiGribIterator_getLength(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_size_t), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_size_t), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLength(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getLength')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getLength
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getLength(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getLength
+
+	function cdiGribIterator_getString(me_dummy, key_dummy, value_dummy, length) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char, len = *), intent(inout) :: value_dummy
+		integer(c_size_t), optional, intent(inout) :: length
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		character(kind = c_char) :: value_temp(len(value_dummy))
+		integer :: value_i
+		logical :: value_padding = .true.
+		integer(c_size_t), target :: length_temp
+		type(c_ptr) :: length_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getString(me_dummy, key_dummy, value_dummy, length) bind(c, name = 'cdiGribIterator_&
+			&getString')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				character(kind = c_char) :: value_dummy(*)
+				type(c_ptr), value :: length
+			end function lib_cdiGribIterator_getString
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		do value_i = len(value_dummy), 1, -1
+			if(value_dummy(value_i:value_i) /= ' ') value_padding = .false.
+			if(value_padding) then
+				value_temp(value_i) = c_null_char
+			else
+				value_temp(value_i) = value_dummy(value_i:value_i)
+			end if
+		end do
+		length_ptr = c_null_ptr
+		if(present(length)) length_ptr = c_loc(length_temp)
+		result = lib_cdiGribIterator_getString(me_dummy%ptr, key_temp, value_temp, length_ptr)
+		value_padding = .false.
+		do value_i = 1, len(value_dummy)
+			if(value_temp(value_i) == c_null_char) value_padding = .true.
+			if(value_padding) then
+				value_dummy(value_i:value_i) = ' '
+			else
+				value_dummy(value_i:value_i) = value_temp(value_i)
+			end if
+		end do
+		if(present(length)) length = length_temp
+	end function cdiGribIterator_getString
+
+	function cdiGribIterator_getSize(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_size_t), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_size_t), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getSize(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getSize')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getSize
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getSize(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getSize
+
+	function cdiGribIterator_getLongArray(me_dummy, key_dummy, value, array_size) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), optional, intent(inout) :: value
+		integer(c_size_t), optional, intent(inout) :: array_size
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_long), target :: value_temp
+		type(c_ptr) :: value_ptr
+		integer(c_size_t), target :: array_size_temp
+		type(c_ptr) :: array_size_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLongArray(me_dummy, key_dummy, value, array_size) bind(c, name = 'cdiGribIterator&
+			&_getLongArray')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+				type(c_ptr), value :: array_size
+			end function lib_cdiGribIterator_getLongArray
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		array_size_ptr = c_null_ptr
+		if(present(array_size)) array_size_ptr = c_loc(array_size_temp)
+		result = lib_cdiGribIterator_getLongArray(me_dummy%ptr, key_temp, value_ptr, array_size_ptr)
+		if(present(value)) value = value_temp
+		if(present(array_size)) array_size = array_size_temp
+	end function cdiGribIterator_getLongArray
+
+	function cdiGribIterator_getDoubleArray(me_dummy, key_dummy, value, array_size) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), optional, intent(inout) :: value
+		integer(c_size_t), optional, intent(inout) :: array_size
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		real(c_double), target :: value_temp
+		type(c_ptr) :: value_ptr
+		integer(c_size_t), target :: array_size_temp
+		type(c_ptr) :: array_size_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getDoubleArray(me_dummy, key_dummy, value, array_size) bind(c, name = 'cdiGribIterat&
+			&or_getDoubleArray')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+				type(c_ptr), value :: array_size
+			end function lib_cdiGribIterator_getDoubleArray
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		array_size_ptr = c_null_ptr
+		if(present(array_size)) array_size_ptr = c_loc(array_size_temp)
+		result = lib_cdiGribIterator_getDoubleArray(me_dummy%ptr, key_temp, value_ptr, array_size_ptr)
+		if(present(value)) value = value_temp
+		if(present(array_size)) array_size = array_size_temp
+	end function cdiGribIterator_getDoubleArray
+
+	function cdiGribIterator_inqEdition(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiGribIterator_inqEdition(me_dummy) bind(c, name = 'cdiGribIterator_inqEdition')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiGribIterator_inqEdition
+		end interface
+		result = lib_cdiGribIterator_inqEdition(me_dummy%ptr)
+	end function cdiGribIterator_inqEdition
+
+	function cdiGribIterator_inqLongValue(me_dummy, key_dummy) result(result)
+		integer(c_long) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			integer(c_long) function lib_cdiGribIterator_inqLongValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqLongValue')
+				import c_char, c_long, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqLongValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqLongValue(me_dummy%ptr, key_temp)
+	end function cdiGribIterator_inqLongValue
+
+	function cdiGribIterator_inqLongDefaultValue(me_dummy, key_dummy, defaultValue_dummy) result(result)
+		integer(c_long) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), value :: defaultValue_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			integer(c_long) function lib_cdiGribIterator_inqLongDefaultValue(me_dummy, key_dummy, defaultValue_dummy) bind(c, name = 'cdiGri&
+			&bIterator_inqLongDefaultValue')
+				import c_char, c_long, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				integer(c_long), value :: defaultValue_dummy
+			end function lib_cdiGribIterator_inqLongDefaultValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqLongDefaultValue(me_dummy%ptr, key_temp, defaultValue_dummy)
+	end function cdiGribIterator_inqLongDefaultValue
+
+	function cdiGribIterator_inqDoubleValue(me_dummy, key_dummy) result(result)
+		real(c_double) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			real(c_double) function lib_cdiGribIterator_inqDoubleValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqDoubleValue')
+				import c_char, c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqDoubleValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqDoubleValue(me_dummy%ptr, key_temp)
+	end function cdiGribIterator_inqDoubleValue
+
+	function cdiGribIterator_inqDoubleDefaultValue(me_dummy, key_dummy, defaultValue_dummy) result(result)
+		real(c_double) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), value :: defaultValue_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			real(c_double) function lib_cdiGribIterator_inqDoubleDefaultValue(me_dummy, key_dummy, defaultValue_dummy) bind(c, name = 'cdiGr&
+			&ibIterator_inqDoubleDefaultValue')
+				import c_char, c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				real(c_double), value :: defaultValue_dummy
+			end function lib_cdiGribIterator_inqDoubleDefaultValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqDoubleDefaultValue(me_dummy%ptr, key_temp, defaultValue_dummy)
+	end function cdiGribIterator_inqDoubleDefaultValue
+
+	function cdiGribIterator_inqStringValue(me_dummy, key_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiGribIterator_inqStringValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqStringValue')
+				import c_char, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqStringValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		cString = lib_cdiGribIterator_inqStringValue(me_dummy%ptr, key_temp)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiGribIterator_inqStringValue
+
+	function vlistCreate() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_vlistCreate() bind(c, name = 'vlistCreate')
+				import c_int
+			end function lib_vlistCreate
+		end interface
+		result = lib_vlistCreate()
+	end function vlistCreate
+
+	subroutine vlistDestroy(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistDestroy(vlistID_dummy) bind(c, name = 'vlistDestroy')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistDestroy
+		end interface
+		call lib_vlistDestroy(vlistID_dummy)
+	end subroutine vlistDestroy
+
+	function vlistDuplicate(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistDuplicate(vlistID_dummy) bind(c, name = 'vlistDuplicate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistDuplicate
+		end interface
+		result = lib_vlistDuplicate(vlistID_dummy)
+	end function vlistDuplicate
+
+	subroutine vlistCopy(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCopy(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCopy')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCopy
+		end interface
+		call lib_vlistCopy(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCopy
+
+	subroutine vlistCopyFlag(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCopyFlag(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCopyFlag')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCopyFlag
+		end interface
+		call lib_vlistCopyFlag(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCopyFlag
+
+	subroutine vlistClearFlag(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistClearFlag(vlistID_dummy) bind(c, name = 'vlistClearFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistClearFlag
+		end interface
+		call lib_vlistClearFlag(vlistID_dummy)
+	end subroutine vlistClearFlag
+
+	subroutine vlistCat(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCat(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCat')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCat
+		end interface
+		call lib_vlistCat(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCat
+
+	subroutine vlistMerge(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistMerge(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistMerge')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistMerge
+		end interface
+		call lib_vlistMerge(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistMerge
+
+	subroutine vlistPrint(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistPrint(vlistID_dummy) bind(c, name = 'vlistPrint')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistPrint
+		end interface
+		call lib_vlistPrint(vlistID_dummy)
+	end subroutine vlistPrint
+
+	function vlistNumber(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNumber(vlistID_dummy) bind(c, name = 'vlistNumber')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNumber
+		end interface
+		result = lib_vlistNumber(vlistID_dummy)
+	end function vlistNumber
+
+	function vlistNvars(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNvars(vlistID_dummy) bind(c, name = 'vlistNvars')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNvars
+		end interface
+		result = lib_vlistNvars(vlistID_dummy)
+	end function vlistNvars
+
+	function vlistNgrids(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNgrids(vlistID_dummy) bind(c, name = 'vlistNgrids')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNgrids
+		end interface
+		result = lib_vlistNgrids(vlistID_dummy)
+	end function vlistNgrids
+
+	function vlistNzaxis(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNzaxis(vlistID_dummy) bind(c, name = 'vlistNzaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNzaxis
+		end interface
+		result = lib_vlistNzaxis(vlistID_dummy)
+	end function vlistNzaxis
+
+	subroutine vlistDefNtsteps(vlistID_dummy, nts_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: nts_dummy
+		interface
+			subroutine lib_vlistDefNtsteps(vlistID_dummy, nts_dummy) bind(c, name = 'vlistDefNtsteps')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: nts_dummy
+			end subroutine lib_vlistDefNtsteps
+		end interface
+		call lib_vlistDefNtsteps(vlistID_dummy, nts_dummy)
+	end subroutine vlistDefNtsteps
+
+	function vlistNtsteps(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNtsteps(vlistID_dummy) bind(c, name = 'vlistNtsteps')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNtsteps
+		end interface
+		result = lib_vlistNtsteps(vlistID_dummy)
+	end function vlistNtsteps
+
+	function vlistGridsizeMax(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistGridsizeMax(vlistID_dummy) bind(c, name = 'vlistGridsizeMax')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistGridsizeMax
+		end interface
+		result = lib_vlistGridsizeMax(vlistID_dummy)
+	end function vlistGridsizeMax
+
+	function vlistGrid(vlistID_dummy, index_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			integer(c_int) function lib_vlistGrid(vlistID_dummy, index_dummy) bind(c, name = 'vlistGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_vlistGrid
+		end interface
+		result = lib_vlistGrid(vlistID_dummy, index_dummy)
+	end function vlistGrid
+
+	function vlistGridIndex(vlistID_dummy, gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_vlistGridIndex(vlistID_dummy, gridID_dummy) bind(c, name = 'vlistGridIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID_dummy
+			end function lib_vlistGridIndex
+		end interface
+		result = lib_vlistGridIndex(vlistID_dummy, gridID_dummy)
+	end function vlistGridIndex
+
+	subroutine vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy) bind(c, name = 'vlistChangeGridIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_vlistChangeGridIndex
+		end interface
+		call lib_vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy)
+	end subroutine vlistChangeGridIndex
+
+	subroutine vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID1_dummy
+		integer(c_int), value :: gridID2_dummy
+		interface
+			subroutine lib_vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy) bind(c, name = 'vlistChangeGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID1_dummy
+				integer(c_int), value :: gridID2_dummy
+			end subroutine lib_vlistChangeGrid
+		end interface
+		call lib_vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy)
+	end subroutine vlistChangeGrid
+
+	function vlistZaxis(vlistID_dummy, index_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			integer(c_int) function lib_vlistZaxis(vlistID_dummy, index_dummy) bind(c, name = 'vlistZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_vlistZaxis
+		end interface
+		result = lib_vlistZaxis(vlistID_dummy, index_dummy)
+	end function vlistZaxis
+
+	function vlistZaxisIndex(vlistID_dummy, zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_vlistZaxisIndex(vlistID_dummy, zaxisID_dummy) bind(c, name = 'vlistZaxisIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_vlistZaxisIndex
+		end interface
+		result = lib_vlistZaxisIndex(vlistID_dummy, zaxisID_dummy)
+	end function vlistZaxisIndex
+
+	subroutine vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy) bind(c, name = 'vlistChangeZaxisIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_vlistChangeZaxisIndex
+		end interface
+		call lib_vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy)
+	end subroutine vlistChangeZaxisIndex
+
+	subroutine vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: zaxisID1_dummy
+		integer(c_int), value :: zaxisID2_dummy
+		interface
+			subroutine lib_vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy) bind(c, name = 'vlistChangeZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: zaxisID1_dummy
+				integer(c_int), value :: zaxisID2_dummy
+			end subroutine lib_vlistChangeZaxis
+		end interface
+		call lib_vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy)
+	end subroutine vlistChangeZaxis
+
+	function vlistNrecs(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNrecs(vlistID_dummy) bind(c, name = 'vlistNrecs')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNrecs
+		end interface
+		result = lib_vlistNrecs(vlistID_dummy)
+	end function vlistNrecs
+
+	subroutine vlistDefTaxis(vlistID_dummy, taxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_vlistDefTaxis(vlistID_dummy, taxisID_dummy) bind(c, name = 'vlistDefTaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_vlistDefTaxis
+		end interface
+		call lib_vlistDefTaxis(vlistID_dummy, taxisID_dummy)
+	end subroutine vlistDefTaxis
+
+	function vlistInqTaxis(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqTaxis(vlistID_dummy) bind(c, name = 'vlistInqTaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqTaxis
+		end interface
+		result = lib_vlistInqTaxis(vlistID_dummy)
+	end function vlistInqTaxis
+
+	subroutine vlistDefTable(vlistID_dummy, tableID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: tableID_dummy
+		interface
+			subroutine lib_vlistDefTable(vlistID_dummy, tableID_dummy) bind(c, name = 'vlistDefTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_vlistDefTable
+		end interface
+		call lib_vlistDefTable(vlistID_dummy, tableID_dummy)
+	end subroutine vlistDefTable
+
+	function vlistInqTable(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqTable(vlistID_dummy) bind(c, name = 'vlistInqTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqTable
+		end interface
+		result = lib_vlistInqTable(vlistID_dummy)
+	end function vlistInqTable
+
+	subroutine vlistDefInstitut(vlistID_dummy, instID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: instID_dummy
+		interface
+			subroutine lib_vlistDefInstitut(vlistID_dummy, instID_dummy) bind(c, name = 'vlistDefInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: instID_dummy
+			end subroutine lib_vlistDefInstitut
+		end interface
+		call lib_vlistDefInstitut(vlistID_dummy, instID_dummy)
+	end subroutine vlistDefInstitut
+
+	function vlistInqInstitut(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqInstitut(vlistID_dummy) bind(c, name = 'vlistInqInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqInstitut
+		end interface
+		result = lib_vlistInqInstitut(vlistID_dummy)
+	end function vlistInqInstitut
+
+	subroutine vlistDefModel(vlistID_dummy, modelID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: modelID_dummy
+		interface
+			subroutine lib_vlistDefModel(vlistID_dummy, modelID_dummy) bind(c, name = 'vlistDefModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: modelID_dummy
+			end subroutine lib_vlistDefModel
+		end interface
+		call lib_vlistDefModel(vlistID_dummy, modelID_dummy)
+	end subroutine vlistDefModel
+
+	function vlistInqModel(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqModel(vlistID_dummy) bind(c, name = 'vlistInqModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqModel
+		end interface
+		result = lib_vlistInqModel(vlistID_dummy)
+	end function vlistInqModel
+
+	function vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: tsteptype_dummy
+		interface
+			integer(c_int) function lib_vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy) bind(c, name = 'vlistDefVar&
+			&')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: tsteptype_dummy
+			end function lib_vlistDefVar
+		end interface
+		result = lib_vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy)
+	end function vlistDefVar
+
+	subroutine vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy) bind(c, name = 'vlistChangeVarGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_vlistChangeVarGrid
+		end interface
+		call lib_vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy)
+	end subroutine vlistChangeVarGrid
+
+	subroutine vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy) bind(c, name = 'vlistChangeVarZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_vlistChangeVarZaxis
+		end interface
+		call lib_vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy)
+	end subroutine vlistChangeVarZaxis
+
+	subroutine vlistInqVar(vlistID_dummy, varID_dummy, gridID, zaxisID, tsteptype)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: gridID
+		integer(c_int), optional, intent(inout) :: zaxisID
+		integer(c_int), optional, intent(inout) :: tsteptype
+		integer(c_int), target :: gridID_temp
+		type(c_ptr) :: gridID_ptr
+		integer(c_int), target :: zaxisID_temp
+		type(c_ptr) :: zaxisID_ptr
+		integer(c_int), target :: tsteptype_temp
+		type(c_ptr) :: tsteptype_ptr
+		interface
+			subroutine lib_vlistInqVar(vlistID_dummy, varID_dummy, gridID, zaxisID, tsteptype) bind(c, name = 'vlistInqVar')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: gridID
+				type(c_ptr), value :: zaxisID
+				type(c_ptr), value :: tsteptype
+			end subroutine lib_vlistInqVar
+		end interface
+		gridID_ptr = c_null_ptr
+		if(present(gridID)) gridID_ptr = c_loc(gridID_temp)
+		zaxisID_ptr = c_null_ptr
+		if(present(zaxisID)) zaxisID_ptr = c_loc(zaxisID_temp)
+		tsteptype_ptr = c_null_ptr
+		if(present(tsteptype)) tsteptype_ptr = c_loc(tsteptype_temp)
+		call lib_vlistInqVar(vlistID_dummy, varID_dummy, gridID_ptr, zaxisID_ptr, tsteptype_ptr)
+		if(present(gridID)) gridID = gridID_temp
+		if(present(zaxisID)) zaxisID = zaxisID_temp
+		if(present(tsteptype)) tsteptype = tsteptype_temp
+	end subroutine vlistInqVar
+
+	function vlistInqVarGrid(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarGrid(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarGrid
+		end interface
+		result = lib_vlistInqVarGrid(vlistID_dummy, varID_dummy)
+	end function vlistInqVarGrid
+
+	function vlistInqVarZaxis(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarZaxis(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarZaxis
+		end interface
+		result = lib_vlistInqVarZaxis(vlistID_dummy, varID_dummy)
+	end function vlistInqVarZaxis
+
+	function vlistInqVarID(vlistID_dummy, code_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: code_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarID(vlistID_dummy, code_dummy) bind(c, name = 'vlistInqVarID')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: code_dummy
+			end function lib_vlistInqVarID
+		end interface
+		result = lib_vlistInqVarID(vlistID_dummy, code_dummy)
+	end function vlistInqVarID
+
+	subroutine vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: tsteptype_dummy
+		interface
+			subroutine lib_vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy) bind(c, name = 'vlistDefVarTsteptype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: tsteptype_dummy
+			end subroutine lib_vlistDefVarTsteptype
+		end interface
+		call lib_vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy)
+	end subroutine vlistDefVarTsteptype
+
+	function vlistInqVarTsteptype(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTsteptype(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTsteptype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTsteptype
+		end interface
+		result = lib_vlistInqVarTsteptype(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTsteptype
+
+	subroutine vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: comptype_dummy
+		interface
+			subroutine lib_vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy) bind(c, name = 'vlistDefVarCompType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: comptype_dummy
+			end subroutine lib_vlistDefVarCompType
+		end interface
+		call lib_vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy)
+	end subroutine vlistDefVarCompType
+
+	function vlistInqVarCompType(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCompType(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCompType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCompType
+		end interface
+		result = lib_vlistInqVarCompType(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCompType
+
+	subroutine vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: complevel_dummy
+		interface
+			subroutine lib_vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy) bind(c, name = 'vlistDefVarCompLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: complevel_dummy
+			end subroutine lib_vlistDefVarCompLevel
+		end interface
+		call lib_vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy)
+	end subroutine vlistDefVarCompLevel
+
+	function vlistInqVarCompLevel(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCompLevel(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCompLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCompLevel
+		end interface
+		result = lib_vlistInqVarCompLevel(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCompLevel
+
+	subroutine vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: param_dummy
+		interface
+			subroutine lib_vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy) bind(c, name = 'vlistDefVarParam')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: param_dummy
+			end subroutine lib_vlistDefVarParam
+		end interface
+		call lib_vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy)
+	end subroutine vlistDefVarParam
+
+	function vlistInqVarParam(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarParam(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarParam')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarParam
+		end interface
+		result = lib_vlistInqVarParam(vlistID_dummy, varID_dummy)
+	end function vlistInqVarParam
+
+	subroutine vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: code_dummy
+		interface
+			subroutine lib_vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy) bind(c, name = 'vlistDefVarCode')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: code_dummy
+			end subroutine lib_vlistDefVarCode
+		end interface
+		call lib_vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy)
+	end subroutine vlistDefVarCode
+
+	function vlistInqVarCode(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCode(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCode')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCode
+		end interface
+		result = lib_vlistInqVarCode(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCode
+
+	subroutine vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: datatype_dummy
+		interface
+			subroutine lib_vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy) bind(c, name = 'vlistDefVarDatatype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: datatype_dummy
+			end subroutine lib_vlistDefVarDatatype
+		end interface
+		call lib_vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy)
+	end subroutine vlistDefVarDatatype
+
+	function vlistInqVarDatatype(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarDatatype(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarDatatype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarDatatype
+		end interface
+		result = lib_vlistInqVarDatatype(vlistID_dummy, varID_dummy)
+	end function vlistInqVarDatatype
+
+	subroutine vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: chunktype_dummy
+		interface
+			subroutine lib_vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy) bind(c, name = 'vlistDefVarChunkType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: chunktype_dummy
+			end subroutine lib_vlistDefVarChunkType
+		end interface
+		call lib_vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy)
+	end subroutine vlistDefVarChunkType
+
+	function vlistInqVarChunkType(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarChunkType(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarChunkType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarChunkType
+		end interface
+		result = lib_vlistInqVarChunkType(vlistID_dummy, varID_dummy)
+	end function vlistInqVarChunkType
+
+	subroutine vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: xyz_dummy
+		interface
+			subroutine lib_vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy) bind(c, name = 'vlistDefVarXYZ')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: xyz_dummy
+			end subroutine lib_vlistDefVarXYZ
+		end interface
+		call lib_vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy)
+	end subroutine vlistDefVarXYZ
+
+	function vlistInqVarXYZ(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarXYZ(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarXYZ')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarXYZ
+		end interface
+		result = lib_vlistInqVarXYZ(vlistID_dummy, varID_dummy)
+	end function vlistInqVarXYZ
+
+	function vlistInqVarNumber(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarNumber(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarNumber')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarNumber
+		end interface
+		result = lib_vlistInqVarNumber(vlistID_dummy, varID_dummy)
+	end function vlistInqVarNumber
+
+	subroutine vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: instID_dummy
+		interface
+			subroutine lib_vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy) bind(c, name = 'vlistDefVarInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: instID_dummy
+			end subroutine lib_vlistDefVarInstitut
+		end interface
+		call lib_vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy)
+	end subroutine vlistDefVarInstitut
+
+	function vlistInqVarInstitut(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarInstitut(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarInstitut
+		end interface
+		result = lib_vlistInqVarInstitut(vlistID_dummy, varID_dummy)
+	end function vlistInqVarInstitut
+
+	subroutine vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: modelID_dummy
+		interface
+			subroutine lib_vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy) bind(c, name = 'vlistDefVarModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: modelID_dummy
+			end subroutine lib_vlistDefVarModel
+		end interface
+		call lib_vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy)
+	end subroutine vlistDefVarModel
+
+	function vlistInqVarModel(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarModel(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarModel
+		end interface
+		result = lib_vlistInqVarModel(vlistID_dummy, varID_dummy)
+	end function vlistInqVarModel
+
+	subroutine vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: tableID_dummy
+		interface
+			subroutine lib_vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy) bind(c, name = 'vlistDefVarTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_vlistDefVarTable
+		end interface
+		call lib_vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy)
+	end subroutine vlistDefVarTable
+
+	function vlistInqVarTable(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTable(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTable
+		end interface
+		result = lib_vlistInqVarTable(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTable
+
+	subroutine vlistDefVarName(vlistID_dummy, varID_dummy, name_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarName(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistDefVarName')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_vlistDefVarName
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarName(vlistID_dummy, varID_dummy, name_temp)
+	end subroutine vlistDefVarName
+
+	subroutine vlistInqVarName(vlistID_dummy, varID_dummy, name_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			subroutine lib_vlistInqVarName(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarName')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_vlistInqVarName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		call lib_vlistInqVarName(vlistID_dummy, varID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end subroutine vlistInqVarName
+
+	function vlistCopyVarName(vlistId_dummy, varId_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: vlistId_dummy
+		integer(c_int), value :: varId_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_vlistCopyVarName(vlistId_dummy, varId_dummy) bind(c, name = 'vlistCopyVarName')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistId_dummy
+				integer(c_int), value :: varId_dummy
+			end function lib_vlistCopyVarName
+		end interface
+		cString = lib_vlistCopyVarName(vlistId_dummy, varId_dummy)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function vlistCopyVarName
+
+	subroutine vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy) + 1)
+		integer :: stdname_i
+		interface
+			subroutine lib_vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_dummy) bind(c, name = 'vlistDefVarStdname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_vlistDefVarStdname
+		end interface
+		do stdname_i = 1, len(stdname_dummy)
+		stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+		end do
+		stdname_temp(len(stdname_dummy) + 1) = c_null_char
+		call lib_vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_temp)
+	end subroutine vlistDefVarStdname
+
+	subroutine vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy))
+		integer :: stdname_i
+		logical :: stdname_padding = .true.
+		interface
+			subroutine lib_vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_dummy) bind(c, name = 'vlistInqVarStdname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_vlistInqVarStdname
+		end interface
+		do stdname_i = len(stdname_dummy), 1, -1
+			if(stdname_dummy(stdname_i:stdname_i) /= ' ') stdname_padding = .false.
+			if(stdname_padding) then
+				stdname_temp(stdname_i) = c_null_char
+			else
+				stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+			end if
+		end do
+		call lib_vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_temp)
+		stdname_padding = .false.
+		do stdname_i = 1, len(stdname_dummy)
+			if(stdname_temp(stdname_i) == c_null_char) stdname_padding = .true.
+			if(stdname_padding) then
+				stdname_dummy(stdname_i:stdname_i) = ' '
+			else
+				stdname_dummy(stdname_i:stdname_i) = stdname_temp(stdname_i)
+			end if
+		end do
+	end subroutine vlistInqVarStdname
+
+	subroutine vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			subroutine lib_vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_dummy) bind(c, name = 'vlistDefVarLongname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_vlistDefVarLongname
+		end interface
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		call lib_vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_temp)
+	end subroutine vlistDefVarLongname
+
+	subroutine vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			subroutine lib_vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_dummy) bind(c, name = 'vlistInqVarLongname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_vlistInqVarLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		call lib_vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end subroutine vlistInqVarLongname
+
+	subroutine vlistDefVarUnits(vlistID_dummy, varID_dummy, units_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_vlistDefVarUnits(vlistID_dummy, varID_dummy, units_dummy) bind(c, name = 'vlistDefVarUnits')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_vlistDefVarUnits
+		end interface
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_vlistDefVarUnits(vlistID_dummy, varID_dummy, units_temp)
+	end subroutine vlistDefVarUnits
+
+	subroutine vlistInqVarUnits(vlistID_dummy, varID_dummy, units_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_vlistInqVarUnits(vlistID_dummy, varID_dummy, units_dummy) bind(c, name = 'vlistInqVarUnits')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_vlistInqVarUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_vlistInqVarUnits(vlistID_dummy, varID_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine vlistInqVarUnits
+
+	subroutine vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: missval_dummy
+		interface
+			subroutine lib_vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy) bind(c, name = 'vlistDefVarMissval')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: missval_dummy
+			end subroutine lib_vlistDefVarMissval
+		end interface
+		call lib_vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy)
+	end subroutine vlistDefVarMissval
+
+	function vlistInqVarMissval(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarMissval(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarMissval')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarMissval
+		end interface
+		result = lib_vlistInqVarMissval(vlistID_dummy, varID_dummy)
+	end function vlistInqVarMissval
+
+	subroutine vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: extra_dummy
+		character(kind = c_char) :: extra_temp(len(extra_dummy) + 1)
+		integer :: extra_i
+		interface
+			subroutine lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy) bind(c, name = 'vlistDefVarExtra')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: extra_dummy(*)
+			end subroutine lib_vlistDefVarExtra
+		end interface
+		do extra_i = 1, len(extra_dummy)
+		extra_temp(extra_i) = extra_dummy(extra_i:extra_i)
+		end do
+		extra_temp(len(extra_dummy) + 1) = c_null_char
+		call lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_temp)
+	end subroutine vlistDefVarExtra
+
+	subroutine vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: extra_dummy
+		character(kind = c_char) :: extra_temp(len(extra_dummy))
+		integer :: extra_i
+		logical :: extra_padding = .true.
+		interface
+			subroutine lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy) bind(c, name = 'vlistInqVarExtra')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: extra_dummy(*)
+			end subroutine lib_vlistInqVarExtra
+		end interface
+		do extra_i = len(extra_dummy), 1, -1
+			if(extra_dummy(extra_i:extra_i) /= ' ') extra_padding = .false.
+			if(extra_padding) then
+				extra_temp(extra_i) = c_null_char
+			else
+				extra_temp(extra_i) = extra_dummy(extra_i:extra_i)
+			end if
+		end do
+		call lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_temp)
+		extra_padding = .false.
+		do extra_i = 1, len(extra_dummy)
+			if(extra_temp(extra_i) == c_null_char) extra_padding = .true.
+			if(extra_padding) then
+				extra_dummy(extra_i:extra_i) = ' '
+			else
+				extra_dummy(extra_i:extra_i) = extra_temp(extra_i)
+			end if
+		end do
+	end subroutine vlistInqVarExtra
+
+	subroutine vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: scalefactor_dummy
+		interface
+			subroutine lib_vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy) bind(c, name = 'vlistDefVarScalefactor')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: scalefactor_dummy
+			end subroutine lib_vlistDefVarScalefactor
+		end interface
+		call lib_vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy)
+	end subroutine vlistDefVarScalefactor
+
+	function vlistInqVarScalefactor(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarScalefactor(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarScalefactor')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarScalefactor
+		end interface
+		result = lib_vlistInqVarScalefactor(vlistID_dummy, varID_dummy)
+	end function vlistInqVarScalefactor
+
+	subroutine vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: addoffset_dummy
+		interface
+			subroutine lib_vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy) bind(c, name = 'vlistDefVarAddoffset')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: addoffset_dummy
+			end subroutine lib_vlistDefVarAddoffset
+		end interface
+		call lib_vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy)
+	end subroutine vlistDefVarAddoffset
+
+	function vlistInqVarAddoffset(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarAddoffset(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarAddoffset')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarAddoffset
+		end interface
+		result = lib_vlistInqVarAddoffset(vlistID_dummy, varID_dummy)
+	end function vlistInqVarAddoffset
+
+	subroutine vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: timave_dummy
+		interface
+			subroutine lib_vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy) bind(c, name = 'vlistDefVarTimave')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: timave_dummy
+			end subroutine lib_vlistDefVarTimave
+		end interface
+		call lib_vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy)
+	end subroutine vlistDefVarTimave
+
+	function vlistInqVarTimave(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTimave(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTimave')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTimave
+		end interface
+		result = lib_vlistInqVarTimave(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTimave
+
+	subroutine vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: timaccu_dummy
+		interface
+			subroutine lib_vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy) bind(c, name = 'vlistDefVarTimaccu')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: timaccu_dummy
+			end subroutine lib_vlistDefVarTimaccu
+		end interface
+		call lib_vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy)
+	end subroutine vlistDefVarTimaccu
+
+	function vlistInqVarTimaccu(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTimaccu(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTimaccu')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTimaccu
+		end interface
+		result = lib_vlistInqVarTimaccu(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTimaccu
+
+	subroutine vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: typeOfGeneratingProcess_dummy
+		interface
+			subroutine lib_vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy) bind(c, name = 'vli&
+			&stDefVarTypeOfGeneratingProcess')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: typeOfGeneratingProcess_dummy
+			end subroutine lib_vlistDefVarTypeOfGeneratingProcess
+		end interface
+		call lib_vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy)
+	end subroutine vlistDefVarTypeOfGeneratingProcess
+
+	function vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTypeOfGene&
+			&ratingProcess')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTypeOfGeneratingProcess
+		end interface
+		result = lib_vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTypeOfGeneratingProcess
+
+	subroutine vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: productDefinitionTemplate_dummy
+		interface
+			subroutine lib_vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy) bind(c, name = &
+			&'vlistDefVarProductDefinitionTemplate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: productDefinitionTemplate_dummy
+			end subroutine lib_vlistDefVarProductDefinitionTemplate
+		end interface
+		call lib_vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy)
+	end subroutine vlistDefVarProductDefinitionTemplate
+
+	function vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarProductD&
+			&efinitionTemplate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarProductDefinitionTemplate
+		end interface
+		result = lib_vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy)
+	end function vlistInqVarProductDefinitionTemplate
+
+	function vlistInqVarSize(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarSize(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarSize')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarSize
+		end interface
+		result = lib_vlistInqVarSize(vlistID_dummy, varID_dummy)
+	end function vlistInqVarSize
+
+	subroutine vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			subroutine lib_vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy) bind(c, name = 'vlistDefIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+				integer(c_int), value :: index_dummy
+			end subroutine lib_vlistDefIndex
+		end interface
+		call lib_vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy)
+	end subroutine vlistDefIndex
+
+	function vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		interface
+			integer(c_int) function lib_vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy) bind(c, name = 'vlistInqIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+			end function lib_vlistInqIndex
+		end interface
+		result = lib_vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy)
+	end function vlistInqIndex
+
+	subroutine vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		integer(c_int), value :: flag_dummy
+		interface
+			subroutine lib_vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy) bind(c, name = 'vlistDefFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+				integer(c_int), value :: flag_dummy
+			end subroutine lib_vlistDefFlag
+		end interface
+		call lib_vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy)
+	end subroutine vlistDefFlag
+
+	function vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		interface
+			integer(c_int) function lib_vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy) bind(c, name = 'vlistInqFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+			end function lib_vlistInqFlag
+		end interface
+		result = lib_vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy)
+	end function vlistInqFlag
+
+	function vlistFindVar(vlistID_dummy, fvarID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: fvarID_dummy
+		interface
+			integer(c_int) function lib_vlistFindVar(vlistID_dummy, fvarID_dummy) bind(c, name = 'vlistFindVar')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: fvarID_dummy
+			end function lib_vlistFindVar
+		end interface
+		result = lib_vlistFindVar(vlistID_dummy, fvarID_dummy)
+	end function vlistFindVar
+
+	function vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: fvarID_dummy
+		integer(c_int), value :: flevelID_dummy
+		interface
+			integer(c_int) function lib_vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy) bind(c, name = 'vlistFindLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: fvarID_dummy
+				integer(c_int), value :: flevelID_dummy
+			end function lib_vlistFindLevel
+		end interface
+		result = lib_vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy)
+	end function vlistFindLevel
+
+	function vlistMergedVar(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistMergedVar(vlistID_dummy, varID_dummy) bind(c, name = 'vlistMergedVar')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistMergedVar
+		end interface
+		result = lib_vlistMergedVar(vlistID_dummy, varID_dummy)
+	end function vlistMergedVar
+
+	function vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			integer(c_int) function lib_vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy) bind(c, name = 'vlistMergedLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+			end function lib_vlistMergedLevel
+		end interface
+		result = lib_vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy)
+	end function vlistMergedLevel
+
+	subroutine vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: ensID_dummy
+		integer(c_int), value :: ensCount_dummy
+		integer(c_int), value :: forecast_type_dummy
+		interface
+			subroutine lib_vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy) bind(c, name = &
+			&'vlistDefVarEnsemble')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: ensID_dummy
+				integer(c_int), value :: ensCount_dummy
+				integer(c_int), value :: forecast_type_dummy
+			end subroutine lib_vlistDefVarEnsemble
+		end interface
+		call lib_vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy)
+	end subroutine vlistDefVarEnsemble
+
+	function vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID, ensCount, forecast_type) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: ensID
+		integer(c_int), optional, intent(inout) :: ensCount
+		integer(c_int), optional, intent(inout) :: forecast_type
+		integer(c_int), target :: ensID_temp
+		type(c_ptr) :: ensID_ptr
+		integer(c_int), target :: ensCount_temp
+		type(c_ptr) :: ensCount_ptr
+		integer(c_int), target :: forecast_type_temp
+		type(c_ptr) :: forecast_type_ptr
+		interface
+			integer(c_int) function lib_vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID, ensCount, forecast_type) bind(c, name = 'vlis&
+			&tInqVarEnsemble')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: ensID
+				type(c_ptr), value :: ensCount
+				type(c_ptr), value :: forecast_type
+			end function lib_vlistInqVarEnsemble
+		end interface
+		ensID_ptr = c_null_ptr
+		if(present(ensID)) ensID_ptr = c_loc(ensID_temp)
+		ensCount_ptr = c_null_ptr
+		if(present(ensCount)) ensCount_ptr = c_loc(ensCount_temp)
+		forecast_type_ptr = c_null_ptr
+		if(present(forecast_type)) forecast_type_ptr = c_loc(forecast_type_temp)
+		result = lib_vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID_ptr, ensCount_ptr, forecast_type_ptr)
+		if(present(ensID)) ensID = ensID_temp
+		if(present(ensCount)) ensCount = ensCount_temp
+		if(present(forecast_type)) forecast_type = forecast_type_temp
+	end function vlistInqVarEnsemble
+
+	subroutine cdiClearAdditionalKeys()
+		interface
+			subroutine lib_cdiClearAdditionalKeys() bind(c, name = 'cdiClearAdditionalKeys')
+			end subroutine lib_cdiClearAdditionalKeys
+		end interface
+		call lib_cdiClearAdditionalKeys()
+	end subroutine cdiClearAdditionalKeys
+
+	subroutine cdiDefAdditionalKey(string_dummy)
+		character(kind = c_char, len = *), intent(in) :: string_dummy
+		character(kind = c_char) :: string_temp(len(string_dummy) + 1)
+		integer :: string_i
+		interface
+			subroutine lib_cdiDefAdditionalKey(string_dummy) bind(c, name = 'cdiDefAdditionalKey')
+				import c_char
+				character(kind = c_char) :: string_dummy(*)
+			end subroutine lib_cdiDefAdditionalKey
+		end interface
+		do string_i = 1, len(string_dummy)
+		string_temp(string_i) = string_dummy(string_i:string_i)
+		end do
+		string_temp(len(string_dummy) + 1) = c_null_char
+		call lib_cdiDefAdditionalKey(string_temp)
+	end subroutine cdiDefAdditionalKey
+
+	subroutine vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: value_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy) bind(c, name = 'vlistDefVarIntKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: value_dummy
+			end subroutine lib_vlistDefVarIntKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_temp, value_dummy)
+	end subroutine vlistDefVarIntKey
+
+	subroutine vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		real(c_double), value :: value_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy) bind(c, name = 'vlistDefVarDblKey')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				real(c_double), value :: value_dummy
+			end subroutine lib_vlistDefVarDblKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_temp, value_dummy)
+	end subroutine vlistDefVarDblKey
+
+	function vlistHasVarKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistHasVarKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistHasVarKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistHasVarKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistHasVarKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistHasVarKey
+
+	function vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			real(c_double) function lib_vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarDblKey')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistInqVarDblKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistInqVarDblKey
+
+	function vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarIntKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistInqVarIntKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistInqVarIntKey
+
+	function vlistInqNatts(vlistID_dummy, varID_dummy, nattsp) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: nattsp
+		integer(c_int), target :: nattsp_temp
+		type(c_ptr) :: nattsp_ptr
+		interface
+			integer(c_int) function lib_vlistInqNatts(vlistID_dummy, varID_dummy, nattsp) bind(c, name = 'vlistInqNatts')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: nattsp
+			end function lib_vlistInqNatts
+		end interface
+		nattsp_ptr = c_null_ptr
+		if(present(nattsp)) nattsp_ptr = c_loc(nattsp_temp)
+		result = lib_vlistInqNatts(vlistID_dummy, varID_dummy, nattsp_ptr)
+		if(present(nattsp)) nattsp = nattsp_temp
+	end function vlistInqNatts
+
+	function vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_dummy, typep, lenp) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: attrnum_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		integer(c_int), optional, intent(inout) :: typep
+		integer(c_int), optional, intent(inout) :: lenp
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		integer(c_int), target :: typep_temp
+		type(c_ptr) :: typep_ptr
+		integer(c_int), target :: lenp_temp
+		type(c_ptr) :: lenp_ptr
+		interface
+			integer(c_int) function lib_vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_dummy, typep, lenp) bind(c, name = 'vlis&
+			&tInqAtt')
+				import c_char, c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: attrnum_dummy
+				character(kind = c_char) :: name_dummy(*)
+				type(c_ptr), value :: typep
+				type(c_ptr), value :: lenp
+			end function lib_vlistInqAtt
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		typep_ptr = c_null_ptr
+		if(present(typep)) typep_ptr = c_loc(typep_temp)
+		lenp_ptr = c_null_ptr
+		if(present(lenp)) lenp_ptr = c_loc(lenp_temp)
+		result = lib_vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_temp, typep_ptr, lenp_ptr)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		if(present(typep)) typep = typep_temp
+		if(present(lenp)) lenp = lenp_temp
+	end function vlistInqAtt
+
+	function vlistDelAtt(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDelAtt(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistDelAtt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistDelAtt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDelAtt(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistDelAtt
+
+	function vlistDefAttInt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, ip_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: type_dummy
+		integer(c_int), value :: len_dummy
+		integer(c_int), intent(in) :: ip_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDefAttInt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, ip_vec_dummy) bind(c, &
+			&name = 'vlistDefAttInt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: type_dummy
+				integer(c_int), value :: len_dummy
+				integer(c_int), intent(in) :: ip_vec_dummy(*)
+			end function lib_vlistDefAttInt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttInt(vlistID_dummy, varID_dummy, name_temp, type_dummy, len_dummy, ip_vec_dummy)
+	end function vlistDefAttInt
+
+	function vlistDefAttFlt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, dp_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: type_dummy
+		integer(c_int), value :: len_dummy
+		real(c_double), intent(in) :: dp_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDefAttFlt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, dp_vec_dummy) bind(c, &
+			&name = 'vlistDefAttFlt')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: type_dummy
+				integer(c_int), value :: len_dummy
+				real(c_double), intent(in) :: dp_vec_dummy(*)
+			end function lib_vlistDefAttFlt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttFlt(vlistID_dummy, varID_dummy, name_temp, type_dummy, len_dummy, dp_vec_dummy)
+	end function vlistDefAttFlt
+
+	function vlistDefAttTxt(vlistID_dummy, varID_dummy, name_dummy, len_dummy, tp_cbuf_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: len_dummy
+		character(kind = c_char, len = *), intent(in) :: tp_cbuf_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: tp_cbuf_temp(len(tp_cbuf_dummy) + 1)
+		integer :: tp_cbuf_i
+		interface
+			integer(c_int) function lib_vlistDefAttTxt(vlistID_dummy, varID_dummy, name_dummy, len_dummy, tp_cbuf_dummy) bind(c, name = 'vli&
+			&stDefAttTxt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: len_dummy
+				character(kind = c_char) :: tp_cbuf_dummy(*)
+			end function lib_vlistDefAttTxt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do tp_cbuf_i = 1, len(tp_cbuf_dummy)
+		tp_cbuf_temp(tp_cbuf_i) = tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i)
+		end do
+		tp_cbuf_temp(len(tp_cbuf_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttTxt(vlistID_dummy, varID_dummy, name_temp, len_dummy, tp_cbuf_temp)
+	end function vlistDefAttTxt
+
+	function vlistInqAttInt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, ip_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		integer(c_int), intent(inout) :: ip_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqAttInt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, ip_vec_dummy) bind(c, name = 'vli&
+			&stInqAttInt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				integer(c_int), intent(inout) :: ip_vec_dummy(*)
+			end function lib_vlistInqAttInt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqAttInt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, ip_vec_dummy)
+	end function vlistInqAttInt
+
+	function vlistInqAttFlt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, dp_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		real(c_double), intent(inout) :: dp_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqAttFlt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, dp_vec_dummy) bind(c, name = 'vli&
+			&stInqAttFlt')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				real(c_double), intent(inout) :: dp_vec_dummy(*)
+			end function lib_vlistInqAttFlt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqAttFlt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, dp_vec_dummy)
+	end function vlistInqAttFlt
+
+	function vlistInqAttTxt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, tp_cbuf_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		character(kind = c_char, len = *), intent(inout) :: tp_cbuf_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: tp_cbuf_temp(len(tp_cbuf_dummy))
+		integer :: tp_cbuf_i
+		logical :: tp_cbuf_padding = .true.
+		interface
+			integer(c_int) function lib_vlistInqAttTxt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, tp_cbuf_dummy) bind(c, name = 'vl&
+			&istInqAttTxt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				character(kind = c_char) :: tp_cbuf_dummy(*)
+			end function lib_vlistInqAttTxt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do tp_cbuf_i = len(tp_cbuf_dummy), 1, -1
+			if(tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) /= ' ') tp_cbuf_padding = .false.
+			if(tp_cbuf_padding) then
+				tp_cbuf_temp(tp_cbuf_i) = c_null_char
+			else
+				tp_cbuf_temp(tp_cbuf_i) = tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i)
+			end if
+		end do
+		result = lib_vlistInqAttTxt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, tp_cbuf_temp)
+		tp_cbuf_padding = .false.
+		do tp_cbuf_i = 1, len(tp_cbuf_dummy)
+			if(tp_cbuf_temp(tp_cbuf_i) == c_null_char) tp_cbuf_padding = .true.
+			if(tp_cbuf_padding) then
+				tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) = ' '
+			else
+				tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) = tp_cbuf_temp(tp_cbuf_i)
+			end if
+		end do
+	end function vlistInqAttTxt
+
+	subroutine gridName(gridtype_dummy, gridname_dummy)
+		integer(c_int), value :: gridtype_dummy
+		character(kind = c_char, len = *), intent(inout) :: gridname_dummy
+		character(kind = c_char) :: gridname_temp(len(gridname_dummy))
+		integer :: gridname_i
+		logical :: gridname_padding = .true.
+		interface
+			subroutine lib_gridName(gridtype_dummy, gridname_dummy) bind(c, name = 'gridName')
+				import c_char, c_int
+				integer(c_int), value :: gridtype_dummy
+				character(kind = c_char) :: gridname_dummy(*)
+			end subroutine lib_gridName
+		end interface
+		do gridname_i = len(gridname_dummy), 1, -1
+			if(gridname_dummy(gridname_i:gridname_i) /= ' ') gridname_padding = .false.
+			if(gridname_padding) then
+				gridname_temp(gridname_i) = c_null_char
+			else
+				gridname_temp(gridname_i) = gridname_dummy(gridname_i:gridname_i)
+			end if
+		end do
+		call lib_gridName(gridtype_dummy, gridname_temp)
+		gridname_padding = .false.
+		do gridname_i = 1, len(gridname_dummy)
+			if(gridname_temp(gridname_i) == c_null_char) gridname_padding = .true.
+			if(gridname_padding) then
+				gridname_dummy(gridname_i:gridname_i) = ' '
+			else
+				gridname_dummy(gridname_i:gridname_i) = gridname_temp(gridname_i)
+			end if
+		end do
+	end subroutine gridName
+
+	function gridNamePtr(gridtype_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: gridtype_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_gridNamePtr(gridtype_dummy) bind(c, name = 'gridNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: gridtype_dummy
+			end function lib_gridNamePtr
+		end interface
+		result => null()
+		ptr = lib_gridNamePtr(gridtype_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function gridNamePtr
+
+	subroutine gridCompress(gridID_dummy)
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_gridCompress(gridID_dummy) bind(c, name = 'gridCompress')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_gridCompress
+		end interface
+		call lib_gridCompress(gridID_dummy)
+	end subroutine gridCompress
+
+	subroutine gridDefMaskGME(gridID_dummy, mask_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(in) :: mask_vec_dummy(*)
+		interface
+			subroutine lib_gridDefMaskGME(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridDefMaskGME')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(in) :: mask_vec_dummy(*)
+			end subroutine lib_gridDefMaskGME
+		end interface
+		call lib_gridDefMaskGME(gridID_dummy, mask_vec_dummy)
+	end subroutine gridDefMaskGME
+
+	function gridInqMaskGME(gridID_dummy, mask_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: mask_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqMaskGME(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridInqMaskGME')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: mask_vec_dummy(*)
+			end function lib_gridInqMaskGME
+		end interface
+		result = lib_gridInqMaskGME(gridID_dummy, mask_vec_dummy)
+	end function gridInqMaskGME
+
+	subroutine gridDefMask(gridID_dummy, mask_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(in) :: mask_vec_dummy(*)
+		interface
+			subroutine lib_gridDefMask(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridDefMask')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(in) :: mask_vec_dummy(*)
+			end subroutine lib_gridDefMask
+		end interface
+		call lib_gridDefMask(gridID_dummy, mask_vec_dummy)
+	end subroutine gridDefMask
+
+	function gridInqMask(gridID_dummy, mask_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: mask_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqMask(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridInqMask')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: mask_vec_dummy(*)
+			end function lib_gridInqMask
+		end interface
+		result = lib_gridInqMask(gridID_dummy, mask_vec_dummy)
+	end function gridInqMask
+
+	subroutine gridPrint(gridID_dummy, index_dummy, opt_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: opt_dummy
+		interface
+			subroutine lib_gridPrint(gridID_dummy, index_dummy, opt_dummy) bind(c, name = 'gridPrint')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: opt_dummy
+			end subroutine lib_gridPrint
+		end interface
+		call lib_gridPrint(gridID_dummy, index_dummy, opt_dummy)
+	end subroutine gridPrint
+
+	function gridCreate(gridtype_dummy, size_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridtype_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			integer(c_int) function lib_gridCreate(gridtype_dummy, size_dummy) bind(c, name = 'gridCreate')
+				import c_int
+				integer(c_int), value :: gridtype_dummy
+				integer(c_int), value :: size_dummy
+			end function lib_gridCreate
+		end interface
+		result = lib_gridCreate(gridtype_dummy, size_dummy)
+	end function gridCreate
+
+	subroutine gridDestroy(gridID_dummy)
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_gridDestroy(gridID_dummy) bind(c, name = 'gridDestroy')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_gridDestroy
+		end interface
+		call lib_gridDestroy(gridID_dummy)
+	end subroutine gridDestroy
+
+	function gridDuplicate(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridDuplicate(gridID_dummy) bind(c, name = 'gridDuplicate')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridDuplicate
+		end interface
+		result = lib_gridDuplicate(gridID_dummy)
+	end function gridDuplicate
+
+	function gridInqType(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqType(gridID_dummy) bind(c, name = 'gridInqType')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqType
+		end interface
+		result = lib_gridInqType(gridID_dummy)
+	end function gridInqType
+
+	function gridInqSize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqSize(gridID_dummy) bind(c, name = 'gridInqSize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqSize
+		end interface
+		result = lib_gridInqSize(gridID_dummy)
+	end function gridInqSize
+
+	subroutine gridDefXsize(gridID_dummy, xsize_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: xsize_dummy
+		interface
+			subroutine lib_gridDefXsize(gridID_dummy, xsize_dummy) bind(c, name = 'gridDefXsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: xsize_dummy
+			end subroutine lib_gridDefXsize
+		end interface
+		call lib_gridDefXsize(gridID_dummy, xsize_dummy)
+	end subroutine gridDefXsize
+
+	function gridInqXsize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqXsize(gridID_dummy) bind(c, name = 'gridInqXsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXsize
+		end interface
+		result = lib_gridInqXsize(gridID_dummy)
+	end function gridInqXsize
+
+	subroutine gridDefYsize(gridID_dummy, ysize_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ysize_dummy
+		interface
+			subroutine lib_gridDefYsize(gridID_dummy, ysize_dummy) bind(c, name = 'gridDefYsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ysize_dummy
+			end subroutine lib_gridDefYsize
+		end interface
+		call lib_gridDefYsize(gridID_dummy, ysize_dummy)
+	end subroutine gridDefYsize
+
+	function gridInqYsize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqYsize(gridID_dummy) bind(c, name = 'gridInqYsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYsize
+		end interface
+		result = lib_gridInqYsize(gridID_dummy)
+	end function gridInqYsize
+
+	subroutine gridDefNP(gridID_dummy, np_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: np_dummy
+		interface
+			subroutine lib_gridDefNP(gridID_dummy, np_dummy) bind(c, name = 'gridDefNP')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: np_dummy
+			end subroutine lib_gridDefNP
+		end interface
+		call lib_gridDefNP(gridID_dummy, np_dummy)
+	end subroutine gridDefNP
+
+	function gridInqNP(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNP(gridID_dummy) bind(c, name = 'gridInqNP')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNP
+		end interface
+		result = lib_gridInqNP(gridID_dummy)
+	end function gridInqNP
+
+	subroutine gridDefXvals(gridID_dummy, xvals_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: xvals_vec_dummy(*)
+		interface
+			subroutine lib_gridDefXvals(gridID_dummy, xvals_vec_dummy) bind(c, name = 'gridDefXvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: xvals_vec_dummy(*)
+			end subroutine lib_gridDefXvals
+		end interface
+		call lib_gridDefXvals(gridID_dummy, xvals_vec_dummy)
+	end subroutine gridDefXvals
+
+	function gridInqXvals(gridID_dummy, xvals_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: xvals_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqXvals(gridID_dummy, xvals_vec_dummy) bind(c, name = 'gridInqXvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: xvals_vec_dummy(*)
+			end function lib_gridInqXvals
+		end interface
+		result = lib_gridInqXvals(gridID_dummy, xvals_vec_dummy)
+	end function gridInqXvals
+
+	subroutine gridDefYvals(gridID_dummy, yvals_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: yvals_vec_dummy(*)
+		interface
+			subroutine lib_gridDefYvals(gridID_dummy, yvals_vec_dummy) bind(c, name = 'gridDefYvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: yvals_vec_dummy(*)
+			end subroutine lib_gridDefYvals
+		end interface
+		call lib_gridDefYvals(gridID_dummy, yvals_vec_dummy)
+	end subroutine gridDefYvals
+
+	function gridInqYvals(gridID_dummy, yvals_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: yvals_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqYvals(gridID_dummy, yvals_vec_dummy) bind(c, name = 'gridInqYvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: yvals_vec_dummy(*)
+			end function lib_gridInqYvals
+		end interface
+		result = lib_gridInqYvals(gridID_dummy, yvals_vec_dummy)
+	end function gridInqYvals
+
+	subroutine gridDefXname(gridID_dummy, xname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xname_dummy
+		character(kind = c_char) :: xname_temp(len(xname_dummy) + 1)
+		integer :: xname_i
+		interface
+			subroutine lib_gridDefXname(gridID_dummy, xname_dummy) bind(c, name = 'gridDefXname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xname_dummy(*)
+			end subroutine lib_gridDefXname
+		end interface
+		do xname_i = 1, len(xname_dummy)
+		xname_temp(xname_i) = xname_dummy(xname_i:xname_i)
+		end do
+		xname_temp(len(xname_dummy) + 1) = c_null_char
+		call lib_gridDefXname(gridID_dummy, xname_temp)
+	end subroutine gridDefXname
+
+	subroutine gridInqXname(gridID_dummy, xname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xname_dummy
+		character(kind = c_char) :: xname_temp(len(xname_dummy))
+		integer :: xname_i
+		logical :: xname_padding = .true.
+		interface
+			subroutine lib_gridInqXname(gridID_dummy, xname_dummy) bind(c, name = 'gridInqXname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xname_dummy(*)
+			end subroutine lib_gridInqXname
+		end interface
+		do xname_i = len(xname_dummy), 1, -1
+			if(xname_dummy(xname_i:xname_i) /= ' ') xname_padding = .false.
+			if(xname_padding) then
+				xname_temp(xname_i) = c_null_char
+			else
+				xname_temp(xname_i) = xname_dummy(xname_i:xname_i)
+			end if
+		end do
+		call lib_gridInqXname(gridID_dummy, xname_temp)
+		xname_padding = .false.
+		do xname_i = 1, len(xname_dummy)
+			if(xname_temp(xname_i) == c_null_char) xname_padding = .true.
+			if(xname_padding) then
+				xname_dummy(xname_i:xname_i) = ' '
+			else
+				xname_dummy(xname_i:xname_i) = xname_temp(xname_i)
+			end if
+		end do
+	end subroutine gridInqXname
+
+	subroutine gridDefXlongname(gridID_dummy, xlongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xlongname_dummy
+		character(kind = c_char) :: xlongname_temp(len(xlongname_dummy) + 1)
+		integer :: xlongname_i
+		interface
+			subroutine lib_gridDefXlongname(gridID_dummy, xlongname_dummy) bind(c, name = 'gridDefXlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xlongname_dummy(*)
+			end subroutine lib_gridDefXlongname
+		end interface
+		do xlongname_i = 1, len(xlongname_dummy)
+		xlongname_temp(xlongname_i) = xlongname_dummy(xlongname_i:xlongname_i)
+		end do
+		xlongname_temp(len(xlongname_dummy) + 1) = c_null_char
+		call lib_gridDefXlongname(gridID_dummy, xlongname_temp)
+	end subroutine gridDefXlongname
+
+	subroutine gridInqXlongname(gridID_dummy, xlongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xlongname_dummy
+		character(kind = c_char) :: xlongname_temp(len(xlongname_dummy))
+		integer :: xlongname_i
+		logical :: xlongname_padding = .true.
+		interface
+			subroutine lib_gridInqXlongname(gridID_dummy, xlongname_dummy) bind(c, name = 'gridInqXlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xlongname_dummy(*)
+			end subroutine lib_gridInqXlongname
+		end interface
+		do xlongname_i = len(xlongname_dummy), 1, -1
+			if(xlongname_dummy(xlongname_i:xlongname_i) /= ' ') xlongname_padding = .false.
+			if(xlongname_padding) then
+				xlongname_temp(xlongname_i) = c_null_char
+			else
+				xlongname_temp(xlongname_i) = xlongname_dummy(xlongname_i:xlongname_i)
+			end if
+		end do
+		call lib_gridInqXlongname(gridID_dummy, xlongname_temp)
+		xlongname_padding = .false.
+		do xlongname_i = 1, len(xlongname_dummy)
+			if(xlongname_temp(xlongname_i) == c_null_char) xlongname_padding = .true.
+			if(xlongname_padding) then
+				xlongname_dummy(xlongname_i:xlongname_i) = ' '
+			else
+				xlongname_dummy(xlongname_i:xlongname_i) = xlongname_temp(xlongname_i)
+			end if
+		end do
+	end subroutine gridInqXlongname
+
+	subroutine gridDefXunits(gridID_dummy, xunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xunits_dummy
+		character(kind = c_char) :: xunits_temp(len(xunits_dummy) + 1)
+		integer :: xunits_i
+		interface
+			subroutine lib_gridDefXunits(gridID_dummy, xunits_dummy) bind(c, name = 'gridDefXunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xunits_dummy(*)
+			end subroutine lib_gridDefXunits
+		end interface
+		do xunits_i = 1, len(xunits_dummy)
+		xunits_temp(xunits_i) = xunits_dummy(xunits_i:xunits_i)
+		end do
+		xunits_temp(len(xunits_dummy) + 1) = c_null_char
+		call lib_gridDefXunits(gridID_dummy, xunits_temp)
+	end subroutine gridDefXunits
+
+	subroutine gridInqXunits(gridID_dummy, xunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xunits_dummy
+		character(kind = c_char) :: xunits_temp(len(xunits_dummy))
+		integer :: xunits_i
+		logical :: xunits_padding = .true.
+		interface
+			subroutine lib_gridInqXunits(gridID_dummy, xunits_dummy) bind(c, name = 'gridInqXunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xunits_dummy(*)
+			end subroutine lib_gridInqXunits
+		end interface
+		do xunits_i = len(xunits_dummy), 1, -1
+			if(xunits_dummy(xunits_i:xunits_i) /= ' ') xunits_padding = .false.
+			if(xunits_padding) then
+				xunits_temp(xunits_i) = c_null_char
+			else
+				xunits_temp(xunits_i) = xunits_dummy(xunits_i:xunits_i)
+			end if
+		end do
+		call lib_gridInqXunits(gridID_dummy, xunits_temp)
+		xunits_padding = .false.
+		do xunits_i = 1, len(xunits_dummy)
+			if(xunits_temp(xunits_i) == c_null_char) xunits_padding = .true.
+			if(xunits_padding) then
+				xunits_dummy(xunits_i:xunits_i) = ' '
+			else
+				xunits_dummy(xunits_i:xunits_i) = xunits_temp(xunits_i)
+			end if
+		end do
+	end subroutine gridInqXunits
+
+	subroutine gridDefYname(gridID_dummy, yname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: yname_dummy
+		character(kind = c_char) :: yname_temp(len(yname_dummy) + 1)
+		integer :: yname_i
+		interface
+			subroutine lib_gridDefYname(gridID_dummy, yname_dummy) bind(c, name = 'gridDefYname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yname_dummy(*)
+			end subroutine lib_gridDefYname
+		end interface
+		do yname_i = 1, len(yname_dummy)
+		yname_temp(yname_i) = yname_dummy(yname_i:yname_i)
+		end do
+		yname_temp(len(yname_dummy) + 1) = c_null_char
+		call lib_gridDefYname(gridID_dummy, yname_temp)
+	end subroutine gridDefYname
+
+	subroutine gridInqYname(gridID_dummy, yname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: yname_dummy
+		character(kind = c_char) :: yname_temp(len(yname_dummy))
+		integer :: yname_i
+		logical :: yname_padding = .true.
+		interface
+			subroutine lib_gridInqYname(gridID_dummy, yname_dummy) bind(c, name = 'gridInqYname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yname_dummy(*)
+			end subroutine lib_gridInqYname
+		end interface
+		do yname_i = len(yname_dummy), 1, -1
+			if(yname_dummy(yname_i:yname_i) /= ' ') yname_padding = .false.
+			if(yname_padding) then
+				yname_temp(yname_i) = c_null_char
+			else
+				yname_temp(yname_i) = yname_dummy(yname_i:yname_i)
+			end if
+		end do
+		call lib_gridInqYname(gridID_dummy, yname_temp)
+		yname_padding = .false.
+		do yname_i = 1, len(yname_dummy)
+			if(yname_temp(yname_i) == c_null_char) yname_padding = .true.
+			if(yname_padding) then
+				yname_dummy(yname_i:yname_i) = ' '
+			else
+				yname_dummy(yname_i:yname_i) = yname_temp(yname_i)
+			end if
+		end do
+	end subroutine gridInqYname
+
+	subroutine gridDefYlongname(gridID_dummy, ylongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: ylongname_dummy
+		character(kind = c_char) :: ylongname_temp(len(ylongname_dummy) + 1)
+		integer :: ylongname_i
+		interface
+			subroutine lib_gridDefYlongname(gridID_dummy, ylongname_dummy) bind(c, name = 'gridDefYlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ylongname_dummy(*)
+			end subroutine lib_gridDefYlongname
+		end interface
+		do ylongname_i = 1, len(ylongname_dummy)
+		ylongname_temp(ylongname_i) = ylongname_dummy(ylongname_i:ylongname_i)
+		end do
+		ylongname_temp(len(ylongname_dummy) + 1) = c_null_char
+		call lib_gridDefYlongname(gridID_dummy, ylongname_temp)
+	end subroutine gridDefYlongname
+
+	subroutine gridInqYlongname(gridID_dummy, ylongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: ylongname_dummy
+		character(kind = c_char) :: ylongname_temp(len(ylongname_dummy))
+		integer :: ylongname_i
+		logical :: ylongname_padding = .true.
+		interface
+			subroutine lib_gridInqYlongname(gridID_dummy, ylongname_dummy) bind(c, name = 'gridInqYlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ylongname_dummy(*)
+			end subroutine lib_gridInqYlongname
+		end interface
+		do ylongname_i = len(ylongname_dummy), 1, -1
+			if(ylongname_dummy(ylongname_i:ylongname_i) /= ' ') ylongname_padding = .false.
+			if(ylongname_padding) then
+				ylongname_temp(ylongname_i) = c_null_char
+			else
+				ylongname_temp(ylongname_i) = ylongname_dummy(ylongname_i:ylongname_i)
+			end if
+		end do
+		call lib_gridInqYlongname(gridID_dummy, ylongname_temp)
+		ylongname_padding = .false.
+		do ylongname_i = 1, len(ylongname_dummy)
+			if(ylongname_temp(ylongname_i) == c_null_char) ylongname_padding = .true.
+			if(ylongname_padding) then
+				ylongname_dummy(ylongname_i:ylongname_i) = ' '
+			else
+				ylongname_dummy(ylongname_i:ylongname_i) = ylongname_temp(ylongname_i)
+			end if
+		end do
+	end subroutine gridInqYlongname
+
+	subroutine gridDefYunits(gridID_dummy, yunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: yunits_dummy
+		character(kind = c_char) :: yunits_temp(len(yunits_dummy) + 1)
+		integer :: yunits_i
+		interface
+			subroutine lib_gridDefYunits(gridID_dummy, yunits_dummy) bind(c, name = 'gridDefYunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yunits_dummy(*)
+			end subroutine lib_gridDefYunits
+		end interface
+		do yunits_i = 1, len(yunits_dummy)
+		yunits_temp(yunits_i) = yunits_dummy(yunits_i:yunits_i)
+		end do
+		yunits_temp(len(yunits_dummy) + 1) = c_null_char
+		call lib_gridDefYunits(gridID_dummy, yunits_temp)
+	end subroutine gridDefYunits
+
+	subroutine gridInqYunits(gridID_dummy, yunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: yunits_dummy
+		character(kind = c_char) :: yunits_temp(len(yunits_dummy))
+		integer :: yunits_i
+		logical :: yunits_padding = .true.
+		interface
+			subroutine lib_gridInqYunits(gridID_dummy, yunits_dummy) bind(c, name = 'gridInqYunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yunits_dummy(*)
+			end subroutine lib_gridInqYunits
+		end interface
+		do yunits_i = len(yunits_dummy), 1, -1
+			if(yunits_dummy(yunits_i:yunits_i) /= ' ') yunits_padding = .false.
+			if(yunits_padding) then
+				yunits_temp(yunits_i) = c_null_char
+			else
+				yunits_temp(yunits_i) = yunits_dummy(yunits_i:yunits_i)
+			end if
+		end do
+		call lib_gridInqYunits(gridID_dummy, yunits_temp)
+		yunits_padding = .false.
+		do yunits_i = 1, len(yunits_dummy)
+			if(yunits_temp(yunits_i) == c_null_char) yunits_padding = .true.
+			if(yunits_padding) then
+				yunits_dummy(yunits_i:yunits_i) = ' '
+			else
+				yunits_dummy(yunits_i:yunits_i) = yunits_temp(yunits_i)
+			end if
+		end do
+	end subroutine gridInqYunits
+
+	subroutine gridInqXstdname(gridID_dummy, xstdname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xstdname_dummy
+		character(kind = c_char) :: xstdname_temp(len(xstdname_dummy))
+		integer :: xstdname_i
+		logical :: xstdname_padding = .true.
+		interface
+			subroutine lib_gridInqXstdname(gridID_dummy, xstdname_dummy) bind(c, name = 'gridInqXstdname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xstdname_dummy(*)
+			end subroutine lib_gridInqXstdname
+		end interface
+		do xstdname_i = len(xstdname_dummy), 1, -1
+			if(xstdname_dummy(xstdname_i:xstdname_i) /= ' ') xstdname_padding = .false.
+			if(xstdname_padding) then
+				xstdname_temp(xstdname_i) = c_null_char
+			else
+				xstdname_temp(xstdname_i) = xstdname_dummy(xstdname_i:xstdname_i)
+			end if
+		end do
+		call lib_gridInqXstdname(gridID_dummy, xstdname_temp)
+		xstdname_padding = .false.
+		do xstdname_i = 1, len(xstdname_dummy)
+			if(xstdname_temp(xstdname_i) == c_null_char) xstdname_padding = .true.
+			if(xstdname_padding) then
+				xstdname_dummy(xstdname_i:xstdname_i) = ' '
+			else
+				xstdname_dummy(xstdname_i:xstdname_i) = xstdname_temp(xstdname_i)
+			end if
+		end do
+	end subroutine gridInqXstdname
+
+	subroutine gridInqYstdname(gridID_dummy, ystdname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: ystdname_dummy
+		character(kind = c_char) :: ystdname_temp(len(ystdname_dummy))
+		integer :: ystdname_i
+		logical :: ystdname_padding = .true.
+		interface
+			subroutine lib_gridInqYstdname(gridID_dummy, ystdname_dummy) bind(c, name = 'gridInqYstdname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ystdname_dummy(*)
+			end subroutine lib_gridInqYstdname
+		end interface
+		do ystdname_i = len(ystdname_dummy), 1, -1
+			if(ystdname_dummy(ystdname_i:ystdname_i) /= ' ') ystdname_padding = .false.
+			if(ystdname_padding) then
+				ystdname_temp(ystdname_i) = c_null_char
+			else
+				ystdname_temp(ystdname_i) = ystdname_dummy(ystdname_i:ystdname_i)
+			end if
+		end do
+		call lib_gridInqYstdname(gridID_dummy, ystdname_temp)
+		ystdname_padding = .false.
+		do ystdname_i = 1, len(ystdname_dummy)
+			if(ystdname_temp(ystdname_i) == c_null_char) ystdname_padding = .true.
+			if(ystdname_padding) then
+				ystdname_dummy(ystdname_i:ystdname_i) = ' '
+			else
+				ystdname_dummy(ystdname_i:ystdname_i) = ystdname_temp(ystdname_i)
+			end if
+		end do
+	end subroutine gridInqYstdname
+
+	subroutine gridDefPrec(gridID_dummy, prec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: prec_dummy
+		interface
+			subroutine lib_gridDefPrec(gridID_dummy, prec_dummy) bind(c, name = 'gridDefPrec')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: prec_dummy
+			end subroutine lib_gridDefPrec
+		end interface
+		call lib_gridDefPrec(gridID_dummy, prec_dummy)
+	end subroutine gridDefPrec
+
+	function gridInqPrec(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqPrec(gridID_dummy) bind(c, name = 'gridInqPrec')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqPrec
+		end interface
+		result = lib_gridInqPrec(gridID_dummy)
+	end function gridInqPrec
+
+	function gridInqXval(gridID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_gridInqXval(gridID_dummy, index_dummy) bind(c, name = 'gridInqXval')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_gridInqXval
+		end interface
+		result = lib_gridInqXval(gridID_dummy, index_dummy)
+	end function gridInqXval
+
+	function gridInqYval(gridID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_gridInqYval(gridID_dummy, index_dummy) bind(c, name = 'gridInqYval')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_gridInqYval
+		end interface
+		result = lib_gridInqYval(gridID_dummy, index_dummy)
+	end function gridInqYval
+
+	function gridInqXinc(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqXinc(gridID_dummy) bind(c, name = 'gridInqXinc')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXinc
+		end interface
+		result = lib_gridInqXinc(gridID_dummy)
+	end function gridInqXinc
+
+	function gridInqYinc(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqYinc(gridID_dummy) bind(c, name = 'gridInqYinc')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYinc
+		end interface
+		result = lib_gridInqYinc(gridID_dummy)
+	end function gridInqYinc
+
+	function gridIsCircular(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridIsCircular(gridID_dummy) bind(c, name = 'gridIsCircular')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridIsCircular
+		end interface
+		result = lib_gridIsCircular(gridID_dummy)
+	end function gridIsCircular
+
+	function gridIsRotated(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridIsRotated(gridID_dummy) bind(c, name = 'gridIsRotated')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridIsRotated
+		end interface
+		result = lib_gridIsRotated(gridID_dummy)
+	end function gridIsRotated
+
+	subroutine gridDefXpole(gridID_dummy, xpole_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: xpole_dummy
+		interface
+			subroutine lib_gridDefXpole(gridID_dummy, xpole_dummy) bind(c, name = 'gridDefXpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: xpole_dummy
+			end subroutine lib_gridDefXpole
+		end interface
+		call lib_gridDefXpole(gridID_dummy, xpole_dummy)
+	end subroutine gridDefXpole
+
+	function gridInqXpole(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqXpole(gridID_dummy) bind(c, name = 'gridInqXpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXpole
+		end interface
+		result = lib_gridInqXpole(gridID_dummy)
+	end function gridInqXpole
+
+	subroutine gridDefYpole(gridID_dummy, ypole_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: ypole_dummy
+		interface
+			subroutine lib_gridDefYpole(gridID_dummy, ypole_dummy) bind(c, name = 'gridDefYpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: ypole_dummy
+			end subroutine lib_gridDefYpole
+		end interface
+		call lib_gridDefYpole(gridID_dummy, ypole_dummy)
+	end subroutine gridDefYpole
+
+	function gridInqYpole(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqYpole(gridID_dummy) bind(c, name = 'gridInqYpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYpole
+		end interface
+		result = lib_gridInqYpole(gridID_dummy)
+	end function gridInqYpole
+
+	subroutine gridDefAngle(gridID_dummy, angle_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: angle_dummy
+		interface
+			subroutine lib_gridDefAngle(gridID_dummy, angle_dummy) bind(c, name = 'gridDefAngle')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: angle_dummy
+			end subroutine lib_gridDefAngle
+		end interface
+		call lib_gridDefAngle(gridID_dummy, angle_dummy)
+	end subroutine gridDefAngle
+
+	function gridInqAngle(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqAngle(gridID_dummy) bind(c, name = 'gridInqAngle')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqAngle
+		end interface
+		result = lib_gridInqAngle(gridID_dummy)
+	end function gridInqAngle
+
+	function gridInqTrunc(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqTrunc(gridID_dummy) bind(c, name = 'gridInqTrunc')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqTrunc
+		end interface
+		result = lib_gridInqTrunc(gridID_dummy)
+	end function gridInqTrunc
+
+	subroutine gridDefTrunc(gridID_dummy, trunc_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: trunc_dummy
+		interface
+			subroutine lib_gridDefTrunc(gridID_dummy, trunc_dummy) bind(c, name = 'gridDefTrunc')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: trunc_dummy
+			end subroutine lib_gridDefTrunc
+		end interface
+		call lib_gridDefTrunc(gridID_dummy, trunc_dummy)
+	end subroutine gridDefTrunc
+
+	subroutine gridDefGMEnd(gridID_dummy, nd_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nd_dummy
+		interface
+			subroutine lib_gridDefGMEnd(gridID_dummy, nd_dummy) bind(c, name = 'gridDefGMEnd')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nd_dummy
+			end subroutine lib_gridDefGMEnd
+		end interface
+		call lib_gridDefGMEnd(gridID_dummy, nd_dummy)
+	end subroutine gridDefGMEnd
+
+	function gridInqGMEnd(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEnd(gridID_dummy) bind(c, name = 'gridInqGMEnd')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEnd
+		end interface
+		result = lib_gridInqGMEnd(gridID_dummy)
+	end function gridInqGMEnd
+
+	subroutine gridDefGMEni(gridID_dummy, ni_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni_dummy
+		interface
+			subroutine lib_gridDefGMEni(gridID_dummy, ni_dummy) bind(c, name = 'gridDefGMEni')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni_dummy
+			end subroutine lib_gridDefGMEni
+		end interface
+		call lib_gridDefGMEni(gridID_dummy, ni_dummy)
+	end subroutine gridDefGMEni
+
+	function gridInqGMEni(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni(gridID_dummy) bind(c, name = 'gridInqGMEni')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni
+		end interface
+		result = lib_gridInqGMEni(gridID_dummy)
+	end function gridInqGMEni
+
+	subroutine gridDefGMEni2(gridID_dummy, ni2_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni2_dummy
+		interface
+			subroutine lib_gridDefGMEni2(gridID_dummy, ni2_dummy) bind(c, name = 'gridDefGMEni2')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni2_dummy
+			end subroutine lib_gridDefGMEni2
+		end interface
+		call lib_gridDefGMEni2(gridID_dummy, ni2_dummy)
+	end subroutine gridDefGMEni2
+
+	function gridInqGMEni2(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni2(gridID_dummy) bind(c, name = 'gridInqGMEni2')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni2
+		end interface
+		result = lib_gridInqGMEni2(gridID_dummy)
+	end function gridInqGMEni2
+
+	subroutine gridDefGMEni3(gridID_dummy, ni3_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni3_dummy
+		interface
+			subroutine lib_gridDefGMEni3(gridID_dummy, ni3_dummy) bind(c, name = 'gridDefGMEni3')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni3_dummy
+			end subroutine lib_gridDefGMEni3
+		end interface
+		call lib_gridDefGMEni3(gridID_dummy, ni3_dummy)
+	end subroutine gridDefGMEni3
+
+	function gridInqGMEni3(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni3(gridID_dummy) bind(c, name = 'gridInqGMEni3')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni3
+		end interface
+		result = lib_gridInqGMEni3(gridID_dummy)
+	end function gridInqGMEni3
+
+	subroutine gridDefNumber(gridID_dummy, number_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: number_dummy
+		interface
+			subroutine lib_gridDefNumber(gridID_dummy, number_dummy) bind(c, name = 'gridDefNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: number_dummy
+			end subroutine lib_gridDefNumber
+		end interface
+		call lib_gridDefNumber(gridID_dummy, number_dummy)
+	end subroutine gridDefNumber
+
+	function gridInqNumber(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNumber(gridID_dummy) bind(c, name = 'gridInqNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNumber
+		end interface
+		result = lib_gridInqNumber(gridID_dummy)
+	end function gridInqNumber
+
+	subroutine gridDefPosition(gridID_dummy, position_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: position_dummy
+		interface
+			subroutine lib_gridDefPosition(gridID_dummy, position_dummy) bind(c, name = 'gridDefPosition')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: position_dummy
+			end subroutine lib_gridDefPosition
+		end interface
+		call lib_gridDefPosition(gridID_dummy, position_dummy)
+	end subroutine gridDefPosition
+
+	function gridInqPosition(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqPosition(gridID_dummy) bind(c, name = 'gridInqPosition')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqPosition
+		end interface
+		result = lib_gridInqPosition(gridID_dummy)
+	end function gridInqPosition
+
+	subroutine gridDefReference(gridID_dummy, reference_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: reference_dummy
+		character(kind = c_char) :: reference_temp(len(reference_dummy) + 1)
+		integer :: reference_i
+		interface
+			subroutine lib_gridDefReference(gridID_dummy, reference_dummy) bind(c, name = 'gridDefReference')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: reference_dummy(*)
+			end subroutine lib_gridDefReference
+		end interface
+		do reference_i = 1, len(reference_dummy)
+		reference_temp(reference_i) = reference_dummy(reference_i:reference_i)
+		end do
+		reference_temp(len(reference_dummy) + 1) = c_null_char
+		call lib_gridDefReference(gridID_dummy, reference_temp)
+	end subroutine gridDefReference
+
+	function gridInqReference(gridID_dummy, reference_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: reference_dummy
+		character(kind = c_char) :: reference_temp(len(reference_dummy))
+		integer :: reference_i
+		logical :: reference_padding = .true.
+		interface
+			integer(c_int) function lib_gridInqReference(gridID_dummy, reference_dummy) bind(c, name = 'gridInqReference')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: reference_dummy(*)
+			end function lib_gridInqReference
+		end interface
+		do reference_i = len(reference_dummy), 1, -1
+			if(reference_dummy(reference_i:reference_i) /= ' ') reference_padding = .false.
+			if(reference_padding) then
+				reference_temp(reference_i) = c_null_char
+			else
+				reference_temp(reference_i) = reference_dummy(reference_i:reference_i)
+			end if
+		end do
+		result = lib_gridInqReference(gridID_dummy, reference_temp)
+		reference_padding = .false.
+		do reference_i = 1, len(reference_dummy)
+			if(reference_temp(reference_i) == c_null_char) reference_padding = .true.
+			if(reference_padding) then
+				reference_dummy(reference_i:reference_i) = ' '
+			else
+				reference_dummy(reference_i:reference_i) = reference_temp(reference_i)
+			end if
+		end do
+	end function gridInqReference
+
+	subroutine gridDefUUID(gridID_dummy, uuid_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char), intent(in) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_gridDefUUID(gridID_dummy, uuid_dummy) bind(c, name = 'gridDefUUID')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char), intent(in) :: uuid_dummy(*)
+			end subroutine lib_gridDefUUID
+		end interface
+		call lib_gridDefUUID(gridID_dummy, uuid_dummy)
+	end subroutine gridDefUUID
+
+	subroutine gridInqUUID(gridID_dummy, uuid_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char), intent(inout) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_gridInqUUID(gridID_dummy, uuid_dummy) bind(c, name = 'gridInqUUID')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char), intent(inout) :: uuid_dummy(*)
+			end subroutine lib_gridInqUUID
+		end interface
+		call lib_gridInqUUID(gridID_dummy, uuid_dummy)
+	end subroutine gridInqUUID
+
+	subroutine gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yinc_dumm&
+	&y, projflag_dummy, scanflag_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: originLon_dummy
+		real(c_double), value :: originLat_dummy
+		real(c_double), value :: lonParY_dummy
+		real(c_double), value :: lat1_dummy
+		real(c_double), value :: lat2_dummy
+		real(c_double), value :: xinc_dummy
+		real(c_double), value :: yinc_dummy
+		integer(c_int), value :: projflag_dummy
+		integer(c_int), value :: scanflag_dummy
+		interface
+			subroutine lib_gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yin&
+			&c_dummy, projflag_dummy, scanflag_dummy) bind(c, name = 'gridDefLCC')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: originLon_dummy
+				real(c_double), value :: originLat_dummy
+				real(c_double), value :: lonParY_dummy
+				real(c_double), value :: lat1_dummy
+				real(c_double), value :: lat2_dummy
+				real(c_double), value :: xinc_dummy
+				real(c_double), value :: yinc_dummy
+				integer(c_int), value :: projflag_dummy
+				integer(c_int), value :: scanflag_dummy
+			end subroutine lib_gridDefLCC
+		end interface
+		call lib_gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yinc_dummy&
+		&, projflag_dummy, scanflag_dummy)
+	end subroutine gridDefLCC
+
+	subroutine gridInqLCC(gridID_dummy, originLon, originLat, lonParY, lat1, lat2, xinc, yinc, projflag, scanflag)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: originLon
+		real(c_double), optional, intent(inout) :: originLat
+		real(c_double), optional, intent(inout) :: lonParY
+		real(c_double), optional, intent(inout) :: lat1
+		real(c_double), optional, intent(inout) :: lat2
+		real(c_double), optional, intent(inout) :: xinc
+		real(c_double), optional, intent(inout) :: yinc
+		integer(c_int), optional, intent(inout) :: projflag
+		integer(c_int), optional, intent(inout) :: scanflag
+		real(c_double), target :: originLon_temp
+		type(c_ptr) :: originLon_ptr
+		real(c_double), target :: originLat_temp
+		type(c_ptr) :: originLat_ptr
+		real(c_double), target :: lonParY_temp
+		type(c_ptr) :: lonParY_ptr
+		real(c_double), target :: lat1_temp
+		type(c_ptr) :: lat1_ptr
+		real(c_double), target :: lat2_temp
+		type(c_ptr) :: lat2_ptr
+		real(c_double), target :: xinc_temp
+		type(c_ptr) :: xinc_ptr
+		real(c_double), target :: yinc_temp
+		type(c_ptr) :: yinc_ptr
+		integer(c_int), target :: projflag_temp
+		type(c_ptr) :: projflag_ptr
+		integer(c_int), target :: scanflag_temp
+		type(c_ptr) :: scanflag_ptr
+		interface
+			subroutine lib_gridInqLCC(gridID_dummy, originLon, originLat, lonParY, lat1, lat2, xinc, yinc, projflag, scanflag) bind(c, name &
+			&= 'gridInqLCC')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: originLon
+				type(c_ptr), value :: originLat
+				type(c_ptr), value :: lonParY
+				type(c_ptr), value :: lat1
+				type(c_ptr), value :: lat2
+				type(c_ptr), value :: xinc
+				type(c_ptr), value :: yinc
+				type(c_ptr), value :: projflag
+				type(c_ptr), value :: scanflag
+			end subroutine lib_gridInqLCC
+		end interface
+		originLon_ptr = c_null_ptr
+		if(present(originLon)) originLon_ptr = c_loc(originLon_temp)
+		originLat_ptr = c_null_ptr
+		if(present(originLat)) originLat_ptr = c_loc(originLat_temp)
+		lonParY_ptr = c_null_ptr
+		if(present(lonParY)) lonParY_ptr = c_loc(lonParY_temp)
+		lat1_ptr = c_null_ptr
+		if(present(lat1)) lat1_ptr = c_loc(lat1_temp)
+		lat2_ptr = c_null_ptr
+		if(present(lat2)) lat2_ptr = c_loc(lat2_temp)
+		xinc_ptr = c_null_ptr
+		if(present(xinc)) xinc_ptr = c_loc(xinc_temp)
+		yinc_ptr = c_null_ptr
+		if(present(yinc)) yinc_ptr = c_loc(yinc_temp)
+		projflag_ptr = c_null_ptr
+		if(present(projflag)) projflag_ptr = c_loc(projflag_temp)
+		scanflag_ptr = c_null_ptr
+		if(present(scanflag)) scanflag_ptr = c_loc(scanflag_temp)
+		call lib_gridInqLCC(gridID_dummy, originLon_ptr, originLat_ptr, lonParY_ptr, lat1_ptr, lat2_ptr, xinc_ptr, yinc_ptr, projflag_ptr&
+		&, scanflag_ptr)
+		if(present(originLon)) originLon = originLon_temp
+		if(present(originLat)) originLat = originLat_temp
+		if(present(lonParY)) lonParY = lonParY_temp
+		if(present(lat1)) lat1 = lat1_temp
+		if(present(lat2)) lat2 = lat2_temp
+		if(present(xinc)) xinc = xinc_temp
+		if(present(yinc)) yinc = yinc_temp
+		if(present(projflag)) projflag = projflag_temp
+		if(present(scanflag)) scanflag = scanflag_temp
+	end subroutine gridInqLCC
+
+	subroutine gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: earth_radius_dummy
+		real(c_double), value :: lon_0_dummy
+		real(c_double), value :: lat_0_dummy
+		real(c_double), value :: lat_1_dummy
+		real(c_double), value :: lat_2_dummy
+		interface
+			subroutine lib_gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy) bind(c, name = &
+			&'gridDefLcc2')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: earth_radius_dummy
+				real(c_double), value :: lon_0_dummy
+				real(c_double), value :: lat_0_dummy
+				real(c_double), value :: lat_1_dummy
+				real(c_double), value :: lat_2_dummy
+			end subroutine lib_gridDefLcc2
+		end interface
+		call lib_gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy)
+	end subroutine gridDefLcc2
+
+	subroutine gridInqLcc2(gridID_dummy, earth_radius, lon_0, lat_0, lat_1, lat_2)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: earth_radius
+		real(c_double), optional, intent(inout) :: lon_0
+		real(c_double), optional, intent(inout) :: lat_0
+		real(c_double), optional, intent(inout) :: lat_1
+		real(c_double), optional, intent(inout) :: lat_2
+		real(c_double), target :: earth_radius_temp
+		type(c_ptr) :: earth_radius_ptr
+		real(c_double), target :: lon_0_temp
+		type(c_ptr) :: lon_0_ptr
+		real(c_double), target :: lat_0_temp
+		type(c_ptr) :: lat_0_ptr
+		real(c_double), target :: lat_1_temp
+		type(c_ptr) :: lat_1_ptr
+		real(c_double), target :: lat_2_temp
+		type(c_ptr) :: lat_2_ptr
+		interface
+			subroutine lib_gridInqLcc2(gridID_dummy, earth_radius, lon_0, lat_0, lat_1, lat_2) bind(c, name = 'gridInqLcc2')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: earth_radius
+				type(c_ptr), value :: lon_0
+				type(c_ptr), value :: lat_0
+				type(c_ptr), value :: lat_1
+				type(c_ptr), value :: lat_2
+			end subroutine lib_gridInqLcc2
+		end interface
+		earth_radius_ptr = c_null_ptr
+		if(present(earth_radius)) earth_radius_ptr = c_loc(earth_radius_temp)
+		lon_0_ptr = c_null_ptr
+		if(present(lon_0)) lon_0_ptr = c_loc(lon_0_temp)
+		lat_0_ptr = c_null_ptr
+		if(present(lat_0)) lat_0_ptr = c_loc(lat_0_temp)
+		lat_1_ptr = c_null_ptr
+		if(present(lat_1)) lat_1_ptr = c_loc(lat_1_temp)
+		lat_2_ptr = c_null_ptr
+		if(present(lat_2)) lat_2_ptr = c_loc(lat_2_temp)
+		call lib_gridInqLcc2(gridID_dummy, earth_radius_ptr, lon_0_ptr, lat_0_ptr, lat_1_ptr, lat_2_ptr)
+		if(present(earth_radius)) earth_radius = earth_radius_temp
+		if(present(lon_0)) lon_0 = lon_0_temp
+		if(present(lat_0)) lat_0 = lat_0_temp
+		if(present(lat_1)) lat_1 = lat_1_temp
+		if(present(lat_2)) lat_2 = lat_2_temp
+	end subroutine gridInqLcc2
+
+	subroutine gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: earth_radius_dummy
+		real(c_double), value :: lon_0_dummy
+		real(c_double), value :: lat_0_dummy
+		interface
+			subroutine lib_gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy) bind(c, name = 'gridDefLaea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: earth_radius_dummy
+				real(c_double), value :: lon_0_dummy
+				real(c_double), value :: lat_0_dummy
+			end subroutine lib_gridDefLaea
+		end interface
+		call lib_gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy)
+	end subroutine gridDefLaea
+
+	subroutine gridInqLaea(gridID_dummy, earth_radius, lon_0, lat_0)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: earth_radius
+		real(c_double), optional, intent(inout) :: lon_0
+		real(c_double), optional, intent(inout) :: lat_0
+		real(c_double), target :: earth_radius_temp
+		type(c_ptr) :: earth_radius_ptr
+		real(c_double), target :: lon_0_temp
+		type(c_ptr) :: lon_0_ptr
+		real(c_double), target :: lat_0_temp
+		type(c_ptr) :: lat_0_ptr
+		interface
+			subroutine lib_gridInqLaea(gridID_dummy, earth_radius, lon_0, lat_0) bind(c, name = 'gridInqLaea')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: earth_radius
+				type(c_ptr), value :: lon_0
+				type(c_ptr), value :: lat_0
+			end subroutine lib_gridInqLaea
+		end interface
+		earth_radius_ptr = c_null_ptr
+		if(present(earth_radius)) earth_radius_ptr = c_loc(earth_radius_temp)
+		lon_0_ptr = c_null_ptr
+		if(present(lon_0)) lon_0_ptr = c_loc(lon_0_temp)
+		lat_0_ptr = c_null_ptr
+		if(present(lat_0)) lat_0_ptr = c_loc(lat_0_temp)
+		call lib_gridInqLaea(gridID_dummy, earth_radius_ptr, lon_0_ptr, lat_0_ptr)
+		if(present(earth_radius)) earth_radius = earth_radius_temp
+		if(present(lon_0)) lon_0 = lon_0_temp
+		if(present(lat_0)) lat_0 = lat_0_temp
+	end subroutine gridInqLaea
+
+	subroutine gridDefArea(gridID_dummy, area_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: area_vec_dummy(*)
+		interface
+			subroutine lib_gridDefArea(gridID_dummy, area_vec_dummy) bind(c, name = 'gridDefArea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: area_vec_dummy(*)
+			end subroutine lib_gridDefArea
+		end interface
+		call lib_gridDefArea(gridID_dummy, area_vec_dummy)
+	end subroutine gridDefArea
+
+	subroutine gridInqArea(gridID_dummy, area_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: area_vec_dummy(*)
+		interface
+			subroutine lib_gridInqArea(gridID_dummy, area_vec_dummy) bind(c, name = 'gridInqArea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: area_vec_dummy(*)
+			end subroutine lib_gridInqArea
+		end interface
+		call lib_gridInqArea(gridID_dummy, area_vec_dummy)
+	end subroutine gridInqArea
+
+	function gridHasArea(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridHasArea(gridID_dummy) bind(c, name = 'gridHasArea')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridHasArea
+		end interface
+		result = lib_gridHasArea(gridID_dummy)
+	end function gridHasArea
+
+	subroutine gridDefNvertex(gridID_dummy, nvertex_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nvertex_dummy
+		interface
+			subroutine lib_gridDefNvertex(gridID_dummy, nvertex_dummy) bind(c, name = 'gridDefNvertex')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nvertex_dummy
+			end subroutine lib_gridDefNvertex
+		end interface
+		call lib_gridDefNvertex(gridID_dummy, nvertex_dummy)
+	end subroutine gridDefNvertex
+
+	function gridInqNvertex(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNvertex(gridID_dummy) bind(c, name = 'gridInqNvertex')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNvertex
+		end interface
+		result = lib_gridInqNvertex(gridID_dummy)
+	end function gridInqNvertex
+
+	subroutine gridDefXbounds(gridID_dummy, xbounds_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: xbounds_vec_dummy(*)
+		interface
+			subroutine lib_gridDefXbounds(gridID_dummy, xbounds_vec_dummy) bind(c, name = 'gridDefXbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: xbounds_vec_dummy(*)
+			end subroutine lib_gridDefXbounds
+		end interface
+		call lib_gridDefXbounds(gridID_dummy, xbounds_vec_dummy)
+	end subroutine gridDefXbounds
+
+	function gridInqXbounds(gridID_dummy, xbounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: xbounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqXbounds(gridID_dummy, xbounds_vec_dummy) bind(c, name = 'gridInqXbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: xbounds_vec_dummy(*)
+			end function lib_gridInqXbounds
+		end interface
+		result = lib_gridInqXbounds(gridID_dummy, xbounds_vec_dummy)
+	end function gridInqXbounds
+
+	subroutine gridDefYbounds(gridID_dummy, ybounds_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: ybounds_vec_dummy(*)
+		interface
+			subroutine lib_gridDefYbounds(gridID_dummy, ybounds_vec_dummy) bind(c, name = 'gridDefYbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: ybounds_vec_dummy(*)
+			end subroutine lib_gridDefYbounds
+		end interface
+		call lib_gridDefYbounds(gridID_dummy, ybounds_vec_dummy)
+	end subroutine gridDefYbounds
+
+	function gridInqYbounds(gridID_dummy, ybounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: ybounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqYbounds(gridID_dummy, ybounds_vec_dummy) bind(c, name = 'gridInqYbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: ybounds_vec_dummy(*)
+			end function lib_gridInqYbounds
+		end interface
+		result = lib_gridInqYbounds(gridID_dummy, ybounds_vec_dummy)
+	end function gridInqYbounds
+
+	subroutine gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nrowlon_dummy
+		integer(c_int), intent(in) :: rowlon_vec_dummy(*)
+		interface
+			subroutine lib_gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy) bind(c, name = 'gridDefRowlon')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nrowlon_dummy
+				integer(c_int), intent(in) :: rowlon_vec_dummy(*)
+			end subroutine lib_gridDefRowlon
+		end interface
+		call lib_gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy)
+	end subroutine gridDefRowlon
+
+	subroutine gridInqRowlon(gridID_dummy, rowlon_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: rowlon_vec_dummy(*)
+		interface
+			subroutine lib_gridInqRowlon(gridID_dummy, rowlon_vec_dummy) bind(c, name = 'gridInqRowlon')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: rowlon_vec_dummy(*)
+			end subroutine lib_gridInqRowlon
+		end interface
+		call lib_gridInqRowlon(gridID_dummy, rowlon_vec_dummy)
+	end subroutine gridInqRowlon
+
+	subroutine gridChangeType(gridID_dummy, gridtype_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: gridtype_dummy
+		interface
+			subroutine lib_gridChangeType(gridID_dummy, gridtype_dummy) bind(c, name = 'gridChangeType')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: gridtype_dummy
+			end subroutine lib_gridChangeType
+		end interface
+		call lib_gridChangeType(gridID_dummy, gridtype_dummy)
+	end subroutine gridChangeType
+
+	subroutine gridDefComplexPacking(gridID_dummy, lpack_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: lpack_dummy
+		interface
+			subroutine lib_gridDefComplexPacking(gridID_dummy, lpack_dummy) bind(c, name = 'gridDefComplexPacking')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: lpack_dummy
+			end subroutine lib_gridDefComplexPacking
+		end interface
+		call lib_gridDefComplexPacking(gridID_dummy, lpack_dummy)
+	end subroutine gridDefComplexPacking
+
+	function gridInqComplexPacking(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqComplexPacking(gridID_dummy) bind(c, name = 'gridInqComplexPacking')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqComplexPacking
+		end interface
+		result = lib_gridInqComplexPacking(gridID_dummy)
+	end function gridInqComplexPacking
+
+	subroutine zaxisName(zaxistype_dummy, zaxisname_dummy)
+		integer(c_int), value :: zaxistype_dummy
+		character(kind = c_char, len = *), intent(inout) :: zaxisname_dummy
+		character(kind = c_char) :: zaxisname_temp(len(zaxisname_dummy))
+		integer :: zaxisname_i
+		logical :: zaxisname_padding = .true.
+		interface
+			subroutine lib_zaxisName(zaxistype_dummy, zaxisname_dummy) bind(c, name = 'zaxisName')
+				import c_char, c_int
+				integer(c_int), value :: zaxistype_dummy
+				character(kind = c_char) :: zaxisname_dummy(*)
+			end subroutine lib_zaxisName
+		end interface
+		do zaxisname_i = len(zaxisname_dummy), 1, -1
+			if(zaxisname_dummy(zaxisname_i:zaxisname_i) /= ' ') zaxisname_padding = .false.
+			if(zaxisname_padding) then
+				zaxisname_temp(zaxisname_i) = c_null_char
+			else
+				zaxisname_temp(zaxisname_i) = zaxisname_dummy(zaxisname_i:zaxisname_i)
+			end if
+		end do
+		call lib_zaxisName(zaxistype_dummy, zaxisname_temp)
+		zaxisname_padding = .false.
+		do zaxisname_i = 1, len(zaxisname_dummy)
+			if(zaxisname_temp(zaxisname_i) == c_null_char) zaxisname_padding = .true.
+			if(zaxisname_padding) then
+				zaxisname_dummy(zaxisname_i:zaxisname_i) = ' '
+			else
+				zaxisname_dummy(zaxisname_i:zaxisname_i) = zaxisname_temp(zaxisname_i)
+			end if
+		end do
+	end subroutine zaxisName
+
+	function zaxisCreate(zaxistype_dummy, size_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxistype_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			integer(c_int) function lib_zaxisCreate(zaxistype_dummy, size_dummy) bind(c, name = 'zaxisCreate')
+				import c_int
+				integer(c_int), value :: zaxistype_dummy
+				integer(c_int), value :: size_dummy
+			end function lib_zaxisCreate
+		end interface
+		result = lib_zaxisCreate(zaxistype_dummy, size_dummy)
+	end function zaxisCreate
+
+	subroutine zaxisDestroy(zaxisID_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_zaxisDestroy(zaxisID_dummy) bind(c, name = 'zaxisDestroy')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_zaxisDestroy
+		end interface
+		call lib_zaxisDestroy(zaxisID_dummy)
+	end subroutine zaxisDestroy
+
+	function zaxisInqType(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqType(zaxisID_dummy) bind(c, name = 'zaxisInqType')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqType
+		end interface
+		result = lib_zaxisInqType(zaxisID_dummy)
+	end function zaxisInqType
+
+	function zaxisInqSize(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqSize(zaxisID_dummy) bind(c, name = 'zaxisInqSize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqSize
+		end interface
+		result = lib_zaxisInqSize(zaxisID_dummy)
+	end function zaxisInqSize
+
+	function zaxisDuplicate(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisDuplicate(zaxisID_dummy) bind(c, name = 'zaxisDuplicate')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisDuplicate
+		end interface
+		result = lib_zaxisDuplicate(zaxisID_dummy)
+	end function zaxisDuplicate
+
+	subroutine zaxisResize(zaxisID_dummy, size_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			subroutine lib_zaxisResize(zaxisID_dummy, size_dummy) bind(c, name = 'zaxisResize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: size_dummy
+			end subroutine lib_zaxisResize
+		end interface
+		call lib_zaxisResize(zaxisID_dummy, size_dummy)
+	end subroutine zaxisResize
+
+	subroutine zaxisPrint(zaxisID_dummy, index_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			subroutine lib_zaxisPrint(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisPrint')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end subroutine lib_zaxisPrint
+		end interface
+		call lib_zaxisPrint(zaxisID_dummy, index_dummy)
+	end subroutine zaxisPrint
+
+	subroutine zaxisDefLevels(zaxisID_dummy, levels_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: levels_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefLevels(zaxisID_dummy, levels_vec_dummy) bind(c, name = 'zaxisDefLevels')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: levels_vec_dummy(*)
+			end subroutine lib_zaxisDefLevels
+		end interface
+		call lib_zaxisDefLevels(zaxisID_dummy, levels_vec_dummy)
+	end subroutine zaxisDefLevels
+
+	subroutine zaxisInqLevels(zaxisID_dummy, levels_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: levels_vec_dummy(*)
+		interface
+			subroutine lib_zaxisInqLevels(zaxisID_dummy, levels_vec_dummy) bind(c, name = 'zaxisInqLevels')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: levels_vec_dummy(*)
+			end subroutine lib_zaxisInqLevels
+		end interface
+		call lib_zaxisInqLevels(zaxisID_dummy, levels_vec_dummy)
+	end subroutine zaxisInqLevels
+
+	subroutine zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), value :: levels_dummy
+		interface
+			subroutine lib_zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy) bind(c, name = 'zaxisDefLevel')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), value :: levels_dummy
+			end subroutine lib_zaxisDefLevel
+		end interface
+		call lib_zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy)
+	end subroutine zaxisDefLevel
+
+	function zaxisInqLevel(zaxisID_dummy, levelID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			real(c_double) function lib_zaxisInqLevel(zaxisID_dummy, levelID_dummy) bind(c, name = 'zaxisInqLevel')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: levelID_dummy
+			end function lib_zaxisInqLevel
+		end interface
+		result = lib_zaxisInqLevel(zaxisID_dummy, levelID_dummy)
+	end function zaxisInqLevel
+
+	subroutine zaxisDefNlevRef(gridID_dummy, nhlev_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nhlev_dummy
+		interface
+			subroutine lib_zaxisDefNlevRef(gridID_dummy, nhlev_dummy) bind(c, name = 'zaxisDefNlevRef')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nhlev_dummy
+			end subroutine lib_zaxisDefNlevRef
+		end interface
+		call lib_zaxisDefNlevRef(gridID_dummy, nhlev_dummy)
+	end subroutine zaxisDefNlevRef
+
+	function zaxisInqNlevRef(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqNlevRef(gridID_dummy) bind(c, name = 'zaxisInqNlevRef')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_zaxisInqNlevRef
+		end interface
+		result = lib_zaxisInqNlevRef(gridID_dummy)
+	end function zaxisInqNlevRef
+
+	subroutine zaxisDefNumber(gridID_dummy, number_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: number_dummy
+		interface
+			subroutine lib_zaxisDefNumber(gridID_dummy, number_dummy) bind(c, name = 'zaxisDefNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: number_dummy
+			end subroutine lib_zaxisDefNumber
+		end interface
+		call lib_zaxisDefNumber(gridID_dummy, number_dummy)
+	end subroutine zaxisDefNumber
+
+	function zaxisInqNumber(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqNumber(gridID_dummy) bind(c, name = 'zaxisInqNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_zaxisInqNumber
+		end interface
+		result = lib_zaxisInqNumber(gridID_dummy)
+	end function zaxisInqNumber
+
+	subroutine zaxisDefUUID(zaxisID_dummy, uuid_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char), intent(in) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_zaxisDefUUID(zaxisID_dummy, uuid_dummy) bind(c, name = 'zaxisDefUUID')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char), intent(in) :: uuid_dummy(*)
+			end subroutine lib_zaxisDefUUID
+		end interface
+		call lib_zaxisDefUUID(zaxisID_dummy, uuid_dummy)
+	end subroutine zaxisDefUUID
+
+	subroutine zaxisInqUUID(zaxisID_dummy, uuid_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char), intent(inout) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_zaxisInqUUID(zaxisID_dummy, uuid_dummy) bind(c, name = 'zaxisInqUUID')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char), intent(inout) :: uuid_dummy(*)
+			end subroutine lib_zaxisInqUUID
+		end interface
+		call lib_zaxisInqUUID(zaxisID_dummy, uuid_dummy)
+	end subroutine zaxisInqUUID
+
+	subroutine zaxisDefName(zaxisID_dummy, name_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_zaxisDefName(zaxisID_dummy, name_dummy) bind(c, name = 'zaxisDefName')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_zaxisDefName
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_zaxisDefName(zaxisID_dummy, name_temp)
+	end subroutine zaxisDefName
+
+	subroutine zaxisInqName(zaxisID_dummy, name_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			subroutine lib_zaxisInqName(zaxisID_dummy, name_dummy) bind(c, name = 'zaxisInqName')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_zaxisInqName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		call lib_zaxisInqName(zaxisID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end subroutine zaxisInqName
+
+	subroutine zaxisDefLongname(zaxisID_dummy, longname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			subroutine lib_zaxisDefLongname(zaxisID_dummy, longname_dummy) bind(c, name = 'zaxisDefLongname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_zaxisDefLongname
+		end interface
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		call lib_zaxisDefLongname(zaxisID_dummy, longname_temp)
+	end subroutine zaxisDefLongname
+
+	subroutine zaxisInqLongname(zaxisID_dummy, longname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			subroutine lib_zaxisInqLongname(zaxisID_dummy, longname_dummy) bind(c, name = 'zaxisInqLongname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_zaxisInqLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		call lib_zaxisInqLongname(zaxisID_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end subroutine zaxisInqLongname
+
+	subroutine zaxisDefUnits(zaxisID_dummy, units_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_zaxisDefUnits(zaxisID_dummy, units_dummy) bind(c, name = 'zaxisDefUnits')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_zaxisDefUnits
+		end interface
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_zaxisDefUnits(zaxisID_dummy, units_temp)
+	end subroutine zaxisDefUnits
+
+	subroutine zaxisInqUnits(zaxisID_dummy, units_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_zaxisInqUnits(zaxisID_dummy, units_dummy) bind(c, name = 'zaxisInqUnits')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_zaxisInqUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_zaxisInqUnits(zaxisID_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine zaxisInqUnits
+
+	subroutine zaxisInqStdname(zaxisID_dummy, stdname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy))
+		integer :: stdname_i
+		logical :: stdname_padding = .true.
+		interface
+			subroutine lib_zaxisInqStdname(zaxisID_dummy, stdname_dummy) bind(c, name = 'zaxisInqStdname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_zaxisInqStdname
+		end interface
+		do stdname_i = len(stdname_dummy), 1, -1
+			if(stdname_dummy(stdname_i:stdname_i) /= ' ') stdname_padding = .false.
+			if(stdname_padding) then
+				stdname_temp(stdname_i) = c_null_char
+			else
+				stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+			end if
+		end do
+		call lib_zaxisInqStdname(zaxisID_dummy, stdname_temp)
+		stdname_padding = .false.
+		do stdname_i = 1, len(stdname_dummy)
+			if(stdname_temp(stdname_i) == c_null_char) stdname_padding = .true.
+			if(stdname_padding) then
+				stdname_dummy(stdname_i:stdname_i) = ' '
+			else
+				stdname_dummy(stdname_i:stdname_i) = stdname_temp(stdname_i)
+			end if
+		end do
+	end subroutine zaxisInqStdname
+
+	subroutine zaxisDefPrec(zaxisID_dummy, prec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: prec_dummy
+		interface
+			subroutine lib_zaxisDefPrec(zaxisID_dummy, prec_dummy) bind(c, name = 'zaxisDefPrec')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: prec_dummy
+			end subroutine lib_zaxisDefPrec
+		end interface
+		call lib_zaxisDefPrec(zaxisID_dummy, prec_dummy)
+	end subroutine zaxisDefPrec
+
+	function zaxisInqPrec(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqPrec(zaxisID_dummy) bind(c, name = 'zaxisInqPrec')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqPrec
+		end interface
+		result = lib_zaxisInqPrec(zaxisID_dummy)
+	end function zaxisInqPrec
+
+	subroutine zaxisDefPositive(zaxisID_dummy, positive_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: positive_dummy
+		interface
+			subroutine lib_zaxisDefPositive(zaxisID_dummy, positive_dummy) bind(c, name = 'zaxisDefPositive')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: positive_dummy
+			end subroutine lib_zaxisDefPositive
+		end interface
+		call lib_zaxisDefPositive(zaxisID_dummy, positive_dummy)
+	end subroutine zaxisDefPositive
+
+	function zaxisInqPositive(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqPositive(zaxisID_dummy) bind(c, name = 'zaxisInqPositive')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqPositive
+		end interface
+		result = lib_zaxisInqPositive(zaxisID_dummy)
+	end function zaxisInqPositive
+
+	subroutine zaxisDefLtype(zaxisID_dummy, ltype_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: ltype_dummy
+		interface
+			subroutine lib_zaxisDefLtype(zaxisID_dummy, ltype_dummy) bind(c, name = 'zaxisDefLtype')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: ltype_dummy
+			end subroutine lib_zaxisDefLtype
+		end interface
+		call lib_zaxisDefLtype(zaxisID_dummy, ltype_dummy)
+	end subroutine zaxisDefLtype
+
+	function zaxisInqLtype(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqLtype(zaxisID_dummy) bind(c, name = 'zaxisInqLtype')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqLtype
+		end interface
+		result = lib_zaxisInqLtype(zaxisID_dummy)
+	end function zaxisInqLtype
+
+	function zaxisInqLevelsPtr(zaxisID_dummy) result(result)
+		type(c_ptr) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			type(c_ptr) function lib_zaxisInqLevelsPtr(zaxisID_dummy) bind(c, name = 'zaxisInqLevelsPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqLevelsPtr
+		end interface
+		result = lib_zaxisInqLevelsPtr(zaxisID_dummy)
+	end function zaxisInqLevelsPtr
+
+	subroutine zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: size_dummy
+		real(c_double), intent(in) :: vct_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy) bind(c, name = 'zaxisDefVct')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: size_dummy
+				real(c_double), intent(in) :: vct_vec_dummy(*)
+			end subroutine lib_zaxisDefVct
+		end interface
+		call lib_zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy)
+	end subroutine zaxisDefVct
+
+	subroutine zaxisInqVct(zaxisID_dummy, vct_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: vct_vec_dummy(*)
+		interface
+			subroutine lib_zaxisInqVct(zaxisID_dummy, vct_vec_dummy) bind(c, name = 'zaxisInqVct')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: vct_vec_dummy(*)
+			end subroutine lib_zaxisInqVct
+		end interface
+		call lib_zaxisInqVct(zaxisID_dummy, vct_vec_dummy)
+	end subroutine zaxisInqVct
+
+	function zaxisInqVctSize(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqVctSize(zaxisID_dummy) bind(c, name = 'zaxisInqVctSize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqVctSize
+		end interface
+		result = lib_zaxisInqVctSize(zaxisID_dummy)
+	end function zaxisInqVctSize
+
+	function zaxisInqVctPtr(zaxisID_dummy) result(result)
+		type(c_ptr) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			type(c_ptr) function lib_zaxisInqVctPtr(zaxisID_dummy) bind(c, name = 'zaxisInqVctPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqVctPtr
+		end interface
+		result = lib_zaxisInqVctPtr(zaxisID_dummy)
+	end function zaxisInqVctPtr
+
+	subroutine zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: lbounds_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy) bind(c, name = 'zaxisDefLbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: lbounds_vec_dummy(*)
+			end subroutine lib_zaxisDefLbounds
+		end interface
+		call lib_zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy)
+	end subroutine zaxisDefLbounds
+
+	function zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: lbounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy) bind(c, name = 'zaxisInqLbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: lbounds_vec_dummy(*)
+			end function lib_zaxisInqLbounds
+		end interface
+		result = lib_zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy)
+	end function zaxisInqLbounds
+
+	function zaxisInqLbound(zaxisID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_zaxisInqLbound(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisInqLbound')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_zaxisInqLbound
+		end interface
+		result = lib_zaxisInqLbound(zaxisID_dummy, index_dummy)
+	end function zaxisInqLbound
+
+	subroutine zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: ubounds_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy) bind(c, name = 'zaxisDefUbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: ubounds_vec_dummy(*)
+			end subroutine lib_zaxisDefUbounds
+		end interface
+		call lib_zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy)
+	end subroutine zaxisDefUbounds
+
+	function zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: ubounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy) bind(c, name = 'zaxisInqUbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: ubounds_vec_dummy(*)
+			end function lib_zaxisInqUbounds
+		end interface
+		result = lib_zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy)
+	end function zaxisInqUbounds
+
+	function zaxisInqUbound(zaxisID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_zaxisInqUbound(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisInqUbound')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_zaxisInqUbound
+		end interface
+		result = lib_zaxisInqUbound(zaxisID_dummy, index_dummy)
+	end function zaxisInqUbound
+
+	subroutine zaxisDefWeights(zaxisID_dummy, weights_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: weights_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefWeights(zaxisID_dummy, weights_vec_dummy) bind(c, name = 'zaxisDefWeights')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: weights_vec_dummy(*)
+			end subroutine lib_zaxisDefWeights
+		end interface
+		call lib_zaxisDefWeights(zaxisID_dummy, weights_vec_dummy)
+	end subroutine zaxisDefWeights
+
+	function zaxisInqWeights(zaxisID_dummy, weights_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: weights_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqWeights(zaxisID_dummy, weights_vec_dummy) bind(c, name = 'zaxisInqWeights')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: weights_vec_dummy(*)
+			end function lib_zaxisInqWeights
+		end interface
+		result = lib_zaxisInqWeights(zaxisID_dummy, weights_vec_dummy)
+	end function zaxisInqWeights
+
+	subroutine zaxisChangeType(zaxisID_dummy, zaxistype_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: zaxistype_dummy
+		interface
+			subroutine lib_zaxisChangeType(zaxisID_dummy, zaxistype_dummy) bind(c, name = 'zaxisChangeType')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: zaxistype_dummy
+			end subroutine lib_zaxisChangeType
+		end interface
+		call lib_zaxisChangeType(zaxisID_dummy, zaxistype_dummy)
+	end subroutine zaxisChangeType
+
+	function taxisCreate(timetype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: timetype_dummy
+		interface
+			integer(c_int) function lib_taxisCreate(timetype_dummy) bind(c, name = 'taxisCreate')
+				import c_int
+				integer(c_int), value :: timetype_dummy
+			end function lib_taxisCreate
+		end interface
+		result = lib_taxisCreate(timetype_dummy)
+	end function taxisCreate
+
+	subroutine taxisDestroy(taxisID_dummy)
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_taxisDestroy(taxisID_dummy) bind(c, name = 'taxisDestroy')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_taxisDestroy
+		end interface
+		call lib_taxisDestroy(taxisID_dummy)
+	end subroutine taxisDestroy
+
+	function taxisDuplicate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisDuplicate(taxisID_dummy) bind(c, name = 'taxisDuplicate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisDuplicate
+		end interface
+		result = lib_taxisDuplicate(taxisID_dummy)
+	end function taxisDuplicate
+
+	subroutine taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy)
+		integer(c_int), value :: taxisIDdes_dummy
+		integer(c_int), value :: taxisIDsrc_dummy
+		interface
+			subroutine lib_taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy) bind(c, name = 'taxisCopyTimestep')
+				import c_int
+				integer(c_int), value :: taxisIDdes_dummy
+				integer(c_int), value :: taxisIDsrc_dummy
+			end subroutine lib_taxisCopyTimestep
+		end interface
+		call lib_taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy)
+	end subroutine taxisCopyTimestep
+
+	subroutine taxisDefType(taxisID_dummy, type_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: type_dummy
+		interface
+			subroutine lib_taxisDefType(taxisID_dummy, type_dummy) bind(c, name = 'taxisDefType')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: type_dummy
+			end subroutine lib_taxisDefType
+		end interface
+		call lib_taxisDefType(taxisID_dummy, type_dummy)
+	end subroutine taxisDefType
+
+	subroutine taxisDefVdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefVdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefVdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefVdate
+		end interface
+		call lib_taxisDefVdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefVdate
+
+	subroutine taxisDefVtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefVtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefVtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefVtime
+		end interface
+		call lib_taxisDefVtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefVtime
+
+	function taxisInqVdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqVdate(taxisID_dummy) bind(c, name = 'taxisInqVdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqVdate
+		end interface
+		result = lib_taxisInqVdate(taxisID_dummy)
+	end function taxisInqVdate
+
+	function taxisInqVtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqVtime(taxisID_dummy) bind(c, name = 'taxisInqVtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqVtime
+		end interface
+		result = lib_taxisInqVtime(taxisID_dummy)
+	end function taxisInqVtime
+
+	subroutine taxisDefRdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefRdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefRdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefRdate
+		end interface
+		call lib_taxisDefRdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefRdate
+
+	subroutine taxisDefRtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefRtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefRtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefRtime
+		end interface
+		call lib_taxisDefRtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefRtime
+
+	function taxisInqRdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqRdate(taxisID_dummy) bind(c, name = 'taxisInqRdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqRdate
+		end interface
+		result = lib_taxisInqRdate(taxisID_dummy)
+	end function taxisInqRdate
+
+	function taxisInqRtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqRtime(taxisID_dummy) bind(c, name = 'taxisInqRtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqRtime
+		end interface
+		result = lib_taxisInqRtime(taxisID_dummy)
+	end function taxisInqRtime
+
+	subroutine taxisDefFdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefFdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefFdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefFdate
+		end interface
+		call lib_taxisDefFdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefFdate
+
+	subroutine taxisDefFtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefFtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefFtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefFtime
+		end interface
+		call lib_taxisDefFtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefFtime
+
+	function taxisInqFdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqFdate(taxisID_dummy) bind(c, name = 'taxisInqFdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqFdate
+		end interface
+		result = lib_taxisInqFdate(taxisID_dummy)
+	end function taxisInqFdate
+
+	function taxisInqFtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqFtime(taxisID_dummy) bind(c, name = 'taxisInqFtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqFtime
+		end interface
+		result = lib_taxisInqFtime(taxisID_dummy)
+	end function taxisInqFtime
+
+	function taxisHasBounds(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisHasBounds(taxisID_dummy) bind(c, name = 'taxisHasBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisHasBounds
+		end interface
+		result = lib_taxisHasBounds(taxisID_dummy)
+	end function taxisHasBounds
+
+	subroutine taxisDeleteBounds(taxisID_dummy)
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_taxisDeleteBounds(taxisID_dummy) bind(c, name = 'taxisDeleteBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_taxisDeleteBounds
+		end interface
+		call lib_taxisDeleteBounds(taxisID_dummy)
+	end subroutine taxisDeleteBounds
+
+	subroutine taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: vdate_lb_dummy
+		integer(c_int), value :: vdate_ub_dummy
+		interface
+			subroutine lib_taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy) bind(c, name = 'taxisDefVdateBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: vdate_lb_dummy
+				integer(c_int), value :: vdate_ub_dummy
+			end subroutine lib_taxisDefVdateBounds
+		end interface
+		call lib_taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy)
+	end subroutine taxisDefVdateBounds
+
+	subroutine taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: vtime_lb_dummy
+		integer(c_int), value :: vtime_ub_dummy
+		interface
+			subroutine lib_taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy) bind(c, name = 'taxisDefVtimeBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: vtime_lb_dummy
+				integer(c_int), value :: vtime_ub_dummy
+			end subroutine lib_taxisDefVtimeBounds
+		end interface
+		call lib_taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy)
+	end subroutine taxisDefVtimeBounds
+
+	subroutine taxisInqVdateBounds(taxisID_dummy, vdate_lb, vdate_ub)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), optional, intent(inout) :: vdate_lb
+		integer(c_int), optional, intent(inout) :: vdate_ub
+		integer(c_int), target :: vdate_lb_temp
+		type(c_ptr) :: vdate_lb_ptr
+		integer(c_int), target :: vdate_ub_temp
+		type(c_ptr) :: vdate_ub_ptr
+		interface
+			subroutine lib_taxisInqVdateBounds(taxisID_dummy, vdate_lb, vdate_ub) bind(c, name = 'taxisInqVdateBounds')
+				import c_int, c_ptr
+				integer(c_int), value :: taxisID_dummy
+				type(c_ptr), value :: vdate_lb
+				type(c_ptr), value :: vdate_ub
+			end subroutine lib_taxisInqVdateBounds
+		end interface
+		vdate_lb_ptr = c_null_ptr
+		if(present(vdate_lb)) vdate_lb_ptr = c_loc(vdate_lb_temp)
+		vdate_ub_ptr = c_null_ptr
+		if(present(vdate_ub)) vdate_ub_ptr = c_loc(vdate_ub_temp)
+		call lib_taxisInqVdateBounds(taxisID_dummy, vdate_lb_ptr, vdate_ub_ptr)
+		if(present(vdate_lb)) vdate_lb = vdate_lb_temp
+		if(present(vdate_ub)) vdate_ub = vdate_ub_temp
+	end subroutine taxisInqVdateBounds
+
+	subroutine taxisInqVtimeBounds(taxisID_dummy, vtime_lb, vtime_ub)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), optional, intent(inout) :: vtime_lb
+		integer(c_int), optional, intent(inout) :: vtime_ub
+		integer(c_int), target :: vtime_lb_temp
+		type(c_ptr) :: vtime_lb_ptr
+		integer(c_int), target :: vtime_ub_temp
+		type(c_ptr) :: vtime_ub_ptr
+		interface
+			subroutine lib_taxisInqVtimeBounds(taxisID_dummy, vtime_lb, vtime_ub) bind(c, name = 'taxisInqVtimeBounds')
+				import c_int, c_ptr
+				integer(c_int), value :: taxisID_dummy
+				type(c_ptr), value :: vtime_lb
+				type(c_ptr), value :: vtime_ub
+			end subroutine lib_taxisInqVtimeBounds
+		end interface
+		vtime_lb_ptr = c_null_ptr
+		if(present(vtime_lb)) vtime_lb_ptr = c_loc(vtime_lb_temp)
+		vtime_ub_ptr = c_null_ptr
+		if(present(vtime_ub)) vtime_ub_ptr = c_loc(vtime_ub_temp)
+		call lib_taxisInqVtimeBounds(taxisID_dummy, vtime_lb_ptr, vtime_ub_ptr)
+		if(present(vtime_lb)) vtime_lb = vtime_lb_temp
+		if(present(vtime_ub)) vtime_ub = vtime_ub_temp
+	end subroutine taxisInqVtimeBounds
+
+	subroutine taxisDefCalendar(taxisID_dummy, calendar_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: calendar_dummy
+		interface
+			subroutine lib_taxisDefCalendar(taxisID_dummy, calendar_dummy) bind(c, name = 'taxisDefCalendar')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: calendar_dummy
+			end subroutine lib_taxisDefCalendar
+		end interface
+		call lib_taxisDefCalendar(taxisID_dummy, calendar_dummy)
+	end subroutine taxisDefCalendar
+
+	function taxisInqCalendar(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqCalendar(taxisID_dummy) bind(c, name = 'taxisInqCalendar')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqCalendar
+		end interface
+		result = lib_taxisInqCalendar(taxisID_dummy)
+	end function taxisInqCalendar
+
+	subroutine taxisDefTunit(taxisID_dummy, tunit_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: tunit_dummy
+		interface
+			subroutine lib_taxisDefTunit(taxisID_dummy, tunit_dummy) bind(c, name = 'taxisDefTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: tunit_dummy
+			end subroutine lib_taxisDefTunit
+		end interface
+		call lib_taxisDefTunit(taxisID_dummy, tunit_dummy)
+	end subroutine taxisDefTunit
+
+	function taxisInqTunit(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqTunit(taxisID_dummy) bind(c, name = 'taxisInqTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqTunit
+		end interface
+		result = lib_taxisInqTunit(taxisID_dummy)
+	end function taxisInqTunit
+
+	subroutine taxisDefForecastTunit(taxisID_dummy, tunit_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: tunit_dummy
+		interface
+			subroutine lib_taxisDefForecastTunit(taxisID_dummy, tunit_dummy) bind(c, name = 'taxisDefForecastTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: tunit_dummy
+			end subroutine lib_taxisDefForecastTunit
+		end interface
+		call lib_taxisDefForecastTunit(taxisID_dummy, tunit_dummy)
+	end subroutine taxisDefForecastTunit
+
+	function taxisInqForecastTunit(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqForecastTunit(taxisID_dummy) bind(c, name = 'taxisInqForecastTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqForecastTunit
+		end interface
+		result = lib_taxisInqForecastTunit(taxisID_dummy)
+	end function taxisInqForecastTunit
+
+	subroutine taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy)
+		integer(c_int), value :: taxisID_dummy
+		real(c_double), value :: fc_period_dummy
+		interface
+			subroutine lib_taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy) bind(c, name = 'taxisDefForecastPeriod')
+				import c_double, c_int
+				integer(c_int), value :: taxisID_dummy
+				real(c_double), value :: fc_period_dummy
+			end subroutine lib_taxisDefForecastPeriod
+		end interface
+		call lib_taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy)
+	end subroutine taxisDefForecastPeriod
+
+	function taxisInqForecastPeriod(taxisID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			real(c_double) function lib_taxisInqForecastPeriod(taxisID_dummy) bind(c, name = 'taxisInqForecastPeriod')
+				import c_double, c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqForecastPeriod
+		end interface
+		result = lib_taxisInqForecastPeriod(taxisID_dummy)
+	end function taxisInqForecastPeriod
+
+	subroutine taxisDefNumavg(taxisID_dummy, numavg_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: numavg_dummy
+		interface
+			subroutine lib_taxisDefNumavg(taxisID_dummy, numavg_dummy) bind(c, name = 'taxisDefNumavg')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: numavg_dummy
+			end subroutine lib_taxisDefNumavg
+		end interface
+		call lib_taxisDefNumavg(taxisID_dummy, numavg_dummy)
+	end subroutine taxisDefNumavg
+
+	function taxisInqType(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqType(taxisID_dummy) bind(c, name = 'taxisInqType')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqType
+		end interface
+		result = lib_taxisInqType(taxisID_dummy)
+	end function taxisInqType
+
+	function taxisInqNumavg(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqNumavg(taxisID_dummy) bind(c, name = 'taxisInqNumavg')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqNumavg
+		end interface
+		result = lib_taxisInqNumavg(taxisID_dummy)
+	end function taxisInqNumavg
+
+	function tunitNamePtr(tunitID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tunitID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tunitNamePtr(tunitID_dummy) bind(c, name = 'tunitNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tunitID_dummy
+			end function lib_tunitNamePtr
+		end interface
+		result => null()
+		ptr = lib_tunitNamePtr(tunitID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tunitNamePtr
+
+	function institutDef(center_dummy, subcenter_dummy, name_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: center_dummy
+		integer(c_int), value :: subcenter_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			integer(c_int) function lib_institutDef(center_dummy, subcenter_dummy, name_dummy, longname_dummy) bind(c, name = 'institutDef')
+				import c_char, c_int
+				integer(c_int), value :: center_dummy
+				integer(c_int), value :: subcenter_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_institutDef
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		result = lib_institutDef(center_dummy, subcenter_dummy, name_temp, longname_temp)
+	end function institutDef
+
+	function institutInq(center_dummy, subcenter_dummy, name_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: center_dummy
+		integer(c_int), value :: subcenter_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			integer(c_int) function lib_institutInq(center_dummy, subcenter_dummy, name_dummy, longname_dummy) bind(c, name = 'institutInq')
+				import c_char, c_int
+				integer(c_int), value :: center_dummy
+				integer(c_int), value :: subcenter_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_institutInq
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		result = lib_institutInq(center_dummy, subcenter_dummy, name_temp, longname_temp)
+	end function institutInq
+
+	function institutInqNumber() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_institutInqNumber() bind(c, name = 'institutInqNumber')
+				import c_int
+			end function lib_institutInqNumber
+		end interface
+		result = lib_institutInqNumber()
+	end function institutInqNumber
+
+	function institutInqCenter(instID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		interface
+			integer(c_int) function lib_institutInqCenter(instID_dummy) bind(c, name = 'institutInqCenter')
+				import c_int
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqCenter
+		end interface
+		result = lib_institutInqCenter(instID_dummy)
+	end function institutInqCenter
+
+	function institutInqSubcenter(instID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		interface
+			integer(c_int) function lib_institutInqSubcenter(instID_dummy) bind(c, name = 'institutInqSubcenter')
+				import c_int
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqSubcenter
+		end interface
+		result = lib_institutInqSubcenter(instID_dummy)
+	end function institutInqSubcenter
+
+	function institutInqNamePtr(instID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: instID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_institutInqNamePtr(instID_dummy) bind(c, name = 'institutInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_institutInqNamePtr(instID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function institutInqNamePtr
+
+	function institutInqLongnamePtr(instID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: instID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_institutInqLongnamePtr(instID_dummy) bind(c, name = 'institutInqLongnamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqLongnamePtr
+		end interface
+		result => null()
+		ptr = lib_institutInqLongnamePtr(instID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function institutInqLongnamePtr
+
+	function modelDef(instID_dummy, modelgribID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		integer(c_int), value :: modelgribID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_modelDef(instID_dummy, modelgribID_dummy, name_dummy) bind(c, name = 'modelDef')
+				import c_char, c_int
+				integer(c_int), value :: instID_dummy
+				integer(c_int), value :: modelgribID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_modelDef
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_modelDef(instID_dummy, modelgribID_dummy, name_temp)
+	end function modelDef
+
+	function modelInq(instID_dummy, modelgribID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		integer(c_int), value :: modelgribID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			integer(c_int) function lib_modelInq(instID_dummy, modelgribID_dummy, name_dummy) bind(c, name = 'modelInq')
+				import c_char, c_int
+				integer(c_int), value :: instID_dummy
+				integer(c_int), value :: modelgribID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_modelInq
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		result = lib_modelInq(instID_dummy, modelgribID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end function modelInq
+
+	function modelInqInstitut(modelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		interface
+			integer(c_int) function lib_modelInqInstitut(modelID_dummy) bind(c, name = 'modelInqInstitut')
+				import c_int
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqInstitut
+		end interface
+		result = lib_modelInqInstitut(modelID_dummy)
+	end function modelInqInstitut
+
+	function modelInqGribID(modelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		interface
+			integer(c_int) function lib_modelInqGribID(modelID_dummy) bind(c, name = 'modelInqGribID')
+				import c_int
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqGribID
+		end interface
+		result = lib_modelInqGribID(modelID_dummy)
+	end function modelInqGribID
+
+	function modelInqNamePtr(modelID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: modelID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_modelInqNamePtr(modelID_dummy) bind(c, name = 'modelInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_modelInqNamePtr(modelID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function modelInqNamePtr
+
+	subroutine tableWriteC(filename_dummy, tableID_dummy)
+		character(kind = c_char, len = *), intent(in) :: filename_dummy
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char) :: filename_temp(len(filename_dummy) + 1)
+		integer :: filename_i
+		interface
+			subroutine lib_tableWriteC(filename_dummy, tableID_dummy) bind(c, name = 'tableWriteC')
+				import c_char, c_int
+				character(kind = c_char) :: filename_dummy(*)
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_tableWriteC
+		end interface
+		do filename_i = 1, len(filename_dummy)
+		filename_temp(filename_i) = filename_dummy(filename_i:filename_i)
+		end do
+		filename_temp(len(filename_dummy) + 1) = c_null_char
+		call lib_tableWriteC(filename_temp, tableID_dummy)
+	end subroutine tableWriteC
+
+	subroutine tableWrite(filename_dummy, tableID_dummy)
+		character(kind = c_char, len = *), intent(in) :: filename_dummy
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char) :: filename_temp(len(filename_dummy) + 1)
+		integer :: filename_i
+		interface
+			subroutine lib_tableWrite(filename_dummy, tableID_dummy) bind(c, name = 'tableWrite')
+				import c_char, c_int
+				character(kind = c_char) :: filename_dummy(*)
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_tableWrite
+		end interface
+		do filename_i = 1, len(filename_dummy)
+		filename_temp(filename_i) = filename_dummy(filename_i:filename_i)
+		end do
+		filename_temp(len(filename_dummy) + 1) = c_null_char
+		call lib_tableWrite(filename_temp, tableID_dummy)
+	end subroutine tableWrite
+
+	function tableRead(tablefile_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: tablefile_dummy
+		character(kind = c_char) :: tablefile_temp(len(tablefile_dummy) + 1)
+		integer :: tablefile_i
+		interface
+			integer(c_int) function lib_tableRead(tablefile_dummy) bind(c, name = 'tableRead')
+				import c_char, c_int
+				character(kind = c_char) :: tablefile_dummy(*)
+			end function lib_tableRead
+		end interface
+		do tablefile_i = 1, len(tablefile_dummy)
+		tablefile_temp(tablefile_i) = tablefile_dummy(tablefile_i:tablefile_i)
+		end do
+		tablefile_temp(len(tablefile_dummy) + 1) = c_null_char
+		result = lib_tableRead(tablefile_temp)
+	end function tableRead
+
+	function tableDef(modelID_dummy, tablenum_dummy, tablename_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		integer(c_int), value :: tablenum_dummy
+		character(kind = c_char, len = *), intent(in) :: tablename_dummy
+		character(kind = c_char) :: tablename_temp(len(tablename_dummy) + 1)
+		integer :: tablename_i
+		interface
+			integer(c_int) function lib_tableDef(modelID_dummy, tablenum_dummy, tablename_dummy) bind(c, name = 'tableDef')
+				import c_char, c_int
+				integer(c_int), value :: modelID_dummy
+				integer(c_int), value :: tablenum_dummy
+				character(kind = c_char) :: tablename_dummy(*)
+			end function lib_tableDef
+		end interface
+		do tablename_i = 1, len(tablename_dummy)
+		tablename_temp(tablename_i) = tablename_dummy(tablename_i:tablename_i)
+		end do
+		tablename_temp(len(tablename_dummy) + 1) = c_null_char
+		result = lib_tableDef(modelID_dummy, tablenum_dummy, tablename_temp)
+	end function tableDef
+
+	function tableInqNamePtr(tableID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqNamePtr(tableID_dummy) bind(c, name = 'tableInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqNamePtr(tableID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqNamePtr
+
+	subroutine tableDefEntry(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy)
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_tableDefEntry(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy) bind(c, name = 'tableDefEntry')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_tableDefEntry
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_tableDefEntry(tableID_dummy, code_dummy, name_temp, longname_temp, units_temp)
+	end subroutine tableDefEntry
+
+	function tableInq(modelID_dummy, tablenum_dummy, tablename_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		integer(c_int), value :: tablenum_dummy
+		character(kind = c_char, len = *), intent(in) :: tablename_dummy
+		character(kind = c_char) :: tablename_temp(len(tablename_dummy) + 1)
+		integer :: tablename_i
+		interface
+			integer(c_int) function lib_tableInq(modelID_dummy, tablenum_dummy, tablename_dummy) bind(c, name = 'tableInq')
+				import c_char, c_int
+				integer(c_int), value :: modelID_dummy
+				integer(c_int), value :: tablenum_dummy
+				character(kind = c_char) :: tablename_dummy(*)
+			end function lib_tableInq
+		end interface
+		do tablename_i = 1, len(tablename_dummy)
+		tablename_temp(tablename_i) = tablename_dummy(tablename_i:tablename_i)
+		end do
+		tablename_temp(len(tablename_dummy) + 1) = c_null_char
+		result = lib_tableInq(modelID_dummy, tablenum_dummy, tablename_temp)
+	end function tableInq
+
+	function tableInqNumber() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_tableInqNumber() bind(c, name = 'tableInqNumber')
+				import c_int
+			end function lib_tableInqNumber
+		end interface
+		result = lib_tableInqNumber()
+	end function tableInqNumber
+
+	function tableInqNum(tableID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		interface
+			integer(c_int) function lib_tableInqNum(tableID_dummy) bind(c, name = 'tableInqNum')
+				import c_int
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqNum
+		end interface
+		result = lib_tableInqNum(tableID_dummy)
+	end function tableInqNum
+
+	function tableInqModel(tableID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		interface
+			integer(c_int) function lib_tableInqModel(tableID_dummy) bind(c, name = 'tableInqModel')
+				import c_int
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqModel
+		end interface
+		result = lib_tableInqModel(tableID_dummy)
+	end function tableInqModel
+
+	subroutine tableInqPar(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy)
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_tableInqPar(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy) bind(c, name = 'tableInqPar')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_tableInqPar
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_tableInqPar(tableID_dummy, code_dummy, name_temp, longname_temp, units_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine tableInqPar
+
+	function tableInqParCode(tableID_dummy, name_dummy, code) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		integer(c_int), optional, intent(inout) :: code
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		integer(c_int), target :: code_temp
+		type(c_ptr) :: code_ptr
+		interface
+			integer(c_int) function lib_tableInqParCode(tableID_dummy, name_dummy, code) bind(c, name = 'tableInqParCode')
+				import c_char, c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				type(c_ptr), value :: code
+			end function lib_tableInqParCode
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		code_ptr = c_null_ptr
+		if(present(code)) code_ptr = c_loc(code_temp)
+		result = lib_tableInqParCode(tableID_dummy, name_temp, code_ptr)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		if(present(code)) code = code_temp
+	end function tableInqParCode
+
+	function tableInqParName(tableID_dummy, code_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParName(tableID_dummy, code_dummy, name_dummy) bind(c, name = 'tableInqParName')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_tableInqParName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		result = lib_tableInqParName(tableID_dummy, code_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end function tableInqParName
+
+	function tableInqParLongname(tableID_dummy, code_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParLongname(tableID_dummy, code_dummy, longname_dummy) bind(c, name = 'tableInqParLongname')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_tableInqParLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		result = lib_tableInqParLongname(tableID_dummy, code_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end function tableInqParLongname
+
+	function tableInqParUnits(tableID_dummy, code_dummy, units_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParUnits(tableID_dummy, code_dummy, units_dummy) bind(c, name = 'tableInqParUnits')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end function lib_tableInqParUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		result = lib_tableInqParUnits(tableID_dummy, code_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end function tableInqParUnits
+
+	function tableInqParNamePtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParNamePtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParNamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParNamePtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParNamePtr
+
+	function tableInqParLongnamePtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParLongnamePtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParLongnamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParLongnamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParLongnamePtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParLongnamePtr
+
+	function tableInqParUnitsPtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParUnitsPtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParUnitsPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParUnitsPtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParUnitsPtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParUnitsPtr
+
+	subroutine streamDefHistory(streamID_dummy, size_dummy, history_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: size_dummy
+		character(kind = c_char, len = *), intent(in) :: history_dummy
+		character(kind = c_char) :: history_temp(len(history_dummy) + 1)
+		integer :: history_i
+		interface
+			subroutine lib_streamDefHistory(streamID_dummy, size_dummy, history_dummy) bind(c, name = 'streamDefHistory')
+				import c_char, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: size_dummy
+				character(kind = c_char) :: history_dummy(*)
+			end subroutine lib_streamDefHistory
+		end interface
+		do history_i = 1, len(history_dummy)
+		history_temp(history_i) = history_dummy(history_i:history_i)
+		end do
+		history_temp(len(history_dummy) + 1) = c_null_char
+		call lib_streamDefHistory(streamID_dummy, size_dummy, history_temp)
+	end subroutine streamDefHistory
+
+	function streamInqHistorySize(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqHistorySize(streamID_dummy) bind(c, name = 'streamInqHistorySize')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqHistorySize
+		end interface
+		result = lib_streamInqHistorySize(streamID_dummy)
+	end function streamInqHistorySize
+
+	subroutine streamInqHistoryString(streamID_dummy, history_dummy)
+		integer(c_int), value :: streamID_dummy
+		character(kind = c_char, len = *), intent(inout) :: history_dummy
+		character(kind = c_char) :: history_temp(len(history_dummy))
+		integer :: history_i
+		logical :: history_padding = .true.
+		interface
+			subroutine lib_streamInqHistoryString(streamID_dummy, history_dummy) bind(c, name = 'streamInqHistoryString')
+				import c_char, c_int
+				integer(c_int), value :: streamID_dummy
+				character(kind = c_char) :: history_dummy(*)
+			end subroutine lib_streamInqHistoryString
+		end interface
+		do history_i = len(history_dummy), 1, -1
+			if(history_dummy(history_i:history_i) /= ' ') history_padding = .false.
+			if(history_padding) then
+				history_temp(history_i) = c_null_char
+			else
+				history_temp(history_i) = history_dummy(history_i:history_i)
+			end if
+		end do
+		call lib_streamInqHistoryString(streamID_dummy, history_temp)
+		history_padding = .false.
+		do history_i = 1, len(history_dummy)
+			if(history_temp(history_i) == c_null_char) history_padding = .true.
+			if(history_padding) then
+				history_dummy(history_i:history_i) = ' '
+			else
+				history_dummy(history_i:history_i) = history_temp(history_i)
+			end if
+		end do
+	end subroutine streamInqHistoryString
+
+	subroutine gribapiLibraryVersion(major_version, minor_version, revision_version)
+		integer(c_int), optional, intent(inout) :: major_version
+		integer(c_int), optional, intent(inout) :: minor_version
+		integer(c_int), optional, intent(inout) :: revision_version
+		integer(c_int), target :: major_version_temp
+		type(c_ptr) :: major_version_ptr
+		integer(c_int), target :: minor_version_temp
+		type(c_ptr) :: minor_version_ptr
+		integer(c_int), target :: revision_version_temp
+		type(c_ptr) :: revision_version_ptr
+		interface
+			subroutine lib_gribapiLibraryVersion(major_version, minor_version, revision_version) bind(c, name = 'gribapiLibraryVersion')
+				import c_ptr
+				type(c_ptr), value :: major_version
+				type(c_ptr), value :: minor_version
+				type(c_ptr), value :: revision_version
+			end subroutine lib_gribapiLibraryVersion
+		end interface
+		major_version_ptr = c_null_ptr
+		if(present(major_version)) major_version_ptr = c_loc(major_version_temp)
+		minor_version_ptr = c_null_ptr
+		if(present(minor_version)) minor_version_ptr = c_loc(minor_version_temp)
+		revision_version_ptr = c_null_ptr
+		if(present(revision_version)) revision_version_ptr = c_loc(revision_version_temp)
+		call lib_gribapiLibraryVersion(major_version_ptr, minor_version_ptr, revision_version_ptr)
+		if(present(major_version)) major_version = major_version_temp
+		if(present(minor_version)) minor_version = minor_version_temp
+		if(present(revision_version)) revision_version = revision_version_temp
+	end subroutine gribapiLibraryVersion
 
 end module mo_cdi
diff --git a/libcdi/src/model.c b/libcdi/src/model.c
index b14181e..fdd58e9 100644
--- a/libcdi/src/model.c
+++ b/libcdi/src/model.c
@@ -132,11 +132,6 @@ void modelInit(void)
   if ( env ) MODEL_Debug = atoi(env);
 }
 
-int modelSize ( void )
-{
-  return reshCountType ( &modelOps );
-}
-
 struct modelLoc
 {
   char *name;
diff --git a/libcdi/src/namespace.c b/libcdi/src/namespace.c
index 15fc5ed..c850c52 100644
--- a/libcdi/src/namespace.c
+++ b/libcdi/src/namespace.c
@@ -21,7 +21,7 @@
 #include "cdi_int.h"
 #include "stream_cdf.h"
 
-static int nNamespaces = 1;
+static unsigned nNamespaces = 1;
 static int activeNamespace = 0;
 
 #ifdef HAVE_LIBNETCDF
@@ -61,7 +61,7 @@ static const union namespaceSwitchValue
   defaultSwitches_[NUM_NAMESPACE_SWITCH] = defaultSwitches;
 #endif
 
-struct Namespace
+static struct Namespace
 {
   statusCode resStage;
   union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
@@ -70,9 +70,9 @@ struct Namespace
   .switches = defaultSwitches
 };
 
-struct Namespace *namespaces = &initialNamespace;
+static struct Namespace *namespaces = &initialNamespace;
 
-static int namespacesSize = 1;
+static unsigned namespacesSize = 1;
 
 #if  defined  (HAVE_LIBPTHREAD)
 #  include <pthread.h>
@@ -151,10 +151,10 @@ namespaceNew()
   if (namespacesSize > nNamespaces)
     {
       /* namespace is already available and only needs reinitialization */
-      for (int i = 0; i < namespacesSize; ++i)
+      for (unsigned i = 0; i < namespacesSize; ++i)
         if (namespaces[i].resStage == STAGE_UNUSED)
           {
-            newNamespaceID = i;
+            newNamespaceID = (int)i;
             break;
           }
     }
@@ -171,7 +171,7 @@ namespaceNew()
   else if (namespacesSize < NUM_NAMESPACES)
     {
       /* make room for additional namespace */
-      newNamespaceID = namespacesSize;
+      newNamespaceID = (int)namespacesSize;
       namespaces
         = (struct Namespace *)xrealloc(namespaces, ((size_t)namespacesSize + 1) * sizeof (namespaces[0]));
       ++namespacesSize;
@@ -203,7 +203,8 @@ namespaceDelete(int namespaceID)
 {
   NAMESPACE_INIT();
   NAMESPACE_LOCK();
-  xassert(namespaceID < namespacesSize && nNamespaces);
+  xassert(namespaceID >= 0 && (unsigned)namespaceID < namespacesSize
+          && nNamespaces);
   reshListDestruct(namespaceID);
   namespaces[namespaceID].resStage = STAGE_UNUSED;
   --nNamespaces;
@@ -212,13 +213,13 @@ namespaceDelete(int namespaceID)
 
 int namespaceGetNumber ()
 {
-  return nNamespaces;
+  return (int)nNamespaces;
 }
 
 
 void namespaceSetActive ( int nId )
 {
-  xassert(nId < namespacesSize && nId >= 0
+  xassert((unsigned)nId < namespacesSize
           && namespaces[nId].resStage != STAGE_UNUSED);
   activeNamespace = nId;
 }
@@ -294,9 +295,9 @@ void cdiReset(void)
 {
   NAMESPACE_INIT();
   NAMESPACE_LOCK();
-  for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
+  for (unsigned namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
     if (namespaces[namespaceID].resStage != STAGE_UNUSED)
-      namespaceDelete(namespaceID);
+      namespaceDelete((int)namespaceID);
   if (namespaces != &initialNamespace)
     {
       free(namespaces);
diff --git a/libcdi/src/pio_interface.c b/libcdi/src/pio_interface.c
index 19d3b7d..d4c67fb 100644
--- a/libcdi/src/pio_interface.c
+++ b/libcdi/src/pio_interface.c
@@ -155,7 +155,7 @@ in order of vSizes
 
 static void
 varMapGen(int *vSizes, int *sSizes, int *varMapping,
-          int nStreams, int *nodeSizes, int nNodes)
+          unsigned nStreams, int *nodeSizes, int nNodes)
 {
 
   int weightsStreams[nStreams];
@@ -170,9 +170,9 @@ varMapGen(int *vSizes, int *sSizes, int *varMapping,
 
   int buckets[nProcsColl];
 
-  for ( i = 0; i < nStreams; i++ )
+  for (unsigned i = 0; i < nStreams; i++ )
     {
-      nVars += * ( sSizes + i );
+      nVars += sSizes[i];
       weightsStreams[i] = 0;
       for ( j = 0; j < * ( sSizes + i ); j++ )
 	weightsStreams[i] += * ( vSizes + offset++ );
@@ -185,13 +185,13 @@ varMapGen(int *vSizes, int *sSizes, int *varMapping,
   for ( j = 0; j < nNodes; j++ )
     w[j] = ( double ) * ( nodeSizes + j ) / ( double ) nPEs;
 
-  mapProblems ( weightsStreams, streamMapping, nStreams, nNodes, w );
+  mapProblems(weightsStreams, streamMapping, (int)nStreams, nNodes, w);
   free ( w );
 
   for ( i = 0; i < nNodes; i++ )
     {
       nVarsNode = 0;
-      for ( j = 0; j < nStreams; j++ )
+      for (unsigned j = 0; j < nStreams; j++)
 	if ( * ( streamMapping + j ) == i )
 	  nVarsNode += * ( sSizes + j );
 
@@ -201,12 +201,12 @@ varMapGen(int *vSizes, int *sSizes, int *varMapping,
       offset = 0;
       offsetN = 0;
 
-      for ( j = 0; j < nStreams; j++ )
-	if ( * ( streamMapping + j ) == i )
+      for (unsigned j = 0; j < nStreams; j++ )
+	if (streamMapping[j] == i)
 	  for ( k = 0; k < * ( sSizes + j ); k ++ )
-	    * ( weightsVarsNode + offsetN++ ) = * ( vSizes + offset++ );
+	    weightsVarsNode[offsetN++] = vSizes[offset++];
 	else
-	  offset += * ( sSizes + j );
+	  offset += sSizes[j];
 
       for ( j = 0; j < * ( nodeSizes + i ); j ++ )
 	w[j] = 1.0 / ( double ) * ( nodeSizes + i );
@@ -217,7 +217,7 @@ varMapGen(int *vSizes, int *sSizes, int *varMapping,
       offset = 0;
       offsetN = 0;
 
-      for ( j = 0; j < nStreams; j++ )
+      for (unsigned j = 0; j < nStreams; j++)
 	if ( * ( streamMapping + j ) == i )
 	  for ( k = 0; k < * ( sSizes + j ); k ++ )
 	    * ( varMapping + offset ++ ) =
@@ -249,28 +249,28 @@ varMapGen(int *vSizes, int *sSizes, int *varMapping,
 static void
 varsMapNDeco(int nNodes, int *nodeSizes)
 {
-  int nStreams, nVars, * resHs, * streamSizes, * varSizes, * varMapping,
+  int nVars, * resHs, * streamSizes, * varSizes, * varMapping,
     * collectsData;
   int k = 0;
   int nProcsColl = commInqNProcsColl ();
 
   xdebug ( "START, nProcsColl=%d", nProcsColl );
 
-  nStreams = streamSize ();
+  unsigned nStreams = reshCountType(&streamOps);
 
-  resHs       = xmalloc((size_t)nStreams * sizeof (resHs[0]));
-  streamSizes = xmalloc((size_t)nStreams * sizeof (streamSizes[0]));
+  resHs       = xmalloc(nStreams * sizeof (resHs[0]));
+  streamSizes = xmalloc(nStreams * sizeof (streamSizes[0]));
   collectsData = xmalloc((size_t)nProcsColl * sizeof (collectsData[0]));
-  streamGetIndexList ( nStreams, resHs );
+  cdiStreamGetIndexList(nStreams, resHs);
 
-  for (int i = 0; i < nStreams; i++ )
-    streamSizes[i] = streamInqNvars ( * ( resHs + i ));
+  for (unsigned i = 0; i < nStreams; i++ )
+    streamSizes[i] = streamInqNvars(resHs[i]);
 
   nVars = sum_int((size_t)nStreams, streamSizes);
   varSizes   = xcalloc((size_t)nVars, sizeof (varSizes[0]));
   varMapping = xmalloc((size_t)nVars * sizeof (varMapping[0]));
 
-  for (int i = 0; i < nStreams; i++ )
+  for (unsigned i = 0; i < nStreams; i++ )
     {
       int vlistID = streamInqVlist(resHs[i]);
       for (int j = 0; j < streamSizes[i]; j++ )
@@ -283,7 +283,7 @@ varsMapNDeco(int nNodes, int *nodeSizes)
 	      nStreams, nodeSizes, nNodes );
 
   k = 0;
-  for (int i = 0; i < nStreams; i++ )
+  for (unsigned i = 0; i < nStreams; i++ )
     for (int j = 0; j < * ( streamSizes + i ); j++ )
       {
         vlistDefVarIOrank ( streamInqVlist ( * ( resHs + i )), j,
@@ -343,7 +343,7 @@ struct collDesc
 static void
 modelWinDefBufferSizes(void)
 {
-  int collID, nstreams, * streamIndexList, streamNo, nvars, varID;
+  int collID, * streamIndexList, nvars, varID;
   size_t sumWinBufferSize = 0;
   int nProcsColl  = commInqNProcsColl ();
   int rankGlob    = commInqRankGlob ();
@@ -353,11 +353,11 @@ modelWinDefBufferSizes(void)
   xdebug("%s", "START");
   xassert(txWin != NULL);
 
-  nstreams = reshCountType ( &streamOps );
+  unsigned nstreams = reshCountType ( &streamOps );
   streamIndexList = xmalloc((size_t)nstreams * sizeof (streamIndexList[0]));
   collIndex = xcalloc((size_t)nProcsColl, sizeof (collIndex[0]));
   reshGetResHListOfType ( nstreams, streamIndexList, &streamOps );
-  for ( streamNo = 0; streamNo < nstreams; streamNo++ )
+  for (unsigned streamNo = 0; streamNo < nstreams; streamNo++ )
     {
       // memory required for data
       int streamID = streamIndexList[streamNo];
diff --git a/libcdi/src/pio_server.c b/libcdi/src/pio_server.c
index 52652fa..8180d7f 100644
--- a/libcdi/src/pio_server.c
+++ b/libcdi/src/pio_server.c
@@ -76,7 +76,7 @@ void serverWinCleanup ()
 static size_t
 collDefBufferSizes()
 {
-  int nstreams, * streamIndexList, streamNo, vlistID, nvars, varID, iorank;
+  int *streamIndexList, vlistID, nvars, varID, iorank;
   int modelID;
   size_t sumGetBufferSizes = 0;
   int rankGlob = commInqRankGlob ();
@@ -85,10 +85,10 @@ collDefBufferSizes()
 
   xassert(rxWin != NULL);
 
-  nstreams = reshCountType ( &streamOps );
+  unsigned nstreams = reshCountType ( &streamOps );
   streamIndexList = xmalloc((size_t)nstreams * sizeof (streamIndexList[0]));
   reshGetResHListOfType ( nstreams, streamIndexList, &streamOps );
-  for ( streamNo = 0; streamNo < nstreams; streamNo++ )
+  for (unsigned streamNo = 0; streamNo < nstreams; streamNo++)
     {
       // space required for data
       vlistID = streamInqVlist ( streamIndexList[streamNo] );
@@ -575,18 +575,18 @@ buildStreamMap(struct winHeaderEntry *winDict)
   /* join with list of streams written to in total */
   {
     int *streamIDs, *streamIsWritten;
-    int numTotalStreamIDs = streamSize();
-    streamIDs = (int*) xmalloc(2 * sizeof (streamIDs[0]) * (size_t)numTotalStreamIDs);
-    streamGetIndexList(numTotalStreamIDs, streamIDs);
+    unsigned numTotalStreamIDs = reshCountType(&streamOps);
+    streamIDs = xmalloc(2 * sizeof (streamIDs[0]) * (size_t)numTotalStreamIDs);
+    cdiStreamGetIndexList(numTotalStreamIDs, streamIDs);
     streamIsWritten = streamIDs + numTotalStreamIDs;
-    for (int i = 0; i < numTotalStreamIDs; ++i)
+    for (unsigned i = 0; i < numTotalStreamIDs; ++i)
       streamIsWritten[i] = streamIsInList(streamMap, numStreamIDs,
                                           streamIDs[i]);
     /* Find what streams are written to at all on any process */
-    xmpi(MPI_Allreduce(MPI_IN_PLACE, streamIsWritten, numTotalStreamIDs,
+    xmpi(MPI_Allreduce(MPI_IN_PLACE, streamIsWritten, (int)numTotalStreamIDs,
                        MPI_INT, MPI_BOR, commInqCommColl()));
     /* append streams written to on other tasks to mapping */
-    for (int i = 0; i < numTotalStreamIDs; ++i)
+    for (unsigned i = 0; i < numTotalStreamIDs; ++i)
       if (streamIsWritten[i] && !streamIsInList(streamMap, numStreamIDs,
                                                 streamIDs[i]))
         numStreamIDs = inventorizeStream(streamMap, numStreamIDs,
@@ -1096,13 +1096,13 @@ void cdiPioServer(void (*postCommSetupActions)(void))
           if ( nfinished == nProcsModel )
             {
               {
-                int nStreams = streamSize ();
+                unsigned nStreams = reshCountType(&streamOps);
 
                 if ( nStreams > 0 )
                   {
-                    int * resHs = xmalloc((size_t)nStreams * sizeof (resHs[0]));
-                    streamGetIndexList ( nStreams, resHs );
-                    for (int streamNo = 0; streamNo < nStreams; ++streamNo)
+                    int *resHs = xmalloc(nStreams * sizeof (resHs[0]));
+                    cdiStreamGetIndexList(nStreams, resHs);
+                    for (unsigned streamNo = 0; streamNo < nStreams; ++streamNo)
                       streamClose(resHs[streamNo]);
                     free(resHs);
                   }
diff --git a/libcdi/src/pio_util.c b/libcdi/src/pio_util.c
index 16f8870..07ae4dd 100644
--- a/libcdi/src/pio_util.c
+++ b/libcdi/src/pio_util.c
@@ -66,7 +66,7 @@ void pcdiXMPI(int iret, const char *filename, int line)
           "errorString: \"%s\"\n",
           rank, filename, line,
           errorString[0], errorString[1]);
-  MPI_Abort(MPI_COMM_WORLD, iret);
+  MPI_Abort(MPI_COMM_WORLD, 1);
 }
 
 /*****************************************************************************/
diff --git a/libcdi/src/proprietarySystemWorkarounds.c b/libcdi/src/proprietarySystemWorkarounds.c
new file mode 100644
index 0000000..3c3f741
--- /dev/null
+++ b/libcdi/src/proprietarySystemWorkarounds.c
@@ -0,0 +1,45 @@
+#include "proprietarySystemWorkarounds.h"
+#include "dmemory.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+char* myStrDup(const char* string)
+{
+  char* result = xmalloc(strlen(string) + 1);
+  if(result)
+    {
+      strcpy(result, string);
+    }
+  else
+    {
+      errno = ENOMEM;
+    }
+  return result;
+}
+
+char* myAsprintf(char* format, ...)
+{
+  va_list args;
+  int size = 64;
+  char *buffer = xmalloc(size);
+  int nchars;
+  //Try to print in the allocated space.
+  va_start(args, format);
+  nchars = vsnprintf(buffer, size, format, args);
+  va_end(args);
+  if (nchars >= size)
+    {
+      //Reallocate buffer now that we know how much space is needed.
+      size = nchars + 1;
+      buffer = xrealloc(buffer, size);
+      va_start(args, format);
+      vsnprintf(buffer, size, format, args);
+      va_end(args);
+    }
+  return buffer;
+}
+
diff --git a/libcdi/src/proprietarySystemWorkarounds.h b/libcdi/src/proprietarySystemWorkarounds.h
new file mode 100644
index 0000000..ee3151e
--- /dev/null
+++ b/libcdi/src/proprietarySystemWorkarounds.h
@@ -0,0 +1,8 @@
+#ifndef INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
+#define INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
+
+char* myStrDup(const char* string);      //This exactly implements the standardized behavior of strdup().
+
+char* myAsprintf(char* format, ...) __attribute__((format(printf, 1, 2)));       //This implementation differs from standard asprintf() function in the way the resulting string pointer is returned.
+
+#endif
diff --git a/libcdi/src/referenceCounting.c b/libcdi/src/referenceCounting.c
new file mode 100644
index 0000000..3b5172f
--- /dev/null
+++ b/libcdi/src/referenceCounting.c
@@ -0,0 +1,28 @@
+#include "referenceCounting.h"
+
+#include "error.h"
+
+void cdiRefObject_construct(CdiReferencedObject* me)
+{
+  me->destructor = cdiRefObject_destruct;
+  me->refCount = 1;
+}
+
+void cdiRefObject_retain(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount++;
+  xassert(oldCount && "A reference counted object was used after it was destructed.");
+}
+
+void cdiRefObject_release(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount--;
+  xassert(oldCount && "A reference counted object was released too often.");
+  if(oldCount == 1)
+    {
+      me->destructor(me);
+      free(me);
+    }
+}
+
+void cdiRefObject_destruct(CdiReferencedObject* me) { /* Empty for now, but that's no reason not to call it! */ }
diff --git a/libcdi/src/referenceCounting.h b/libcdi/src/referenceCounting.h
new file mode 100644
index 0000000..6df196c
--- /dev/null
+++ b/libcdi/src/referenceCounting.h
@@ -0,0 +1,38 @@
+#ifndef INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+#define INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+
+#include "error.h"
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+/*
+This is a base class for all objects that need reference counting.
+A CdiReferencedObject has a reference count of one when it is constructed, refObjectRetain() increments the reference count, refObject Release() decrements it.
+When the reference count reaches zero, the destructor function is called before the memory of the object is deallocated with free().
+
+>>> Warning <<<
+This code is currently not thread-safe.
+
+We are currently using the C99 standard, which does not have atomic types.
+Also, there are still tons of systems out there that have a gcc without wrong C11 atomics support
+(__STDC_NO_ATOMICS__ not defined even though stdatomics.h is not even present).
+Consequently, it is impossible to write preprocessor code to even check for the presence of atomic types.
+So, we have two options: provide multithreading support by means of locks, or wait a year or two before doing this right.
+I, for one, prefer doing things right.
+*/
+typedef struct CdiReferencedObject CdiReferencedObject;
+struct CdiReferencedObject {
+  //protected:
+    void (*destructor)(CdiReferencedObject* me);  //Subclass constructors should set this to their own destructor.
+
+  //private:    //Subclasses may read it to determine whether there is only one reference, though.
+    size_t refCount;
+};
+
+void cdiRefObject_construct(CdiReferencedObject* me);
+void cdiRefObject_retain(CdiReferencedObject* me);
+void cdiRefObject_release(CdiReferencedObject* me);
+void cdiRefObject_destruct(CdiReferencedObject* me);
+
+#endif
diff --git a/libcdi/src/resource_handle.c b/libcdi/src/resource_handle.c
index 2ab1d45..5c6cfdd 100644
--- a/libcdi/src/resource_handle.c
+++ b/libcdi/src/resource_handle.c
@@ -431,19 +431,17 @@ void *reshGetValue(const char * caller, const char* expressionString, cdiResH re
 
 /**************************************************************/
 
-void reshGetResHListOfType ( int c, int * resHs, const resOps * ops )
+void reshGetResHListOfType(unsigned numIDs, int resHs[numIDs], const resOps *ops)
 {
-  int i, j = 0, nsp;
-
   xassert ( resHs && ops );
 
   LIST_INIT(1);
 
   LIST_LOCK();
 
-  nsp = namespaceGetActive ();
-
-  for ( i = 0; i < resHList[nsp].size && j < c; i++ )
+  int nsp = namespaceGetActive();
+  unsigned j = 0;
+  for (int i = 0; i < resHList[nsp].size && j < numIDs; i++ )
     if ((resHList[nsp].resources[i].status & RESH_IN_USE_BIT)
         && resHList[nsp].resources[i].res.v.ops == ops)
       resHs[j++] = namespaceIdxEncode2(nsp, i);
@@ -500,20 +498,21 @@ cdiResHFilterApply(const resOps *p,
 
 /**************************************************************/
 
-int reshCountType ( const resOps * ops )
+unsigned reshCountType(const resOps *ops)
 {
-  int i, nsp, countType = 0;
+  unsigned countType = 0;
 
-  xassert ( ops );
+  xassert(ops);
 
   LIST_INIT(1);
 
   LIST_LOCK();
 
-  nsp = namespaceGetActive ();
+  int nsp = namespaceGetActive ();
 
   listElem_t *r = resHList[nsp].resources;
-  for ( i = 0; i < resHList[nsp].size; i++ )
+  size_t len = (size_t)resHList[nsp].size;
+  for (size_t i = 0; i < len; i++ )
     countType += ((r[i].status & RESH_IN_USE_BIT) && r[i].res.v.ops == ops);
 
   LIST_UNLOCK();
@@ -658,10 +657,10 @@ void reshSetStatus ( cdiResH resH, const resOps * ops, int status )
             nspT.idx >= 0 &&
             nspT.idx < resHList[nsp].size );
 
+  xassert ( resHList[nsp].resources );
   listElem = resHList[nsp].resources + nspT.idx;
 
-  xassert ( listElem &&
-            listElem->res.v.ops == ops );
+  xassert ( listElem->res.v.ops == ops );
 
   listElem->status = status;
 
diff --git a/libcdi/src/resource_handle.h b/libcdi/src/resource_handle.h
index aad9a0c..b2c376d 100644
--- a/libcdi/src/resource_handle.h
+++ b/libcdi/src/resource_handle.h
@@ -57,13 +57,13 @@ void   reshRemove ( cdiResH, const resOps * );
 /*> doesn't check resource type */
 void reshDestroy(cdiResH);
 
-int    reshCountType ( const resOps * );
+unsigned reshCountType(const resOps *resTypeOps);
 
 void * reshGetValue(const char* caller, const char* expressionString, cdiResH id, const resOps* ops);
 #define reshGetVal(resH, ops)  reshGetValue(__func__, #resH, resH, ops)
 
 
-void   reshGetResHListOfType ( int, int *, const resOps * );
+void reshGetResHListOfType(unsigned numIDs, int IDs[numIDs], const resOps *ops);
 
 enum cdiApplyRet {
   CDI_APPLY_ERROR = -1,
diff --git a/libcdi/src/serialize.h b/libcdi/src/serialize.h
index a24589f..71de8ad 100644
--- a/libcdi/src/serialize.h
+++ b/libcdi/src/serialize.h
@@ -8,8 +8,12 @@
 #include <string.h>
 
 #include "cdi.h"
+#ifndef  CDI_CKSUM_H_
 #include "cdi_cksum.h"
+#endif
+#ifndef  _ERROR_H
 #include "error.h"
+#endif
 
 /*
  * Generic interfaces for (de-)marshalling
diff --git a/libcdi/src/servicelib.c b/libcdi/src/servicelib.c
index 56df92e..a632f7a 100644
--- a/libcdi/src/servicelib.c
+++ b/libcdi/src/servicelib.c
@@ -2,6 +2,8 @@
 #  include "config.h"
 #endif
 
+#ifdef HAVE_LIBSERVICE
+
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
@@ -609,3 +611,4 @@ void srvWrite(int fileID, srvrec_t *srvp)
  * require-trailing-newline: t
  * End:
  */
+#endif  /* HAVE_LIBSERVICE */
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index 356b443..79931f3 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -308,11 +308,14 @@ int streamInqByteorder(int streamID)
 }
 
 
-char *streamFilesuffix(int filetype)
+const char *streamFilesuffix(int filetype)
 {
   // static char *fileSuffix[] = {"", ".grb", ".g2", ".nc", ".nc", ".nc4", ".nc4", ".srv", ".ext", ".ieg"};
-  static char *fileSuffix[] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
-  int size = (int) (sizeof(fileSuffix)/sizeof(char *));
+  /* note: the 2nd dimenstion of the fileSuffix array must be equal to or
+   * larger than the length of the longest suffix (dot and \0 terminator
+   * included) */
+  static const char fileSuffix[][5] = {"", ".grb", ".grb", ".nc", ".nc", ".nc", ".nc", ".srv", ".ext", ".ieg"};
+  int size = (int)(sizeof(fileSuffix)/sizeof(fileSuffix[0]));
 
   if ( filetype > 0 && filetype < size )
     return (fileSuffix[filetype]);
@@ -321,7 +324,7 @@ char *streamFilesuffix(int filetype)
 }
 
 
-char *streamFilename(int streamID)
+const char *streamFilename(int streamID)
 {
   stream_t *streamptr = stream_to_pointer(streamID);
 
@@ -2171,9 +2174,9 @@ void cdiStreamSetupVlist(stream_t *streamptr, int vlistID, int vlistIDorig)
 }
 
 
-void streamGetIndexList ( int nstreams, int * streamIndexList )
+void cdiStreamGetIndexList(unsigned numIDs, int IDs[numIDs])
 {
-  reshGetResHListOfType ( nstreams, streamIndexList, &streamOps );
+  reshGetResHListOfType(numIDs, IDs, &streamOps);
 }
 
 int streamInqNvars ( int streamID )
@@ -2276,7 +2279,6 @@ void streamPrintP   ( void * streamptr, FILE * fp )
   fprintf ( fp, "vlistIDorig   = %d\n", sp->vlistIDorig );
 }
 
-
 enum {
   streamNint = 11,
 };
diff --git a/libcdi/src/stream_cdf.c b/libcdi/src/stream_cdf.c
index ed7d7f3..5b98b3f 100644
--- a/libcdi/src/stream_cdf.c
+++ b/libcdi/src/stream_cdf.c
@@ -208,20 +208,29 @@ int isTimeAxisUnits(const char *timeunits)
 static
 void scanTimeString(const char *ptu, int *rdate, int *rtime)
 {
-  int year, month, day;
+  int year = 1, month = 1, day = 1;
   int hour = 0, minute = 0, second = 0;
-  int v1, v2, v3;
+  int v1 = 1, v2 = 1, v3 = 1;
 
   *rdate = 0;
   *rtime = 0;
 
-  v1 = atoi(ptu);
-  if ( v1 < 0 ) ptu++;
-  while ( isdigit((int) *ptu) ) ptu++;
-  v2 = atoi(++ptu);
-  while ( isdigit((int) *ptu) ) ptu++;
-  v3 = atoi(++ptu);
-  while ( isdigit((int) *ptu) ) ptu++;
+  if ( *ptu )
+    {
+      v1 = atoi(ptu);
+      if ( v1 < 0 ) ptu++;
+      while ( isdigit((int) *ptu) ) ptu++;
+      if ( *ptu )
+        {
+          v2 = atoi(++ptu);
+          while ( isdigit((int) *ptu) ) ptu++;
+          if ( *ptu )
+            {
+              v3 = atoi(++ptu);
+              while ( isdigit((int) *ptu) ) ptu++;
+            }
+        }
+    }
 
   if ( v3 > 999 && v1 < 32 )
     { year = v3; month = v2; day = v1; }
@@ -360,44 +369,60 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
 static
 void cdfGetAttInt(int fileID, int ncvarid, char *attname, int attlen, int *attint)
 {
+  nc_type atttype;
   size_t nc_attlen;
-  int *pintatt;
 
+  *attint = 0;
+
+  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
   cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  if ( (int)nc_attlen > attlen )
-    pintatt = (int *) malloc(nc_attlen * sizeof (int));
-  else
-    pintatt = attint;
+  if ( atttype != NC_CHAR )
+    {
+      int *pintatt = NULL;
+
+      if ( (int)nc_attlen > attlen )
+        pintatt = (int *) malloc(nc_attlen * sizeof (int));
+      else
+        pintatt = attint;
 
-  cdf_get_att_int(fileID, ncvarid, attname, pintatt);
+      cdf_get_att_int(fileID, ncvarid, attname, pintatt);
 
-  if ( (int)nc_attlen > attlen )
-    {
-      memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
-      free(pintatt);
+      if ( (int)nc_attlen > attlen )
+        {
+          memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
+          free(pintatt);
+        }
     }
 }
 
 static
 void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
 {
+  nc_type atttype;
   size_t nc_attlen;
-  double *pdoubleatt;
 
+  *attdouble = 0;
+
+  cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
   cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  if ( (int)nc_attlen > attlen )
-    pdoubleatt = (double *) malloc(nc_attlen * sizeof (double));
-  else
-    pdoubleatt = attdouble;
+  if ( atttype != NC_CHAR )
+    {
+      double *pdoubleatt = NULL;
+
+      if ( (int)nc_attlen > attlen )
+        pdoubleatt = (double *) malloc(nc_attlen * sizeof (double));
+      else
+        pdoubleatt = attdouble;
 
-  cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
+      cdf_get_att_double(fileID, ncvarid, attname, pdoubleatt);
 
-  if ( (int)nc_attlen > attlen )
-    {
-      memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
-      free(pdoubleatt);
+      if ( (int)nc_attlen > attlen )
+        {
+          memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
+          free(pdoubleatt);
+        }
     }
 }
 
@@ -417,9 +442,9 @@ void cdfGetAttText(int fileID, int ncvarid, char *attname, int attlen, char *att
         {
           cdf_get_att_text(fileID, ncvarid, attname, attbuf);
 
-          attbuf[nc_attlen++] = 0;
+          if ( (int) nc_attlen > (attlen-1) ) nc_attlen = (size_t)(attlen-1);
 
-          if ( (int) nc_attlen > attlen ) nc_attlen = (size_t)attlen;
+          attbuf[nc_attlen++] = 0;
           memcpy(atttext, attbuf, nc_attlen);
         }
       else
@@ -599,13 +624,15 @@ void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
   free(attBuf);
 }
 
+
 void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int memtype  = MEMTYPE_DOUBLE;
   int vlistID1 = streamptr1->vlistID;
-  int tsID1    = streamptr1->curTsID;
-  int recID1   = streamptr1->tsteps[tsID1].curRecID;
-  int ivarID   = streamptr1->tsteps[tsID1].records[recID1].varID;
+  int tsID     = streamptr1->curTsID;
+  int vrecID   = streamptr1->tsteps[tsID].curRecID;
+  int recID    = streamptr1->tsteps[tsID].recIDs[vrecID];
+  int ivarID   = streamptr1->tsteps[tsID].records[recID].varID;
   int gridID   = vlistInqVarGrid(vlistID1, ivarID);
   int datasize = gridInqSize(gridID);
 
@@ -867,8 +894,8 @@ int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, char* taxis_n
 
   /* fprintf(stderr, "time has bounds\n"); */
 
-  if ( nc_inq_dimid(fileID, "nb2", &dims[1]) != NC_NOERR )
-    cdf_def_dim(fileID, "nb2", 2, &dims[1]);
+  if ( nc_inq_dimid(fileID, "bnds", &dims[1]) != NC_NOERR )
+    cdf_def_dim(fileID, "bnds", 2, &dims[1]);
 
   if ( taxis->climatology )
     {
@@ -1483,8 +1510,8 @@ void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
           if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
             {
               size_t nvertex = 2;
-              if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-                cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
+              if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+                cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
             }
         }
 
@@ -1613,8 +1640,8 @@ void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
           if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
             {
               size_t nvertex = 2;
-              if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-                cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
+              if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+                cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
             }
         }
 
@@ -1769,8 +1796,8 @@ void cdfDefCurvilinear(stream_t *streamptr, int gridID)
       if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
         {
           size_t nvertex = 4;
-          if ( nc_inq_dimid(fileID, "nv4", &nvdimID) != NC_NOERR )
-            cdf_def_dim(fileID, "nv4", nvertex, &nvdimID);
+          if ( nc_inq_dimid(fileID, "vertices", &nvdimID) != NC_NOERR )
+            cdf_def_dim(fileID, "vertices", nvertex, &nvdimID);
         }
 
       dimIDs[0] = ydimID;
@@ -1793,7 +1820,7 @@ void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 
           if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
             {
-              strcat(xaxisname, "_bnds");
+              strcat(xaxisname, "_vertices");
               dimIDs[0] = ydimID;
               dimIDs[1] = xdimID;
               dimIDs[2] = nvdimID;
@@ -1821,7 +1848,7 @@ void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 
           if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
             {
-              strcat(yaxisname, "_bnds");
+              strcat(yaxisname, "_vertices");
               dimIDs[0] = ydimID;
               dimIDs[1] = xdimID;
               dimIDs[2] = nvdimID;
@@ -2144,7 +2171,7 @@ void cdfDefUnstructured(stream_t *streamptr, int gridID)
       char axisname[CDI_MAX_NAME];
       char vertname[CDI_MAX_NAME];
       strcpy(axisname, "ncells");
-      strcpy(vertname, "nv");
+      strcpy(vertname, "vertices");
 
       checkGridName('V', xaxisname, fileID, vlistID, gridID, ngrids, 'X');
       checkGridName('V', yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
@@ -2549,8 +2576,8 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
 	  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
             {
               size_t nvertex = 2;
-	      if ( nc_inq_dimid(fileID, "nb2", &nvdimID) != NC_NOERR )
-		cdf_def_dim(fileID, "nb2", nvertex, &nvdimID);
+	      if ( nc_inq_dimid(fileID, "bnds", &nvdimID) != NC_NOERR )
+		cdf_def_dim(fileID, "bnds", nvertex, &nvdimID);
 
 	      if ( nvdimID != UNDEFID )
 		{
@@ -2622,7 +2649,7 @@ void cdfDefPole(stream_t *streamptr, int gridID)
       cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", strlen(mapname), mapname);
       cdf_put_att_double(fileID, ncvarid, "grid_north_pole_latitude", NC_DOUBLE, 1, &ypole);
       cdf_put_att_double(fileID, ncvarid, "grid_north_pole_longitude", NC_DOUBLE, 1, &xpole);
-      if ( angle > 0 )
+      if ( IS_NOT_EQUAL(angle, 0) )
         cdf_put_att_double(fileID, ncvarid, "north_pole_grid_longitude", NC_DOUBLE, 1, &angle);
     }
 
@@ -3383,12 +3410,11 @@ size_t cdfDoInputDataTransformationDP(size_t valueCount, double *data, bool have
   const bool haveOffset   = IS_NOT_EQUAL(offset, 0);
   const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
   size_t missValCount = 0;
-  if (validMin == VALIDMISS)
-    validMin = DBL_MIN;
-  if (validMax == VALIDMISS)
-    validMax = DBL_MAX;
 
-  bool haveRangeCheck = (validMax != DBL_MAX) | (validMin != DBL_MIN);
+  if ( IS_EQUAL(validMin, VALIDMISS) ) validMin = DBL_MIN;
+  if ( IS_EQUAL(validMax, VALIDMISS) ) validMax = DBL_MAX;
+
+  bool haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin,DBL_MIN));
   assert(!haveRangeCheck || haveMissVal);
 
   switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
@@ -3482,12 +3508,10 @@ size_t cdfDoInputDataTransformationSP(size_t valueCount, float *data, bool haveM
   const bool haveScaleFactor = IS_NOT_EQUAL(scaleFactor, 1);
   size_t missValCount = 0;
 
-  if (validMin == VALIDMISS)
-    validMin = DBL_MIN;
-  if (validMax == VALIDMISS)
-    validMax = DBL_MAX;
+  if ( IS_EQUAL(validMin, VALIDMISS) ) validMin = DBL_MIN;
+  if ( IS_EQUAL(validMax, VALIDMISS) ) validMax = DBL_MAX;
 
-  bool haveRangeCheck = (validMax != DBL_MAX) | (validMin != DBL_MIN);
+  bool haveRangeCheck = (IS_NOT_EQUAL(validMax, DBL_MAX)) | (IS_NOT_EQUAL(validMin,DBL_MIN));
   assert(!haveRangeCheck || haveMissVal);
 
   switch ((int)haveMissVal | ((int)haveScaleFactor << 1)
@@ -4442,37 +4466,37 @@ static
 void cdfCreateRecords(stream_t *streamptr, int tsID)
 {
   int varID, levelID, recID, vrecID, zaxisID;
-  int nvars, nlev, nrecs, nvrecs;
-  record_t *records = NULL;
-  int *recIDs = NULL;
-  int vlistID;
+  int nlev, nvrecs;
 
-  vlistID  = streamptr->vlistID;
+  int vlistID  = streamptr->vlistID;
 
   if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
 
   if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
 
+  tsteps_t* sourceTstep = streamptr->tsteps;
+  tsteps_t* destTstep = sourceTstep + tsID;
+
+  int nvars = vlistNvars(vlistID);
+  int nrecs = vlistNrecs(vlistID);
+
+  if ( nrecs <= 0 ) return;
+
   if ( tsID == 0 )
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
+      nvrecs = nrecs; /* use all records at first timestep */
 
       streamptr->nrecs += nrecs;
 
-      if ( nrecs > 0 )
-        records = (record_t *)xmalloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+      destTstep->records    = (record_t *)xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
+      destTstep->recIDs     = (int *)xmalloc((size_t)nvrecs*sizeof (int));;
+      for ( recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
 
-      nvrecs = nrecs; /* use all records at first timestep */
-      if ( nvrecs > 0 ) recIDs = (int *)xmalloc((size_t)nvrecs * sizeof (int));
-      streamptr->tsteps[tsID].recIDs     = recIDs;
-      for ( recID = 0; recID < nvrecs; recID++ )
-        recIDs[recID] = recID;
+      record_t *records = destTstep->records;
 
       recID = 0;
       for ( varID = 0; varID < nvars; varID++ )
@@ -4490,9 +4514,6 @@ void cdfCreateRecords(stream_t *streamptr, int tsID)
     }
   else if ( tsID == 1 )
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
-
       nvrecs = 0;
       for ( varID = 0; varID < nvars; varID++ )
         {
@@ -4505,58 +4526,47 @@ void cdfCreateRecords(stream_t *streamptr, int tsID)
 
       streamptr->nrecs += nvrecs;
 
-      records = (record_t *) malloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nvrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+      destTstep->records    = (record_t *) xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
 
-      memcpy(streamptr->tsteps[tsID].records,
-             streamptr->tsteps[0].records,
-             (size_t)nrecs * sizeof (record_t));
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
 
       if ( nvrecs )
         {
-          recIDs = (int *) malloc((size_t)nvrecs * sizeof (int));
-          streamptr->tsteps[tsID].recIDs     = recIDs;
+          destTstep->recIDs = (int *) xmalloc((size_t)nvrecs * sizeof (int));
           vrecID = 0;
           for ( recID = 0; recID < nrecs; recID++ )
             {
-              varID = records[recID].varID;
+              varID = destTstep->records[recID].varID;
               if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
                 {
-                  recIDs[vrecID++] = recID;
+                  destTstep->recIDs[vrecID++] = recID;
                 }
             }
         }
     }
   else
     {
-      nvars = vlistNvars(vlistID);
-      nrecs = vlistNrecs(vlistID);
+      if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
 
       nvrecs = streamptr->tsteps[1].nrecs;
 
       streamptr->nrecs += nvrecs;
 
-      records = (record_t *)xmalloc((size_t)nrecs * sizeof (record_t));
-      streamptr->tsteps[tsID].records    = records;
-      streamptr->tsteps[tsID].nrecs      = nvrecs;
-      streamptr->tsteps[tsID].nallrecs   = nrecs;
-      streamptr->tsteps[tsID].recordSize = nrecs;
-      streamptr->tsteps[tsID].curRecID   = UNDEFID;
+      destTstep->records    = (record_t *) xmalloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
 
-      memcpy(streamptr->tsteps[tsID].records,
-             streamptr->tsteps[0].records,
-             (size_t)nrecs * sizeof (record_t));
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
 
-      recIDs = (int *) malloc((size_t)nvrecs * sizeof(int));
-      streamptr->tsteps[tsID].recIDs     = recIDs;
+      destTstep->recIDs     = (int *) xmalloc((size_t)nvrecs * sizeof(int));
 
-      memcpy(streamptr->tsteps[tsID].recIDs,
-             streamptr->tsteps[1].recIDs,
-             (size_t)nvrecs * sizeof (int));
+      memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
     }
 }
 
@@ -4780,6 +4790,12 @@ int isDBLAxis(/*const char *units,*/ const char *longname)
 }
 
 static
+int unitsIsMeter(const char *units)
+{
+  return (*units == 'm' && (strcmp(units, "m") == 0 || strncmp(units, "meter", 5) == 0));
+}
+
+static
 int isDepthAxis(const char *stdname, const char *longname)
 {
   int status = FALSE;
@@ -4955,20 +4971,23 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                           int timedimid, int modelID, int format)
 {
   int ncid;
-  int ncvarid;
   int ncdimid;
   int nvdims, nvatts;
   int *dimidsp;
+  int iatt;
+  int i;
+  int tablenum;
   nc_type xtype, atttype;
   size_t attlen;
   char name[CDI_MAX_NAME];
   char attname[CDI_MAX_NAME];
   const int attstringlen = 8192; char attstring[8192];
-  int iatt;
-  int i;
-  int tablenum;
 
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  int nchecked_vars = 0;
+  char *checked_vars[9];
+  for ( i = 0; i < 9; ++i ) checked_vars[i] = NULL;
+
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
       ncid    = ncvars[ncvarid].ncid;
       dimidsp = ncvars[ncvarid].dimids;
@@ -5000,7 +5019,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                   for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = (int)chunks[i];
                   if ( CDI_Debug )
                     {
-                      fprintf(stderr, "\nchunking %d %d %d\nchunks ", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
+                      fprintf(stderr, "%s: chunking %d %d %d  chunks ", name, storage_in, NC_CONTIGUOUS, NC_CHUNKED);
                       for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
                       fprintf(stderr, "\n");
                     }
@@ -5087,13 +5106,13 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "trunc_type") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               if ( memcmp(attstring, "Triangular", attlen) == 0 )
                 ncvars[ncvarid].gridtype = GRID_SPECTRAL;
             }
           else if ( strcmp(attname, "grid_type") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               strtolower(attstring);
 
               if      ( strcmp(attstring, "gaussian reduced") == 0 )
@@ -5136,7 +5155,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "level_type") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               strtolower(attstring);
 
               if      ( strcmp(attstring, "toa") == 0 )
@@ -5209,7 +5228,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               int status, ncboundsid;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 
               status = nc_inq_varid(ncid, attstring, &ncboundsid);
 
@@ -5227,7 +5246,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               int status, ncboundsid;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 
               status = nc_inq_varid(ncid, attstring, &ncboundsid);
 
@@ -5244,7 +5263,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               char *pstring, *cell_measures = NULL, *cell_var = NULL;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               pstring = attstring;
 
               while ( isspace((int) *pstring) ) pstring++;
@@ -5285,7 +5304,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               char *pstring, *xvarname = NULL, *yvarname = NULL;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               pstring = attstring;
 
               while ( isspace((int) *pstring) ) pstring++;
@@ -5313,7 +5332,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
               int dimvarid;
               extern int cdiIgnoreAttCoordinates;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               pstring = attstring;
 
               for ( i = 0; i < MAX_COORDVARS; i++ )
@@ -5336,7 +5355,17 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                         }
                     }
                   else
-                    Warning("%s - %s", nc_strerror(status), varname);
+                    {
+                      int k;
+                      for ( k = 0; k < nchecked_vars; ++k )
+                        if ( strcmp(checked_vars[k], varname) == 0 ) break;
+
+                      if ( k == nchecked_vars )
+                        {
+                          if ( nchecked_vars < 9 ) checked_vars[nchecked_vars++] = strdup(varname);
+                          Warning("%s - %s", nc_strerror(status), varname);
+                        }
+                    }
 
                   if ( lstop ) break;
                 }
@@ -5351,7 +5380,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
               int dimvarid;
               extern int cdiIgnoreAttCoordinates;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               pstring = attstring;
 
               for ( i = 0; i < MAX_AUXVARS; i++ )
@@ -5386,7 +5415,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
               int status;
               int nc_gmap_id;
 
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 
               status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
               if ( status == NC_NOERR )
@@ -5401,7 +5430,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "positive") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               strtolower(attstring);
 
               if    ( memcmp(attstring, "down", 4) == 0 ) ncvars[ncvarid].positive = POSITIVE_DOWN;
@@ -5485,7 +5514,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "_Unsigned") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
               strtolower(attstring);
 
               if ( memcmp(attstring, "true", 4) == 0 )
@@ -5501,7 +5530,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "cdi") == 0 && xtypeIsText(atttype) )
             {
-	      cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+	      cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 	      strtolower(attstring);
 
 	      if ( memcmp(attstring, "ignore", 6) == 0 )
@@ -5512,7 +5541,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             }
           else if ( strcmp(attname, "axis") == 0 && xtypeIsText(atttype) )
             {
-              cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 	      attlen = strlen(attstring);
 
 	      if ( (int) attlen > nvdims )
@@ -5624,7 +5653,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 		}
 	      else if ( attrtype == NC_CHAR )
 		{
-		  cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+		  cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 		  attstring[attlen] = 0;
 		  printf("txt: %s.%s = %s\n", ncvars[ncvarid].name, attname, attstring);
 		}
@@ -5634,6 +5663,8 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 	    }
 	}
     }
+
+  for ( i = 0; i < 9; ++i ) if ( checked_vars[i] ) free(checked_vars[i]);
 }
 
 static
@@ -5765,7 +5796,7 @@ void verify_coordinate_vars_1(int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int t
                 {
                   ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
 		}
-	      else if ( strcmp(ncvars[ncvarid].units, "m")   == 0 )
+	      else if ( unitsIsMeter(ncvars[ncvarid].units) )
 		{
 		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
 		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
@@ -5852,7 +5883,7 @@ void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
                   ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
 		  continue;
 		}
-	      else if ( strcmp(ncvars[ncvarid].units, "m")   == 0 )
+	      else if ( unitsIsMeter(ncvars[ncvarid].units) )
 		{
 		  if ( isDepthAxis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
 		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
@@ -6414,7 +6445,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
                       };
                       char attstring[attstringlen];
 
-		      cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen-1, attstring);
+		      cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen, attstring);
 		      strtolower(attstring);
 
 		      if ( strcmp(attstring, "rotated_latitude_longitude") == 0 )
@@ -7010,7 +7041,7 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
 		}
 	      else if ( xtypeIsText(attrtype) )
 		{
-		  cdfGetAttText(ncid, ncvarid, attname, attstringlen-1, attstring);
+		  cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
 		  vlistDefAttTxt(vlistID, varID, attname, (int)attlen, attstring);
 		}
 	      else
@@ -7108,9 +7139,7 @@ void scan_global_attributes(int fileID, int vlistID, stream_t *streamptr, int ng
   nc_type xtype;
   size_t attlen;
   char attname[CDI_MAX_NAME];
-  enum {
-    attstringlen = 8192,
-  };
+  enum { attstringlen = 65636 };
   char attstring[attstringlen];
   int iatt;
 
@@ -7122,7 +7151,7 @@ void scan_global_attributes(int fileID, int vlistID, stream_t *streamptr, int ng
 
       if ( xtypeIsText(xtype) )
 	{
-	  cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen-1, attstring);
+	  cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen, attstring);
 
           size_t attstrlen = strlen(attstring);
 
@@ -7790,7 +7819,7 @@ int cdfInqContents(stream_t *streamptr)
         };
         char attstring[attstringlen];
 
-	cdfGetAttText(fileID, ncvarid, "calendar", attstringlen-1, attstring);
+	cdfGetAttText(fileID, ncvarid, "calendar", attstringlen, attstring);
 	strtolower(attstring);
 
 	if ( memcmp(attstring, "standard", 8)  == 0 ||
@@ -8033,7 +8062,6 @@ void cdfEndDef(stream_t *streamptr)
 static void cdfDefInstitut(stream_t *streamptr)
 {
   int fileID, instID;
-  char *longname;
   size_t len;
   int vlistID;
 
@@ -8043,7 +8071,7 @@ static void cdfDefInstitut(stream_t *streamptr)
 
   if ( instID != UNDEFID )
     {
-      longname = institutInqLongnamePtr(instID);
+      const char *longname = institutInqLongnamePtr(instID);
       if ( longname )
 	{
 	  len = strlen(longname);
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index 5e8dede..c8f2419 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -152,7 +152,7 @@ int cgribexGetTsteptype(int timerange)
 }
 
 static
-void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, int iret)
+void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
 {
   int compyinc = TRUE;
   int gridtype = cgribexGetGridType(isec2);
@@ -348,7 +348,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
       grid->isRotated = TRUE;
       grid->ypole     = - ISEC2_LatSP*0.001;
       grid->xpole     =   ISEC2_LonSP*0.001 - 180;
-      grid->angle     = 0;
+      grid->angle     = FSEC2_RotAngle;
     }
 
   grid->xvals = NULL;
@@ -385,7 +385,7 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
   record->ltype     = ISEC1_LevelType;
   record->tsteptype = tsteptype;
 
-  cgribexGetGrid(streamptr, isec2, isec4, &grid, iret);
+  cgribexGetGrid(streamptr, isec2, fsec2, isec4, &grid, iret);
 
   int gridID = varDefGrid(vlistID, &grid, 0);
 
@@ -1404,31 +1404,26 @@ static
 void cgribexDefParam(int *isec1, int param)
 {
   int pdis, pcat, pnum;
-  static bool lwarn_pdis = true, lwarn_pnum = true;
 
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
   if ( pnum < 0 ) pnum = -pnum;
 
-  if ( pdis != 255 )
+  static bool lwarn_pdis = true;
+  if ( pdis != 255 && lwarn_pdis )
     {
       char paramstr[32];
       cdiParamToString(param, paramstr, sizeof(paramstr));
-      if ( lwarn_pdis )
-        {
-          Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
-          lwarn_pdis = false;
-        }
+      Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
+      lwarn_pdis = false;
     }
 
-  if ( pnum > 255 )
+  static bool lwarn_pnum = true;
+  if ( pnum > 255 && lwarn_pnum )
     {
-      if ( lwarn_pnum )
-        {
-          Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
-          lwarn_pnum = false;
-          pnum = pnum%256;
-        }
+      Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
+      lwarn_pnum = false;
+      pnum = pnum%256;
     }
 
   ISEC1_CodeTable = pcat;
@@ -1602,7 +1597,7 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
 }
 
 static
-void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
+void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID)
 {
   int gridtype;
   bool lcurvi = false;
@@ -1765,6 +1760,7 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
 	  {
 	    ISEC2_LatSP = - (int)lround(gridInqYpole(gridID) * 1000);
 	    ISEC2_LonSP =   (int)lround((gridInqXpole(gridID) + 180) * 1000);
+            FSEC2_RotAngle = gridInqAngle(gridID);
 	  }
 
 	/* East -> West */
@@ -2199,7 +2195,7 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
 
   cgribexDefParam(isec1, param);
   cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
-  cgribexDefGrid(isec1, isec2, isec4, gridID);
+  cgribexDefGrid(isec1, isec2, fsec2, isec4, gridID);
   cgribexDefLevel(isec1, isec2, fsec2, zaxisID, levelID);
 
   cgribexDefEnsembleVar(isec1, vlistID, varID);
diff --git a/libcdi/src/stream_fcommon.h b/libcdi/src/stream_fcommon.h
index a4b12e7..2296e54 100644
--- a/libcdi/src/stream_fcommon.h
+++ b/libcdi/src/stream_fcommon.h
@@ -1,7 +1,9 @@
 #ifndef STREAM_FCOMMON_H
 #define STREAM_FCOMMON_H
 
+#ifndef  _CDI_INT_H
 #include "cdi_int.h"
+#endif
 
 enum {
   SINGLE_PRECISION = 4,
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index 1da92db..d479208 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -8,6 +8,8 @@
 #include "cdi.h"
 #include "cdi_int.h"
 #include "file.h"
+#include "gribapi_utilities.h"
+#include "stream_grb.h"
 #include "varscan.h"
 #include "datetime.h"
 #include "vlist.h"
@@ -18,7 +20,8 @@
 #if  defined  (HAVE_LIBGRIB_API)
 #  include "cgribex.h"      /* gribGetSize, gribRead, gribGetZip, GRIB1_LTYPE_99 */
 #  include "gribapi.h"
-#  include "grib_api.h"
+
+#  include <grib_api.h>
 #endif
 
 extern int cdiInventoryMode;
@@ -62,59 +65,6 @@ int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t*
 }
 
 static
-int gribapiGetGridType(grib_handle *gh)
-{
-  int gridtype = GRID_GENERIC;
-  int gribgridtype = -1;
-  long lpar;
-
-    {
-      int status;
-      status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
-
-      if ( status ==  0 ) gribgridtype = (int) lpar;
-
-      switch (gribgridtype)
-	{
-	case  GRIB2_GTYPE_LATLON:        { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG ) break;
-                                         }
-	case  GRIB2_GTYPE_LATLON_ROT:    { gridtype = GRID_LONLAT;    break; }
-	case  GRIB2_GTYPE_LCC:           { gridtype = GRID_LCC;       break; }
-	case  GRIB2_GTYPE_GAUSSIAN:      { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG )
-					     gridtype = GRID_GAUSSIAN_REDUCED;
-					   else
-					     gridtype = GRID_GAUSSIAN;
-				  	   break;
-                                         }
-	case  GRIB2_GTYPE_SPECTRAL:      { gridtype = GRID_SPECTRAL;  break; }
-	case  GRIB2_GTYPE_GME:           { gridtype = GRID_GME;       break; }
-	case  GRIB2_GTYPE_UNSTRUCTURED:  { gridtype = GRID_UNSTRUCTURED; break; }
-	}
-    }
-
-  return (gridtype);
-}
-
-static
-int gribapiGetIsRotated(grib_handle *gh)
-{
-  int isRotated = 0;
-  int gribgridtype = -1;
-  long lpar;
-  int status;
-
-  status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
-
-  if ( status ==  0 ) gribgridtype = (int) lpar;
-
-  if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
-
-  return (isRotated);
-}
-
-static
 int gribapiGetZaxisType(long editionNumber, int grib_ltype)
 {
   int zaxistype = ZAXIS_GENERIC;
@@ -210,71 +160,13 @@ int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
 }
 
 static
-int gribapiTimeIsFC(grib_handle *gh)
-{
-  long editionNumber;
-  int isFC = TRUE;
-
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-  if ( editionNumber > 1 )
-    {
-      long sigofrtime;
-
-      GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
-
-      if ( sigofrtime == 3 ) isFC = FALSE;
-    }
-
-  return (isFC);
-}
-
-static
-int gribapiGetTsteptype(grib_handle *gh)
-{
-  int tsteptype = TSTEP_INSTANT;
-  static int lprint = TRUE;
-
-  if ( gribapiTimeIsFC(gh) )
-    {
-      int status;
-      size_t len = 256;
-      char stepType[256];
-
-      status = grib_get_string(gh, "stepType", stepType, &len);
-      if ( status == 0 && len > 1 && len < 256 )
-	{
-	  if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
-	  else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
-	  else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
-	  else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
-	  else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
-	  else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
-	  else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
-	  else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
-	  else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
-	  else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
-	  else if ( lprint )
-	    {
-	      Message("Time stepType %s unsupported, set to instant!", stepType);
-	      lprint = FALSE;
-	    }
-
-	  // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
-	}
-    }
-
-  return (tsteptype);
-}
-
-static
 void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
 {
   long lpar;
 
   GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
   *datadate = (int) lpar;
-  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
+  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);  //FIXME: This looses the seconds in GRIB2 files.
   *datatime = (int) lpar*100;
 }
 
@@ -295,11 +187,8 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
   int status;
   long lpar;
   long sigofrtime = 3;
-  long editionNumber;
-
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-  if ( editionNumber > 1 )
+  if ( gribEditionNumber(gh) > 1 )
     {
       GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
     }
@@ -308,7 +197,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
       GRIB_CHECK(grib_get_long(gh, "timeRangeIndicator", &sigofrtime), 0);
     }
 
-  if ( sigofrtime == 3 )
+  if ( sigofrtime == 3 )        //XXX: This looks like a bug to me, because timeRangeIndicator == 3 does not seem to have the same meaning as significanceOfReferenceTime == 3. I would recommend replacing this condition with `if(!gribapiTimeIsFC())`.
     {
       gribapiGetDataDateTime(gh, vdate, vtime);
     }
@@ -377,330 +266,6 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 }
 
 static
-void gribapiGetGrid(grib_handle *gh, grid_t *grid)
-{
-  long editionNumber;
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-  int gridtype = gribapiGetGridType(gh);
-  /*
-  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      gridtype = GRID_GAUSSIAN;
-      ISEC2_NumLon = 2*ISEC2_NumLat;
-      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
-    }
-  */
-  memset(grid, 0, sizeof(grid_t));
-
-  size_t datasize;
-  GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
-  long numberOfPoints;
-  GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
-
-  switch (gridtype)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-      {
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlon = (int)lpar;
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
-
-	if ( gridtype == GRID_GAUSSIAN )
-          {
-            GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-            grid->np = (int)lpar;
-          }
-
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
-	grid->xinc  = 0;
-	grid->yinc  = 0;
-	grid->xdef  = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
-	if ( gridtype == GRID_LONLAT )
-	  GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &grid->yinc), 0);
-
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
-
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
-
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
-
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_GAUSSIAN_REDUCED:
-      {
-	size_t dummy;
-	long *pl;
-
-        long lpar;
-        GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-        grid->np = (int)lpar;
-
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size   = (int)numberOfPoints;
-
-        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
-        pl          = (long *) malloc((size_t)nlat * sizeof (long));
-	dummy       = (size_t)nlat;
-	GRIB_CHECK(grib_get_long_array(gh, "pl", pl, &dummy), 0);
-        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
-	for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
-	free(pl);
-
-	grid->ysize  = nlat;
-	grid->xinc   = 0;
-	grid->yinc   = 0;
-	grid->xdef   = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
-
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
-
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
-
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
-
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef  = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_LCC:
-      {
-	int nlon, nlat;
-        long lpar;
-
-	GRIB_CHECK(grib_get_long(gh, "Nx", &lpar), 0);
-	nlon = lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ny", &lpar), 0);
-	nlat = lpar;
-
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
-
-	grid->size  = numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
-
-	GRIB_CHECK(grib_get_double(gh, "DxInMetres", &grid->lcc_xinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "DyInMetres", &grid->lcc_yinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat), 0);
-	GRIB_CHECK(grib_get_double(gh, "LoVInDegrees", &grid->lcc_lonParY), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin1InDegrees", &grid->lcc_lat1), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin2InDegrees", &grid->lcc_lat2), 0);
-
-        if ( editionNumber <= 1 )
-          {
-            GRIB_CHECK(grib_get_long(gh, "projectionCenterFlag", &lpar), 0);
-            grid->lcc_projflag  = (int) lpar;
-            GRIB_CHECK(grib_get_long(gh, "scanningMode", &lpar), 0);
-            grid->lcc_scanflag  = (int) lpar;
-          }
-
-	grid->xdef   = 0;
-	grid->ydef   = 0;
-
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	size_t len = 256;
-	char typeOfPacking[256];
-	GRIB_CHECK(grib_get_string(gh, "packingType", typeOfPacking, &len), 0);
-	grid->lcomplex = 0;
-	if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
-
-        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
-	grid->size  = (int)datasize;
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "J", &lpar), 0);
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	grid->trunc = (int)lpar;
-
-	break;
-      }
-    case GRID_GME:
-      {
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-        long lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
-
-	break;
-      }
-    case GRID_UNSTRUCTURED:
-      {
-        unsigned char uuid[CDI_UUID_SIZE];
-    	/*
-        char reference_link[8192];
-        size_t len = sizeof(reference_link);
-        reference_link[0] = 0;
-         */
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-    	grid->size  = (int)numberOfPoints;
-        long lpar;
-        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-          {
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            grid->number   = (int)lpar;
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
-              grid->position = (int)lpar;
-            /*
-            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
-              {
-                if ( strncmp(reference_link, "file://", 7) == 0 )
-                  grid->reference = strdupx(reference_link);
-              }
-            */
-            size_t len = (size_t)CDI_UUID_SIZE;
-            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
-              {
-                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
-              }
-          }
-	break;
-      }
-    case GRID_GENERIC:
-      {
-	int nlon = 0, nlat = 0;
-        long lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-
-	if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
-	  {
-	    grid->xsize = nlon;
-	    grid->ysize = nlat;
-	  }
-	else
-	  {
-	    grid->xsize = 0;
-	    grid->ysize = 0;
-	  }
-
-	break;
-      }
-    default:
-      {
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-	break;
-      }
-    }
-
-  grid->isRotated = FALSE;
-  if ( gribapiGetIsRotated(gh) )
-    {
-      grid->isRotated = TRUE;
-      GRIB_CHECK(grib_get_double(gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole), 0);
-      GRIB_CHECK(grib_get_double(gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole), 0);
-      GRIB_CHECK(grib_get_double(gh, "angleOfRotation", &grid->angle), 0);
-      /* change from south to north pole */
-      grid->ypole = -grid->ypole;
-      grid->xpole =  grid->xpole - 180;
-    }
-
-  grid->xvals = NULL;
-  grid->yvals = NULL;
-  grid->type  = gridtype;
-}
-
-static
 void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
 {
   *leveltype = 0;
@@ -709,8 +274,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
   *level2    = 0;
 
   long lpar;
-  int status = grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar);
-  if ( status == 0 )
+  if(!grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar))       //1 byte
     {
       *leveltype = (int) lpar;
 
@@ -722,10 +286,17 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  { *lbounds = 1; break; }
 	}
 
-      if ( *lbounds == 0 )
+      if ( *lbounds )
+	{
+	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);  //1 byte
+	  *level1 = (int)lpar;
+	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);       //1 byte
+	  *level2 = (int)lpar;
+	}
+      else
 	{
           double dlevel;
-	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
+	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0); //2 byte
 	  if ( *leveltype == 100 ) dlevel *= 100;
 	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
 	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
@@ -733,33 +304,36 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  *level1 = (int) dlevel;
 	  *level2 = 0;
 	}
-      else
-	{
-	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);
-	  *level1 = (int)lpar;
-	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);
-	  *level2 = (int)lpar;
-	}
     }
 }
 
 static
 double grib2ScaleFactor(long factor)
 {
-  double scaleFactor = 0;
-
-  if      ( factor == 0 ) scaleFactor =    1;
-  else if ( factor == 1 ) scaleFactor =    0.1;
-  else if ( factor == 2 ) scaleFactor =    0.01;
-  else if ( factor == 3 ) scaleFactor =    0.001;
-  else if ( factor == 4 ) scaleFactor =    0.0001;
-  else if ( factor == 5 ) scaleFactor =    0.00001;
-  else if ( factor == 6 ) scaleFactor =    0.000001;
-  else if ( factor == 7 ) scaleFactor =    0.0000001;
-  else if ( factor == 8 ) scaleFactor =    0.00000001;
-  else if ( factor == 9 ) scaleFactor =    0.000000001;
-
-  return (scaleFactor);
+  switch(factor)
+    {
+      case GRIB_MISSING_LONG: return 1;
+      case 0: return 1;
+      case 1: return 0.1;
+      case 2: return 0.01;
+      case 3: return 0.001;
+      case 4: return 0.0001;
+      case 5: return 0.00001;
+      case 6: return 0.000001;
+      case 7: return 0.0000001;
+      case 8: return 0.00000001;
+      case 9: return 0.000000001;
+      default: return 0;
+    }
+}
+
+static
+int calcLevel(int level_sf, long factor, long level)
+{
+  double result = 0;
+  if(level != GRIB_MISSING_LONG) result = level*grib2ScaleFactor(factor);
+  if(level_sf) result *= level_sf;
+  return (int)result;
 }
 
 static
@@ -778,66 +352,66 @@ void grib2GetLevel(grib_handle *gh, int *leveltype1, int *leveltype2, int *lboun
   *level_sf   = 0;
   *level_unit = 0;
 
-  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
+  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar); //1 byte
   if ( status == 0 )
     {
       long llevel;
-      double dlevel1 = 0, dlevel2 = 0;
 
       *leveltype1 = (int) lpar;
 
-      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar);
+      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar); //1 byte
       /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
       if ( status == 0 ) *leveltype2 = (int)lpar;
 
       if ( *leveltype1 != 255 && *leveltype2 != 255 && *leveltype2 > 0 ) *lbounds = 1;
-      if ( *leveltype1 == GRIB2_LTYPE_REFERENCE && *leveltype2 == 1 ) *lbounds = 0;
-
-      if ( *leveltype1 == GRIB2_LTYPE_LANDDEPTH )
+      switch(*leveltype1)
         {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_M;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_ISOBARIC )
-        {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_PA;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_SIGMA )
-        {
-          *level_sf = 1000;
-          *level_unit = 0;
-        }
-
-      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);
-      if ( llevel != GRIB_MISSING_LONG )
-        {
-          if ( factor != GRIB_MISSING_LONG )
-            dlevel1 = (double)llevel * grib2ScaleFactor(factor);
-          else
-            dlevel1 = (double)llevel;
+          case GRIB2_LTYPE_REFERENCE:
+            if(*leveltype2 == 1) *lbounds = 0;
+            break;
+
+          case GRIB2_LTYPE_LANDDEPTH:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_M;
+            break;
+
+          case GRIB2_LTYPE_ISOBARIC:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_PA;
+            break;
+
+          case GRIB2_LTYPE_SIGMA:
+            *level_sf = 1000;
+            *level_unit = 0;
+            break;
         }
 
-      if ( *level_sf != 0 ) dlevel1 *= (double)(*level_sf);
+      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);      //1 byte
+      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);      //4 byte
+      *level1 = calcLevel(*level_sf, factor, llevel);
 
-      if ( *lbounds == 1 )
-	{
-          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
-          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0);
-          if ( llevel != GRIB_MISSING_LONG )
-            {
-              if ( factor != GRIB_MISSING_LONG )
-                dlevel2 = (double)llevel * grib2ScaleFactor(factor);
-              else
-                dlevel2 = (double)llevel;
-            }
-
-          if ( *level_sf != 0 ) dlevel2 *= (*level_sf);
+      if ( *lbounds )
+        {
+          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0); //1 byte
+          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0); //4 byte
+          *level2 = calcLevel(*level_sf, factor, llevel);
         }
+    }
+}
 
-      *level1 = (int) dlevel1;
-      *level2 = (int) dlevel2;
+static
+void gribGetLevel(grib_handle *gh, int* leveltype1, int* leveltype2, int* lbounds, int* level1, int* level2, int* level_sf, int* level_unit)
+{
+  if ( gribEditionNumber(gh) <= 1 )
+    {
+      grib1GetLevel(gh, leveltype1, lbounds, level1, level2);
+      *leveltype2 = -1;
+      *level_sf = 0;
+      *level_unit = 0;
+    }
+  else
+    {
+      grib2GetLevel(gh, leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
     }
 }
 
@@ -854,10 +428,9 @@ void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t len
 #if  defined  (HAVE_LIBGRIB_API)
 static
 void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
-		      size_t recsize, off_t position, int datatype, int comptype, size_t len, const char *varname,
+                      size_t recsize, off_t position, int datatype, int comptype, const char *varname,
                       int leveltype1, int leveltype2, int lbounds, int level1, int level2, int level_sf, int level_unit)
 {
-  long editionNumber;
   int zaxistype;
   int gridID = CDI_UNDEFID, varID;
   int levelID = 0;
@@ -882,8 +455,6 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   // numavg  = ISEC1_AvgNum;
   numavg  = 0;
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
   // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
 
   (*record).size      = recsize;
@@ -893,13 +464,24 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   (*record).ilevel2   = level2;
   (*record).ltype     = leveltype1;
   (*record).tsteptype = tsteptype;
-  memcpy((*record).varname, varname, len);
+
+  //FIXME: This may leave the variable name unterminated (which is the behavior that I found in the code).
+  //       I don't know precisely how this field is used, so I did not change this behavior to avoid regressions,
+  //       but I think that it would be better to at least add a line
+  //
+  //           record->varname[sizeof(record->varname) - 1] = 0;`
+  //
+  //       after the `strncpy()` call.
+  //
+  //       I would consider using strdup() (that requires POSIX-2008 compliance, though), or a similar homebrew approach.
+  //       I. e. kick the fixed size array and allocate enough space, whatever that may be.
+  strncpy(record->varname, varname, sizeof(record->varname));
 
   gribapiGetGrid(gh, &grid);
 
   gridID = varDefGrid(vlistID, &grid, 0);
 
-  zaxistype = gribapiGetZaxisType(editionNumber, leveltype1);
+  zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
 
   switch (zaxistype)
     {
@@ -1081,28 +663,6 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
 #endif
 
 static
-int gribapiGetParam(grib_handle *gh)
-{
-  int pdis = 0, pcat = 0, pnum = 0;
-  int param = 0;
-  int status;
-  long lpar;
-
-  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-  pdis = (int) lpar;
-
-  status = grib_get_long(gh, "parameterCategory", &lpar);
-  if ( status == 0 ) pcat = (int) lpar;
-
-  status = grib_get_long(gh, "parameterNumber", &lpar);
-  if ( status == 0 ) pnum = (int) lpar;
-
-  param = cdiEncodeParam(pnum, pcat, pdis);
-
-  return (param);
-}
-
-static
 compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype, char *name)
 {
   compvar2_t compVar;
@@ -1120,6 +680,7 @@ compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int t
 
   return (compVar);
 }
+#endif
 
 static
 int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
@@ -1144,10 +705,102 @@ int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
 
   return (rstatus);
 }
+
+static void ensureBufferSize(size_t requiredSize, size_t* curSize, unsigned char** buffer) {
+  if ( *curSize < requiredSize )
+    {
+      *curSize = requiredSize;
+      *buffer = realloc(*buffer, *curSize);
+    }
+}
+
+#if  defined  (HAVE_LIBGRIB_API)
+static
+grib_handle* gribapiGetDiskRepresentation(long recsize, size_t* buffersize, unsigned char** gribbuffer, int* outDatatype, int* outCompressionType, long* outUnzipsize)
+{
+  int lieee = FALSE;
+
+  grib_handle* gh = grib_handle_new_from_message(NULL, (void *) *gribbuffer, recsize);
+  if(gribEditionNumber(gh) > 1)
+    {
+      size_t len = 256;
+      char typeOfPacking[256];
+
+      if ( grib_get_string(gh, "packingType", typeOfPacking, &len) == 0 )
+        {
+          // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
+          if      ( strncmp(typeOfPacking, "grid_jpeg", len) == 0 ) *outCompressionType = COMPRESS_JPEG;
+          else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = COMPRESS_SZIP;
+          else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = TRUE;
+        }
+    }
+  else
+    {
+      if( gribGetZip(recsize, *gribbuffer, outUnzipsize) > 0 )
+        {
+          *outCompressionType = COMPRESS_SZIP;
+          ensureBufferSize(*outUnzipsize + 100, buffersize, gribbuffer);
+        }
+      else
+        {
+          *outCompressionType = COMPRESS_NONE;
+        }
+    }
+
+  if ( lieee )
+    {
+      *outDatatype = DATATYPE_FLT64;
+      long precision;
+      int status = grib_get_long(gh, "precision", &precision);
+      if ( status == 0 && precision == 1 ) *outDatatype = DATATYPE_FLT32;
+    }
+  else
+    {
+      *outDatatype = DATATYPE_PACK;
+      long bitsPerValue;
+      if ( grib_get_long(gh, "bitsPerValue", &bitsPerValue) == 0 )
+        {
+          if ( bitsPerValue > 0 && bitsPerValue <= 32 ) *outDatatype = (int)bitsPerValue;
+        }
+    }
+  return gh;
+}
 #endif
 
-#define gribWarning(text, nrecs, timestep, varname, paramstr, level1, level2) \
-            Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text)
+typedef enum { CHECKTIME_OK, CHECKTIME_SKIP, CHECKTIME_STOP, CHECKTIME_INCONSISTENT } checkTimeResult;
+static checkTimeResult checkTime(stream_t* streamptr, compvar2_t compVar, const DateTime* verificationTime, const DateTime* expectedVTime) {
+  //First determine whether the current record exists already.
+  int recID = 0;
+  for ( ; recID < streamptr->nrecs; recID++ )
+    {
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
+    }
+  int recordExists = recID < streamptr->nrecs;
+
+  //Then we need to know whether the verification time is consistent.
+  int consistentTime = !memcmp(verificationTime, expectedVTime, sizeof(*verificationTime));
+
+  //Finally, we make a decision.
+  if ( cdiInventoryMode == 1 )
+    {
+      if ( recordExists ) return CHECKTIME_STOP;
+      if ( !consistentTime ) return CHECKTIME_INCONSISTENT;
+    }
+  else
+    {
+      if ( !consistentTime ) return CHECKTIME_STOP;
+      if ( recordExists ) return CHECKTIME_SKIP;
+    }
+  return CHECKTIME_OK;
+}
+
+#define gribWarning(text, nrecs, timestep, varname, param, level1, level2) do \
+  { \
+    char paramstr[32]; \
+    cdiParamToString(param, paramstr, sizeof(paramstr)); \
+    Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text); \
+  } \
+while(0)
 
 int gribapiScanTimestep1(stream_t * streamptr)
 {
@@ -1155,236 +808,122 @@ int gribapiScanTimestep1(stream_t * streamptr)
   off_t recpos = 0;
   unsigned char *gribbuffer = NULL;
   size_t buffersize = 0;
-  int rstatus;
-  int status;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0;
-  int vdate = 0, vtime = 0;
-  int param = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  size_t readsize;
-  int nrecords, nrecs, recID;
-  int nrecs_scanned = 0;
-  int datatype;
-  size_t recsize = 0;
+  DateTime datetime0 = { .date = 10101, .time = 0 };
+  int nrecs_scanned = 0;        //Only used for debug output.
   int warn_time = TRUE;
   // int warn_numavg = TRUE;
-  int taxisID = -1;
   int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
-  taxis_t *taxis;
-  int vlistID;
-  int comptype;
-  long unzipsize;
-  compvar2_t compVar;
   grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  long editionNumber;
-  long lpar;
-  size_t len;
-  int bitsPerValue;
-  int lieee = FALSE;
-  int lbounds;
-  int level_sf, level_unit;
-  int tsteptype;
-  char paramstr[32];
-  char varname[256];
 
   streamptr->curTsID = 0;
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+  int tsID  = tstepsNewEntry(streamptr);
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamptr->fileID;
+  int fileID = streamptr->fileID;
 
-  nrecs = 0;
+  int nrecs = 0;
   while ( TRUE )
     {
-      level1 = 0;
-      level2 = 0;
-      recsize = (size_t)gribGetSize(fileID);
+      int level1 = 0, level2 = 0;
+      size_t recsize = (size_t)gribGetSize(fileID);
       recpos  = fileGetPos(fileID);
 
       if ( recsize == 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
+        {
+          streamptr->ntsteps = 1;
+          break;
+        }
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-      readsize = recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
+      size_t readsize = recsize;
+      int rstatus = gribRead(fileID, gribbuffer, &readsize);        //Search for next 'GRIB', read the following record, and position file offset after it.
       if ( rstatus ) break;
 
-      lieee = FALSE;
-
-      comptype = COMPRESS_NONE;
+      int datatype, comptype = 0;
+      long unzipsize;
+      gh = gribapiGetDiskRepresentation(recsize, &buffersize, &gribbuffer, &datatype, &comptype, &unzipsize);
 
       nrecs_scanned++;
-      gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-      if ( editionNumber <= 1 )
-	{
-          if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-            {
-              comptype = COMPRESS_SZIP;
-              unzipsize += 100;
-              if ( buffersize < (size_t)unzipsize )
-                {
-                  buffersize = (size_t)unzipsize;
-                  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-                }
-            }
-
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
-
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  size_t len = 256;
-	  char typeOfPacking[256];
-
-	  status = grib_get_string(gh, "packingType", typeOfPacking, &len);
-	  if ( status == 0 )
-	    {
-	      // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
-	      if      ( strncmp(typeOfPacking, "grid_jpeg", len)  == 0 ) comptype = COMPRESS_JPEG;
-	      else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) comptype = COMPRESS_SZIP;
-	      else if ( strncmp(typeOfPacking, "grid_ieee", len)  == 0 ) lieee = TRUE;
-	    }
-
-	  param = gribapiGetParam(gh);
-
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
-
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+      int param = gribapiGetParam(gh);
+      int leveltype1 = -1, leveltype2 = -1, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
+      char varname[256];
       varname[0] = 0;
       gribapiGetString(gh, "shortName", varname, sizeof(varname));
-      len = strlen(varname);
-      if ( len > 32 ) len = 32;
-      //printf("param = %s  name = %s   l1 = %d  l2 = %d\n", paramstr, varname, level1, level2);
 
-      tsteptype = gribapiGetTsteptype(gh);
+      int tsteptype = gribapiGetTsteptype(gh);
+      int vdate = 0, vtime = 0;
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
+      DateTime datetime = { .date = vdate, .time = vtime };
       /*
       printf("%d %d %d\n", vdate, vtime, leveltype1);
       */
-      if ( lieee )
+
+      if( datetime0.date == 10101 && datetime0.time == 0 )
         {
-          datatype = DATATYPE_FLT64;
-          status = grib_get_long(gh, "precision", &lpar);
-          if ( status == 0 && lpar == 1 ) datatype = DATATYPE_FLT32;
+          if( memcmp(&datetime, &datetime0, sizeof(datetime)) || !nrecs )       //Do we really need this condition? I have included it in order not to change the number of times gribapiGetDataDateTime() etc. get called. But if those are sideeffect-free, this condition should be removed.
+            {
+              datetime0 = datetime;
+
+              gribapiGetDataDateTime(gh, &rdate, &rtime);
+
+              fcast = gribapiTimeIsFC(gh);
+              if ( fcast ) tunit = gribapiGetTimeUnits(gh);
+            }
         }
-      else
+
+      if(nrecs)
         {
-          datatype = DATATYPE_PACK;
-          status = grib_get_long(gh, "bitsPerValue", &lpar);
-          if ( status == 0 )
+          checkTimeResult result = checkTime(streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname), &datetime, &datetime0);
+          if(result == CHECKTIME_STOP)
+            {
+              break;
+            }
+          else if(result == CHECKTIME_SKIP)
+            {
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              continue;
+            }
+          else if(result == CHECKTIME_INCONSISTENT && warn_time)
             {
-              bitsPerValue = (int) lpar;
-              if ( bitsPerValue > 0 && bitsPerValue <= 32 )
-                datatype = bitsPerValue;
+              gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              warn_time = FALSE;
             }
+          assert(result == CHECKTIME_OK || result == CHECKTIME_INCONSISTENT);
         }
-
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-
-          gribapiGetDataDateTime(gh, &rdate, &rtime);
-
-	  fcast = gribapiTimeIsFC(gh);
-	  if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-	}
-      else
-	{
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
-
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
-
-	  for ( recID = 0; recID < nrecs; recID++ )
-            if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
-
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      if ( recID < nrecs ) break;
-	      if ( warn_time )
-		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
-		  {
-                    if ( datetime0.date == 10101 && datetime0.time == 0 )
-                      {
-                        datetime0.date = datetime.date;
-                        datetime0.time = datetime.time;
-
-                        gribapiGetDataDateTime(gh, &rdate, &rtime);
-
-                        fcast = gribapiTimeIsFC(gh);
-                        if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-                      }
-                    else
-                      {
-                        gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-                        warn_time = FALSE;
-                      }
-                  }
-	    }
-	  else
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
-
-	      if ( recID < nrecs )
-		{
-		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-		  continue;
-		}
-	    }
-	}
       /*
       if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
-	    {
-	      Message("Change numavg from %d to %d not allowed!",
-		      taxis->numavg, ISEC1_AvgNum);
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
+        {
+          if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
+            {
+              Message("Change numavg from %d to %d not allowed!",
+                      taxis->numavg, ISEC1_AvgNum);
+              warn_numavg = FALSE;
+            }
+          else
+            {
+              taxis->numavg = ISEC1_AvgNum;
+            }
+        }
       */
       nrecs++;
 
       if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
                 nrecs, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
 
-      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
+      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, varname,
                        leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
 
       grib_handle_delete(gh);
@@ -1399,6 +938,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
   cdi_generate_vars(streamptr);
 
+  int taxisID = -1;
   if ( fcast )
     {
       taxisID = taxisCreate(TAXIS_RELATIVE);
@@ -1416,10 +956,10 @@ int gribapiScanTimestep1(stream_t * streamptr)
   taxis->vdate = (int)datetime0.date;
   taxis->vtime = (int)datetime0.time;
 
-  vlistID = streamptr->vlistID;
+  int vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  nrecords = streamptr->tsteps[0].nallrecs;
+  int nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
     {
       streamptr->tsteps[0].recordSize = nrecords;
@@ -1429,7 +969,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
   streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
+  for ( int recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[0].recIDs[recID] = recID;
 
   streamptr->record->buffer     = gribbuffer;
@@ -1439,7 +979,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
     {
       tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+        Error("Internal error. tsID = %d", tsID);
 
       streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
@@ -1448,13 +988,13 @@ int gribapiScanTimestep1(stream_t * streamptr)
   if ( streamptr->ntsteps == 1 )
     {
       if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
+        {
+          streamptr->ntsteps = 0;
+          for ( int varID = 0; varID < streamptr->nvars; varID++ )
+            {
+              vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+            }
+        }
     }
 #else
   (void)streamptr;
@@ -1473,53 +1013,32 @@ int gribapiScanTimestep2(stream_t * streamptr)
   unsigned char *gribbuffer = NULL;
   size_t buffersize = 0;
   int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
+  DateTime datetime0;
   // int gridID;
-  size_t readsize;
-  int nrecords, nrecs, recID, rindex;
-  int nrecs_scanned = 0;
-  size_t recsize = 0;
+  int recID;
   //  int warn_numavg = TRUE;
-  int tsteptype;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  long unzipsize;
-  compvar2_t compVar;
   grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
 
   streamptr->curTsID = 1;
 
   fileID  = streamptr->fileID;
-  vlistID = streamptr->vlistID;
-  taxisID = vlistInqTaxis(vlistID);
+  int vlistID = streamptr->vlistID;
+  int taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
   buffersize = streamptr->record->buffersize;
 
-  tsID = streamptr->rtsteps;
+  int tsID = streamptr->rtsteps;
   if ( tsID != 1 )
     Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
   cdi_create_records(streamptr, tsID);
 
-  nrecords = streamptr->tsteps[tsID].nallrecs;
+  int nrecords = streamptr->tsteps[tsID].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
@@ -1527,75 +1046,45 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
   for ( recID = 0; recID < nrecords; recID++ )
     {
-      varID = streamptr->tsteps[0].records[recID].varID;
       streamptr->tsteps[tsID].records[recID].position = streamptr->tsteps[0].records[recID].position;
       streamptr->tsteps[tsID].records[recID].size     = streamptr->tsteps[0].records[recID].size;
     }
 
-  nrecs_scanned = nrecords;
-  rindex = 0;
+  int nrecs_scanned = nrecords; //Only used for debug output
+  int rindex = 0;
   while ( TRUE )
     {
       if ( rindex > nrecords ) break;
 
-      recsize = (size_t)gribGetSize(fileID);
+      size_t recsize = (size_t)gribGetSize(fileID);
       recpos  = fileGetPos(fileID);
       if ( recsize == 0 )
 	{
 	  streamptr->ntsteps = 2;
 	  break;
 	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-      readsize = recsize;
+      size_t readsize = recsize;
       rstatus = gribRead(fileID, gribbuffer, &readsize);
       if ( rstatus ) break;
 
-      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	{
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < (size_t)unzipsize )
-	    {
-	      buffersize = (size_t)unzipsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
-	}
+      long unzipsize;
+      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
       nrecs_scanned++;
       gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-      if ( editionNumber <= 1 )
-	{
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
-
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  param = gribapiGetParam(gh);
-
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
-
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+      int param = gribapiGetParam(gh);
+      int level1 = 0, level2 = 0, leveltype1, leveltype2, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
+      char varname[256];
       varname[0] = 0;
       gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
+      int vdate = 0, vtime = 0;
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
       if ( rindex == 0 )
@@ -1619,7 +1108,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	  datetime0.time = vtime;
 	}
 
-      tsteptype = gribapiGetTsteptype(gh);
+      int tsteptype = gribapiGetTsteptype(gh);
       /*
       if ( ISEC1_AvgNum )
 	{
@@ -1634,17 +1123,19 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	    }
 	}
       */
-      datetime.date  = vdate;
-      datetime.time  = vtime;
+      DateTime datetime = {
+        .date = vdate,
+        .time = vtime
+      };
 
-      compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+      compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
       for ( recID = 0; recID < nrecords; recID++ )
         if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
 
       if ( recID == nrecords )
 	{
-	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 	  return (CDI_EUFSTRUCT);
 	}
 
@@ -1655,7 +1146,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	    {
 	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
-              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 	      continue;
 	    }
 	}
@@ -1664,8 +1155,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
       streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
       if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
-                nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+                  nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
@@ -1679,7 +1174,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	}
 
       streamptr->tsteps[1].records[recID].position = recpos;
-      varID = streamptr->tsteps[tsID].records[recID].varID;
+      int varID = streamptr->tsteps[tsID].records[recID].varID;
       /*
       gridID = vlistInqVarGrid(vlistID, varID);
       if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
@@ -1700,12 +1195,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
   if ( gh ) grib_handle_delete(gh);
 
-  nrecs = 0;
+  int nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
     {
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
+	  int varID = streamptr->tsteps[tsID].records[recID].varID;
 	  vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	}
       else
@@ -1738,37 +1233,10 @@ int gribapiScanTimestep2(stream_t * streamptr)
 #if  defined  (HAVE_LIBGRIB_API)
 int gribapiScanTimestep(stream_t * streamptr)
 {
-  int rstatus = 0;
-  size_t recsize = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer;
-  size_t buffersize = 0;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
   int vrecID, recID;
   //int warn_numavg = TRUE;
-  size_t readsize;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  int rindex, nrecs = 0;
-  int nrecs_scanned;
-  long unzipsize;
-  compvar2_t compVar;
-  grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
-
-  vlistID = streamptr->vlistID;
+  int nrecs = 0;
+  int vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
@@ -1778,13 +1246,13 @@ int gribapiScanTimestep(stream_t * streamptr)
       Message("nts = %d", streamptr->ntsteps);
     }
 
-  tsID  = streamptr->rtsteps;
-  taxis = &streamptr->tsteps[tsID].taxis;
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      gribbuffer = (unsigned char *) streamptr->record->buffer;
-      buffersize = streamptr->record->buffersize;
+      unsigned char* gribbuffer = (unsigned char *) streamptr->record->buffer;
+      size_t buffersize = streamptr->record->buffersize;
 
       cdi_create_records(streamptr, tsID);
 
@@ -1795,17 +1263,21 @@ int gribapiScanTimestep(stream_t * streamptr)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamptr->fileID;
+      int fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
-      rindex = 0;
+      int nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);    //Only used for debug output.
+      int rindex = 0;
+      off_t recpos = 0;
+      DateTime datetime0;
+      grib_handle *gh = NULL;
+      char varname[256];
       while ( TRUE )
 	{
 	  if ( rindex > nrecs ) break;
 
-	  recsize = (size_t)gribGetSize(fileID);
+	  size_t recsize = (size_t)gribGetSize(fileID);
 	  recpos  = fileGetPos(fileID);
 	  if ( recsize == 0 )
 	    {
@@ -1815,69 +1287,38 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	  if ( rindex >= nrecs ) break;
 
-	  if ( recsize > buffersize )
-	    {
-	      buffersize = recsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
+          ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-	  readsize = recsize;
-	  rstatus = gribRead(fileID, gribbuffer, &readsize);
-	  if ( rstatus )
+	  size_t readsize = recsize;
+	  if (gribRead(fileID, gribbuffer, &readsize))
 	    {
 	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
 		      streamptr->tsteps[tsID].recordSize);
 	      break;
 	    }
 
-	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	    {
-	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	      if ( buffersize < (size_t)unzipsize )
-		{
-		  buffersize = (size_t)unzipsize;
-		  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-		}
-	    }
+          long unzipsize;
+	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
           nrecs_scanned++;
 	  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
 	  GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-	  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-	  if ( editionNumber <= 1 )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	      rtabnum = (int) lpar;
-	      GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	      rcode = (int) lpar;
-
-	      param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	      grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-              level_sf = 0;
-              level_unit = 0;
-	    }
-	  else
-	    {
-	      param = gribapiGetParam(gh);
-
-	      grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	    }
-
-          cdiParamToString(param, paramstr, sizeof(paramstr));
+          int param = gribapiGetParam(gh);
+          int level1 = 0, level2 = 0, leveltype1, leveltype2 = -1, lbounds, level_sf, level_unit;
+          gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
           varname[0] = 0;
 	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
+          int vdate = 0, vtime = 0;
 	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
 	  if ( rindex == nrecs ) break;
 
 	  if ( rindex == 0 )
 	    {
-	      taxisID = vlistInqTaxis(vlistID);
+              int taxisID = vlistInqTaxis(vlistID);
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
 		  taxis->type  = TAXIS_RELATIVE;
@@ -1910,12 +1351,14 @@ int gribapiScanTimestep(stream_t * streamptr)
 		}
 	    }
 	  */
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+          DateTime datetime = {
+            .date  = vdate,
+            .time  = vtime
+          };
 
           int tsteptype = gribapiGetTsteptype(gh);
 
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+          compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
@@ -1925,7 +1368,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	  if ( vrecID == nrecs )
 	    {
-	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
 	      if ( cdiInventoryMode == 1 )
 		return (CDI_EUFSTRUCT);
@@ -1940,7 +1383,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 		  if ( CDI_Debug )
-                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
 		  continue;
 		}
@@ -1983,8 +1426,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
       if ( vrecID < nrecs )
 	{
-	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
-	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, paramstr,
+	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, streamptr->tsteps[tsID].records[recID].param,
                       streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
 	  return (CDI_EUFSTRUCT);
 	}
@@ -2014,8 +1456,7 @@ int gribapiScanTimestep(stream_t * streamptr)
       streamptr->ntsteps = tsID;
     }
 
-  rstatus = (int)streamptr->ntsteps;
-  return (rstatus);
+  return (int)streamptr->ntsteps;
 }
 #endif
 
@@ -2029,7 +1470,7 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
 {
   int status = 0;
   long lpar;
-  long editionNumber, numberOfPoints;
+  long numberOfPoints;
   size_t datasize, dummy, recsize;
   grib_handle *gh = NULL;
 
@@ -2051,8 +1492,6 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
   gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
   GRIB_CHECK(my_grib_set_double(gh, "missingValue", missval), 0);
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
   /* get the size of the values array*/
   GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
   GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
@@ -2127,34 +1566,56 @@ void gribapiDefModel(grib_handle *gh, int vlistID, int varID)
 }
 
 static
-void gribapiDefParam(int editionNumber, grib_handle *gh, int param, const char *name)
+void gribapiDefParam(int editionNumber, grib_handle *gh, int param, const char *name, const char *stdname)
 {
-  int pdis, pcat, pnum;
+  bool ldefined = false;
 
+  int pdis, pcat, pnum;
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
   if ( pnum < 0 )
     {
       size_t len;
-      int status;
-      len = strlen(name);
-      status = my_grib_set_string(gh, "shortName", name, &len);
-      if ( status != 0 )
-	Warning("grib_api: No match for shortName=%s", name);
+      len = strlen(stdname);
+      if ( len )
+        {
+          int status = my_grib_set_string(gh, "cfName", stdname, &len);
+          if ( status == 0 ) ldefined = true;
+          else Warning("grib_api: No match for cfName=%s", stdname);
+        }
+
+      if ( ldefined == false )
+        {
+          len = strlen(name);
+          int status = my_grib_set_string(gh, "shortName", name, &len);
+          if ( status == 0 ) ldefined = true;
+          else Warning("grib_api: No match for shortName=%s", name);
+        }
     }
-  else
+
+  if ( ldefined == false )
     {
       if ( pnum < 0 ) pnum = -pnum;
 
       if ( editionNumber <= 1 )
 	{
-	  if ( pdis != 255 )
+          static bool lwarn_pdis = true;
+	  if ( pdis != 255 && lwarn_pdis )
 	    {
 	      char paramstr[32];
 	      cdiParamToString(param, paramstr, sizeof(paramstr));
 	      Warning("Can't convert GRIB2 parameter ID (%s) to GRIB1, set to %d.%d!", paramstr, pnum, pcat);
+              lwarn_pdis = false;
 	    }
 
+          static bool lwarn_pnum = true;
+          if ( pnum > 255 && lwarn_pnum )
+            {
+              Warning("Parameter number %d out of bounds (1-255), set to %d!", pnum, pnum%256);
+              lwarn_pnum = false;
+              pnum = pnum%256;
+            }
+
 	  GRIB_CHECK(my_grib_set_long(gh, "table2Version",        pcat), 0);
 	  GRIB_CHECK(my_grib_set_long(gh, "indicatorOfParameter", pnum), 0);
 	}
@@ -2307,7 +1768,11 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
 
       // printf(">>>>> tsteptype %d  startStep %ld  endStep %ld\n", tsteptype, startStep, endStep);
 
-      if ( proDefTempNum == 0 ) startStep = endStep;
+      // Product Definition Template Number: defined in GRIB_API file 4.0.table
+      // point in time products:
+      if ( (proDefTempNum >= 0 && proDefTempNum <=  7) || 
+           proDefTempNum == 55 || proDefTempNum == 40055 ) // Tile
+        startStep = endStep;
 
       if ( editionNumber > 1 ) GRIB_CHECK(my_grib_set_long(gh, "forecastTime", startStep), 0);
       GRIB_CHECK(my_grib_set_long(gh, "endStep", endStep), 0);
@@ -2806,8 +2271,6 @@ void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2
     }
 }
 
-int zaxisInqLtype2(int zaxisID);
-
 static
 void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
@@ -2840,6 +2303,8 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
       zaxisDefUnits(zaxisID, "Pa");
     }
 
+  int grib2ltype = zaxisTypeToGrib2ltype(zaxistype);
+
   switch (zaxistype)
     {
     case ZAXIS_SURFACE:
@@ -2851,11 +2316,14 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_ISENTROPIC:
       {
 	if ( editionNumber <= 1 )
-          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+          {
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+            GRIB_CHECK(my_grib_set_long(gh, "level", (long)level), 0);
+          }
         else
-          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-
-        GRIB_CHECK(my_grib_set_long(gh, "level", (long)level), 0);
+          {
+            grib2DefLevel(gh, gcinit, grib2ltype, grib2ltype, lbounds, level, dlevel1, dlevel2);
+          }
 
 	break;
       }
@@ -2871,27 +2339,22 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_MIX_LAYER:
     case ZAXIS_ATMOSPHERE:
       {
-        if ( lbounds )
+        if ( editionNumber <= 1 )
           {
-            if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
+            if ( lbounds )
+              {
+                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
+              }
             else
               {
-                gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-                gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
+                GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
               }
-
-            GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
-            GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
           }
         else
           {
-            if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", zaxisTypeToGrib1ltype(zaxistype));
-            else
-              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", zaxisTypeToGrib2ltype(zaxistype));
-
-            GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
+            grib2DefLevel(gh, gcinit, grib2ltype, grib2ltype, lbounds, level, dlevel1, dlevel2);
           }
 
         break;
@@ -2899,28 +2362,24 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_HYBRID:
     case ZAXIS_HYBRID_HALF:
       {
-	if ( lbounds )
-	  {
-	    if ( editionNumber <= 1 )
-	      gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
-            else
-	      {
-		gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
-		gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID);
-	      }
-
-	    GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
-	    GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
-	  }
-	else
-	  {
-	    if ( editionNumber <= 1 )
-              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
+        if ( editionNumber <= 1 )
+          {
+            if ( lbounds )
+              {
+                gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
+                GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+                GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
+              }
             else
-              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
-
-	    GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
-	  }
+              {
+                gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
+                GRIB_CHECK(my_grib_set_long(gh, "level", (long) level), 0);
+              }
+          }
+        else
+          {
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_HYBRID, GRIB2_LTYPE_HYBRID, lbounds, level, dlevel1, dlevel2);
+          }
 
         if ( !gcinit )
           {
@@ -3042,7 +2501,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 size_t len = CDI_UUID_SIZE;
                 zaxisInqUUID(zaxisID, uuid);
                 if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
+                  {
+                    Warning("Can't write UUID!");
+                  }
                 GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
                 GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
               }
@@ -3061,7 +2522,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 size_t len = CDI_UUID_SIZE;
                 zaxisInqUUID(zaxisID, uuid);
                 if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
+                  {
+                    Warning("Can't write UUID!");
+                  }
                 GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
               }
           }
@@ -3098,8 +2561,6 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 {
   size_t recsize = 0;
   void *dummy = NULL;
-  int datatype;
-  int param;
   int lieee = FALSE;
   /*  int ensID, ensCount, forecast_type; *//* Ensemble Data */
   int typeOfGeneratingProcess;
@@ -3107,15 +2568,17 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
   long bitsPerValue;
   long editionNumber = 2;
   char name[256];
+  char stdname[256];
   gribContainer_t *gc = (gribContainer_t *) gribContainer;
   // extern unsigned char _grib_template_GRIB2[];
 
-  param    = vlistInqVarParam(vlistID, varID);
-  datatype = vlistInqVarDatatype(vlistID, varID);
+  int param    = vlistInqVarParam(vlistID, varID);
+  int datatype = vlistInqVarDatatype(vlistID, varID);
   typeOfGeneratingProcess = vlistInqVarTypeOfGeneratingProcess(vlistID, varID);
   productDefinitionTemplate = vlistInqVarProductDefinitionTemplate(vlistID, varID);
 
   vlistInqVarName(vlistID, varID, name);
+  vlistInqVarStdname(vlistID, varID, stdname);
 
 #if defined(GRIBAPIENCODETEST)
   grib_handle *gh = (grib_handle *) gribHandleNew(editionNumber);
@@ -3144,7 +2607,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
   if ( ! gc->init ) gribapiDefInstitut(gh, vlistID, varID);
   if ( ! gc->init ) gribapiDefModel(gh, vlistID, varID);
 
-  if ( ! gc->init ) gribapiDefParam(editionNumber, gh, param, name);
+  if ( ! gc->init ) gribapiDefParam(editionNumber, gh, param, name, stdname);
 
   if ( editionNumber == 2 && (datatype == DATATYPE_FLT32 || datatype == DATATYPE_FLT64) ) lieee = TRUE;
 
diff --git a/libcdi/src/stream_gribapi.h b/libcdi/src/stream_gribapi.h
index d3ff963..6c136bd 100644
--- a/libcdi/src/stream_gribapi.h
+++ b/libcdi/src/stream_gribapi.h
@@ -1,6 +1,10 @@
 #ifndef _STREAM_GRIBAPI_H
 #define _STREAM_GRIBAPI_H
 
+#ifndef  _CDI_INT_H
+#include "cdi_int.h"
+#endif
+
 int gribapiScanTimestep1(stream_t * streamptr);
 int gribapiScanTimestep2(stream_t * streamptr);
 int gribapiScanTimestep(stream_t * streamptr);
diff --git a/libcdi/src/stream_record.c b/libcdi/src/stream_record.c
index 86cc640..073b0cf 100644
--- a/libcdi/src/stream_record.c
+++ b/libcdi/src/stream_record.c
@@ -47,7 +47,7 @@ int recordNewEntry(stream_t *streamptr, int tsID)
       if ( records == NULL )
 	{
           Message("recordSize = %d", recordSize);
-	  SysError("Allocation of record_tTABLE failed");
+	  SysError("Allocation of records failed");
 	}
 
       for ( i = 0; i < recordSize; i++ )
@@ -74,7 +74,7 @@ int recordNewEntry(stream_t *streamptr, int tsID)
       if ( records == NULL )
 	{
           Message("recordSize = %d", recordSize);
-	  SysError("Reallocation of record_tTABLE failed");
+	  SysError("Reallocation of records failed");
 	}
       recordID = recordSize/2;
 
@@ -82,7 +82,6 @@ int recordNewEntry(stream_t *streamptr, int tsID)
 	records[i].used = CDI_UNDEFID;
     }
 
-
   recordInitEntry(&records[recordID]);
 
   records[recordID].used = 1;
@@ -439,9 +438,12 @@ void cdi_create_records(stream_t *streamptr, int tsID)
   unsigned nrecords, maxrecords;
   record_t *records;
 
-  if ( streamptr->tsteps[tsID].records ) return;
+  tsteps_t* sourceTstep = streamptr->tsteps;
+  tsteps_t* destTstep = sourceTstep + tsID;
+
+  if ( destTstep->records ) return;
 
-  int vlistID  = streamptr->vlistID;
+  int vlistID = streamptr->vlistID;
 
   if ( tsID == 0 )
     {
@@ -451,7 +453,9 @@ void cdi_create_records(stream_t *streamptr, int tsID)
 	maxrecords += (unsigned)streamptr->vars[varID].nlevs;
     }
   else
-    maxrecords = (unsigned)streamptr->tsteps[0].recordSize;
+    {
+      maxrecords = (unsigned)sourceTstep->recordSize;
+    }
 
   if ( tsID == 0 )
     {
@@ -460,48 +464,52 @@ void cdi_create_records(stream_t *streamptr, int tsID)
   else if ( tsID == 1 )
     {
       nrecords = 0;
-      maxrecords = (unsigned)streamptr->tsteps[0].recordSize;
-      for (unsigned recID = 0; recID < maxrecords; recID++ )
+      maxrecords = (unsigned)sourceTstep->recordSize;
+      for ( unsigned recID = 0; recID < maxrecords; recID++ )
 	{
-	  int varID = streamptr->tsteps[0].records[recID].varID;
-	  nrecords +=
-            (varID == -1 /* varID = -1 for write mode !!! */
-             || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
+	  int varID = sourceTstep->records[recID].varID;
+	  nrecords += (varID == CDI_UNDEFID /* varID = CDI_UNDEFID for write mode !!! */
+                       || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
+          //    printf("varID nrecords %d %d %d \n", varID, nrecords, vlistInqVarTsteptype(vlistID, varID));
 	}
     }
   else
-    nrecords = (unsigned)streamptr->tsteps[1].nallrecs;
+    {
+      nrecords = (unsigned)streamptr->tsteps[1].nallrecs;
+    }
+  //  printf("tsID, nrecords %d %d\n", tsID, nrecords);
 
   if ( maxrecords > 0 )
     records = (record_t *) malloc(maxrecords * sizeof(record_t));
   else
     records = NULL;
 
-  streamptr->tsteps[tsID].records    = records;
-  streamptr->tsteps[tsID].recordSize = (int)maxrecords;
-  streamptr->tsteps[tsID].nallrecs   = (int)nrecords;
+  destTstep->records    = records;
+  destTstep->recordSize = (int)maxrecords;
+  destTstep->nallrecs   = (int)nrecords;
 
   if ( tsID == 0 )
     {
       for ( unsigned recID = 0; recID < maxrecords; recID++ )
-	recordInitEntry(&streamptr->tsteps[tsID].records[recID]);
+        recordInitEntry(&destTstep->records[recID]);
     }
   else
     {
-      memcpy(streamptr->tsteps[tsID].records,
-	     streamptr->tsteps[0].records,
-	     (size_t)maxrecords * sizeof(record_t));
+      memcpy(destTstep->records, sourceTstep->records, (size_t)maxrecords*sizeof(record_t));
 
       for ( unsigned recID = 0; recID < maxrecords; recID++ )
 	{
-	  int varID = streamptr->tsteps[0].records[recID].varID;
-	  if ( varID != -1 ) /* varID = -1 for write mode !!! */
-	    if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-	      {
-		streamptr->tsteps[tsID].records[recID].position = CDI_UNDEFID;
-		streamptr->tsteps[tsID].records[recID].size     = 0;
-		streamptr->tsteps[tsID].records[recID].used     = FALSE;
-	      }
+          record_t* curRecord = &sourceTstep->records[recID];
+          destTstep->records[recID].used = curRecord->used;
+          if ( curRecord->used != CDI_UNDEFID && curRecord->varID != -1 ) /* curRecord->varID = -1 for write mode !!! */
+            {
+              if ( vlistInqVarTsteptype(vlistID, curRecord->varID) != TSTEP_CONSTANT )
+                {
+                  destTstep->records[recID].position = CDI_UNDEFID;
+                  destTstep->records[recID].size     = 0;
+                  destTstep->records[recID].used     = FALSE;
+                }
+            }
 	}
     }
 }
diff --git a/libcdi/src/stream_srv.c b/libcdi/src/stream_srv.c
index 6e2d2e2..da62efb 100644
--- a/libcdi/src/stream_srv.c
+++ b/libcdi/src/stream_srv.c
@@ -206,25 +206,17 @@ static
 void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
                     size_t recsize, off_t position, int prec)
 {
-  int leveltype;
-  int gridID = CDI_UNDEFID;
-  int levelID = 0;
-  int tsID, recID, varID;
-  int datatype;
-  record_t *record;
-  grid_t grid;
-  int vlistID;
+  int vlistID = streamptr->vlistID;
+  int tsID    = streamptr->curTsID;
+  int recID   = recordNewEntry(streamptr, tsID);
+  record_t *record = &streamptr->tsteps[tsID].records[recID];
 
-  vlistID = streamptr->vlistID;
-  tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamptr, tsID);
-  record  = &streamptr->tsteps[tsID].records[recID];
-
-  (*record).size     = recsize;
-  (*record).position = position;
-  (*record).param    = param;
-  (*record).ilevel   = level;
+  record->size     = recsize;
+  record->position = position;
+  record->param    = param;
+  record->ilevel   = level;
 
+  grid_t grid;
   memset(&grid, 0, sizeof(grid_t));
   grid.type  = GRID_GENERIC;
   grid.size  = xsize*ysize;
@@ -232,21 +224,24 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
   grid.ysize = ysize;
   grid.xvals = NULL;
   grid.yvals = NULL;
-  gridID = varDefGrid(vlistID, &grid, 0);
+  int gridID = varDefGrid(vlistID, &grid, 0);
   /*
   if ( level == 0 ) leveltype = ZAXIS_SURFACE;
   else              leveltype = ZAXIS_GENERIC;
   */
-  leveltype = ZAXIS_GENERIC;
+  int leveltype = ZAXIS_GENERIC;
+
+  int datatype = srvInqDatatype(prec);
 
-  datatype = srvInqDatatype(prec);
+  int levelID = 0;
+  int varID;
 
   varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
 	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1, NULL, NULL, NULL, NULL);
 
   xassert(varID <= SHRT_MAX && levelID <= SHRT_MAX);
-  (*record).varID   = (short)varID;
-  (*record).levelID = (short)levelID;
+  record->varID   = (short)varID;
+  record->levelID = (short)levelID;
 
   streamptr->tsteps[tsID].nallrecs++;
   streamptr->nrecs++;
diff --git a/libcdi/src/table.c b/libcdi/src/table.c
index 083d282..bd7ec02 100644
--- a/libcdi/src/table.c
+++ b/libcdi/src/table.c
@@ -590,9 +590,9 @@ static void partabCheckID(int item)
     Error("item %d name undefined!", item);
 }
 
-char *tableInqNamePtr(int tableID)
+const char *tableInqNamePtr(int tableID)
 {
-  char *tablename = NULL;
+  const char *tablename = NULL;
 
   if ( CDI_Debug )
     Message("tableID = %d", tableID);
@@ -796,27 +796,21 @@ void tableFWriteC(FILE *ptfp, int tableID)
 
 int tableInqParCode(int tableID, char *varname, int *code)
 {
-  int item, npars;
-  int err = 0;
-
-  npars = parTable[tableID].npars;
+  int err = 1;
 
-  if ( tableID == UNDEFID || varname == NULL )
-    {
-      err = 1;
-    }
-  else
+  if ( tableID != UNDEFID && varname != NULL )
     {
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
-	  if ( parTable[tableID].pars[item].name )
-	    if ( strcmp(parTable[tableID].pars[item].name, varname) == 0 )
-	      {
-		*code = parTable[tableID].pars[item].id;
-		break;
-	      }
+	  if ( parTable[tableID].pars[item].name
+               && strcmp(parTable[tableID].pars[item].name, varname) == 0 )
+            {
+              *code = parTable[tableID].pars[item].id;
+              err = 0;
+              break;
+            }
 	}
-      if ( item == npars ) err = 1;
     }
 
   return (err);
@@ -825,27 +819,21 @@ int tableInqParCode(int tableID, char *varname, int *code)
 
 int tableInqParName(int tableID, int code, char *varname)
 {
-  int item, npars;
-  int err = 0;
+  int err = 1;
 
-  npars = parTable[tableID].npars;
-
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
+  if ( tableID != UNDEFID )
     {
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
 	      if ( parTable[tableID].pars[item].name )
-		strcpy(varname, parTable[tableID].pars[item].name);
+		strcpy(varname, parTable[tableID].pars[item].name);     //FIXME: This may overrun the supplied buffer!
+              err = 0;
 	      break;
 	    }
 	}
-      if ( item == npars ) err = 1;
     }
 
   return (err);
@@ -855,12 +843,11 @@ int tableInqParName(int tableID, int code, char *varname)
 const char *tableInqParNamePtr(int tableID, int code)
 {
   const char *name = NULL;
-  int item, npars;
 
   if ( tableID != UNDEFID )
     {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
@@ -877,12 +864,11 @@ const char *tableInqParNamePtr(int tableID, int code)
 const char *tableInqParLongnamePtr(int tableID, int code)
 {
   const char *longname = NULL;
-  int item, npars;
 
   if ( tableID != UNDEFID )
     {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
@@ -899,12 +885,11 @@ const char *tableInqParLongnamePtr(int tableID, int code)
 const char *tableInqParUnitsPtr(int tableID, int code)
 {
   const char *units = NULL;
-  int item, npars;
 
   if ( tableID != UNDEFID )
     {
-      npars = parTable[tableID].npars;
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
@@ -920,30 +905,24 @@ const char *tableInqParUnitsPtr(int tableID, int code)
 
 int tableInqParLongname(int tableID, int code, char *longname)
 {
-  int item, npars;
-  int err = 0;
-
-  npars = parTable[tableID].npars;
-
   if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
     Error("Invalid table ID %d", tableID);
 
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
+  int err = 1;
+
+  if ( tableID != UNDEFID )
     {
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
 	      if ( parTable[tableID].pars[item].longname )
 		strcpy(longname, parTable[tableID].pars[item].longname);
+              err = 0;
 	      break;
 	    }
 	}
-      if ( item == npars ) err = 1;
     }
 
   return (err);
@@ -952,30 +931,25 @@ int tableInqParLongname(int tableID, int code, char *longname)
 
 int tableInqParUnits(int tableID, int code, char *units)
 {
-  int item, npars;
-  int err = 0;
-
-  npars = parTable[tableID].npars;
 
   if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
     Error("Invalid table ID %d", tableID);
 
-  if ( tableID == UNDEFID )
-    {
-      err = 1;
-    }
-  else
+  int err = 1;
+
+  if ( tableID != UNDEFID )
     {
-      for ( item = 0; item < npars; item++ )
+      int npars = parTable[tableID].npars;
+      for ( int item = 0; item < npars; item++ )
 	{
 	  if ( parTable[tableID].pars[item].id == code )
 	    {
 	      if ( parTable[tableID].pars[item].units )
 		strcpy(units, parTable[tableID].pars[item].units);
+              err = 0;
 	      break;
 	    }
 	}
-      if ( item == npars ) err = 1;
     }
 
   return (err);
@@ -984,11 +958,13 @@ int tableInqParUnits(int tableID, int code, char *units)
 
 void tableInqPar(int tableID, int code, char *name, char *longname, char *units)
 {
-  int item, npars;
 
-  npars = parTable[tableID].npars;
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
+    Error("Invalid table ID %d", tableID);
 
-  for ( item = 0; item < npars; item++ )
+  int npars = parTable[tableID].npars;
+
+  for ( int item = 0; item < npars; item++ )
     {
       if ( parTable[tableID].pars[item].id == code )
 	{
diff --git a/libcdi/src/taxis.c b/libcdi/src/taxis.c
index ebe1d51..f1ac7ed 100644
--- a/libcdi/src/taxis.c
+++ b/libcdi/src/taxis.c
@@ -24,7 +24,7 @@ static int DefaultTimeType = TAXIS_ABSOLUTE;
 static int DefaultTimeUnit = TUNIT_HOUR;
 
 
-char *Timeunits[] = {
+const char *Timeunits[] = {
   "undefined",
   "seconds",
   "minutes",
@@ -105,10 +105,10 @@ dup_refcount_string(char *p)
 static int  TAXIS_Debug = 0;   /* If set to 1, debugging */
 
 
-char *tunitNamePtr(int unitID)
+const char *tunitNamePtr(int unitID)
 {
-  char *name;
-  int size = sizeof(Timeunits)/sizeof(char *);
+  const char *name;
+  int size = sizeof(Timeunits)/sizeof(*Timeunits);
 
   if ( unitID > 0 && unitID < size )
     name = Timeunits[unitID];
@@ -533,7 +533,7 @@ void taxisDefForecastPeriod(int taxisID, double fc_period)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if (taxisptr->fc_period != fc_period)
+  if ( IS_NOT_EQUAL(taxisptr->fc_period, fc_period) )
     {
       taxisptr->fc_period = fc_period;
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
@@ -919,10 +919,14 @@ ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
     }
 }
 
+
 void cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
 {
   static int lwarn = TRUE;
 
+  *days = 0;
+  *secs = 0;
+
   if ( timeunit == TUNIT_MINUTE )
     {
       timevalue *= 60;
@@ -937,7 +941,8 @@ void cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
   if ( timeunit == TUNIT_SECOND )
     {
       *days = (int) (timevalue/86400);
-      *secs = (int) (timevalue - *days*86400.);
+      double seconds = timevalue - *days*86400.;
+      *secs = lround(seconds);
       if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
       /*
       {
@@ -950,7 +955,8 @@ void cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
   else if ( timeunit == TUNIT_DAY )
     {
       *days = (int) timevalue;
-      *secs = (int) ((timevalue - *days)*86400 + 0.5);
+      double seconds = (timevalue - *days)*86400;
+      *secs = lround(seconds);
       if ( *secs < 0 ) { *days -= 1; *secs += 86400; };
       /*
       {
diff --git a/libcdi/src/util.c b/libcdi/src/util.c
index 09f5718..8c33813 100644
--- a/libcdi/src/util.c
+++ b/libcdi/src/util.c
@@ -2,6 +2,9 @@
 #  include "config.h"
 #endif
 
+#define _XOPEN_SOURCE 600
+
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <float.h>
@@ -91,6 +94,139 @@ int str2uuid(const char *uuidstr, unsigned char *uuid)
   return iret;
 }
 
+//Returns a malloc'ed string that escapes all spaces and backslashes with backslashes.
+char* cdiEscapeSpaces(const char* string)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current; current++)
+    {
+      if(strchr(" \\", *current)) escapeCount++;
+      length++;
+    }
+
+  char* result = malloc(length + escapeCount + 1);
+  if(!result) return NULL;
+
+  //Do the escaping.
+  for(size_t in = 0, out = 0; in < length;)
+    {
+      if(strchr(" \\", string[in])) result[out++] = '\\';
+      result[out++] = string[in++];
+    }
+  result[length + escapeCount] = 0;     //termination!
+  return result;
+}
+
+//input: a space terminated string that may contain escaped characters
+//output: a new zero terminated string with the escape characters removed
+//*outStringEnd points to the terminating character upon return.
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current && *current != ' '; current++)
+    {
+      if(*current == '\\')
+        {
+          current++, escapeCount++;
+          if(!current) return NULL;
+        }
+      length++;
+    }
+
+  char* result = malloc(length + 1);
+  if(!result) return NULL;
+
+  //Do the unescaping.
+  for(size_t in = 0, out = 0; out < length;)
+    {
+      if(string[in] == '\\') in++;
+      result[out++] = string[in++];
+    }
+  result[length] = 0;   //termination!
+  if(outStringEnd) *outStringEnd = &string[length + escapeCount];
+  return result;
+}
+
+#ifdef HAVE_DECL_UUID_GENERATE
+#include <sys/time.h>
+#include <uuid/uuid.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  static int uuid_seeded = 0;
+  static char uuid_rand_state[31 * sizeof (long)];
+  char *caller_rand_state;
+  if (uuid_seeded)
+    caller_rand_state = setstate(uuid_rand_state);
+  else
+    {
+      struct timeval tv;
+      int status = gettimeofday(&tv, NULL);
+      if (status != 0)
+        {
+          perror("uuid random seed generation failed!");
+          exit(1);
+        }
+      unsigned seed = (unsigned)(tv.tv_sec ^ tv.tv_usec);
+      caller_rand_state = initstate(seed, uuid_rand_state,
+                                    sizeof (uuid_rand_state));
+      uuid_seeded = 1;
+    }
+  uuid_generate(uuid);
+  setstate(caller_rand_state);
+}
+#elif defined (HAVE_DECL_UUID_CREATE)
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+typedef uint32_t u_int32_t;
+#include <uuid.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  unsigned32 status;
+  uuid_create((uuid_t *)uuid, &status);
+  if (status == -1)
+    {
+      perror("uuid generation failed!");
+      exit(1);
+    }
+}
+#else
+#include <sys/time.h>
+void
+create_uuid(unsigned char *uuid)
+{
+  static int uuid_seeded = 0;
+  static char uuid_rand_state[31 * sizeof (long)];
+  char *caller_rand_state;
+  if (uuid_seeded)
+    caller_rand_state = setstate(uuid_rand_state);
+  else
+    {
+      struct timeval tv;
+      int status = gettimeofday(&tv, NULL);
+      if (status != 0)
+        {
+          perror("failed seed generation!");
+          exit(1);
+        }
+      unsigned seed = tv.tv_sec ^ tv.tv_usec;
+      caller_rand_state = initstate(seed, uuid_rand_state,
+                                    sizeof (uuid_rand_state));
+      uuid_seeded = 1;
+    }
+  for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
+    uuid[i] = (unsigned char)random();
+  /* encode variant into msb of octet 8 */
+  uuid[8] = (unsigned char)((uuid[8] & 0x3f) | (1 << 7));
+  /* encode version 4 ((pseudo-)random uuid) into msb of octet 7 */
+  uuid[7] = (unsigned char)((uuid[7] & 0x0f) | (4 << 4));
+  setstate(caller_rand_state);
+}
+#endif
+
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index 2747e7e..559cdb6 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -2,22 +2,20 @@
 #  include "config.h"
 #endif
 
+#include <stdbool.h>
 #include <string.h>
 #include <math.h>
 
 #include "cdi.h"
 #include "cdi_int.h"
 #include "dmemory.h"
+#include "resource_handle.h"
 #include "varscan.h"
 #include "vlist.h"
 #include "grid.h"
 #include "zaxis.h"
 
 
-extern void zaxisGetIndexList(int, int *);
-extern void zaxisDefLtype2(int zaxisID, int ltype2);
-
-
 #undef  UNDEFID
 #define UNDEFID -1
 
@@ -84,12 +82,12 @@ vartable_t;
 
 
 static vartable_t *vartable;
-static int varTablesize = 0;
-static int nvars = 0;
+static unsigned varTablesize = 0;
+static unsigned nvars = 0;
 
 
-static
-void paramInitEntry(int varID, int param)
+static void
+paramInitEntry(unsigned varID, int param)
 {
   vartable[varID].param          = param;
   vartable[varID].prec           = 0;
@@ -122,12 +120,10 @@ void paramInitEntry(int varID, int param)
   vartable[varID].ensdata        = NULL;
 }
 
-static
-int varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *name)
+static unsigned
+varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *name)
 {
-  int varID;
-
-  for ( varID = 0; varID < varTablesize; varID++ )
+  for ( unsigned varID = 0; varID < varTablesize; varID++ )
     {
       if ( vartable[varID].param      == param       &&
 	   vartable[varID].zaxistype  == zaxistype   &&
@@ -145,15 +141,13 @@ int varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char
         }
     }
 
-  return (UNDEFID);
+  return (unsigned)-1;
 }
 
 static
 void varFree(void)
 {
-  int varID;
-
-  for ( varID = 0; varID < nvars; varID++ )
+  for ( unsigned varID = 0; varID < nvars; varID++ )
     {
       if ( vartable[varID].levelTable )
 	free(vartable[varID].levelTable);
@@ -179,8 +173,8 @@ void varFree(void)
   Vctsize = 0;
 }
 
-static
-int levelNewEntry(int varID, int level1, int level2)
+static int
+levelNewEntry(unsigned varID, int level1, int level2)
 {
   int levelID = 0;
   int levelTableSize;
@@ -251,10 +245,10 @@ int levelNewEntry(int varID, int level1, int level2)
 
 #define  UNDEF_PARAM  -4711
 
-static
-int paramNewEntry(int param)
+static unsigned
+paramNewEntry(int param)
 {
-  int varID = 0;
+  unsigned varID = 0;
 
   /*
     Look for a free slot in vartable.
@@ -262,8 +256,6 @@ int paramNewEntry(int param)
   */
   if ( ! varTablesize )
     {
-      int i;
-
       varTablesize = 2;
       vartable = (vartable_t *)xmalloc((size_t)varTablesize
                                        * sizeof (vartable_t));
@@ -273,7 +265,7 @@ int paramNewEntry(int param)
 	  SysError("Allocation of vartable failed");
 	}
 
-      for( i = 0; i < varTablesize; i++ )
+      for( unsigned i = 0; i < varTablesize; i++ )
 	{
 	  vartable[i].param = UNDEF_PARAM;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -295,7 +287,6 @@ int paramNewEntry(int param)
   */
   if ( varID == varTablesize )
     {
-      int i;
 
       varTablesize = 2 * varTablesize;
       vartable = (vartable_t *)xrealloc(vartable, (size_t)varTablesize
@@ -307,7 +298,7 @@ int paramNewEntry(int param)
 	}
       varID = varTablesize/2;
 
-      for( i = varID; i < varTablesize; i++ )
+      for( unsigned i = varID; i < varTablesize; i++ )
 	{
 	  vartable[i].param = UNDEF_PARAM;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -328,13 +319,10 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype1, int ltype2,
 		  const char *name, const char *stdname, const char *longname, const char *units)
 {
-  int varID = UNDEFID;
-  int levelID = -1;
+  unsigned varID = (cdiSplitLtype105 != 1 || zaxistype != ZAXIS_HEIGHT) ?
+    varGetEntry(param, zaxistype, ltype1, tsteptype, name) : (unsigned)UNDEFID;
 
-  if ( ! (cdiSplitLtype105 == 1 && zaxistype == ZAXIS_HEIGHT) )
-    varID = varGetEntry(param, zaxistype, ltype1, tsteptype, name);
-
-  if ( varID == UNDEFID )
+  if ( varID == (unsigned)UNDEFID )
     {
       nvars++;
       varID = paramNewEntry(param);
@@ -372,10 +360,10 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
 
   if ( prec > vartable[varID].prec ) vartable[varID].prec = prec;
 
-  levelID = levelNewEntry(varID, level1, level2);
+  int levelID = levelNewEntry(varID, level1, level2);
   vartable[varID].levelTable[levelID].recID = recID;
 
-  *pvarID   = varID;
+  *pvarID   = (int)varID;
   *plevelID = levelID;
 }
 /*
@@ -445,7 +433,7 @@ int cmpparam(const void* s1, const void* s2)
 
 void cdi_generate_vars(stream_t *streamptr)
 {
-  int varID, gridID, zaxisID;
+  int gridID, zaxisID;
   int instID, modelID, tableID;
   int param, zaxistype, ltype1, ltype2;
   int prec;
@@ -457,40 +445,33 @@ void cdi_generate_vars(stream_t *streamptr)
   double *dlevels = NULL;
   double *dlevels1 = NULL;
   double *dlevels2 = NULL;
-  int index, varid;
   double level_sf = 1;
   int vlistID = streamptr->vlistID;
 
-  int *varids = (int *)xmalloc((size_t)nvars*sizeof(int));
-  for ( varID = 0; varID < nvars; varID++ ) varids[varID] = varID;
+  int *varids = (int *)xmalloc(nvars*sizeof(int));
+  for ( unsigned varID = 0; varID < nvars; varID++ ) varids[varID] = (int)varID;
 
   if ( streamptr->sortname )
     {
-      param_t **varInfo;
-      varInfo    = (param_t **)xmalloc((size_t)nvars * sizeof (param_t *));
-      varInfo[0] = (param_t *)xmalloc((size_t)nvars * sizeof (param_t));
-
-      for ( int index = 1; index < nvars; index++ )
-	varInfo[index] = varInfo[0] + index;
+      param_t *varInfo = (param_t *)xmalloc((size_t)nvars * sizeof (param_t));
 
-      for ( varid = 0; varid < nvars; varid++ )
+      for ( unsigned varID = 0; varID < nvars; varID++ )
 	{
-	  varInfo[varid]->varid = varids[varid];
-	  varInfo[varid]->param = vartable[varid].param;
-	  varInfo[varid]->ltype = vartable[varid].ltype1;
+	  varInfo[varID].varid = varids[varID];
+	  varInfo[varID].param = vartable[varID].param;
+	  varInfo[varID].ltype = vartable[varID].ltype1;
 	}
-      qsort(varInfo[0], (size_t)nvars, sizeof(param_t), cmpparam);
-      for ( varid = 0; varid < nvars; varid++ )
+      qsort(varInfo, (size_t)nvars, sizeof(param_t), cmpparam);
+      for ( unsigned varID = 0; varID < nvars; varID++ )
 	{
-	  varids[varid] = varInfo[varid]->varid;
+	  varids[varID] = varInfo[varID].varid;
 	}
-      free(varInfo[0]);
       free(varInfo);
     }
 
-  for ( index = 0; index < nvars; index++ )
+  for ( unsigned index = 0; index < nvars; index++ )
     {
-      varid      = varids[index];
+      int varid      = varids[index];
 
       gridID     = vartable[varid].gridID;
       param      = vartable[varid].param;
@@ -604,7 +585,7 @@ void cdi_generate_vars(stream_t *streamptr)
       if ( lbounds ) free(dlevels2);
       free(dlevels);
 
-      varID = stream_new_var(streamptr, gridID, zaxisID);
+      int varID = stream_new_var(streamptr, gridID, zaxisID);
       varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
 
       vlistDefVarParam(vlistID, varID, param);
@@ -692,10 +673,10 @@ void cdi_generate_vars(stream_t *streamptr)
       if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
     }
 
-  for ( index = 0; index < nvars; index++ )
+  for ( unsigned index = 0; index < nvars; index++ )
     {
-      varID     = index;
-      varid     = varids[index];
+      int varID = (int)index;
+      int varid = varids[index];
 
       unsigned nlevels = vartable[varid].nlevels;
       /*
@@ -745,6 +726,25 @@ void varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZ
   memcpy(uuidVGrid, uuid, CDI_UUID_SIZE);
 }
 
+struct varDefGridSearchState
+{
+  int resIDValue;
+  const grid_t *queryKey;
+};
+
+static enum cdiApplyRet
+varDefGridSearch(int id, void *res, void *data)
+{
+  struct varDefGridSearchState *state = data;
+  (void)res;
+  if (gridCompare(id, state->queryKey) == 0)
+    {
+      state->resIDValue = id;
+      return CDI_APPLY_STOP;
+    }
+  else
+    return CDI_APPLY_GO_ON;
+}
 
 int varDefGrid(int vlistID, const grid_t *grid, int mode)
 {
@@ -754,19 +754,14 @@ int varDefGrid(int vlistID, const grid_t *grid, int mode)
    */
   int gridglobdefined = FALSE;
   int griddefined;
-  int ngrids;
   int gridID = CDI_UNDEFID;
-  int index;
-  vlist_t *vlistptr;
-  int * gridIndexList, i;
-
-  vlistptr = vlist_to_pointer(vlistID);
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   griddefined = FALSE;
-  ngrids = vlistptr->ngrids;
+  unsigned ngrids = (unsigned)vlistptr->ngrids;
 
   if ( mode == 0 )
-    for ( index = 0; index < ngrids; index++ )
+    for (unsigned index = 0; index < ngrids; index++ )
       {
 	gridID = vlistptr->gridIDs[index];
 	if ( gridID == UNDEFID )
@@ -781,26 +776,14 @@ int varDefGrid(int vlistID, const grid_t *grid, int mode)
 
   if ( ! griddefined )
     {
-      ngrids = gridSize();
-      if ( ngrids > 0 )
-        {
-          gridIndexList = (int*)xmalloc((size_t)ngrids * sizeof(int));
-          gridGetIndexList ( ngrids, gridIndexList );
-          for ( i = 0; i < ngrids; i++ )
-            {
-              gridID = gridIndexList[i];
-              if ( gridCompare(gridID, grid) == 0 )
-                {
-                  gridglobdefined = TRUE;
-                  break;
-                }
-            }
-          if ( gridIndexList ) free ( gridIndexList );
-        }
-
-      ngrids = vlistptr->ngrids;
-      if ( mode == 1 )
-	for ( index = 0; index < ngrids; index++ )
+      struct varDefGridSearchState query = { .queryKey = grid };
+      if ((gridglobdefined
+           = (cdiResHFilterApply(&gridOps, varDefGridSearch, &query)
+              == CDI_APPLY_STOP)))
+        gridID = query.resIDValue;
+
+      if ( mode == 1 && gridglobdefined)
+	for (unsigned index = 0; index < ngrids; index++ )
 	  if ( vlistptr->gridIDs[index] == gridID )
 	    {
 	      gridglobdefined = FALSE;
@@ -811,7 +794,7 @@ int varDefGrid(int vlistID, const grid_t *grid, int mode)
   if ( ! griddefined )
     {
       if ( ! gridglobdefined ) gridID = gridGenerate(grid);
-      ngrids = vlistptr->ngrids;
+      ngrids = (unsigned)vlistptr->ngrids;
       vlistptr->gridIDs[ngrids] = gridID;
       vlistptr->ngrids++;
     }
@@ -866,6 +849,33 @@ int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const dou
   return (differ);
 }
 
+struct varDefZAxisSearchState
+{
+  int resIDValue;
+  int zaxistype;
+  int nlevels;
+  double *levels;
+  int lbounds;
+  char *longname, *units;
+  int ltype;
+};
+
+static enum cdiApplyRet
+varDefZAxisSearch(int id, void *res, void *data)
+{
+  struct varDefZAxisSearchState *state = data;
+  (void)res;
+  if (zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
+                   state->levels, state->longname, state->units, state->ltype)
+      == 0)
+    {
+      state->resIDValue = id;
+      return CDI_APPLY_STOP;
+    }
+  else
+    return CDI_APPLY_GO_ON;
+}
+
 
 int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbounds,
 		double *levels1, double *levels2, int vctsize, double *vct, char *name,
@@ -875,17 +885,15 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbo
     mode: 0 search in vlist and zaxis table
           1 search in zaxis table
    */
-  int zaxisdefined;
+  int zaxisdefined = 0;
   int nzaxis;
   int zaxisID = UNDEFID;
   int index;
   int zaxisglobdefined = 0;
   vlist_t *vlistptr;
-  int i;
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  zaxisdefined = 0;
   nzaxis = vlistptr->nzaxis;
 
   if ( mode == 0 )
@@ -902,27 +910,22 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbo
 
   if ( ! zaxisdefined )
     {
-      nzaxis = zaxisSize();
-      if ( nzaxis > 0 )
-        {
-          int *zaxisIndexList;
-          zaxisIndexList = (int *)xmalloc((size_t)nzaxis * sizeof (int));
-          zaxisGetIndexList ( nzaxis, zaxisIndexList );
-          for ( i = 0; i < nzaxis; i++ )
-            {
-              zaxisID = zaxisIndexList[i];
-              if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
-                {
-                  zaxisglobdefined = 1;
-                  break;
-                }
-            }
-          if ( zaxisIndexList ) free ( zaxisIndexList );
-        }
-
-      nzaxis = vlistptr->nzaxis;
-      if ( mode == 1 )
-	for ( index = 0; index < nzaxis; index++ )
+      struct varDefZAxisSearchState query = {
+        .zaxistype = zaxistype,
+        .nlevels = nlevels,
+        .levels = levels,
+        .lbounds = lbounds,
+        .longname = longname,
+        .units = units,
+        .ltype = ltype1,
+      };
+      if ((zaxisglobdefined
+           = (cdiResHFilterApply(&zaxisOps, varDefZAxisSearch, &query)
+              == CDI_APPLY_STOP)))
+        zaxisID = query.resIDValue;
+
+      if ( mode == 1 && zaxisglobdefined)
+	for (int index = 0; index < nzaxis; index++ )
 	  if ( vlistptr->zaxisIDs[index] == zaxisID )
 	    {
 	      zaxisglobdefined = FALSE;
@@ -959,7 +962,6 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, double *levels, int lbo
 	  zaxisDefLtype(zaxisID, ltype1);
 	}
 
-      nzaxis = vlistptr->nzaxis;
       vlistptr->zaxisIDs[nzaxis] = zaxisID;
       vlistptr->nzaxis++;
     }
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index 579b877..16346e8 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -23,8 +23,6 @@ int    cdiNAdditionalGRIBKeys = 0;
 char*  cdiAdditionalGRIBKeys[MAX_OPT_GRIB_ENTRIES];
 #endif
 
-extern void zaxisGetIndexList ( int, int * );
-
 static int VLIST_Debug = 0;
 
 static void vlist_initialize(void);
@@ -228,32 +226,34 @@ vlist_delete(vlist_t *vlistptr)
   vlistDelAtts(vlistID, CDI_GLOBAL);
 
   int nvars = vlistptr->nvars;
+  var_t *vars = vlistptr->vars;
 
-  for (int varID = 0; varID < nvars; varID++ )
+  for ( int varID = 0; varID < nvars; varID++ )
     {
-      if ( vlistptr->vars[varID].levinfo )  free(vlistptr->vars[varID].levinfo);
-      if ( vlistptr->vars[varID].name )     free(vlistptr->vars[varID].name);
-      if ( vlistptr->vars[varID].longname ) free(vlistptr->vars[varID].longname);
-      if ( vlistptr->vars[varID].stdname )  free(vlistptr->vars[varID].stdname);
-      if ( vlistptr->vars[varID].units )    free(vlistptr->vars[varID].units);
-
-      if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
+      if ( vars[varID].levinfo )  free(vars[varID].levinfo);
+      if ( vars[varID].name )     free(vars[varID].name);
+      if ( vars[varID].longname ) free(vars[varID].longname);
+      if ( vars[varID].stdname )  free(vars[varID].stdname);
+      if ( vars[varID].units )    free(vars[varID].units);
+      if ( vars[varID].ensdata )  free(vars[varID].ensdata);
 
 #if  defined  (HAVE_LIBGRIB_API)
-      for (int i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
-	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
-	  free(vlistptr->vars[varID].opt_grib_int_keyword[i]);
-      }
-      for (int i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++) {
-	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
-	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
-      }
+      for ( int i=0; i<vars[varID].opt_grib_int_nentries; i++ )
+        {
+          if ( vars[varID].opt_grib_int_keyword[i] )
+            free(vars[varID].opt_grib_int_keyword[i]);
+        }
+      for ( int i=0; i<vars[varID].opt_grib_dbl_nentries; i++ )
+        {
+          if ( vars[varID].opt_grib_dbl_keyword[i] )
+            free(vars[varID].opt_grib_dbl_keyword[i]);
+        }
 #endif
 
       vlistDelAtts(vlistID, varID);
     }
 
-  if ( vlistptr->vars ) free(vlistptr->vars);
+  if ( vars ) free(vars);
 
   vlist_delete_entry(vlistptr);
 }
@@ -279,6 +279,45 @@ void vlistDestroy(int vlistID)
     vlist_delete(vlistptr);
 }
 
+static
+void var_copy_entries(var_t *var2, var_t *var1)
+{
+  if ( var1->name )     var2->name     = strdupx(var1->name);
+  if ( var1->longname ) var2->longname = strdupx(var1->longname);
+  if ( var1->stdname )  var2->stdname  = strdupx(var1->stdname);
+  if ( var1->units )    var2->units    = strdupx(var1->units);
+  if ( var1->ensdata )
+    {
+      var2->ensdata = (ensinfo_t *)xmalloc(sizeof(ensinfo_t));
+      memcpy(var2->ensdata, var1->ensdata, sizeof(ensinfo_t));
+    }
+#if  defined  (HAVE_LIBGRIB_API)
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+  var2->opt_grib_int_nentries = var1->opt_grib_int_nentries;
+  for ( int i = 0; i < var1->opt_grib_int_nentries; i++ )
+    {
+      if ( var1->opt_grib_int_keyword[i] )
+        {
+          var2->opt_grib_int_keyword[i] = strdupx(var1->opt_grib_int_keyword[i]);
+          var2->opt_grib_int_val[i]     = var1->opt_grib_int_val[i];
+          var2->opt_grib_int_update[i]  = TRUE;
+        }
+    }
+  var2->opt_grib_dbl_nentries = var1->opt_grib_dbl_nentries;
+  for ( int i = 0; i < var1->opt_grib_dbl_nentries; i++ )
+    {
+      if ( var1->opt_grib_dbl_keyword[i] )
+        {
+          var2->opt_grib_dbl_keyword[i] = strdupx(var1->opt_grib_dbl_keyword[i]);
+          var2->opt_grib_dbl_val[i]     = var1->opt_grib_dbl_val[i];
+          var2->opt_grib_dbl_update[i]  = TRUE;
+        }
+    }
+#endif
+}
+
 /*
 @Function  vlistCopy
 @Title     Copy a variable list
@@ -295,82 +334,37 @@ The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
 */
 void vlistCopy(int vlistID2, int vlistID1)
 {
-  vlist_t *vlistptr1, *vlistptr2;
-
-  vlistptr1 = vlist_to_pointer(vlistID1);
-  vlistptr2 = vlist_to_pointer(vlistID2);
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
 
-  var_t *vlist2vars = vlistptr2->vars;
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
   vlist_copy(vlistptr2, vlistptr1);
 
   vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
 
-  if ( vlistptr1->vars )
+  if ( vars1 )
     {
       int nvars = vlistptr1->nvars;
-
       //vlistptr2->varsAllocated = nvars;
-      vlistptr2->vars
-        = xrealloc(vlist2vars,
-                   (size_t)vlistptr2->varsAllocated * sizeof (var_t));
-      memcpy(vlistptr2->vars, vlistptr1->vars,
-             (size_t)vlistptr2->varsAllocated * sizeof (var_t));
+
+      size_t n = (size_t)vlistptr2->varsAllocated;
+      vars2 = xrealloc(vars2, n*sizeof(var_t));
+      memcpy(vars2, vars1, n*sizeof(var_t));
+      vlistptr2->vars = vars2;
 
       for ( int varID = 0; varID < nvars; varID++ )
         {
-          if ( vlistptr1->vars[varID].name )
-            vlistptr2->vars[varID].name = strdupx(vlistptr1->vars[varID].name);
-
-          if ( vlistptr1->vars[varID].longname )
-            vlistptr2->vars[varID].longname = strdupx(vlistptr1->vars[varID].longname);
-
-          if ( vlistptr1->vars[varID].stdname )
-            vlistptr2->vars[varID].stdname = strdupx(vlistptr1->vars[varID].stdname);
-
-          if ( vlistptr1->vars[varID].units )
-            vlistptr2->vars[varID].units = strdupx(vlistptr1->vars[varID].units);
-
-          if ( vlistptr1->vars[varID].ensdata )
-            {
-              vlistptr2->vars[varID].ensdata = (ensinfo_t *) malloc(sizeof(ensinfo_t));
-              memcpy(vlistptr2->vars[varID].ensdata,
-                     vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
-            }
-#if  defined  (HAVE_LIBGRIB_API)
-          /* ---------------------------------- */
-          /* Local change: 2013-01-28, FP (DWD) */
-          /* ---------------------------------- */
-
-	  vlistptr2->vars[varID].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-	  for (int i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
-	    if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-	      vlistptr2->vars[varID].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-	      vlistptr2->vars[varID].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-	      vlistptr2->vars[varID].opt_grib_int_update[i]  = TRUE;
-	    }
-	  }
-	  vlistptr2->vars[varID].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-	  for (int i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
-	    if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-	      vlistptr2->vars[varID].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-	      vlistptr2->vars[varID].opt_grib_dbl_update[i]  = TRUE;
-	    }
-	  }
-#endif
+          var_copy_entries(&vars2[varID], &vars1[varID]);
 
-	  vlistptr2->vars[varID].atts.nelems = 0;
+	  vars2[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
-          if ( vlistptr1->vars[varID].levinfo )
+          if ( vars1[varID].levinfo )
             {
-              size_t nlevs
-                = (size_t)zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-              vlistptr2->vars[varID].levinfo
-                = xmalloc(nlevs * sizeof (levinfo_t));
-              memcpy(vlistptr2->vars[varID].levinfo,
-                     vlistptr1->vars[varID].levinfo,
-                     nlevs * sizeof (levinfo_t));
+              n = (size_t)zaxisInqSize(vars1[varID].zaxisID);
+              vars2[varID].levinfo = xmalloc(n*sizeof(levinfo_t));
+              memcpy(vars2[varID].levinfo, vars1[varID].levinfo, n*sizeof(levinfo_t));
             }
 	}
     }
@@ -412,9 +406,7 @@ void vlistClearFlag(int vlistID)
         {
           int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
           for ( levID = 0; levID < nlevs; levID++ )
-            {
-              vlistptr->vars[varID].levinfo[levID].flag = FALSE;
-            }
+            vlistptr->vars[varID].levinfo[levID].flag = FALSE;
         }
     }
 }
@@ -445,13 +437,13 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
 
   if ( ! zaxisdefined )
     {
-      nzaxis = zaxisSize();
+      unsigned nzaxis = cdiZaxisCount();
       if ( nzaxis > 0 )
         {
           int *zaxisIndexList = (int *)xmalloc((size_t)nzaxis * sizeof (int));
           reshLock();
-          zaxisGetIndexList ( nzaxis, zaxisIndexList );
-          for ( int index = 0; index < nzaxis; ++index )
+          cdiZaxisGetIndexList(nzaxis, zaxisIndexList);
+          for (unsigned index = 0; index < nzaxis; ++index)
             {
               zaxisID = zaxisIndexList[index];
               if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
@@ -510,8 +502,11 @@ The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 t
 */
 void vlistCopyFlag(int vlistID2, int vlistID1)
 {
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
+
   vlist_copy(vlistptr2, vlistptr1);
 
   vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
@@ -526,83 +521,44 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
       vlistptr2->nzaxis = 0;
 
       for ( int varID = 0; varID < nvars; varID++ )
-        nvars2 += (vlistptr1->vars[varID].flag != 0);
+        nvars2 += (vars1[varID].flag != 0);
 
       vlistptr2->nvars = nvars2;
       vlistptr2->varsAllocated = nvars2;
       if ( nvars2 > 0 )
-        vlistptr2->vars  = (var_t *)xmalloc((size_t)nvars2*sizeof(var_t));
+        vars2 = (var_t *)xmalloc((size_t)nvars2*sizeof(var_t));
       else
-        vlistptr2->vars  = NULL;
+        vars2 = NULL;
+
+      vlistptr2->vars = vars2;
 
       varID2 = 0;
       for ( int varID = 0; varID < nvars; varID++ )
-	if ( vlistptr1->vars[varID].flag )
+	if ( vars1[varID].flag )
 	  {
-	    vlistptr2->vars[varID2].flag = FALSE;
-	    int zaxisID = vlistptr1->vars[varID].zaxisID;
-	    int gridID  = vlistptr1->vars[varID].gridID;
-
-	    memcpy(&vlistptr2->vars[varID2], &vlistptr1->vars[varID], sizeof(var_t));
-
-	    vlistptr1->vars[varID].fvarID = varID2;
-	    vlistptr2->vars[varID2].fvarID = varID;
-
-	    vlistptr2->vars[varID2].mvarID = varID2;
+	    vars2[varID2].flag = FALSE;
+	    int zaxisID = vars1[varID].zaxisID;
+	    int gridID  = vars1[varID].gridID;
 
-	    if ( vlistptr1->vars[varID].name )
-	      vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);
+	    memcpy(&vars2[varID2], &vars1[varID], sizeof(var_t));
 
-	    if ( vlistptr1->vars[varID].longname )
-	      vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);
+	    vars1[varID].fvarID = varID2;
+	    vars2[varID2].fvarID = varID;
 
-	    if ( vlistptr1->vars[varID].stdname )
-	      vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);
+	    vars2[varID2].mvarID = varID2;
 
-	    if ( vlistptr1->vars[varID].units )
-	      vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
-
-            if ( vlistptr1->vars[varID].ensdata )
-              {
-                vlistptr2->vars[varID2].ensdata = (ensinfo_t *)xmalloc(sizeof(ensinfo_t));
-                memcpy(vlistptr2->vars[varID2].ensdata,
-                       vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
-              }
-
-#if  defined  (HAVE_LIBGRIB_API)
-	    /* ---------------------------------- */
-	    /* Local change: 2013-01-28, FP (DWD) */
-	    /* ---------------------------------- */
-
-	    int i;
-	    vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-	    for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
-	      if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-		vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-		vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-                vlistptr2->vars[varID2].opt_grib_int_update[i]  = TRUE;
-	      }
-	    }
-	    vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-	    for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
-	      if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-		vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-                vlistptr2->vars[varID2].opt_grib_dbl_update[i]  = TRUE;
-	      }
-	    }
-#endif
+            var_copy_entries(&vars2[varID2], &vars1[varID]);
 
-	    vlistptr2->vars[varID2].atts.nelems = 0;
+	    vars2[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
-	    int nlevs  = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+	    int nlevs  = zaxisInqSize(vars1[varID].zaxisID);
 	    int nlevs2 = 0;
-            if ( vlistptr1->vars[varID].levinfo )
+            if ( vars1[varID].levinfo )
               for ( int levID = 0; levID < nlevs; levID++ )
-                nlevs2 += (vlistptr1->vars[varID].levinfo[levID].flag != 0);
+                nlevs2 += (vars1[varID].levinfo[levID].flag != 0);
 
-	    vlistptr2->vars[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs2 * sizeof (levinfo_t));
+	    vars2[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs2 * sizeof(levinfo_t));
 
 	    if ( nlevs != nlevs2 )
 	      {
@@ -611,16 +567,16 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 		const double *vct = NULL;
                 char ctemp[CDI_MAX_NAME];
 
-		zaxisID = vlistptr1->vars[varID].zaxisID;
+		zaxisID = vars1[varID].zaxisID;
 		double *levels = (double *)xmalloc((size_t)nlevs2 * sizeof (double));
                 int levID2 = 0;
-                if (!vlistptr1->vars[varID].levinfo)
+                if ( !vars1[varID].levinfo )
                   cdiVlistCreateVarLevInfo(vlistptr1, varID);
                 for ( int levID = 0; levID < nlevs; ++levID )
-                  if ( vlistptr1->vars[varID].levinfo[levID].flag )
+                  if ( vars1[varID].levinfo[levID].flag )
                     {
-                      vlistptr1->vars[varID].levinfo[levID].flevelID = levID2;
-                      vlistptr1->vars[varID].levinfo[levID].mlevelID = levID2;
+                      vars1[varID].levinfo[levID].flevelID = levID2;
+                      vars1[varID].levinfo[levID].mlevelID = levID2;
                       levels[levID2++] = zaxisInqLevel(zaxisID, levID);
                     }
 		int zaxisType = zaxisInqType(zaxisID);
@@ -644,7 +600,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
                     int levID2 = 0;
                     for ( int levID = 0; levID < nlevs; ++levID )
-                      if ( vlistptr1->vars[varID].levinfo[levID].flag )
+                      if ( vars1[varID].levinfo[levID].flag )
                         {
                           lbounds[levID2] = lbounds1[levID];
                           ubounds[levID2] = ubounds1[levID];
@@ -666,21 +622,21 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                 zaxisDefUnits(zaxisID2, ctemp);
 
 		zaxisID = zaxisID2;
-		vlistptr2->vars[varID2].zaxisID = zaxisID2;
+		vars2[varID2].zaxisID = zaxisID2;
 	      }
 
 	    for ( int levID = 0; levID < nlevs2; levID++ )
 	      {
-		vlistptr2->vars[varID2].levinfo[levID].flag  = FALSE;
-		vlistptr2->vars[varID2].levinfo[levID].index = -1;
+		vars2[varID2].levinfo[levID].flag  = FALSE;
+		vars2[varID2].levinfo[levID].index = -1;
 	      }
 
 	    int levID2 = 0;
 	    for ( int levID = 0; levID < nlevs; levID++ )
-	      if ( vlistptr1->vars[varID].levinfo[levID].flag )
+	      if ( vars1[varID].levinfo[levID].flag )
 		{
-		  vlistptr2->vars[varID2].levinfo[levID2].flevelID = levID;
-		  vlistptr2->vars[varID2].levinfo[levID2].mlevelID = levID;
+		  vars2[varID2].levinfo[levID2].flevelID = levID;
+		  vars2[varID2].levinfo[levID2].mlevelID = levID;
 		  levID2++;
 		}
 
@@ -708,9 +664,10 @@ Concatenate the variable list vlistID1 at the end of vlistID2.
 */
 void vlistCat(int vlistID2, int vlistID1)
 {
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
-
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
   int nvars1 = vlistptr1->nvars;
   int nvars2 = vlistptr2->nvars;
   int nvars = nvars1 + nvars2;
@@ -719,87 +676,43 @@ void vlistCat(int vlistID2, int vlistID1)
   if ( nvars > vlistptr2->varsAllocated )
     {
       vlistptr2->varsAllocated = nvars;
-      vlistptr2->vars = xrealloc(vlistptr2->vars,
-                                 (size_t)nvars * sizeof (var_t));
+      vars2 = xrealloc(vars2, (size_t)nvars*sizeof(var_t));
+      vlistptr2->vars = vars2;
     }
-  memcpy(vlistptr2->vars+nvars2, vlistptr1->vars,
-         (size_t)nvars1 * sizeof (var_t));
+  memcpy(vars2+nvars2, vars1, (size_t)nvars1 * sizeof(var_t));
 
-  for (int varID = 0; varID < nvars1; varID++ )
+  for ( int varID = 0; varID < nvars1; varID++ )
     {
       int varID2 = varID + nvars2;
-      vlistptr1->vars[varID].fvarID = varID2;
-      vlistptr2->vars[varID2].fvarID = varID;
+      vars1[varID].fvarID = varID2;
+      vars2[varID2].fvarID = varID;
 
-      vlistptr1->vars[varID].mvarID = varID2;
-      vlistptr2->vars[varID2].mvarID = varID;
+      vars1[varID].mvarID = varID2;
+      vars2[varID2].mvarID = varID;
 
-      if ( vlistptr1->vars[varID].param < 0 )
+      if ( vars1[varID].param < 0 )
 	{
 	  int pnum, pcat, pdis;
-	  cdiDecodeParam(vlistptr1->vars[varID].param, &pnum, &pcat, &pdis);
+	  cdiDecodeParam(vars1[varID].param, &pnum, &pcat, &pdis);
 	  pnum = -(varID2+1);
-	  vlistptr2->vars[varID2].param = cdiEncodeParam(pnum, pcat, pdis);
+	  vars2[varID2].param = cdiEncodeParam(pnum, pcat, pdis);
 	}
 
-      if ( vlistptr1->vars[varID].name )
-        vlistptr2->vars[varID2].name = strdupx(vlistptr1->vars[varID].name);
-
-      if ( vlistptr1->vars[varID].longname )
-        vlistptr2->vars[varID2].longname = strdupx(vlistptr1->vars[varID].longname);
-
-      if ( vlistptr1->vars[varID].stdname )
-        vlistptr2->vars[varID2].stdname = strdupx(vlistptr1->vars[varID].stdname);
-
-      if ( vlistptr1->vars[varID].units )
-        vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
-
-      int nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-      if (vlistptr1->vars[varID].levinfo)
-        {
-          vlistptr2->vars[varID2].levinfo
-            = (levinfo_t *)xmalloc((size_t)nlevs * sizeof (levinfo_t));
-          memcpy(vlistptr2->vars[varID2].levinfo,
-                 vlistptr1->vars[varID].levinfo,
-                 (size_t)nlevs * sizeof (levinfo_t));
-        }
+      var_copy_entries(&vars2[varID2], &vars1[varID]);
 
-      if ( vlistptr1->vars[varID].ensdata )
+      int nlevs = zaxisInqSize(vars1[varID].zaxisID);
+      if ( vars1[varID].levinfo )
         {
-          vlistptr2->vars[varID2].ensdata = (ensinfo_t *) malloc(sizeof(ensinfo_t));
-          memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
+          vars2[varID2].levinfo = (levinfo_t *)xmalloc((size_t)nlevs * sizeof(levinfo_t));
+          memcpy(vars2[varID2].levinfo, vars1[varID].levinfo,
+                 (size_t)nlevs * sizeof(levinfo_t));
         }
 
-#if  defined  (HAVE_LIBGRIB_API)
-      /* ---------------------------------- */
-      /* Local change: 2013-01-28, FP (DWD) */
-      /* ---------------------------------- */
-
-      vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
-      int n = vlistptr1->vars[varID].opt_grib_int_nentries;
-      for (int i = 0; i < n; ++i) {
-	if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
-	  vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
-	  vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
-          vlistptr2->vars[varID2].opt_grib_int_update[i]  = TRUE;
-	}
-      }
-      vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-      n = vlistptr1->vars[varID].opt_grib_dbl_nentries;
-      for (int i = 0; i < n; i++) {
-	if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
-	  vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
-	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
-          vlistptr2->vars[varID2].opt_grib_dbl_update[i]  = TRUE;
-	}
-      }
-#endif
-
-      vlistptr2->vars[varID2].atts.nelems = 0;
+      vars2[varID2].atts.nelems = 0;
       vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
-      vlistAdd2GridIDs(vlistptr2, vlistptr1->vars[varID].gridID);
-      vlistAdd2ZaxisIDs(vlistptr2, vlistptr1->vars[varID].zaxisID);
+      vlistAdd2GridIDs(vlistptr2, vars1[varID].gridID);
+      vlistAdd2ZaxisIDs(vlistptr2, vars1[varID].zaxisID);
     }
 }
 
@@ -820,9 +733,10 @@ Merge the variable list vlistID1 to the variable list vlistID2.
 void vlistMerge(int vlistID2, int vlistID1)
 {
   int varID = 0;
-  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1),
-    *vlistptr2 = vlist_to_pointer(vlistID2);
-
+  vlist_t *vlistptr1 = vlist_to_pointer(vlistID1);
+  vlist_t *vlistptr2 = vlist_to_pointer(vlistID2);
+  var_t *vars1 = vlistptr1->vars;
+  var_t *vars2 = vlistptr2->vars;
   int nvars1 = vlistptr1->nvars;
   int nvars2 = vlistptr2->nvars;
 
@@ -830,15 +744,17 @@ void vlistMerge(int vlistID2, int vlistID1)
     {
       for ( varID = 0; varID < nvars2; varID++ )
 	{
-	  if ( vlistptr1->vars[varID].name && vlistptr2->vars[varID].name )
+          int ngp1 = gridInqSize(vars1[varID].gridID);
+          int ngp2 = gridInqSize(vars2[varID].gridID);
+          if ( ngp1 != ngp2 ) break;
+
+	  if ( vars1[varID].name && vars2[varID].name )
 	    {
-	      if ( strcmp(vlistptr1->vars[varID].name,
-			  vlistptr2->vars[varID].name) != 0 ) break;
+	      if ( strcmp(vars1[varID].name, vars2[varID].name) != 0 ) break;
 	    }
 	  else
 	    {
-	      if ( vlistptr1->vars[varID].param != vlistptr2->vars[varID].param )
-		break;
+	      if ( vars1[varID].param != vars2[varID].param ) break;
 	    }
 	}
     }
@@ -847,36 +763,33 @@ void vlistMerge(int vlistID2, int vlistID1)
     {
       for ( varID = 0; varID < nvars2; varID++ )
         {
-          vlistptr1->vars[varID].fvarID = varID;
-          vlistptr2->vars[varID].fvarID = varID;
+          vars1[varID].fvarID = varID;
+          vars2[varID].fvarID = varID;
 
-          vlistptr1->vars[varID].mvarID = varID;
-          vlistptr2->vars[varID].mvarID = varID;
+          vars1[varID].mvarID = varID;
+          vars2[varID].mvarID = varID;
 
-          int nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-          int nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
+          int nlevs1 = zaxisInqSize(vars1[varID].zaxisID);
+          int nlevs2 = zaxisInqSize(vars2[varID].zaxisID);
 
           int nlevs = nlevs1 + nlevs2;
 
           /*
           fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
           */
-          if (vlistptr1->vars[varID].levinfo)
+          if ( vars1[varID].levinfo )
             {
-              vlistptr2->vars[varID].levinfo =
-                (levinfo_t*)xrealloc(vlistptr2->vars[varID].levinfo,
+              vars2[varID].levinfo = (levinfo_t*)xrealloc(vars2[varID].levinfo,
                                      (size_t)nlevs * sizeof(levinfo_t));
 
-              memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
-                     vlistptr1->vars[varID].levinfo,
-                     (size_t)nlevs1 * sizeof (levinfo_t));
+              memcpy(vars2[varID].levinfo+nlevs2, vars1[varID].levinfo,
+                     (size_t)nlevs1 * sizeof(levinfo_t));
             }
           else
             cdiVlistCreateVarLevInfo(vlistptr1, varID);
+
 	  for ( int levID = 0; levID < nlevs1; levID++ )
-	    {
-	      vlistptr1->vars[varID].levinfo[levID].mlevelID = nlevs2 + levID;
-	    }
+            vars1[varID].levinfo[levID].mlevelID = nlevs2 + levID;
 	}
 
       int *lvar = (int *)xcalloc((size_t)nvars2, sizeof(int));
@@ -885,11 +798,11 @@ void vlistMerge(int vlistID2, int vlistID1)
         {
           if ( lvar[varID] == TRUE ) continue;
 
-          int zaxisID1 = vlistptr1->vars[varID].zaxisID;
-          int zaxisID2 = vlistptr2->vars[varID].zaxisID;
+          int zaxisID1 = vars1[varID].zaxisID;
+          int zaxisID2 = vars2[varID].zaxisID;
           /*
-          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
-          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
+          nlevs1 = zaxisInqSize(vars1[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vars2[varID].zaxisID);
           */
           int nlevs1 = zaxisInqSize(zaxisID1);
           int nlevs2 = zaxisInqSize(zaxisID2);
@@ -907,7 +820,7 @@ void vlistMerge(int vlistID2, int vlistID1)
           zaxisInqLevels(zaxisID1, levels);
           /*
           for ( levID = 0; levID < nlevs1; levID++ )
-            fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vlistptr2->vars[varID].nlevs, levels[levID]);
+            fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
           */
           for ( int levID = 0; levID < nlevs1; levID++ )
             zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
@@ -919,9 +832,9 @@ void vlistMerge(int vlistID2, int vlistID1)
               vlistptr2->zaxisIDs[index] = zaxisID;
 
           for ( int varID2 = 0; varID2 < nvars2; varID2++ )
-            if ( lvar[varID2] == FALSE && vlistptr2->vars[varID2].zaxisID == zaxisID2 )
+            if ( lvar[varID2] == FALSE && vars2[varID2].zaxisID == zaxisID2 )
               {
-                vlistptr2->vars[varID2].zaxisID = zaxisID;
+                vars2[varID2].zaxisID = zaxisID;
                 lvar[varID2] = TRUE;
               }
         }
@@ -1176,6 +1089,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 
   if (vlistptr->taxisID != taxisID)
     {
+      //FIXME: This code seems to leak a taxis_t object if `vlistptr->taxisID` was valid before the call to vlistDefTaxis.
       vlistptr->taxisID = taxisID;
       reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
     }
diff --git a/libcdi/src/vlist.h b/libcdi/src/vlist.h
index fa0b878..5a4ff73 100644
--- a/libcdi/src/vlist.h
+++ b/libcdi/src/vlist.h
@@ -5,10 +5,14 @@
 #include "config.h"
 #endif
 
+#ifndef  _ERROR_H
+#include "error.h"
+#endif
+
 #include <stddef.h>  /* size_t */
 
 #ifndef _CDI_LIMITS_H
-#  include "cdi_limits.h"
+#include "cdi_limits.h"
 #endif
 
 #define VALIDMISS 1.e+303
@@ -148,6 +152,7 @@ vlist_t;
 
 
 vlist_t *vlist_to_pointer(int vlistID);
+void vlistCheckVarID(const char *caller, int vlistID, int varID);
 const char *vlistInqVarNamePtr(int vlistID, int varID);
 const char *vlistInqVarLongnamePtr(int vlistID, int varID);
 const char *vlistInqVarStdnamePtr(int vlistID, int varID);
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index 432d457..1217bc1 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -14,6 +14,14 @@
 #include "namespace.h"
 #include "serialize.h"
 #include "error.h"
+#include "proprietarySystemWorkarounds.h"
+
+#if  defined  (HAVE_LIBGRIB_API)
+#  include "file.h"
+
+#  include <grib_api.h>
+#endif
+
 
 static
 void vlistvarInitEntry(int vlistID, int varID)
@@ -128,7 +136,6 @@ int vlistvarNewEntry(int vlistID)
   return (varID);
 }
 
-static
 void vlistCheckVarID(const char *caller, int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
@@ -496,12 +503,55 @@ void vlistInqVarName(int vlistID, int varID, char *name)
 	}
     }
   else
-    strcpy(name, vlistptr->vars[varID].name);
+    strcpy(name, vlistptr->vars[varID].name);   //FIXME: This may overrun the provided buffer.
 
   return;
 }
 
 /*
+ at Function vlistCopyVarName
+ at Tatle    Get the name of a Variable in a safe way
+
+ at Prototype char* vlistCopyVarName(int vlistId, int varId)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+
+ at Return A pointer to a malloc'ed string. Must be cleaned up with free().
+
+ at Description
+This is the buffer overflow immune version of vlistInqVarName().
+The memory for the returned string is allocated to fit the string via malloc().
+
+ at EndFunction
+*/
+char* vlistCopyVarName(int vlistId, int varId)
+{
+  vlist_t* vlistptr = vlist_to_pointer(vlistId);
+  vlistCheckVarID(__func__, vlistId, varId);
+
+  //If a name is set in the variable description, use that.
+  const char* name = vlistptr->vars[varId].name;
+  if(name) return myStrDup(name);
+
+  //Otherwise we check if we should use the table of parameter descriptions.
+  int param = vlistptr->vars[varId].param;
+  int discipline, category, number;
+  cdiDecodeParam(param, &number, &category, &discipline);
+  if(discipline == 255)
+    {
+      int tableId = vlistptr->vars[varId].tableID;
+      if(( name = tableInqParNamePtr(tableId, number) )) return myStrDup(name);
+
+      //No luck, fall back to outputting a name of the format "var<num>".
+      return myAsprintf("var%d", number);
+    }
+
+  //Finally, we fall back to outputting a name of the format "param<num>.<cat>.<dis>".
+  return myAsprintf("param%d.%d.%d", number, category, discipline);
+}
+
+/*
 @Function  vlistInqVarLongname
 @Title     Get the longname of a Variable
 
@@ -1773,11 +1823,6 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
 #endif
 }
 
-#if  defined  (HAVE_LIBGRIB_API)
-#  include "file.h"
-#  include "grib_api.h"
-#endif
-
 
 /* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
 void cdiClearAdditionalKeys()
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index 16dd437..641808b 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -94,7 +94,7 @@ static int    zaxisGetPackSize ( void * zaxisptr, void *context);
 static void   zaxisPack        ( void * zaxisptr, void * buffer, int size, int *pos, void *context);
 static int    zaxisTxCode      ( void );
 
-static const resOps zaxisOps = {
+const resOps zaxisOps = {
   (int (*)(void *, void *))zaxisCompareP,
   zaxisDestroyP,
   zaxisPrintP,
@@ -105,6 +105,26 @@ static const resOps zaxisOps = {
 
 static int  ZAXIS_Debug = 0;   /* If set to 1, debugging */
 
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit)
+{
+  if(zaxisType < 0 || zaxisType >= CDI_NumZaxistype)
+    {
+      if(outPositive) *outPositive = 0;
+      if(outName) *outName = NULL;
+      if(outLongName) *outLongName = NULL;
+      if(outStdName) *outStdName = NULL;
+      if(outUnit) *outUnit = NULL;
+    }
+  else
+    {
+      if(outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
+      if(outName) *outName = ZaxistypeEntry[zaxisType].name;
+      if(outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
+      if(outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
+      if(outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
+    }
+}
+
 static
 void zaxisDefaultValue(zaxis_t *zaxisptr)
 {
@@ -172,9 +192,9 @@ void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
   zaxisptr2->self = zaxisID2;
 }
 
-int zaxisSize(void)
+unsigned cdiZaxisCount(void)
 {
-  return reshCountType ( &zaxisOps );
+  return reshCountType(&zaxisOps);
 }
 
 static int
@@ -708,6 +728,7 @@ void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
 @Prototype void zaxisInqUUID(int zaxisID, char *uuid)
 @Parameter
     @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item uuid A user supplied buffer of at least 16 bytes.
 
 @Description
 The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
@@ -1136,25 +1157,23 @@ int zaxisDuplicate(int zaxisID)
 }
 
 
-void zaxisPrintKernel ( zaxis_t * zaxisptr, FILE * fp )
+void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
 {
-  int zaxisID;
-  int type;
   unsigned char uuid[CDI_UUID_SIZE];
-  int nlevels, levelID;
-  int nbyte0, nbyte;
+  int levelID;
+  int nbyte;
   double level;
 
   xassert ( zaxisptr );
 
-  zaxisID = zaxisptr->self;
+  int zaxisID = zaxisptr->self;
 
-  type    = zaxisptr->type;
-  nlevels = zaxisptr->size;
+  int type    = zaxisptr->type;
+  int nlevels = zaxisptr->size;
 
-  nbyte0 = 0;
+  int nbyte0 = 0;
   fprintf(fp, "#\n");
-  fprintf(fp, "# zaxisID %d\n", zaxisID);
+  fprintf(fp, "# zaxisID %d\n", index);
   fprintf(fp, "#\n");
   fprintf(fp, "zaxistype = %s\n", zaxisNamePtr(type));
   fprintf(fp, "size      = %d\n", nlevels);
@@ -1249,11 +1268,11 @@ void zaxisPrintKernel ( zaxis_t * zaxisptr, FILE * fp )
 }
 
 
-void zaxisPrint ( int zaxisID )
+void zaxisPrint ( int zaxisID, int index )
 {
   zaxis_t *zaxisptr = reshGetVal(zaxisID, &zaxisOps);
 
-  zaxisPrintKernel ( zaxisptr, stdout );
+  zaxisPrintKernel ( zaxisptr, index, stdout );
 }
 
 
@@ -1264,7 +1283,7 @@ void zaxisPrintP ( void * voidptr, FILE * fp )
 
   xassert ( zaxisptr );
 
-  zaxisPrintKernel(zaxisptr, fp);
+  zaxisPrintKernel(zaxisptr, zaxisptr->self, fp);
 }
 
 
@@ -1638,9 +1657,9 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 }
 
 
-void zaxisGetIndexList ( int nzaxis, int * zaxisResHs )
+void cdiZaxisGetIndexList(unsigned nzaxis, int zaxisResHs[nzaxis])
 {
-  reshGetResHListOfType ( nzaxis, zaxisResHs, &zaxisOps );
+  reshGetResHListOfType(nzaxis, zaxisResHs, &zaxisOps);
 }
 
 #undef ZAXIS_STR_SERIALIZE
diff --git a/libcdi/src/zaxis.h b/libcdi/src/zaxis.h
index 133316d..7d97553 100644
--- a/libcdi/src/zaxis.h
+++ b/libcdi/src/zaxis.h
@@ -1,11 +1,21 @@
 #ifndef _ZAXIS_H
 #define _ZAXIS_H
 
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit);  //The returned const char* point to static storage. Don't free or modify them.
+
 int zaxisSize(void);
 
+unsigned cdiZaxisCount(void);
+
+void cdiZaxisGetIndexList(unsigned numIDs, int IDs[numIDs]);
+
 void
 zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
             int * unpackBufferPos, int originNamespace, void *context,
             int force_id);
 
+void zaxisDefLtype2(int zaxisID, int ltype2);
+
+extern const resOps zaxisOps;
+
 #endif
diff --git a/libcdi/tests/Makefile.am b/libcdi/tests/Makefile.am
index a9b841a..f258bfd 100644
--- a/libcdi/tests/Makefile.am
+++ b/libcdi/tests/Makefile.am
@@ -26,27 +26,24 @@ cksum_read_SOURCES = cksum_read.c \
 	stream_cksum.c stream_cksum.h \
 	ensure_array_size.h ensure_array_size.c
 pio_write_SOURCES = pio_write.c pio_write.h simple_model.c \
-	simple_model_helper.h simple_model_helper.c \
-	create_uuid.h create_uuid.c
+	simple_model_helper.h simple_model_helper.c
 pio_write_deco2d_SOURCES = pio_write.c pio_write.h deco2d_model.c \
-	simple_model_helper.h simple_model_helper.c \
-	create_uuid.h create_uuid.c
-test_resource_copy_SOURCES = test_resource_copy.c \
-	create_uuid.h create_uuid.c
+	simple_model_helper.h simple_model_helper.c
+test_resource_copy_SOURCES = test_resource_copy.c
 test_resource_copy_LDADD = $(UUID_C_LIB) ../src/libcdiresunpack.la $(LDADD)
-test_resource_copy_mpi_SOURCES = test_resource_copy.c \
-	create_uuid.h create_uuid.c
+test_resource_copy_mpi_SOURCES = test_resource_copy.c
 test_cdf_write_SOURCES = test_cdf_write.c
 test_cdf_read_SOURCES = test_cdf_read.c
-
-AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
+#
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
 if USE_MPI
-pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
-pio_write_deco2d_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
+pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)
+pio_write_deco2d_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)
 TESTS +=  test_resource_copy_mpi_run
 check_PROGRAMS += test_resource_copy_mpi
 test_resource_copy_mpi_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
-test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) -DMPI_MARSHALLING
+test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \
+	-DMPI_MARSHALLING
 else
 pio_write_LDADD = $(LDADD) $(UUID_C_LIB)
 pio_write_deco2d_LDADD = $(LDADD) $(UUID_C_LIB)
diff --git a/libcdi/tests/Makefile.in b/libcdi/tests/Makefile.in
index fb5a73d..2cd6def 100644
--- a/libcdi/tests/Makefile.in
+++ b/libcdi/tests/Makefile.in
@@ -109,17 +109,26 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
+	$(top_srcdir)/m4/acx_c_package.m4 \
 	$(top_srcdir)/m4/acx_check_strptr_convert.m4 \
 	$(top_srcdir)/m4/acx_execinfo.m4 \
+	$(top_srcdir)/m4/acx_fortran_package.m4 \
+	$(top_srcdir)/m4/acx_lang_check_include.m4 \
 	$(top_srcdir)/m4/acx_lang_other_suffix_conftest.m4 \
+	$(top_srcdir)/m4/acx_lang_package.m4 \
+	$(top_srcdir)/m4/acx_option_search_libs.m4 \
 	$(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/acx_sl_fc_mod_path_flag.m4 \
 	$(top_srcdir)/m4/acx_sl_mod_suffix.m4 \
-	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.m4 \
-	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
-	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/asx_tr_arg.m4 $(top_srcdir)/m4/asx_unset.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/starlink_fpp.m4 \
+	$(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/m4/ac_lang_program_fortran.m4 \
+	$(top_srcdir)/m4/acx_lang_fortran_check_include.m4 \
+	$(top_srcdir)/m4/acx_lang_c_check_include.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -159,22 +168,21 @@ cksum_write_chunk_OBJECTS = $(am_cksum_write_chunk_OBJECTS)
 cksum_write_chunk_LDADD = $(LDADD)
 cksum_write_chunk_DEPENDENCIES = ../src/libcdi.la
 am_pio_write_OBJECTS = pio_write.$(OBJEXT) simple_model.$(OBJEXT) \
-	simple_model_helper.$(OBJEXT) create_uuid.$(OBJEXT)
+	simple_model_helper.$(OBJEXT)
 pio_write_OBJECTS = $(am_pio_write_OBJECTS)
 am__DEPENDENCIES_1 = ../src/libcdi.la
 am__DEPENDENCIES_2 =
 @USE_MPI_FALSE at pio_write_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 @USE_MPI_FALSE@	$(am__DEPENDENCIES_2)
 @USE_MPI_TRUE at pio_write_DEPENDENCIES = ../src/libcdipio.la \
- at USE_MPI_TRUE@	$(am__DEPENDENCIES_2)
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2)
 am_pio_write_deco2d_OBJECTS = pio_write.$(OBJEXT) \
-	deco2d_model.$(OBJEXT) simple_model_helper.$(OBJEXT) \
-	create_uuid.$(OBJEXT)
+	deco2d_model.$(OBJEXT) simple_model_helper.$(OBJEXT)
 pio_write_deco2d_OBJECTS = $(am_pio_write_deco2d_OBJECTS)
 @USE_MPI_FALSE at pio_write_deco2d_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 @USE_MPI_FALSE@	$(am__DEPENDENCIES_2)
 @USE_MPI_TRUE at pio_write_deco2d_DEPENDENCIES = ../src/libcdipio.la \
- at USE_MPI_TRUE@	$(am__DEPENDENCIES_2)
+ at USE_MPI_TRUE@	$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2)
 am_test_cdf_read_OBJECTS = test_cdf_read.$(OBJEXT)
 test_cdf_read_OBJECTS = $(am_test_cdf_read_OBJECTS)
 test_cdf_read_LDADD = $(LDADD)
@@ -187,14 +195,12 @@ am_test_grib_OBJECTS = test_grib.$(OBJEXT)
 test_grib_OBJECTS = $(am_test_grib_OBJECTS)
 test_grib_LDADD = $(LDADD)
 test_grib_DEPENDENCIES = ../src/libcdi.la
-am_test_resource_copy_OBJECTS = test_resource_copy.$(OBJEXT) \
-	create_uuid.$(OBJEXT)
+am_test_resource_copy_OBJECTS = test_resource_copy.$(OBJEXT)
 test_resource_copy_OBJECTS = $(am_test_resource_copy_OBJECTS)
 test_resource_copy_DEPENDENCIES = $(am__DEPENDENCIES_2) \
 	../src/libcdiresunpack.la $(am__DEPENDENCIES_1)
 am_test_resource_copy_mpi_OBJECTS =  \
-	test_resource_copy_mpi-test_resource_copy.$(OBJEXT) \
-	test_resource_copy_mpi-create_uuid.$(OBJEXT)
+	test_resource_copy_mpi-test_resource_copy.$(OBJEXT)
 test_resource_copy_mpi_OBJECTS = $(am_test_resource_copy_mpi_OBJECTS)
 @USE_MPI_FALSE at test_resource_copy_mpi_DEPENDENCIES =  \
 @USE_MPI_FALSE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
@@ -331,6 +337,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -378,6 +385,11 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MPIROOT = @MPIROOT@
+MPI_C_INCLUDE = @MPI_C_INCLUDE@
+MPI_C_LIB = @MPI_C_LIB@
+MPI_FC_INCLUDE = @MPI_FC_INCLUDE@
+MPI_FC_LIB = @MPI_FC_LIB@
 MPI_LAUNCH = @MPI_LAUNCH@
 NC_CONFIG = @NC_CONFIG@
 NETCDF_INCLUDE = @NETCDF_INCLUDE@
@@ -496,30 +508,27 @@ cksum_read_SOURCES = cksum_read.c \
 	ensure_array_size.h ensure_array_size.c
 
 pio_write_SOURCES = pio_write.c pio_write.h simple_model.c \
-	simple_model_helper.h simple_model_helper.c \
-	create_uuid.h create_uuid.c
+	simple_model_helper.h simple_model_helper.c
 
 pio_write_deco2d_SOURCES = pio_write.c pio_write.h deco2d_model.c \
-	simple_model_helper.h simple_model_helper.c \
-	create_uuid.h create_uuid.c
-
-test_resource_copy_SOURCES = test_resource_copy.c \
-	create_uuid.h create_uuid.c
+	simple_model_helper.h simple_model_helper.c
 
+test_resource_copy_SOURCES = test_resource_copy.c
 test_resource_copy_LDADD = $(UUID_C_LIB) ../src/libcdiresunpack.la $(LDADD)
-test_resource_copy_mpi_SOURCES = test_resource_copy.c \
-	create_uuid.h create_uuid.c
-
+test_resource_copy_mpi_SOURCES = test_resource_copy.c
 test_cdf_write_SOURCES = test_cdf_write.c
 test_cdf_read_SOURCES = test_cdf_read.c
-AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
+#
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
 @USE_MPI_FALSE at pio_write_LDADD = $(LDADD) $(UUID_C_LIB)
- at USE_MPI_TRUE@pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
+ at USE_MPI_TRUE@pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)
 @USE_MPI_FALSE at pio_write_deco2d_LDADD = $(LDADD) $(UUID_C_LIB)
- at USE_MPI_TRUE@pio_write_deco2d_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
+ at USE_MPI_TRUE@pio_write_deco2d_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)
 @USE_MPI_FALSE at test_resource_copy_mpi_LDADD = $(LDADD) $(UUID_C_LIB)
 @USE_MPI_TRUE at test_resource_copy_mpi_LDADD = ../src/libcdipio.la $(UUID_C_LIB)
- at USE_MPI_TRUE@test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) -DMPI_MARSHALLING
+ at USE_MPI_TRUE@test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \
+ at USE_MPI_TRUE@	-DMPI_MARSHALLING
+
 LDADD = ../src/libcdi.la -lm
 AM_CPPFLAGS = -I$(top_srcdir)/src
 #
@@ -662,7 +671,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_verify.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_write.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_write_chunk.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/create_uuid.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/deco2d_model.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ensure_array_size.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_write.Po at am__quote@
@@ -673,7 +681,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_cdf_write.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_grib.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_resource_copy.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_resource_copy_mpi-create_uuid.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/var_cksum.Po at am__quote@
 
@@ -712,20 +719,6 @@ test_resource_copy_mpi-test_resource_copy.obj: test_resource_copy.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -c -o test_resource_copy_mpi-test_resource_copy.obj `if test -f 'test_resource_copy.c'; then $(CYGPATH_W) 'test_resource_copy.c'; else $(CYGPATH_W) '$(srcdir)/test_resource_copy.c'; fi`
 
-test_resource_copy_mpi-create_uuid.o: create_uuid.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -MT test_resource_copy_mpi-create_uuid.o -MD -MP -MF $(DEPDIR)/test_resource_copy_mpi-create_uuid.Tpo -c -o test_resource_copy_mpi-create_uuid.o `test -f 'create_uuid.c' || echo '$(srcdir)/'`create_uuid.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_resource_copy_mpi-create_uuid.Tpo $(DEPDIR)/test_resource_copy_mpi-create_uuid.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='create_uuid.c' object='test_resource_copy_mpi-create_uuid.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -c -o test_resource_copy_mpi-create_uuid.o `test -f 'create_uuid.c' || echo '$(srcdir)/'`create_uuid.c
-
-test_resource_copy_mpi-create_uuid.obj: create_uuid.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -MT test_resource_copy_mpi-create_uuid.obj -MD -MP -MF $(DEPDIR)/test_resource_copy_mpi-create_uuid.Tpo -c -o test_resource_copy_mpi-create_uuid.obj `if test -f 'create_uuid.c'; then $(CYGPATH_W) 'create_uuid.c'; else $(CYGPATH_W) '$(srcdir)/create_uuid.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_resource_copy_mpi-create_uuid.Tpo $(DEPDIR)/test_resource_copy_mpi-create_uuid.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='create_uuid.c' object='test_resource_copy_mpi-create_uuid.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -c -o test_resource_copy_mpi-create_uuid.obj `if test -f 'create_uuid.c'; then $(CYGPATH_W) 'create_uuid.c'; else $(CYGPATH_W) '$(srcdir)/create_uuid.c'; fi`
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/libcdi/tests/create_uuid.c b/libcdi/tests/create_uuid.c
deleted file mode 100644
index d15e3d1..0000000
--- a/libcdi/tests/create_uuid.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
-#endif
-
-#define _XOPEN_SOURCE 600
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "create_uuid.h"
-
-
-
-#ifdef HAVE_DECL_UUID_GENERATE
-#include <sys/time.h>
-#include <uuid/uuid.h>
-void
-create_uuid(unsigned char *uuid)
-{
-  static int uuid_seeded = 0;
-  static char uuid_rand_state[31 * sizeof (long)];
-  char *caller_rand_state;
-  if (uuid_seeded)
-    caller_rand_state = setstate(uuid_rand_state);
-  else
-    {
-      struct timeval tv;
-      int status = gettimeofday(&tv, NULL);
-      if (status != 0)
-        {
-          perror("uuid random seed generation failed!");
-          exit(1);
-        }
-      unsigned seed = (unsigned)(tv.tv_sec ^ tv.tv_usec);
-      caller_rand_state = initstate(seed, uuid_rand_state,
-                                    sizeof (uuid_rand_state));
-      uuid_seeded = 1;
-    }
-  uuid_generate(uuid);
-  setstate(caller_rand_state);
-}
-#elif defined (HAVE_DECL_UUID_CREATE)
-typedef uint8_t u_int8_t;
-typedef uint16_t u_int16_t;
-typedef uint32_t u_int32_t;
-#include <uuid.h>
-void
-create_uuid(unsigned char *uuid)
-{
-  unsigned32 status;
-  uuid_create((uuid_t *)uuid, &status);
-  if (status == -1)
-    {
-      perror("uuid generation failed!");
-      exit(1);
-    }
-}
-#else
-#include <sys/time.h>
-void
-create_uuid(unsigned char *uuid)
-{
-  static int uuid_seeded = 0;
-  static char uuid_rand_state[31 * sizeof (long)];
-  char *caller_rand_state;
-  if (uuid_seeded)
-    caller_rand_state = setstate(uuid_rand_state);
-  else
-    {
-      struct timeval tv;
-      int status = gettimeofday(&tv, NULL);
-      if (status != 0)
-        {
-          perror("failed seed generation!");
-          exit(1);
-        }
-      unsigned seed = tv.tv_sec ^ tv.tv_usec;
-      caller_rand_state = initstate(seed, uuid_rand_state,
-                                    sizeof (uuid_rand_state));
-      uuid_seeded = 1;
-    }
-  for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
-    uuid[i] = (unsigned char)random();
-  /* encode variant into msb of octet 8 */
-  uuid[8] = (unsigned char)((uuid[8] & 0x3f) | (1 << 7));
-  /* encode version 4 ((pseudo-)random uuid) into msb of octet 7 */
-  uuid[7] = (unsigned char)((uuid[7] & 0x0f) | (4 << 4));
-  setstate(caller_rand_state);
-}
-#endif
diff --git a/libcdi/util/sunf95preproc-wrapper b/libcdi/util/sunf95preproc-wrapper
index c3e4760..4427021 100755
--- a/libcdi/util/sunf95preproc-wrapper
+++ b/libcdi/util/sunf95preproc-wrapper
@@ -69,7 +69,11 @@ if [ "${FC+set}" != set ]; then
 fi
 FC=${FC-$F90C}
 # nagfor 5.3 up chokes on -EP flag
-nag=`$FC -V 2>&1 | sed -n '/^NAG/s/NAG Fortran Compiler.*/NAG/;t print;b;: print; p'`
+nag=`$FC -V 2>&1 | sed -n '/^NAG/s/NAG Fortran Compiler.*/NAG/
+t print
+b
+: print
+p'`
 [ x"$nag" = xNAG ] || FCFLAGS=${FCFLAGS--EP}
 # append -fpp if necessary
 IFStr=`echo "$IFS" | sed -n '$!s/$/\\\\n/
diff --git a/m4/._ax_pthread.m4 b/m4/._ax_pthread.m4
new file mode 100644
index 0000000..cddd2a5
Binary files /dev/null and b/m4/._ax_pthread.m4 differ
diff --git a/m4/acx_options.m4 b/m4/acx_options.m4
index a5eefc3..a3c77df 100644
--- a/m4/acx_options.m4
+++ b/m4/acx_options.m4
@@ -141,6 +141,7 @@ NETCDF_LIBS=''
 ENABLE_NETCDF=no
 ENABLE_NC2=no
 ENABLE_NC4=no
+ENABLE_NC4HDF5=no
 AC_ARG_WITH([netcdf],
             [AS_HELP_STRING([--with-netcdf=<yes|no|directory> (default=no)],[location of netcdf library (lib and include subdirs)])],
             [AS_CASE(["$with_netcdf"],
@@ -153,6 +154,7 @@ AC_ARG_WITH([netcdf],
                                             ENABLE_NETCDF=yes],
                                            [AC_MSG_ERROR([Could not link to netcdf library])])
                             NETCDF_LIBS=" -lnetcdf"
+			    
                             AC_CHECK_PROG(NC_CONFIG,nc-config,nc-config)
                             AS_IF([test "x$NC_CONFIG" != "x"],
                                   [AC_MSG_CHECKING([netcdf's nc2 support])
@@ -164,7 +166,12 @@ AC_ARG_WITH([netcdf],
                                    AS_IF([test "x$($NC_CONFIG --has-nc4)" = "xyes"],
                                          [AC_DEFINE([HAVE_NETCDF4],[1],[Define to 1 for NETCDF4 support])
                                           ENABLE_NC4=yes
-                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])])],
+                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])])
+			           AC_MSG_CHECKING([netcdf's nc4/hdf5 support])
+                                   AS_IF([test "x$($NC_CONFIG --has-hdf5)" = "xyes"],
+                                         [AC_DEFINE([HAVE_NC4HDF5],[1],[Define to 1 for NETCDF4/HDF5 support])
+                                          ENABLE_NC4HDF5=yes
+                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])]) ],
                                   [AS_ECHO([Could not find nc-config! go on with default configuration])])],
                      [*],[AS_IF([test -d "$with_netcdf"],
                                 [NETCDF_ROOT=$with_netcdf
@@ -195,14 +202,26 @@ AC_ARG_WITH([netcdf],
                                    AS_IF([test "x$($NC_CONFIG --has-nc4)" = "xyes"],
                                          [AC_DEFINE([HAVE_NETCDF4],[1],[Define to 1 for NETCDF4 support])
                                           ENABLE_NC4=yes
-                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])])],
+                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])])
+			           AC_MSG_CHECKING([netcdf's nc4/hdf5 support])
+                                   AS_IF([test "x$($NC_CONFIG --has-hdf5)" = "xyes"],
+                                         [AC_DEFINE([HAVE_NC4HDF5],[1],[Define to 1 for NETCDF4/HDF5 support])
+                                          ENABLE_NC4HDF5=yes
+                                          AC_MSG_RESULT([yes])],[AC_MSG_RESULT([no])]) ],
                                    [AC_MSG_RESULT([Could not find nc-config! go on with default configuration])])],
                                 [AC_MSG_NOTICE([$with_netcdf is not a directory! NETCDF suppressed])])])],
             [AC_MSG_CHECKING([for NETCDF library])
              AC_MSG_RESULT([suppressed])])
+
+AS_IF([test "x$ENABLE_NC4HDF5" = "xyes"],
+      [AC_SEARCH_LIBS([H5TS_mutex_lock], [netcdf],
+               [AC_DEFINE([HAVE_NC4HDF5_THREADSAFE],[1],[Define to 1 for NETCDF4/HDF5 threadsafe support])],,
+	       [-lhdf5_hl -lhdf5])])
+
 AC_SUBST([ENABLE_NETCDF])
 AC_SUBST([ENABLE_NC2])
 AC_SUBST([ENABLE_NC4])
+AC_SUBST([ENABLE_NC4HDF5])
 AC_SUBST([NETCDF_ROOT])
 AC_SUBST([NETCDF_INCLUDE])
 AC_SUBST([NETCDF_LIBS])
diff --git a/src/Adisit.c b/src/Adisit.c
index adc0c8e..2d75ce1 100644
--- a/src/Adisit.c
+++ b/src/Adisit.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -178,7 +178,7 @@ void *Adisit(void *argument)
   int nvars, code, gridID, zaxisID;
   int vlistID1, vlistID2;
   int offset;
-  int ngrids, nlevel;
+  int nlevel;
   int i;
   int nmiss;
   int thoID = -1, saoID = -1;
@@ -198,7 +198,7 @@ void *Adisit(void *argument)
 
   operatorID = cdoOperatorID();
 
-  if ( operatorArgc() == 1 ) pin = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) pin = parameter2double(operatorArgv()[0]);
   
   streamID1 = streamOpenRead(cdoStreamName(0));
 
@@ -238,17 +238,8 @@ void *Adisit(void *argument)
   if ( saoID == -1 ) cdoAbort("Sea water salinity not found!");
   if ( thoID == -1 ) cdoAbort("Potential or Insitu temperature not found!");
 
-  ngrids = vlistNgrids(vlistID1);
   gridID = vlistGrid(vlistID1, 0);
-  gridsize = gridInqSize(gridID);
-
-  /* check gridsize */
-  for ( i = 1; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridsize != gridInqSize(gridID) )
-	cdoAbort("Grids have different size!");
-    }
+  gridsize = vlist_check_gridsize(vlistID1);
 
   zaxisID = vlistInqVarZaxis(vlistID1, saoID);
   nlevel1 = zaxisInqSize(zaxisID);
diff --git a/src/Afterburner.c b/src/Afterburner.c
new file mode 100644
index 0000000..4f0f882
--- /dev/null
+++ b/src/Afterburner.c
@@ -0,0 +1,2414 @@
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <cdi.h>
+
+#if defined(CDO)
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream_write.h"
+#endif
+
+#if defined(AFTERBURNER)
+#include "afterdoc.h"
+#endif
+
+#include "afterburner.h"
+#include "constants.h"
+#include "compare.h"
+#include "vct_l191.h"
+
+#if  defined  (HAVE_LIBPTHREAD)
+#include <pthread.h>
+#endif
+
+#if defined (_OPENMP)
+#include <omp.h>
+#endif
+
+#if ! defined (VERSION)
+#define  VERSION  "0.0.1"
+#endif
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if defined(AFTERBURNER)
+static double starttime = 0.0;
+#endif
+
+void afterInqHistory(int fileID);
+void afterDefHistory(int fileID, char *histstring);
+
+int   scan_par_obsolate(char *namelist, char *name, int def);
+void  scan_code(char *namelist, struct Variable *vars, int maxCodes, int *numCodes);
+int   scan_par(int verbose, char *namelist, char *name, int def);
+int   scan_time(int verbose, char *namelist, int *hours, int max_hours);
+void  scan_darray(char *namelist, char *name, double *values, int maxValues, int *numValues);
+
+long  get_nfft(void);
+
+char   *zaxisNamePtr(int leveltype);
+char   *vlistInqVarNamePtr(int vlistID, int varID);
+char   *vlistInqVarLongnamePtr(int vlistID, int varID);
+char   *vlistInqVarUnitsPtr(int vlistID, int varID);
+
+typedef struct {
+  int lana, nrecs;
+  struct Variable *vars;
+  struct Control *globs;
+}
+RARG;
+
+#if defined(AFTERBURNER)
+int stdin_is_tty  = 0;  /* true if stdin  is character device */
+int stdout_is_tty = 0;  /* true if stdout is character device */
+#endif
+
+static int lstdout = 1;
+ 
+static int Source = 0;
+
+static int ofiletype = -1;
+
+static int DataType = -1;
+
+static char *filename;
+static char **ifiles;
+static char *ifile  = NULL;
+static char *ofile  = NULL;
+#if defined(AFTERBURNER)
+static char *ofile2 = NULL;
+#endif
+
+static int ofileidx = 0;
+
+static int specGridID  = -1;
+static int gaussGridID = -1;
+static int iVertID = -1;
+static int oVertID = -1;
+
+static int Lhybrid2pressure = FALSE;
+
+int    TsID;
+#if  defined  (HAVE_LIBPTHREAD)
+int    ParallelRead = TRUE;
+#else
+int    ParallelRead = FALSE;
+#endif
+
+#define TIMESTEP_INTERVAL  -1
+#define MONTHLY_INTERVAL    0
+#define DAILY_INTERVAL      1
+#define UNLIM_INTERVAL      2
+
+#define MaxHours  24
+int nrqh;
+int hours[MaxHours+1];
+
+static double *LevelFound;
+
+static
+void cdiError(int cdiErrno, const char *fmt, ...)
+{
+  va_list args;
+	
+  va_start(args, fmt);
+
+  printf("\n");
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
+
+  va_end(args);
+
+  fprintf(stderr, "%s\n", cdiStringError(cdiErrno));
+
+  if ( _ExitOnError ) exit(1);
+}
+
+static
+void lprintf(FILE *fp)
+{
+  int inum;
+  int num = 67;
+  int cval = '-';
+
+  fprintf(fp, " ");
+  for (inum = 0; inum < num; inum++)
+    fprintf(fp, "%c", cval);
+  fprintf(fp, "\n");
+}
+
+static
+void FreeMean(struct Variable *vars)
+{
+  for ( int code = 0; code < MaxCodes; code++ )
+    if ( vars[code].mean )
+      {
+	free(vars[code].mean);
+	vars[code].mean = NULL;
+      }
+}
+
+
+static
+void after_PostProcess(struct Control *globs)
+{
+  if ( globs->EndOfInterval )
+    {
+      if ( lstdout )
+	{
+	  if      ( globs->OutputInterval == DAILY_INTERVAL )
+	    fprintf(stdout, " Processed Day %2d  Month %2d  Year %04d",
+		    globs->OldDate.dy, globs->OldDate.mo, globs->OldDate.yr);
+	  else if ( globs->OutputInterval == MONTHLY_INTERVAL )
+	    fprintf(stdout, " Processed Month %2d  Year %04d", globs->OldDate.mo, globs->OldDate.yr);
+	  else if ( globs->OutputInterval == UNLIM_INTERVAL )
+	    fprintf(stdout, " Processed range from %6.4d-%2.2d-%2.2d to %6.4d-%2.2d-%2.2d",
+		    globs->StartDate.yr, globs->StartDate.mo, globs->StartDate.dy,
+		    globs->OldDate.yr, globs->OldDate.mo, globs->OldDate.dy);
+
+	  if ( globs->Mean ) fprintf(stdout, "  (Mean of %3d Terms)\n", globs->MeanCount);
+	  else               fprintf(stdout, "   Terms %3d\n", globs->MeanCount);
+	}
+
+      globs->EndOfInterval = FALSE;
+      globs->MeanCount = 0;
+    }
+}
+
+/* ================= */
+/* switch input file */
+/* ================= */
+static
+void after_SwitchFile(struct Control *globs)
+{
+  int echam4 = FALSE;
+  int i, n;
+  char y3, y2, y1, y0;
+  char         m1, m0;
+  char         d1, d0;
+
+  streamClose(globs->istreamID);
+
+  if ( globs->Multi > 0 )
+    {
+      i = strlen(ifile);
+      if ( i < 10 )
+	{
+	  fprintf(stderr, " Not a valid filename: %s \n", ifile);
+	  exit(1);
+	}
+
+      if ( ifile[i-3] == '.' )
+	{
+	  echam4 = TRUE;
+	  y3 = ifile[i-9]; y2 = ifile[i-8];
+	  y1 = ifile[i-7]; y0 = ifile[i-6];
+	  m1 = ifile[i-5]; m0 = ifile[i-4];
+	  d1 = ifile[i-2]; d0 = ifile[i-1];
+	}
+      else
+	{
+	  y3 = ifile[i-6]; y2 = ifile[i-5];
+	  y1 = ifile[i-4]; y0 = ifile[i-3];
+	  m1 = ifile[i-2]; m0 = ifile[i-1];
+	  d1 = '0';        d0 = '1'   ;
+	}
+
+      for ( n = 0; n < globs->DayIn; n++ )
+	{
+	  if ( d0 =='9' ) { d0 = '0'; d1++; }
+	  else d0++;
+	  if ( d1 == '3' && d0 > '0' )
+	    {
+	      d1 = '0'; d0 = '1';
+	      if ( m1 == '0' )
+		{
+		  if ( m0 == '9' ) { m0 = '0'; m1 = '1'; }
+		  else m0++;
+		}
+	      else
+		{
+		  if ( m0 < '2' ) m0++;
+		  else
+		    {
+		      m1 = '0';  m0 = '1';  y0++;
+		      if ( y0 > '9' ) { y0 = '0'; y1++; }
+		      if ( y1 > '9' ) {
+			y1 = (char) '0';
+			if ( isdigit((int)y2) ) y2++;
+			else                    y2 = '1';
+			if ( y2 > '9' )
+			  {
+			    y2 = (char) '0';
+			    if ( isdigit((int)y3) ) y3++;
+			    else                    y3 = '1';
+			  }
+		      }
+		    }
+		}
+	    }
+	}
+
+      if ( echam4 )
+	{
+	  ifile[i-9] = y3; ifile[i-8] = y2;
+	  ifile[i-7] = y1; ifile[i-6] = y0;
+	  ifile[i-5] = m1; ifile[i-4] = m0;
+	  ifile[i-2] = d1; ifile[i-1] = d0;
+	}
+      else
+	{
+	  ifile[i-6] = y3; ifile[i-5] = y2;
+	  ifile[i-4] = y1; ifile[i-3] = y0;
+	  ifile[i-2] = m1; ifile[i-1] = m0;
+	}
+
+      globs->Multi--;
+    }
+
+  if ( globs->Nfiles > 0 ) ifile = ifiles[--globs->Nfiles];
+
+  fprintf(stderr, " Continuation file: %s\n", ifile);
+
+  globs->istreamID = streamOpenRead(ifile);
+  if ( globs->istreamID < 0 ) cdiError(globs->istreamID, "Open failed on %s", ifile);
+
+  globs->ivlistID = streamInqVlist(globs->istreamID);
+  globs->taxisID  = vlistInqTaxis(globs->ivlistID);
+}
+
+static
+int after_getDate(struct Date datetime)
+{
+  return cdiEncodeDate(datetime.yr, datetime.mo, datetime.dy);
+}
+
+static
+int after_getTime(struct Date datetime)
+{
+  return cdiEncodeTime(datetime.hr, datetime.mn, 0);
+}
+
+static
+void after_setDateTime(struct Date *datetime, int date, int time)
+{
+  int sec;
+  cdiDecodeDate(date, &datetime->yr, &datetime->mo, &datetime->dy);
+  cdiDecodeTime(time, &datetime->hr, &datetime->mn, &sec);
+}
+
+static
+void after_printProcessStatus(int tsID)
+{
+  static int counthead = FALSE;
+
+  if ( tsID == -1 )
+    {
+      if ( stdout_is_tty )
+	{
+	  fprintf(stdout, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
+	  fflush(stdout);
+	}
+
+      counthead = FALSE;
+    }
+  else
+    {
+      if ( counthead == FALSE )
+	{
+	  if ( stdout_is_tty )
+	    fprintf(stdout, " Process timestep :       ");
+
+	  counthead = TRUE;
+	}
+
+      if ( stdout_is_tty )
+	{
+	  fprintf(stdout, "\b\b\b\b\b\b%6d", tsID);
+	  fflush(stdout);
+	}
+    }
+}
+
+static
+int after_setNextDate(struct Control *globs)
+{
+  int nrecs;
+  int i;
+  int vdate, vtime;
+
+  int righttime = FALSE;
+  while ( TRUE )
+    {
+      nrecs = streamInqTimestep(globs->istreamID, TsID);
+      if ( nrecs == 0 && ( globs->Multi > 0 || globs->Nfiles > 0 ) )
+	{
+	  if ( lstdout ) after_printProcessStatus(-1);
+
+	  after_SwitchFile(globs);
+	 
+	  if ( globs->istreamID >= 0 )
+	    {
+	      TsID = 0;
+	      nrecs = streamInqTimestep(globs->istreamID, TsID);
+	    }
+	}
+      if ( nrecs == 0 ) break;
+
+#if defined(CDO)
+      //      processDefTimesteps(globs->istreamID);
+#endif
+      vdate = taxisInqVdate(globs->taxisID);
+      vtime = taxisInqVtime(globs->taxisID);
+
+      after_setDateTime(&globs->NextDate, vdate, vtime);
+
+      for ( i = 0; i < nrqh; i++ )
+	if ( hours[i] < 0 || hours[i] == globs->NextDate.hr )
+	  {
+	    righttime = TRUE;
+	    break;
+	  }
+
+      if ( righttime )
+	break;
+      else
+	TsID += 1;	  
+    }
+
+  return (nrecs);
+}
+
+
+static int num_recs = 0;
+
+static
+void *after_readTimestep(void *arg)
+{
+  int i;
+  int recID, varID, gridID, zaxisID, levelID, timeID;
+  int code, leveltype;
+  int nmiss;
+  int analysisData, nrecs;
+  struct Variable *vars;
+  struct Control *globs;
+  RARG *rarg = (RARG *) arg;
+
+  nrecs        = rarg->nrecs;
+  analysisData = rarg->lana;
+  vars         = rarg->vars;
+  globs        = rarg->globs;
+
+  for ( code = 0; code < MaxCodes; code++ ) vars[code].nmiss0 = 0;
+
+  int level = 0;
+  int levelOffset = 0;
+
+  for ( recID = 0; recID < nrecs; recID++ )
+    {
+      streamInqRecord(globs->istreamID, &varID, &levelID);
+
+      code = vlistInqVarCode(globs->ivlistID, varID);
+      if ( code <= 0 || code >= MaxCodes ) continue;
+
+      /* Skip records containing unneeded codes */
+
+      if ( ! vars[code].needed0 ) continue;
+
+      vlistInqVar(globs->ivlistID, varID, &gridID, &zaxisID, &timeID);
+
+      leveltype = zaxisInqType(zaxisID);
+	  
+      /* Skip records with unselected levels */
+
+      levelOffset = -1;
+      /*
+	if ( vars[code].ozaxisID != vars[code].izaxisID && ! Lhybrid2pressure )
+      */
+      if ( (vars[code].ozaxisID != vars[code].izaxisID) && (leveltype == ZAXIS_PRESSURE) )
+	{
+	  level = (int) zaxisInqLevel(zaxisID, levelID);
+	  for ( i = 0; i < globs->NumLevelRequest; ++i )
+	    {
+	      if ( IS_EQUAL(globs->LevelRequest[i], level) )
+		{
+		  levelOffset = i;
+		  break;
+		}
+	    }
+
+	  if ( levelOffset < 0 ) continue;
+
+	  zaxisID = vars[code].ozaxisID;
+	  levelID = levelOffset;
+	}
+
+      if ( globs->Debug )
+	{
+	  fprintf(stderr, "T%d", globs->Truncation);
+
+	  fprintf(stderr, "  Code %3d   Level%6d   %6.4d-%2.2d-%2.2d  %2.2d:%2.2d:00\n",
+		  code, (int) zaxisInqLevel(zaxisID, levelID),
+		  globs->OldDate.yr, globs->OldDate.mo, globs->OldDate.dy, globs->OldDate.hr, globs->OldDate.mn);
+	}
+
+      streamReadRecord(globs->istreamID, globs->Field, &nmiss);
+
+      if ( analysisData )
+	after_AnalysisAddRecord(globs, vars, code, gridID, zaxisID, levelID, nmiss);
+      else
+	after_EchamAddRecord(globs, vars, code, gridID, zaxisID, levelID, nmiss);
+
+      if ( iVertID != -1 && oVertID != -1 && (vars[code].izaxisID == iVertID) )
+	vars[code].ozaxisID = oVertID;
+    }
+
+  TsID++;
+  /*
+    printf("%3d  date = %d  time = %04d\n", TsID, vdate, vtime);
+  */
+  num_recs = after_setNextDate(globs);
+
+  return ((void *) &num_recs);
+}
+
+static
+void after_defineNextTimestep(struct Control *globs)
+{
+  static int otsID = 0;
+  int vdate = after_getDate(globs->OldDate);
+  int vtime = after_getTime(globs->OldDate);
+  taxisDefVdate(globs->taxisID2, vdate);
+  taxisDefVtime(globs->taxisID2, vtime);
+
+  if ( globs->Mean != 2 )
+    {
+      if ( otsID == 0 )
+	{
+	  vlistDefTaxis(globs->ovlistID, globs->taxisID2);
+	  streamDefVlist(globs->ostreamID, globs->ovlistID);
+	}
+      taxisDefNumavg(globs->taxisID2, globs->MeanCount+1);
+      streamDefTimestep(globs->ostreamID,  otsID);
+    }
+
+#if defined(AFTERBURNER)
+  if ( globs->Mean >= 2 )
+    {
+      if ( otsID == 0 )
+	{
+	  vlistDefTaxis(globs->ovlistID2, globs->taxisID2);
+	  streamDefVlist(globs->ostreamID2, globs->ovlistID2);
+	}
+      taxisDefNumavg(globs->taxisID2, globs->MeanCount+1);
+      streamDefTimestep(globs->ostreamID2, otsID);
+    }
+#endif
+
+  otsID++;
+}
+
+static
+void after_setEndOfInterval(struct Control *globs, int nrecs)
+{
+  if ( nrecs == 0 )
+    {
+      globs->EndOfInterval = TRUE;
+    }
+  else
+    {
+      if      ( globs->OutputInterval == DAILY_INTERVAL )
+	globs->EndOfInterval = globs->NewDate.dy != globs->OldDate.dy;
+      else if ( globs->OutputInterval == MONTHLY_INTERVAL )
+	globs->EndOfInterval = globs->NewDate.mo != globs->OldDate.mo;
+      else if ( globs->OutputInterval == UNLIM_INTERVAL )
+	globs->EndOfInterval = FALSE;
+      else
+	Error( "output interval %d not implemented!\n", globs->OutputInterval);
+    }
+}
+
+static
+void after_moveTimestep(struct Variable *vars)
+{
+  int code;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    vars[code].nmiss = vars[code].nmiss0;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].hybrid0 )
+      {
+	vars[code].hybrid  = vars[code].hybrid0;
+	vars[code].hybrid0 = NULL;
+      }
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].spectral0 )
+      {
+	vars[code].spectral  = vars[code].spectral0;
+	vars[code].spectral0 = NULL;
+      }
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].grid0 )
+      {
+	vars[code].grid  = vars[code].grid0;
+	vars[code].grid0 = NULL;
+      }
+}
+
+static
+void after_control(struct Control *globs, struct Variable *vars)
+{
+  int i;
+  int tsFirst, nrecs;
+  int rdate, rtime;
+  int vdate, vtime;
+  int code;
+  RARG rarg;
+  void *statusp = NULL;
+#if  defined  (HAVE_LIBPTHREAD)
+  pthread_t thrID;
+  pthread_attr_t attr;
+  int rval;
+
+  if ( ParallelRead )
+    {
+      size_t stacksize;
+
+      pthread_attr_init(&attr);
+      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+      int status = pthread_attr_getstacksize(&attr, &stacksize);
+      if ( stacksize < 2097152 )
+	{
+	  stacksize = 2097152;
+	  pthread_attr_setstacksize(&attr, stacksize);
+	}
+    }
+#endif
+
+  for ( code = 0; code < MaxCodes; code++ )
+    vars[code].needed0 = vars[code].needed;
+
+  TsID = 0;
+
+  int righttime = FALSE;
+  while ( (nrecs = streamInqTimestep(globs->istreamID, TsID)) > 0 )
+    {
+      vdate = taxisInqVdate(globs->taxisID);
+      vtime = taxisInqVtime(globs->taxisID);
+      after_setDateTime(&globs->StartDate, vdate, vtime);
+      after_setDateTime(&globs->NewDate, vdate, vtime);
+
+      for ( i = 0; i < nrqh; i++ )
+	if ( hours[i] < 0 || hours[i] == globs->NewDate.hr )
+	  {
+	    righttime = TRUE;
+	    break;
+	  }
+
+      if ( righttime )
+	break;
+      else
+	TsID++;	  
+    }
+
+  if ( taxisInqType(globs->taxisID) == TAXIS_RELATIVE )
+    {
+      rdate = taxisInqRdate(globs->taxisID);
+      rtime = taxisInqRtime(globs->taxisID);
+    }
+  else
+    {
+      rdate = after_getDate(globs->StartDate);
+      rtime = after_getTime(globs->StartDate);
+    }
+
+  if ( ofiletype == FILETYPE_NC || ofiletype == FILETYPE_NC2 || ofiletype == FILETYPE_NC4 )
+    {
+      taxisDefCalendar(globs->taxisID2, CALENDAR_PROLEPTIC);
+      taxisDefType(globs->taxisID2, TAXIS_RELATIVE);
+      taxisDefTunit(globs->taxisID2, TUNIT_DAY);
+      taxisDefRdate(globs->taxisID2, rdate);
+      taxisDefRtime(globs->taxisID2, rtime);
+    }
+
+  globs->OldDate = globs->NewDate;
+
+  tsFirst = TRUE;
+
+  while ( nrecs > 0 )
+    {
+      rarg.nrecs = nrecs;
+      rarg.lana  = globs->AnalysisData;
+      rarg.vars  = vars;
+      rarg.globs = globs;
+
+      if ( tsFirst || ParallelRead == FALSE )
+	{
+	  if ( ParallelRead == FALSE )
+	    {
+	      statusp = after_readTimestep(&rarg);
+	    }
+#if  defined  (HAVE_LIBPTHREAD)
+	  else
+	    {
+	      rval = pthread_create(&thrID, &attr, after_readTimestep, &rarg);
+	      if ( rval != 0 ) Error( "pthread_create failed!");
+	    }
+#endif
+
+	  if ( tsFirst )
+	    {
+	      if ( globs->Type >  0 ) after_legini_setup(globs, vars);
+	    }
+
+#if  defined  (HAVE_LIBPTHREAD)
+	  if ( ParallelRead )
+	    {
+	      pthread_join(thrID, &statusp);
+	      if ( *(int *)statusp < 0 )
+		Error( "after_readTimestep error! (status = %d)", *(int *)statusp);
+	    }
+#endif
+	  tsFirst = FALSE;
+	}
+#if  defined  (HAVE_LIBPTHREAD)
+      else
+	{
+	  pthread_join(thrID, &statusp);
+	  if ( *(int *)statusp < 0 )
+	    Error( "after_readTimestep error! (status = %d)", *(int *)statusp);
+	}
+#endif
+      nrecs = *(int *)statusp;
+
+      globs->MeanCount0 = globs->MeanCount;
+      globs->NewDate = globs->NextDate;
+
+      after_moveTimestep(vars);
+
+#if  defined  (HAVE_LIBPTHREAD)
+      if ( nrecs && ParallelRead )
+	{
+	  rval = pthread_create(&thrID, &attr, after_readTimestep, &rarg);
+	  if ( rval != 0 ) Error( "pthread_create failed!");
+	}
+#endif
+
+      after_setEndOfInterval(globs, nrecs);
+      
+      if ( lstdout ) after_printProcessStatus(TsID);
+
+      if ( lstdout && globs->EndOfInterval ) after_printProcessStatus(-1);
+      
+      if ( globs->Mean == 0 || globs->EndOfInterval ) after_defineNextTimestep(globs);
+
+      if ( globs->AnalysisData )
+	after_processPL(globs, vars);
+      else
+	after_processML(globs, vars);
+
+      after_PostProcess(globs);
+      
+      if ( nrecs )
+	{
+	  if ( globs->AnalysisData )
+	    after_AnalysisDependencies(vars, MaxCodes);
+	  else
+	    after_EchamDependencies(vars, MaxCodes, globs->Type, Source);
+	}
+	
+      globs->OldDate = globs->NewDate;
+    }
+
+#if  defined  (HAVE_LIBPTHREAD)
+  if ( ParallelRead )
+    {
+      pthread_attr_destroy(&attr);
+    }
+#endif
+}
+
+static
+void after_setLevel(struct Control *globs)
+{
+  int k, l, found;
+  int removeLevel[MaxLevel];
+  double level;
+  int checkLevel = TRUE;
+  int numplevelDefault;  /* default pressure level */
+  long plevelDefault[] = { 100000, 92500, 85000, 70000, 60000, 50000,  \
+			    40000, 30000, 25000, 20000, 15000, 10000,  \
+			     7000,  5000,  3000,  2000, 1000 };
+  int numhlevelDefault;  /* default height level */
+  long hlevelDefault[] = {  0, 1000, 2000, 5000, 10000, 15000, 20000, 25000, 30000 };
+
+  numplevelDefault = sizeof(plevelDefault)/sizeof(plevelDefault[0]);
+  numhlevelDefault = sizeof(hlevelDefault)/sizeof(hlevelDefault[0]);
+
+  if ( iVertID != -1 )
+    if ( zaxisInqType(iVertID) == ZAXIS_HYBRID && globs->Type > 20 )
+      Lhybrid2pressure = TRUE;
+
+  if ( globs->Verbose ) lprintf(stdout);
+
+  if ( globs->NumLevelRequest == 0 )
+    {
+      if ( iVertID == -1 )
+	{
+	  if ( globs->Verbose ) fprintf(stdout," No level detected\n");
+	}
+      else
+	{
+	  if ( Lhybrid2pressure )
+	    {
+	      if ( globs->unitsel == 0 )
+		{
+		  if ( globs->Verbose ) fprintf(stdout," Default pressure level selected:\n");
+		  globs->NumLevelRequest = numplevelDefault;
+		  for ( l = 0; l < globs->NumLevelRequest; l++ ) globs->LevelRequest[l] = plevelDefault[l];
+		  oVertID = zaxisCreate(ZAXIS_PRESSURE, globs->NumLevelRequest);
+		  zaxisDefLevels(oVertID, globs->LevelRequest);
+		}
+	      else
+		{
+		  if ( globs->Verbose ) fprintf(stdout," Default height level selected:\n");
+		  globs->NumLevelRequest = numhlevelDefault;
+		  for ( l = 0; l < globs->NumLevelRequest; l++ ) globs->LevelRequest[l] = hlevelDefault[l];
+		  oVertID = zaxisCreate(ZAXIS_HEIGHT, globs->NumLevelRequest);
+		  zaxisDefLevels(oVertID, globs->LevelRequest);
+		}
+	    }
+	  else
+	    {
+	      if ( globs->Verbose )
+		{
+		  if ( zaxisInqType(iVertID) == ZAXIS_HYBRID )
+		    fprintf(stdout," All detected hybrid level selected:\n");
+		  else
+		    fprintf(stdout," All detected pressure level selected:\n");
+		}
+	      globs->NumLevelRequest = globs->NumLevelFound;
+	      for ( l = 0; l < globs->NumLevelRequest; l++ ) globs->LevelRequest[l] = LevelFound[l];
+	      oVertID = iVertID;
+	    }
+	}
+      checkLevel = FALSE;
+    }
+  else
+    {
+      if ( iVertID == -1 )
+	{
+	  if ( globs->Verbose )	fprintf(stdout," No level detected\n");
+	  checkLevel = FALSE;
+	}
+      else if ( globs->NumLevelRequest == 1 && IS_EQUAL(globs->LevelRequest[0], 0) )
+	{
+	  if ( globs->Verbose ) fprintf(stdout," No level selected\n");
+	  globs->NumLevelRequest = 0;
+	  checkLevel = FALSE;
+	}
+      else if ( globs->Verbose )
+	{
+	  if ( Lhybrid2pressure )
+	    {
+	      if ( globs->unitsel == 0 )
+		fprintf(stdout," Selected pressure level:\n");
+	      else
+		fprintf(stdout," Selected height level:\n");
+	    }
+	  else
+	    {
+	      if ( zaxisInqType(iVertID) == ZAXIS_HYBRID )
+		fprintf(stdout," Selected hybrid level:\n");
+	      else
+		{
+		  if ( globs->unitsel == 0 )
+		    fprintf(stdout," Selected pressure level:\n");
+		  else
+		    fprintf(stdout," Selected height level:\n");
+		}
+	    }
+	}
+    }
+
+  if ( globs->Verbose && iVertID != -1 )
+    for ( l = 0; l < globs->NumLevelRequest; l++ )
+      fprintf(stdout, "  Level %2d = %13.4f\n", l+1, globs->LevelRequest[l]);
+
+  if ( checkLevel )
+    {
+      for ( k = 0; k < globs->NumLevelRequest; k++ ) removeLevel[k] = FALSE;
+      for ( k = 0; k < globs->NumLevelRequest; k++ )
+	{
+	  level = globs->LevelRequest[k];
+	  for ( l = k+1; l < globs->NumLevelRequest; l++ )
+	    if ( removeLevel[l] == FALSE && IS_EQUAL(level, globs->LevelRequest[l]) )
+	      {
+		if ( globs->Verbose )
+		  fprintf(stdout, "  Level %2d = %13.4f double request\n", l+1, globs->LevelRequest[l]);
+		removeLevel[l] = TRUE;
+	      }
+	}
+
+      l = 0;
+      for ( k = 0; k < globs->NumLevelRequest; k++ )
+	if ( removeLevel[k] == FALSE )
+	  globs->LevelRequest[l++] = globs->LevelRequest[k];
+
+      globs->NumLevelRequest = l;
+
+      if ( globs->AnalysisData || globs->Type < 30 )
+	{
+	  for ( k = 0; k < globs->NumLevelRequest; k++ ) removeLevel[k] = FALSE;
+	  for ( k = 0; k < globs->NumLevelRequest; k++ )
+	    {
+	      level = globs->LevelRequest[k];
+	      found = FALSE;
+	      for ( l = 0; l < globs->NumLevelFound; l++ )
+		if ( IS_EQUAL(level, LevelFound[l]) ) found = TRUE;
+
+	      if ( ! found )
+		{
+		  fprintf(stdout, "  Level %2d = %14.4f not in input\n",
+			  k+1, globs->LevelRequest[k]);
+		  removeLevel[k] = TRUE;
+		}
+	    }
+
+	  l = 0;
+	  for ( k = 0; k < globs->NumLevelRequest; k++ )
+	    if ( removeLevel[k] == FALSE )
+	      globs->LevelRequest[l++] = globs->LevelRequest[k];
+
+	  if ( l != globs->NumLevelRequest )
+	    {
+	      extern int labort_after;
+	      if ( globs->Verbose ) lprintf(stdout);
+	      if ( labort_after )
+		Error( "Inconsistent or invalid level list!");
+	      else
+		Warning( "Inconsistent or invalid level list!");
+	    }
+
+	  globs->NumLevelRequest = l;
+	}
+    }
+
+  if ( globs->Verbose ) lprintf(stdout);
+}
+
+static
+void after_defineLevel(struct Control *globs, struct Variable *vars)
+{
+  int code, i;
+
+  /* hybrid, pressure, height */
+
+  switch ( globs->Type ) {
+  case  0:
+  case 10:
+  case 11:
+  case 20:
+    {
+      if ( iVertID == -1 ) break;
+
+      if ( zaxisInqType(iVertID) == ZAXIS_HYBRID )
+	{
+	  if ( oVertID == -1 )
+	    {
+	      if ( globs->NumLevelRequest > globs->NumLevelFound )
+		Error( "Too much level requested");
+
+	      if ( globs->NumLevelFound == globs->NumLevelRequest )
+		{
+		  for ( i = 0; i < globs->NumLevelRequest; i++ )
+		    if ( IS_NOT_EQUAL(globs->LevelRequest[i], LevelFound[i]) ) break;
+
+		  if ( i == globs->NumLevelRequest )
+		    oVertID = iVertID;
+		}
+
+	      if ( oVertID == -1 && globs->NumLevelRequest > 0 )
+		{
+		  oVertID = zaxisCreate(ZAXIS_HYBRID, globs->NumLevelRequest);
+		  zaxisDefLevels(oVertID, globs->LevelRequest);
+		  zaxisDefVct(oVertID, globs->nvct, globs->vct);
+		}
+	    }
+	      
+	  for ( code = 0; code < MaxCodes; code++ )
+	    {
+	      if ( vars[code].selected )
+		{
+		  if ( vars[code].izaxisID != -1 )
+		    if ( zaxisInqType(vars[code].izaxisID) == ZAXIS_HYBRID &&
+			 zaxisInqSize(vars[code].izaxisID) >= globs->NumLevelRequest )
+		      vars[code].ozaxisID = oVertID;
+		}
+	    }
+	}
+      else
+	Error( "%s level data unsupported for TYPE %d",
+	      zaxisNamePtr(zaxisInqType(iVertID)), globs->Type);	    
+
+      break;
+    }
+  case 30:
+  case 40:
+  case 41:
+  case 50:
+  case 60:
+  case 61:
+  case 70:
+    {
+      if ( iVertID == -1 ) break;
+
+      if ( oVertID == -1 )
+	{
+	  if ( globs->unitsel == 0 )
+	    oVertID = zaxisCreate(ZAXIS_PRESSURE, globs->NumLevelRequest);
+	  else
+	    oVertID = zaxisCreate(ZAXIS_HEIGHT, globs->NumLevelRequest);
+
+	  zaxisDefLevels(oVertID, globs->LevelRequest);
+	}
+
+      for ( code = 0; code < MaxCodes; code++ )
+	{
+	  if ( vars[code].selected )
+	    {
+	      if ( vars[code].izaxisID != -1 )
+		if ( zaxisInqType(vars[code].izaxisID) == zaxisInqType(iVertID) &&
+		     zaxisInqSize(vars[code].izaxisID) == globs->NumLevel &&
+		     zaxisInqSize(vars[code].izaxisID) >  1 )
+		  vars[code].ozaxisID = oVertID;
+	    }
+	}
+
+      break;
+    }
+  default:
+    Error( "TYPE %d unsupported", globs->Type);
+  }
+}
+
+static
+void after_defineGrid(struct Control *globs, struct Variable *vars)
+{
+  int ogridID = -1;
+  int code;
+
+  /* spectral, fourier, gauss, zonal mean */
+
+  switch ( globs->Type ) {
+  case  0:
+  case 50:
+    {
+      if ( specGridID == -1 )
+	{
+	  if ( globs->DimSP == 0 )
+	    Error( "dim spectral undefined");
+	  if ( globs->Truncation == 0 )
+	    Error( "truncation undefined");
+	    
+	  specGridID = gridCreate(GRID_SPECTRAL, globs->DimSP);
+	  gridDefTrunc(specGridID, globs->Truncation);
+	}
+
+      ogridID = specGridID;
+      break;
+    }
+  case 20:
+  case 30:
+  case 70:
+    {
+      if ( gaussGridID == -1 )
+	{
+	  if ( globs->Longitudes == 0 )
+	    Error( "number of longitudes undefined");
+	  if ( globs->Latitudes == 0 )
+	    Error( "number of latitudes undefined");
+	    
+	  gaussGridID = gridCreate(GRID_GAUSSIAN, globs->Longitudes*globs->Latitudes);
+	  gridDefXsize(gaussGridID, globs->Longitudes);
+	  gridDefYsize(gaussGridID, globs->Latitudes);
+	}
+
+      ogridID = gaussGridID;
+      break;
+    }
+  case 10:
+  case 40:
+  case 60:
+    {
+      if ( globs->Fouriers == 0 )
+	Error( "number of fourier coefficients undefined");
+      if ( globs->Latitudes == 0 )
+	Error( "number of latitudes undefined");
+	    
+      ogridID = gridCreate(GRID_FOURIER, globs->Fouriers*globs->Latitudes);
+      gridDefXsize(ogridID, globs->Latitudes);
+      gridDefYsize(ogridID, globs->Fouriers);
+      break;
+    }
+  case 11:
+  case 41:
+  case 61:
+    {
+      if ( globs->Latitudes == 0 )
+	Error( "Number of latitudes undefined");
+	    
+      ogridID = gridCreate(GRID_GAUSSIAN, globs->Latitudes);
+      gridDefXsize(ogridID, 1);
+      gridDefYsize(ogridID, globs->Latitudes);
+      break;
+    }
+  default:
+    Error( "TYPE %d unsupported", globs->Type);
+  }
+
+  if ( ogridID != -1 )
+    for ( code = 0; code < MaxCodes; code++ )
+      {
+	if ( vars[code].selected )
+	  {
+	    vars[code].ogridID = ogridID;
+	  }
+      }
+
+  if ( ogridID == -1 )
+    Error( "out grid undefined");
+}
+
+static
+void after_setCodes(struct Control *globs, struct Variable *vars, int maxCodes, int numCodes)
+{
+  int code;
+  int table, modelID, tableID;
+  char *name, *longname;
+  int varID;
+
+  if ( globs->Verbose ) lprintf(stdout);
+
+  if ( numCodes == 0 )
+    {
+      if ( globs->Verbose ) fprintf(stdout, " All detected codes selected:\n");
+      
+      for ( code = 0; code < maxCodes; code++ )
+	if ( vars[code].detected ) vars[code].selected = 1;
+    }
+  else if ( globs->Verbose )
+    fprintf(stdout, " Selected codes:\n");
+
+  if ( globs->Verbose )
+    {
+      fprintf(stdout, "  Table Code Name              Longname\n");
+      fprintf(stdout, "  ----- ---- ----              --------\n");
+    }
+
+  for ( code = 0; code < maxCodes; code++ )
+    if ( vars[code].selected )
+      {
+	table    = 0;
+	name     = NULL;
+	longname = NULL;
+	varID    = vars[code].ivarID;
+
+	if ( varID == CDI_UNDEFID )
+	  {
+	    modelID  = vlistInqVarModel(globs->ivlistID, 0);
+	    table    = 128;
+	    tableID  = tableInq(modelID, table, NULL);
+
+	    vars[code].tableID = tableID;
+	  }
+	else
+	  {
+	    tableID  = vlistInqVarTable(globs->ivlistID, varID);
+	    table    = tableInqNum(tableID);
+	    name     = vlistInqVarNamePtr(globs->ivlistID, varID);
+	    longname = vlistInqVarLongnamePtr(globs->ivlistID, varID);
+	  }
+	if ( name     == NULL )     name = (char*) tableInqParNamePtr(tableID, code);
+	if ( longname == NULL ) longname = (char*) tableInqParLongnamePtr(tableID, code);
+	
+	if ( globs->Verbose )
+	  {
+	    fprintf(stdout, " %5d", table);
+	    fprintf(stdout, " %4d", code);
+	    if ( name == NULL )
+	      fprintf(stdout, "  var%d", code);
+	    else
+	      {
+		fprintf(stdout, "  %-16s", name);
+	    if ( longname != NULL )
+	      fprintf(stdout, "  %s", longname);
+	      }
+	    fprintf(stdout, "\n");
+	  }
+      }
+}
+
+static
+void after_checkNamelist(struct Control *globs)
+{
+  if ( globs->Mean && globs->Type < 20 )
+    {
+      Error("Mean is only available for TYPE >= 20!");
+    }
+
+  if ( globs->Extrapolate == FALSE && globs->Type >= 30 )
+    {
+      if ( globs->Type > 30 )
+	Error("EXTRAPOLATE = 0 is only available for TYPE = 30!");
+      if ( globs->Mean )
+	Error("EXTRAPOLATE = 0 is only available with MEAN = 0!");
+    }
+}
+
+static
+void after_usage(void)
+{
+  fprintf(stderr, "\nafter [options] <InputFiles> <OutputFile> <VarianceFile>\n");
+#if defined (_OPENMP)
+  fprintf(stderr, "     option -P <nthreads> : Set number of OpenMP threads\n");
+#endif
+  fprintf(stderr, "     option -a            : Forces analysis data process\n");
+  fprintf(stderr, "     option -c            : Print available codes and names\n");
+  fprintf(stderr, "     option -d            : Debug mode\n");
+  fprintf(stderr, "     option -v <vctfile>  : Read vct from vctfile\n");
+  /*  fprintf(stderr, "     option -h : help (this output)\n"); */
+  /*  fprintf(stderr, "     option -p : parallel read on\n"); */
+  fprintf(stderr, "  <InputFiles> : ECHAM or ECMWF Ana or ReAna files\n");
+  fprintf(stderr, "  <OutputFile> : GRIB, netCDF or SERVICE format file\n");
+  fprintf(stderr, "<VarianceFile> : GRIB, netCDF or SERVICE format file\n");
+  fprintf(stderr, "  namelist is read from <stdin>\n");
+  fprintf(stderr, "  output is written to <stdout>\n\n");
+
+  fprintf(stderr, "  default Namelist: \n");
+  fprintf(stderr, "  &SELECT\n");
+  fprintf(stderr, "    TYPE = 0, CODE = -1, LEVEL = -1, MULTI = 0, DAYIN = 30,\n");
+  fprintf(stderr, "    MEAN = 0, TIMESEL = -1, UNITSEL = 0,\n");
+  fprintf(stderr, "    FORMAT = 0, PRECISION = 0, SZIP = 0\n");
+  fprintf(stderr, "  &END\n");
+
+  exit(1);
+}
+
+static
+void after_parini(struct Control *globs, struct Variable *vars)
+{
+  char namelist[65536];
+
+  if ( stdin_is_tty ) 
+    {
+#if defined(CDO)
+      fprintf(stderr, "Default namelist: \n");
+      fprintf(stderr, "  TYPE = 0, CODE = -1, LEVEL = -1, MULTI = 0, DAYIN = 30, MEAN = 0, TIMESEL = -1, UNITSEL = 0\n");
+#endif
+      fprintf(stdout, "Enter namelist parameter:\n");
+    }
+  else
+    {
+      fseek(stdin, 0L, SEEK_END);
+      long length = ftell(stdin);
+      if ( length == 0L )
+	{
+	  fprintf(stderr,"\n stdin not connected\n");
+	  after_usage();
+	}
+      fseek(stdin, 0L, SEEK_SET);
+    }
+
+  int i = 1;
+  namelist[0] = ' ';
+  int c = getchar();
+  while ((c != EOF) && i < (int)(sizeof(namelist) - 1))
+    {
+           if ((c >= '0' && c <= '9') ||
+               (c == '-' || c == '.'))  namelist[i++] = c;
+      else if  (c >= 'a' && c <= 'z')   namelist[i++] = c;
+      else if  (c >= 'A' && c <= 'Z')   namelist[i++] = tolower(c);
+      else c = ' ';
+
+      if (c == ' ' && namelist[i-1] != ' ') namelist[i++] = c;
+      c = getchar();
+    }
+  namelist[i] = 0;
+
+  if ( globs->Debug )
+    {
+      lprintf(stderr);
+      fprintf(stderr,"  Length of namelist:%4d bytes\n", (int) strlen(namelist));
+
+      for (i = 0; i < (int)strlen(namelist); i += 60)
+	fprintf(stderr,"  namelist[%02d]=%-60.60s\n", i, namelist+i);
+      lprintf(stderr);
+    }
+
+  if ( globs->Verbose )
+    {
+      lprintf(stdout);
+      fprintf(stdout, " Namelist:\n");
+    }
+  
+  globs->Type           = scan_par(globs->Verbose, namelist, "type",  0);
+  globs->Multi          = scan_par(globs->Verbose, namelist, "multi", 0);
+  globs->Mean           = scan_par(globs->Verbose, namelist, "mean",  0);
+  globs->OutputInterval = scan_par(globs->Verbose, namelist, "interval", MONTHLY_INTERVAL);
+
+#if defined(CDO)
+  if ( globs->Mean >= 2 )
+    cdoAbort("Namelist parameter MEAN=%d out of bounds (0:1)", globs->Mean);
+#endif
+
+  int fileFormat = scan_par(globs->Verbose, namelist, "format", -1);
+  int gribFormat = scan_par_obsolate(namelist, "grib",   0);
+  int cdfFormat  = scan_par_obsolate(namelist, "netcdf", 0);
+
+  if ( gribFormat && cdfFormat ) Error( "GRIB or netCDF?");
+
+  switch ( fileFormat )
+    {
+#if defined(CDO)
+    case -1: ofiletype = -1;            break;
+#else
+    case -1: ofiletype = FILETYPE_SRV;  break;
+#endif
+    case  0: ofiletype = FILETYPE_SRV;  break;
+    case  1: ofiletype = FILETYPE_GRB;  break;
+    case  2: ofiletype = FILETYPE_NC;   break;
+    case  3: ofiletype = FILETYPE_EXT;  break;
+    case  4: ofiletype = FILETYPE_NC2;  break;
+    case  6: ofiletype = FILETYPE_NC4;  break;
+    default: Error( "unknown file format %d", fileFormat);
+    }
+
+  if ( gribFormat )  ofiletype = FILETYPE_GRB;
+  if ( cdfFormat  )  ofiletype = FILETYPE_NC;
+
+  int precision = scan_par(globs->Verbose, namelist, "precision", 0);
+  if ( precision )
+    switch ( precision )
+      {
+      case  8: DataType = DATATYPE_PACK8;  break;
+      case 16: DataType = DATATYPE_PACK16; break;
+      case 24: DataType = DATATYPE_PACK24; break;
+      case 32: DataType = DATATYPE_FLT32;  break;
+      case 64: DataType = DATATYPE_FLT64;  break;
+      default: Error( "unsupported data precision %d", precision);
+      }
+
+
+  globs->unitsel        = scan_par(globs->Verbose, namelist, "unitsel",  0);
+  globs->DayIn          = scan_par(globs->Verbose, namelist, "dayinc",  30);
+  globs->Extrapolate    = scan_par(globs->Verbose, namelist, "extrapolate",  1);
+  globs->Szip           = scan_par(globs->Verbose, namelist, "szip",  0);
+  int mars              = scan_par_obsolate(namelist, "mars", 0);
+
+  if ( globs->Multi ) --globs->Multi;
+
+  if ( mars )
+    {
+      extern int Mars;
+      Mars = 1;
+      PlanetRD     = C_MARS_RD;
+      PlanetGrav   = C_MARS_GRAV;
+      PlanetRadius = C_MARS_RADIUS;
+    }
+
+  nrqh = scan_time(globs->Verbose, namelist, hours, MaxHours);
+  scan_code(namelist, vars, MaxCodes, &globs->NumCodesRequest);
+
+  scan_darray(namelist, "level", globs->LevelRequest, MaxLevel, &globs->NumLevelRequest);
+  if ( globs->NumLevelRequest == 1 )
+    if ( IS_EQUAL(globs->LevelRequest[0], -1) )
+      globs->NumLevelRequest = 0;
+
+  if ( globs->Verbose ) lprintf(stdout);
+
+  after_checkNamelist(globs);
+}
+
+static
+void after_dimcalc(struct Control *globs)
+{  
+  if ( globs->AnalysisData ) globs->NumLevel = globs->NumLevelRequest;
+
+  if ( globs->Latitudes == 0 )
+    {
+      globs->Latitudes = 2 * ((globs->Truncation*3 + 3) / 4);
+      if ( globs->Truncation == 30 ) globs->Latitudes = 48;
+    }
+
+  if ( globs->Longitudes == 0 )
+    {
+      globs->Longitudes = globs->Latitudes * 2;
+      if ( globs->Truncation == 62 ) globs->Longitudes = 192;
+    }
+
+  globs->Waves         = globs->Truncation + 1;
+  globs->Fouriers      = globs->Waves * 2;
+  globs->DimSP         = (globs->Truncation + 1) * (globs->Truncation + 2);
+  globs->DimFC         = globs->Latitudes * globs->Fouriers;
+  globs->DimGP         = globs->Latitudes * globs->Longitudes;
+  globs->Dim3GP        = globs->NumLevel * globs->DimGP;
+  globs->Dim3FC        = globs->NumLevel * globs->DimFC;
+  globs->Dim3SP        = globs->NumLevel * globs->DimSP;
+  globs->HalfLevels    = globs->NumLevel + 1;
+  globs->DimSP_half    = globs->DimSP / 2;
+
+  if ( globs->AnalysisData )
+    fprintf(stdout, " Found Ana or Re-Ana Data\n");
+
+  if ( globs->Verbose )
+    {
+      fprintf(stdout, " Dimensions:\n");
+      fprintf(stdout, "  Truncation        = %4d\n", globs->Truncation);
+      fprintf(stdout, "  Levels            = %4d\n", globs->NumLevel);
+      fprintf(stdout, "  Latitudes         = %4d\n", globs->Latitudes);
+      fprintf(stdout, "  Longitudes        = %4d\n", globs->Longitudes);
+      lprintf(stdout);
+    }
+}
+
+/* ----------------------------------------------------------- */
+/* Extract basic dimension information                         */
+/* ----------------------------------------------------------- */
+static
+void after_precntl(struct Control *globs, struct Variable *vars)
+{
+  int l;
+  int code = 0;
+  int gridID, zaxisID, varID, timeID;
+  int i, index, leveltype, gridtype;
+  int datasize, numlevel;
+  int vertfound = 0;
+  int nhzaxis = 0;
+  int FieldDim = 0;
+
+  int nvars   = vlistNvars(globs->ivlistID);
+  int ngrids  = vlistNgrids(globs->ivlistID);
+  int nverts  = vlistNzaxis(globs->ivlistID);
+  int ntsteps = vlistNtsteps(globs->ivlistID);
+
+  if ( globs->Debug )
+    {
+      Message( "nvars      = %d", nvars);
+      Message( "ngrids     = %d", ngrids);
+      Message( "nverts     = %d", nverts);
+      Message( "ntsteps    = %d", ntsteps);
+    }
+
+  for ( index = 0; index < ngrids; index++ )
+    {
+      gridID   = vlistGrid(globs->ivlistID, index);
+      gridtype = gridInqType(gridID);
+      datasize = gridInqSize(gridID);
+
+      if ( datasize > FieldDim ) FieldDim = datasize;
+
+      if ( gridtype == GRID_SPECTRAL && globs->Truncation == 0 )
+	{
+	  specGridID = gridID;
+	  globs->Truncation = gridInqTrunc(gridID);
+	}
+      else if ( gridtype == GRID_GAUSSIAN && globs->Latitudes == 0 )
+	{
+	  gaussGridID = gridID;
+	  globs->Longitudes  = gridInqXsize(gridID);
+	  globs->Latitudes   = gridInqYsize(gridID);
+	}
+    }
+
+  if ( globs->Truncation == 0 && globs->Latitudes == 0 )
+    Error("Unsupported file structure!\n");
+
+  if ( globs->Truncation == 0 )
+    {
+      if ( globs->Latitudes )
+	{
+	  switch ( globs->Latitudes ) {
+	  case 512: globs->Truncation = 511; break;
+	  case 320: globs->Truncation = 213; break;
+	  case 192: globs->Truncation = 127; break;
+	  case 160: globs->Truncation = 106; break;
+	  case 128: globs->Truncation =  85; break;
+	  case  96: globs->Truncation =  63; break;
+	  case  94: globs->Truncation =  62; break;
+	  case  64: globs->Truncation =  42; break;
+	  case  48: globs->Truncation =  31; break;
+	  case  32: globs->Truncation =  21; break;
+	  default :
+	    fprintf(stderr,"%d Gaussian latitudes not supported.\n", globs->Latitudes);
+	  }
+	}
+    }
+
+  for ( index = 0; index < nverts; index++ )
+    {
+      zaxisID   = vlistZaxis(globs->ivlistID, index);
+      leveltype = zaxisInqType(zaxisID);
+      numlevel  = zaxisInqSize(zaxisID);
+      /*
+	printf("leveltype : %d %d\n", leveltype, zaxisInqSize(zaxisID));
+      */	
+      if ( numlevel > 1 )
+	{
+	  if ( leveltype == ZAXIS_HYBRID || leveltype == ZAXIS_PRESSURE )
+	    {
+	      if ( leveltype == ZAXIS_HYBRID && globs->nvct == 0 )
+		{
+		  nhzaxis++;
+		  if ( numlevel != (zaxisInqVctSize(zaxisID)/2 - 1) )
+		    {
+		      if ( ! (numlevel == 191 && zaxisInqVctSize(zaxisID) == 0) )
+			{
+			  Warning( "Skip %d hybrid level data with %d levels!",
+				  (zaxisInqVctSize(zaxisID)/2 - 1), numlevel);
+			  continue;
+			}
+		    }
+		}
+
+	      if ( iVertID != - 1 )
+		Warning( "More than %d different vertical grid structure found!", vertfound);
+
+	      vertfound++;
+
+	      if ( iVertID != -1 ) continue;
+
+	      iVertID = zaxisID;
+	      globs->NumLevelFound = numlevel;
+	      LevelFound = (double *) malloc(globs->NumLevelFound*sizeof(double));
+	      for ( l = 0; l < globs->NumLevelFound; l++ )
+		LevelFound[l] = (int) zaxisInqLevel(zaxisID, l);
+
+	      if ( leveltype == ZAXIS_HYBRID )
+		{
+		  if ( globs->nvct == 0 )
+		    {
+		      if ( zaxisInqVctSize(zaxisID) )
+			{
+			  globs->nvct = zaxisInqVctSize(zaxisID);
+
+			  if ( globs->vct == NULL )
+			    {
+			      globs->vct = (double *) malloc(globs->nvct*sizeof(double));
+			      memcpy(globs->vct, zaxisInqVctPtr(zaxisID), globs->nvct*sizeof(double));
+			    }
+			}
+		      else
+			{
+			  if ( numlevel == 191 )
+			    {
+			      fprintf(stderr," Using internal VCT for L191\n");
+			      globs->nvct = (191+1)*2;
+			      globs->vct = (double *) malloc(globs->nvct*sizeof(double));
+			      memcpy(globs->vct, VCT_L191, globs->nvct*sizeof(double));
+			      zaxisDefVct(zaxisID, globs->nvct, globs->vct);
+			    }
+			  else
+			    {
+			      Error( "VCT not defined in inputfile!");
+			    }
+			}
+		    }
+
+		  if ( numlevel != (globs->nvct/2 - 1) )
+		    Error( "Number of hybrid levels %d does not match vct levels %d",
+			  numlevel, globs->nvct/2-1);
+
+		  if ( globs->Debug )
+		    for ( i = 0; i < globs->nvct/2; i++ )
+		      fprintf(stderr," vct: %4d %10.4f %10.4f\n", i, globs->vct[i], globs->vct[i+globs->nvct/2]);
+		}
+
+	      if ( leveltype == ZAXIS_PRESSURE ) globs->AnalysisData = TRUE;
+	    }
+	}
+    }
+
+  if ( nhzaxis > 0 && globs->nvct == 0 ) Error( "VCT missing!");
+
+  globs->NumLevel = globs->NumLevelFound;
+
+  if (  specGridID != -1 ) globs->Spectral = TRUE;
+  if ( gaussGridID != -1 ) globs->Gaussian = TRUE;
+
+  if ( globs->Debug )
+    fprintf(stderr, "   T = %3d   L = %2d\n", globs->Truncation, globs->NumLevelFound);
+
+  if ( globs->Debug )
+    fprintf(stderr," CODE CHECK\n");
+
+  if ( globs->Verbose )
+    {
+      int instID  = vlistInqVarInstitut(globs->ivlistID, 0);
+      int modelID = vlistInqVarModel(globs->ivlistID, 0);
+
+      lprintf(stdout);
+      fprintf(stdout, " Institute : ");
+      if ( instID == CDI_UNDEFID )
+	fprintf(stdout, "unknown\n");
+      else
+	{
+	  if ( institutInqLongnamePtr(instID) )
+	    fprintf(stdout, "%s\n", institutInqLongnamePtr(instID));
+	  else
+	    fprintf(stdout, "name unknown\n");
+	}
+
+      fprintf(stdout, " Source    : ");
+      if ( modelID == CDI_UNDEFID )
+	fprintf(stdout, "unknown\n");
+      else
+	{
+	  if ( modelInqNamePtr(modelID) )
+	    {
+	      if ( strncmp(modelInqNamePtr(modelID), "ECHAM5", 6) == 0 ) Source = S_ECHAM5;
+	      fprintf(stdout, "%s\n", modelInqNamePtr(modelID));
+	    }
+	  else
+	    fprintf(stdout, "name unknown\n");
+	}
+    }
+  
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      vlistInqVar(globs->ivlistID, varID, &gridID, &zaxisID, &timeID);
+      code      = vlistInqVarCode(globs->ivlistID, varID);
+      if ( code <= 0 || code >= MaxCodes )
+	{
+	  Warning( "Code number %d out of range, variable ignored!", code);
+	  continue;
+	}
+      gridtype  = gridInqType(gridID);
+      numlevel  = zaxisInqSize(zaxisID);
+      leveltype = zaxisInqType(zaxisID);
+
+      vars[code].ivarID  = varID;
+      vars[code].igridID = gridID;
+      vars[code].ogridID = gridID;
+      vars[code].izaxisID = zaxisID;
+      vars[code].ozaxisID = zaxisID;
+
+      vars[code].detected = TRUE;
+
+      if ( globs->Debug )
+	fprintf(stderr,"Code %3d  Levels = %3d  LevelType = %3d  GridType = %3d\n",
+		code, numlevel, leveltype, gridtype);
+    }
+
+  if ( globs->Debug )
+    Message( "FieldDim = %d\n", FieldDim);
+
+  globs->Field = (double *) malloc(FieldDim*sizeof(double));
+
+  if ( globs->Debug )
+    for ( code = 0; code < MaxCodes; code++ )
+      {
+	if ( vars[code].detected )
+	  fprintf(stderr," Detected Code %3d with %3d level\n",
+		  code, zaxisInqSize(vars[code].izaxisID));
+      }
+}
+
+/*
+ * -----------------------------------------------------------
+ * Define output variables
+ * -----------------------------------------------------------
+ */
+static
+void after_postcntl(struct Control *globs, struct Variable *vars)
+{
+  int code = 0;
+  int gridID, zaxisID;
+  int ovarID, ogridID, ozaxisID;
+  int ovarID2;
+  int ivarID, instID, modelID, tableID;
+  char *name, *longname, *units;
+  char histstring[99];
+  int datatype;
+
+  sprintf(histstring, "afterburner version %s  type = %d", VERSION, globs->Type);
+
+#if defined(AFTERBURNER)
+  afterInqHistory(globs->istreamID);
+  if ( globs->Mean != 2 ) afterDefHistory(globs->ostreamID, histstring);
+  if ( globs->Mean >= 2 ) afterDefHistory(globs->ostreamID2, histstring);
+#endif
+
+  if ( globs->Debug ) lprintf(stdout);
+  if ( globs->Debug )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].detected )
+	{
+	  gridID = vars[code].igridID;
+	  zaxisID = vars[code].izaxisID;
+	  fprintf(stderr," Detected Code %3d  grid %-8s size %5d  level %2d %-8s\n",
+		  code, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID),
+		  zaxisInqSize(zaxisID), zaxisNamePtr(zaxisInqType(zaxisID)));
+	}
+
+
+  if ( globs->Debug ) lprintf(stdout);
+  if ( globs->Debug )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].needed )
+	{
+	  fprintf(stderr,"   Needed Code %3d\n", code);
+	}
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].selected )
+      {
+	name     = NULL;
+	longname = NULL;
+	units    = NULL;
+	ivarID   = vars[code].ivarID;
+	ogridID  = vars[code].ogridID;
+	ozaxisID = vars[code].ozaxisID;
+
+	if ( ogridID == -1 )
+	  {
+	    /*
+	    Warning( "undefined grid for code %d", code);
+	    */
+	    continue;
+	  }
+	if ( ozaxisID == -1 )
+	  {
+	    /*
+	    Warning( "undefined level for code %d", code);
+	    */
+	    continue;
+	  }
+
+	instID   = vlistInqVarInstitut(globs->ivlistID, ivarID);
+	modelID  = vlistInqVarModel(globs->ivlistID, ivarID);
+	tableID  = vlistInqVarTable(globs->ivlistID, ivarID);
+
+	vars[code].missval  = vlistInqVarMissval(globs->ivlistID, ivarID);
+	vars[code].samp     = NULL;
+
+	if ( DataType != -1 )
+	  datatype = DataType;
+	else
+	  datatype = vlistInqVarDatatype(globs->ivlistID, ivarID);
+
+	if ( vars[code].comp )
+	  {
+	    tableID = vars[code].tableID;
+	  }
+	else
+	  {
+	    name     = vlistInqVarNamePtr(globs->ivlistID, ivarID);
+	    longname = vlistInqVarLongnamePtr(globs->ivlistID, ivarID);
+	    units    = vlistInqVarUnitsPtr(globs->ivlistID, ivarID);
+	  }
+
+	if ( globs->Mean != 2 )
+	  {
+	    vlistDefTaxis(globs->ovlistID, globs->taxisID2);
+	    ovarID = vlistDefVar(globs->ovlistID, ogridID, ozaxisID, TIME_VARIABLE);
+	    vlistDefVarCode(globs->ovlistID, ovarID, code);
+	    vars[code].ovarID = ovarID;
+	    vlistDefVarInstitut(globs->ovlistID, ovarID, instID);
+	    vlistDefVarModel(globs->ovlistID, ovarID, modelID);
+	    vlistDefVarTable(globs->ovlistID, ovarID, tableID);
+	    if ( globs->Mean ) vlistDefVarTimave(globs->ovlistID, ovarID, 1);
+	    if ( name )        vlistDefVarName(globs->ovlistID, ovarID, name);
+	    if ( longname )    vlistDefVarLongname(globs->ovlistID, ovarID, longname);
+	    if ( units )       vlistDefVarUnits(globs->ovlistID, ovarID, units);
+	    vlistDefVarDatatype(globs->ovlistID, ovarID, datatype);
+	    vlistDefVarMissval(globs->ovlistID, ovarID, vars[code].missval);
+	  }
+
+	if ( globs->Mean >= 2 )
+	  {
+	    vlistDefTaxis(globs->ovlistID2, globs->taxisID2);
+	    ovarID2 = vlistDefVar(globs->ovlistID2, ogridID, ozaxisID, TIME_VARIABLE);
+	    vlistDefVarCode(globs->ovlistID2, ovarID2, code);
+	    vars[code].ovarID2 = ovarID2;
+	    vlistDefVarInstitut(globs->ovlistID2, ovarID2, instID);
+	    vlistDefVarModel(globs->ovlistID2, ovarID2, modelID);
+	    vlistDefVarTable(globs->ovlistID2, ovarID2, tableID);
+	    if ( globs->Mean ) vlistDefVarTimave(globs->ovlistID2, ovarID2, 1);
+	    if ( name )        vlistDefVarName(globs->ovlistID2, ovarID2, name);
+	    if ( longname )    vlistDefVarLongname(globs->ovlistID2, ovarID2, longname);
+	    if ( units )       vlistDefVarUnits(globs->ovlistID2, ovarID2, units);
+	    vlistDefVarDatatype(globs->ovlistID2, ovarID2, datatype);
+	    vlistDefVarMissval(globs->ovlistID2, ovarID2, vars[code].missval);
+	  }
+      }
+
+  if ( globs->Debug ) lprintf(stdout);
+  if ( globs->Debug )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].selected )
+	{
+	  gridID  = vars[code].ogridID;
+	  zaxisID = vars[code].ozaxisID;
+	  fprintf(stderr," Selected Code %3d  grid %-8s size %5d  level %2d %-8s\n",
+		  code, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID),
+		  zaxisInqSize(zaxisID), zaxisNamePtr(zaxisInqType(zaxisID)));
+	}
+}
+
+#if defined(AFTERBURNER)
+static
+void after_readVct(struct Control *globs, const char *vctfile)
+{
+  char line[1024];
+  int i, n;
+  double va, vb;
+
+  FILE *fp = fopen(vctfile, "r");
+  if ( fp == NULL ) SysError( "Open failed on %s", vctfile);
+
+  while ( fgets(line, 1023, fp) ) globs->nvct++;
+
+  globs->nvct *= 2;
+  globs->vct = (double *) malloc(globs->nvct*sizeof(double));
+
+  rewind(fp);
+  for ( i = 0; i < globs->nvct/2; i++ )
+    {
+      fgets(line, 1023, fp);
+      sscanf(line, "%d %lg %lg", &n, &va, &vb);
+      globs->vct[i]               = va;
+      globs->vct[i+globs->nvct/2] = vb;
+    }
+  fprintf(stdout, "  Reading VCT for %d hybrid levels from file %s\n", globs->nvct/2-1, vctfile);
+
+  fclose(fp);
+}
+#endif
+
+#if defined(AFTERBURNER)
+static
+void after_version(void)
+{
+#if defined (COMPILER)
+  fprintf(stderr, "Compiler: %s\n", COMPILER);
+#endif
+#if defined (COMP_VERSION)
+  fprintf(stderr, " version: %s\n", COMP_VERSION);
+#endif
+#if defined (HAVE_LIBSZ) || defined (_OPENMP)
+  fprintf(stderr, "    with:");
+#if defined (HAVE_LIBSZ)
+  fprintf(stderr, " libsz");
+#endif
+#if defined (_OPENMP)
+  fprintf(stderr, " OpenMP");
+#endif
+  fprintf(stderr, "\n");
+#endif
+#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
+  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
+	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
+#endif
+  cdiPrintVersion();
+  fprintf(stderr, "\n");
+}
+#endif
+
+static
+void after_control_init(struct Control *globs)
+{
+  memset(globs, 0, sizeof(struct Control));
+
+  globs->AnalysisData = 0; /* 0 = ECHAM Data, 1 = ECMWF Spectral Analyses */
+  globs->DayIn       = 0; /* day increment of infiles if Multi = TRUE    */
+  globs->Debug       = FALSE;
+  globs->Extrapolate = TRUE;
+  globs->Szip        = FALSE;
+
+  globs->istreamID   = CDI_UNDEFID;
+  globs->ostreamID   = CDI_UNDEFID;
+  globs->ostreamID2  = CDI_UNDEFID;
+  globs->ivlistID    = CDI_UNDEFID;
+  globs->ovlistID    = CDI_UNDEFID;
+  globs->ovlistID2   = CDI_UNDEFID;
+  globs->taxisID     = -1;
+  globs->taxisID2    = -1;
+}
+
+
+static
+void after_variable_init(struct Variable *vars)
+{
+  memset(vars, 0, sizeof(struct Variable));
+
+  vars->ivarID   = -1;
+  vars->ovarID   = -1;
+  vars->ovarID2  = -1;
+  vars->izaxisID = -1;
+  vars->ozaxisID = -1;
+  vars->igridID  = -1;
+  vars->ogridID  = -1;
+  vars->tableID  = -1;
+}
+
+#if defined(AFTERBURNER)
+static
+void after_printCodes(void)
+{
+  int tableID = tableInq(-1, 128, "echam4");
+  int ncodes;
+  int codes[] = {34,35,36,131,132,135,148,149,151,156,157,259,260,261,262,263,264,268,269,270,271,275};
+
+  ncodes = sizeof(codes)/sizeof(codes[0]);
+
+  lprintf(stdout);
+
+  fprintf(stdout, "  Code Name              Longname\n");
+  fprintf(stdout, "  ---- ----              --------\n");
+
+  for ( int i = 0; i < ncodes; i++ )
+    {
+      int code     = codes[i];
+      const char *name     = tableInqParNamePtr(tableID, code);
+      const char *longname = tableInqParLongnamePtr(tableID, code);
+
+      fprintf(stdout, " %4d", code);
+      if ( name == NULL )
+	fprintf(stdout, "  var%d", code);
+      else
+	{
+	  fprintf(stdout, "  %-16s", name);
+	  if ( longname != NULL )
+	    fprintf(stdout, "  %s", longname);
+	}
+      fprintf(stdout, "\n");
+    }
+
+  lprintf(stdout);
+}
+#endif
+
+/* =============================================== */
+/* procstat   - appends info about memory usage    */
+/*              and time consumption               */
+/* =============================================== */
+#if defined(AFTERBURNER)
+static
+void after_procstat(char *procpath, int truncation)
+{
+  FILE *sf;
+  double MaxMBytes;
+  time_t tp;
+  long  yy, mm, dd, hh, mi;
+  char mtype[12];
+  char *proc;
+  char *name;
+  char  stat_file[128];
+  double CPUTime;
+
+  CPUTime = ((double) clock() - starttime ) / CLOCKS_PER_SEC;
+
+  (void) time(&tp);
+  yy    = gmtime(&tp)->tm_year + 1900;
+  mm    = gmtime(&tp)->tm_mon + 1;
+  dd    = gmtime(&tp)->tm_mday   ;
+  hh    = gmtime(&tp)->tm_hour   ;
+  mi    = gmtime(&tp)->tm_min    ;
+  name  = getpwuid(getuid())->pw_name;
+
+  proc = strrchr(procpath,'/');
+  if (proc == 0) proc = procpath;
+  else           proc++         ;
+
+  strcpy(stat_file, "/pf/m/m214003/local/log/after.log");
+
+  MaxMBytes = (double) memTotal() / 1048576.;
+
+  sf = fopen(stat_file, "a");
+  if ( sf )
+    {
+      char unknown[] = "";
+      char *hostname;
+
+      if ( (hostname = getenv("HOST")) == NULL ) hostname = unknown;
+
+      setvbuf(sf, (char *)NULL, _IONBF, 0);
+      fprintf(sf, "%.7s %4.4ld.%2.2ld.%2.2ld %2.2ld:%2.2ld %s "
+	      "%-9.9s %7.1f %7.1f T%3.3d %s\n",
+	      name,   yy,   mm,   dd,   hh,   mi,   VERSION,
+	      proc, MaxMBytes, CPUTime, truncation, hostname);
+
+      fclose(sf);
+    }
+
+#if defined (CRAY)
+#  if defined (_CRAYMPP)
+     strcpy(mtype, " CRAYMPP --");
+#  elif (_MAXVL == 64)
+     strcpy(mtype, " CRAYVL64 -");
+#  elif (_MAXVL == 128)
+     strcpy(mtype, " CRAYVL128 ");
+#  else
+     strcpy(mtype, " CRAY -----");
+#  endif
+#elif defined (SX)
+     strcpy(mtype, " NECSX ----");
+#elif defined (__uxp__)
+     strcpy(mtype, " FUJI -----");
+#elif defined (sun)
+     strcpy(mtype, " SUN ------");
+#elif defined (i386)
+     strcpy(mtype, " i386 -----");
+#elif defined (sgi)
+     strcpy(mtype, " sgi ------");
+#else
+     strcpy(mtype, "-----------");
+#endif
+
+  fprintf(stdout, "   NORMAL EXIT\n");
+  fprintf(stdout, " ------   End    after  -%-11.11s- %7.1f sec", mtype, CPUTime);
+  if ( MaxMBytes > 0 )
+    fprintf(stdout, " --- %7.1f MB ---\n", MaxMBytes);
+  else
+    fprintf(stdout, " ----------------\n");
+}
+#endif
+
+static
+void after_processing(struct Control *globs, struct Variable *vars)
+{
+  int i;
+
+  //#if defined(_PSTREAM_H)
+  //  globs->istreamID = streamOpenRead(cdoStreamName(0));
+  //#else
+  globs->istreamID = streamOpenRead(ifile);
+  if ( globs->istreamID < 0 ) cdiError(globs->istreamID, "Open failed on %s", ifile);
+  //#endif
+  if ( ofiletype == -1 ) ofiletype = streamInqFiletype(globs->istreamID);
+
+  globs->ivlistID = streamInqVlist(globs->istreamID);
+  globs->taxisID  = vlistInqTaxis(globs->ivlistID);
+  globs->taxisID2 = taxisDuplicate(globs->taxisID);
+
+  if ( globs->Mean != 2 )
+    {
+#if defined(_PSTREAM_WRITE_H)
+      globs->ostreamID = streamOpenWrite(cdoStreamName(ofileidx), ofiletype);
+#else
+      globs->ostreamID = streamOpenWrite(ofile, ofiletype);
+      if ( globs->ostreamID < 0 ) cdiError(globs->ostreamID, "Open failed on %s", ofile);
+#endif
+
+      if ( globs->Szip ) streamDefCompType(globs->ostreamID, COMPRESS_SZIP);
+
+      globs->ovlistID = vlistCreate();
+    }
+#if defined(AFTERBURNER)
+  if ( globs->Mean >= 2 )
+    {
+      globs->ostreamID2 = streamOpenWrite(ofile2, ofiletype);
+      if ( globs->ostreamID2 < 0 ) cdiError(globs->ostreamID2, "Open failed on %s", ofile2);
+
+      if ( globs->Szip ) streamDefCompType(globs->ostreamID, COMPRESS_SZIP);
+
+      globs->ovlistID2 = vlistCreate();
+    }
+#endif
+
+  /* ---------------- */
+  /*  pre-processing  */
+  /* ---------------- */
+  after_precntl(globs, vars);
+
+  /* ----------------- */
+  /*  initializations  */
+  /* ----------------- */
+
+  after_setCodes(globs, vars, MaxCodes, globs->NumCodesRequest);
+
+  if ( globs->unitsel == 2 )
+    for (i = 0; i < globs->NumLevelRequest; i++) globs->LevelRequest[i] = globs->LevelRequest[i] * 1000;
+
+  if ( ! globs->AnalysisData )
+    for (i = 0; i < globs->NumLevelRequest; i++)
+      {
+	if ( (globs->LevelRequest[i] >= 65535) && globs->unitsel && ofiletype == FILETYPE_GRB )
+	  {
+	    fprintf(stderr,"\n Level %9.2f out of range (max=65535)!\n", globs->LevelRequest[i]);
+	    exit(1);
+	  }
+
+	if ( !globs->unitsel && globs->Type >= 20 && globs->NumLevelRequest > 1 && IS_EQUAL(globs->LevelRequest[i], 0))
+	  {
+	    fprintf(stderr,"\n Level %9.2f illegal for Type %d\n", globs->LevelRequest[i], globs->Type);
+	    exit(1);
+	  }
+      }
+
+  after_setLevel(globs);
+
+  after_dimcalc(globs);
+
+  globs->rcoslat          = (double *) malloc(globs->Latitudes*sizeof(double));
+  globs->coslat           = (double *) malloc(globs->Latitudes*sizeof(double));
+  globs->DerivationFactor = (double *) malloc(globs->Latitudes*sizeof(double));
+
+  if ( globs->Type < 50 && globs->AnalysisData )
+    {
+      fprintf(stderr," ::::::::::::::::::::::::::::::::::::::::::::::\n");
+      fprintf(stderr," -> Type < 50 is not appropriate for Analysis.\n");
+      fprintf(stderr," -> Please check wether you can use Type >= 50.\n");
+      fprintf(stderr," -> Premature Exit. Sorry.\n");
+      exit(1);
+    }
+
+  if ( globs->Type == 10 || globs->Type == 40 || globs->Type == 60 )
+    {
+      if ( ofiletype == FILETYPE_GRB )
+	Error("Can't write fourier coefficients to GRIB!");
+      else if ( ofiletype == FILETYPE_NC || ofiletype == FILETYPE_NC2 ||
+		ofiletype == FILETYPE_NC4 )
+	Error("Can't write fourier coefficients to netCDF!");
+    }
+
+  filename = strrchr(ifile,'/');
+  if (filename == 0) filename = ifile;
+  else               filename++ ;
+
+  if ( globs->Type >= 30 && globs->Type < 50 &&
+      (vars[DIVERGENCE].selected || vars[VELOPOT].selected ||
+       vars[VORTICITY].selected  || vars[STREAM].selected  ||
+       globs->AnalysisData) )
+    {
+      /*
+      int newtype = 0;
+      */
+      if ( globs->Type == 30 ) globs->Type = 70;
+      if ( globs->Type == 40 ) globs->Type = 60;
+      if ( globs->Type == 41 ) globs->Type = 61;
+
+      if ( globs->AnalysisData )
+	fprintf(stderr,"\n TYPE changed to %d (for analysis data)\n", globs->Type);
+      else
+	fprintf(stderr,"\n TYPE changed to %d (with code %d, %d, %d or %d)\n",
+		globs->Type, DIVERGENCE, VELOPOT, VORTICITY, STREAM);
+      /*
+      if ( globs->Type == 30 ) newtype = 70;
+      if ( globs->Type == 40 ) newtype = 60;
+      if ( globs->Type == 41 ) newtype = 61;
+
+      if ( globs->AnalysisData )
+	fprintf(stderr,"\n Attention: TYPE isn't changed to %d anymore (for analysis data)!!!\n", globs->Type);
+      else
+	fprintf(stderr,"\n Attention: TYPE isn't changed to %d anymore (with code %d, %d, %d or %d)!!!\n",
+		newtype, DIVERGENCE, VELOPOT, VORTICITY, STREAM);
+      */
+    }
+
+  if ( globs->AnalysisData ) after_AnalysisDependencies(vars, MaxCodes);
+  else
+    {
+      after_EchamDependencies(vars, MaxCodes, globs->Type, Source);
+      vars[GEOPOTENTIAL].needed |= globs->Type >= 30 || vars[SLP].comp || vars[GEOPOTHEIGHT].comp;
+    }
+
+  /*  if ( vars[U_WIND].needed || vars[V_WIND].needed ) */
+  if ( vars[U_WIND].comp || vars[V_WIND].comp )
+    {
+      globs->dv2uv_f1 = (double *) malloc(globs->DimSP_half*sizeof(double));
+      globs->dv2uv_f2 = (double *) malloc(globs->DimSP_half*sizeof(double));
+      geninx(globs->Truncation, globs->dv2uv_f1, globs->dv2uv_f2);
+    }
+
+  /* --------- */
+  /*  Control  */
+  /* --------- */
+
+  after_defineLevel(globs, vars);
+
+  after_defineGrid(globs, vars);
+
+  after_postcntl(globs, vars); /* define output variables */
+
+  after_control(globs, vars);
+
+#if defined(_PSTREAM_WRITE_H)
+  if ( globs->ostreamID  != CDI_UNDEFID ) pstreamClose(globs->ostreamID);
+#else
+  if ( globs->ostreamID2 != CDI_UNDEFID ) streamClose(globs->ostreamID2);
+  if ( globs->ostreamID  != CDI_UNDEFID ) streamClose(globs->ostreamID);
+#endif
+#if defined(CDO)
+  processDefVarNum(vlistNvars(globs->ivlistID), globs->istreamID);
+  processAddNvals(streamNvals(globs->istreamID));
+#endif
+  streamClose(globs->istreamID);
+
+  if ( globs->rcoslat )          free(globs->rcoslat);
+  if ( globs->coslat )           free(globs->coslat);
+  if ( globs->DerivationFactor ) free(globs->DerivationFactor);
+
+  if ( globs->Field ) free(globs->Field);
+
+  if ( globs->poli ) free(globs->poli);
+  if ( globs->pold ) free(globs->pold);
+  if ( globs->pdev ) free(globs->pdev);
+  if ( globs->pol2 ) free(globs->pol2);  if ( globs->pol3 ) free(globs->pol3);
+}
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+#if defined(AFTERBURNER)
+static
+int afterburner(int argc, char *argv[])
+{
+  int   i, code;
+  char *proc = argv[0];
+  char  Line[132];
+  int c;
+  int fargc0, fargcn;
+  FILE *fp;
+  int numThreads = 0;
+  char *Vctfile = NULL;
+  extern int dmemory_ExitOnError;
+
+  dmemory_ExitOnError = 1;
+
+  starttime = (double) clock();
+
+#if defined(AFTERBURNER)
+  { /* check character device on stdin and stdout */
+    struct stat statbuf;
+    fstat(0, &statbuf);
+    if ( S_ISCHR(statbuf.st_mode) ) stdin_is_tty = 1;  
+    fstat(1, &statbuf);
+    if ( S_ISCHR(statbuf.st_mode) ) stdout_is_tty = 1;  
+  }
+#endif
+
+  /* ------------------- */
+  /*  print information  */
+  /* ------------------- */
+
+  lprintf(stdout);
+  fprintf(stdout,"  afterburner version %s\n", VERSION);
+  fprintf(stdout,"  ECHAM & analyses postprocessor\n");
+
+  if ( sizeof(double) != 8 || sizeof(int) < 4 )
+    {
+      fprintf(stderr, "byte size of type double %d\n", (int) sizeof(double));
+      fprintf(stderr, "byte size of type int %d\n",    (int) sizeof(int));
+      fprintf(stderr, "byte size of type size_t %d\n", (int) sizeof(size_t));
+      return(1);
+    }
+
+  fp = fopen("/pf/m/m214003/doc/afterburner.doc","r");
+  if ( fp )
+    {
+      do
+	{
+	  fgets(Line, 130, fp);
+	  fprintf(stdout, "%s", &Line[1]);
+	}
+      while ( ! feof(fp) && Line[0] == '#' );
+      fclose(fp);
+    }
+
+  struct Control *globs = (struct Control *) malloc(sizeof(struct Control));
+  after_control_init(globs);
+
+  globs->Verbose = 1;
+
+  /* --------------------- */
+  /*  options & filenames  */
+  /* --------------------- */
+  extern int labort_after;
+
+  while ( (c = getopt(argc, argv, "P:b:v:acdgpVw")) != EOF )
+    switch (c)
+      {
+      case 'a': globs->AnalysisData = 1; break;
+      case 'b': Message( "option -b not longer needed!\n"); break;
+      case 'c': after_printCodes(); break;
+      case 'd': globs->Debug = 1; break;
+      case 'p': ParallelRead = TRUE; break;
+      case 'P': numThreads = atoi(optarg); break;
+      case 'V': after_version(); break;
+      case 'v': Vctfile = optarg; break;
+      case 'w': labort_after = FALSE; break;
+      default:  Message( "option -%c unsupported!", optopt); after_usage();
+      }
+
+#if defined (_OPENMP)
+  /* ParallelRead = TRUE; */
+
+  lprintf(stdout);
+  if ( numThreads <= 0 ) numThreads = 1;
+  omp_set_num_threads(numThreads);
+  if ( omp_get_max_threads() > omp_get_num_procs() )
+    fprintf(stdout, " Number of threads is greater than number of Cores=%d!\n", omp_get_num_procs());
+  fprintf(stdout, " OpenMP:  num_procs = %d  max_threads = %d\n", omp_get_num_procs(), omp_get_max_threads());
+#else
+  if ( numThreads > 0 )
+    {
+      fprintf(stderr, "Option -P failed, OpenMP support not compiled in!\n");
+      return(-1);
+    }
+#endif
+
+  if ( ParallelRead )
+    {
+#if  defined  (HAVE_LIBPTHREAD)
+      fprintf(stdout, " Parallel read enabled\n");
+#else
+      fprintf(stdout, " Parallel read disabled\n");
+      ParallelRead = FALSE;
+#endif
+    }
+
+  fargc0 = optind;
+  fargcn = argc;
+
+  if ( optind < argc ) ifile = argv[optind++];
+  if ( ! ifile )
+    {
+      Message( "*** Missing input file ***");
+      after_usage();
+    }
+
+  struct Variable vars[MaxCodes+5];
+  for ( code = 0; code < MaxCodes+5; code++ ) after_variable_init(&vars[code]);
+
+  after_parini(globs, vars); /* read namelist parameter */
+
+  fprintf(stdout, "   Input File: %-25s\n", ifile);
+  if ( globs->Mean >= 2 )
+    {
+      if ( fargcn-fargc0 >= 3 ) ofile2 = argv[--fargcn];
+      if ( ! ofile2 )
+	{
+	  Message( "*** Missing variance file ***");
+	  after_usage();
+	}
+    }
+
+  if ( globs->Mean != 2 )
+    {
+      if ( optind < argc ) ofile = argv[optind++];
+      if ( fargcn-fargc0 >= 2 ) ofile = argv[--fargcn];
+      if ( ! ofile )
+	{
+	  Message( "*** Missing output file ***");
+	  after_usage();
+	}
+      fprintf(stdout, "  Output File: %-25s\n", ofile);
+    }
+
+  globs->Nfiles = fargcn-fargc0-1;
+  if ( globs->Nfiles > 0 )
+    {
+      if ( globs->Multi > 0 )
+	Error( "Namelist parameter MULTI works only with one inputfile");
+
+      ifiles = (char **) malloc(globs->Nfiles*sizeof(char*));
+      for ( i = 0; i < globs->Nfiles; i++ )
+	ifiles[i] = argv[--fargcn];
+    }
+
+  if ( ofile2 )
+    fprintf(stdout, "Variance File: %-25s\n", ofile2);
+
+  if ( globs->Debug )
+    {
+      extern int afterDebug;
+      afterDebug = globs->Debug;
+      fprintf(stderr, "* Debug on!                              *\n");
+      fprintf(stderr, "  Maximum ffts to run in parallel:  %ld\n", get_nfft());
+    }
+
+  /* read option VCT */
+  if ( Vctfile ) after_readVct(globs, Vctfile);
+
+  /* --------------------- */
+  /*  open in/output file  */
+  /* --------------------- */
+
+  cdiDefGlobal("REGULARGRID", 1);
+
+  after_processing(globs, vars);
+
+  after_procstat(proc, globs->Truncation);
+
+  FreeMean(vars);
+
+  free(globs);
+
+  return(0);
+}
+#endif
+
+#if defined(CDO)
+void *Afterburner(void *argument)
+{
+  cdoInitialize(argument);
+
+  lstdout = !cdoSilentMode;
+
+  struct Control *globs = (struct Control *) malloc(sizeof(struct Control));
+  after_control_init(globs);
+
+  globs->Verbose = cdoVerbose;
+
+  struct Variable vars[MaxCodes+5];
+  for ( int code = 0; code < MaxCodes+5; code++ ) after_variable_init(&vars[code]);
+
+  after_parini(globs, vars); /* read namelist parameter */
+
+  if ( cdoDefaultFileType != CDI_UNDEFID ) ofiletype = cdoDefaultFileType;
+
+  int streamCnt = cdoStreamCnt();
+  int nfiles = streamCnt - 1;
+
+  ofileidx = nfiles;
+
+  ifile = cdoStreamName(0)->args;
+  ofile = cdoStreamName(nfiles)->args;
+
+  globs->Nfiles = nfiles-1;
+  if ( globs->Nfiles > 0 )
+    {
+      if ( globs->Multi > 0 )
+	Error( "Namelist parameter MULTI works only with one inputfile");
+
+      ifiles = (char **) malloc(globs->Nfiles*sizeof(char*));
+      for ( int i = 0; i < globs->Nfiles; ++i )
+	ifiles[i] = cdoStreamName(--nfiles)->args;
+      for ( int i = 0; i < globs->Nfiles; ++i ) printf("files %d %s\n", i+1, ifiles[i]);
+    }
+
+  after_processing(globs, vars);
+
+  FreeMean(vars);
+
+  free(globs);
+
+  cdoFinish();
+
+  return (0);
+}
+#else
+int main(int argc, char *argv[])
+{
+  return afterburner(argc, argv);
+}
+#endif
diff --git a/src/Arith.c b/src/Arith.c
index 7dae0b8..61c8ef1 100644
--- a/src/Arith.c
+++ b/src/Arith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Arithc.c b/src/Arithc.c
index 822779b..a6fddf2 100644
--- a/src/Arithc.c
+++ b/src/Arithc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -97,7 +97,7 @@ void *Arithc(void *argument)
   operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg(cdoOperatorEnter(operatorID));
-  rconst = atof(operatorArgv()[0]);
+  rconst = parameter2double(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Arithdays.c b/src/Arithdays.c
index 4d31bda..6288216 100644
--- a/src/Arithdays.c
+++ b/src/Arithdays.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Arithlat.c b/src/Arithlat.c
index d30275f..ccb2fc9 100644
--- a/src/Arithlat.c
+++ b/src/Arithlat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -125,18 +125,7 @@ void *Arithlat(void *argument)
 	      
 	      gridInqXunits(gridID, units);
 
-	      if ( memcmp(units, "degree", 6) == 0 )
-		{
-		  for ( i = 0; i < gridsize; ++i ) scale[i] *= DEG2RAD;
-		}
-	      else if ( memcmp(units, "radian", 6) == 0 )
-		{
-		  /* No conversion necessary */
-		}
-	      else
-		{
-		  cdoWarning("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
-		}
+	      grid_to_radian(units, gridsize, scale, "grid latitudes");
 
 	      if ( operfunc == func_mul )
 		for ( i = 0; i < gridsize; ++i ) scale[i] = cos(scale[i]);
diff --git a/src/CDIread.c b/src/CDIread.c
index 67d8332..8b19644 100644
--- a/src/CDIread.c
+++ b/src/CDIread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -95,7 +95,6 @@ void *CDIread(void *argument)
   double tw, tw0, t0, twsum = 0;
   float *farray = NULL;
   double *darray = NULL;
-  extern int timer_read;
 
   sinfo[0] = 0;
 
@@ -112,7 +111,7 @@ void *CDIread(void *argument)
 
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
-  if ( operatorArgc() == 1 ) nruns = atol(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) nruns = parameter2int(operatorArgv()[0]);
 
   if ( nruns <  0 ) nruns = 0;
   if ( nruns > 99 ) nruns = 99;
diff --git a/src/CDItest.c b/src/CDItest.c
index 479cb2e..e869f61 100644
--- a/src/CDItest.c
+++ b/src/CDItest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@ void *CDItest(void *argument)
   UNUSED(operatorID);
 
   //  operatorInputArg("Number of copies");
-  if ( operatorArgc() == 1 ) max_copy = atoi(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) max_copy = parameter2int(operatorArgv()[0]);
 
   processStartTime(&s_utime, &s_stime);
 
diff --git a/src/CDIwrite.c b/src/CDIwrite.c
index 4cdb5fc..ed26527 100644
--- a/src/CDIwrite.c
+++ b/src/CDIwrite.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -111,7 +111,6 @@ void *CDIwrite(void *argument)
   double tw, tw0, t0, twsum = 0;
   double ***vars = NULL;
   float *farray = NULL;
-  extern int timer_write;
 
   srand(seed);
   sinfo[0] = 0;
@@ -130,11 +129,11 @@ void *CDIwrite(void *argument)
   if ( operatorArgc() > 5 ) cdoAbort("Too many arguments!");
 
   gridfile = defaultgrid;
-  if ( operatorArgc() >= 1 ) nruns = atol(operatorArgv()[0]);
+  if ( operatorArgc() >= 1 ) nruns = parameter2int(operatorArgv()[0]);
   if ( operatorArgc() >= 2 ) gridfile = operatorArgv()[1];
-  if ( operatorArgc() >= 3 ) nlevs = atol(operatorArgv()[2]);
-  if ( operatorArgc() >= 4 ) ntimesteps = atol(operatorArgv()[3]);
-  if ( operatorArgc() >= 5 ) nvars = atol(operatorArgv()[4]);
+  if ( operatorArgc() >= 3 ) nlevs = parameter2int(operatorArgv()[2]);
+  if ( operatorArgc() >= 4 ) ntimesteps = parameter2int(operatorArgv()[3]);
+  if ( operatorArgc() >= 5 ) nvars = parameter2int(operatorArgv()[4]);
 
   if ( nruns <  0 ) nruns = 0;
   if ( nruns > 99 ) nruns = 99;
diff --git a/src/Cat.c b/src/Cat.c
index ba5e6c5..7b6372c 100644
--- a/src/Cat.c
+++ b/src/Cat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,6 @@ void *Cat(void *argument)
   int nrecs;
   int tsID1, tsID2 = 0, recID, varID, levelID;
   int vlistID1, vlistID2 = CDI_UNDEFID;
-  int streamCnt, nfiles, indf;
   int taxisID1, taxisID2 = CDI_UNDEFID;
   int lcopy = FALSE;
   int gridsize;
@@ -51,10 +50,10 @@ void *Cat(void *argument)
   timer_cat = timer_new("cat");
   if ( cdoTimer ) timer_start(timer_cat);
 
-  streamCnt = cdoStreamCnt();
-  nfiles = streamCnt - 1;
+  int streamCnt = cdoStreamCnt();
+  int nfiles = streamCnt - 1;
 
-  for ( indf = 0; indf < nfiles; indf++ )
+  for ( int indf = 0; indf < nfiles; ++indf )
     {
       if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
       if ( cdoTimer ) tw0 = timer_val(timer_cat);
diff --git a/src/Change.c b/src/Change.c
index b2ee482..077f0c5 100644
--- a/src/Change.c
+++ b/src/Change.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -85,7 +85,7 @@ void *Change(void *argument)
     {
       if ( nch%2 ) cdoAbort("Odd number of input arguments!");
       for ( i = 0; i < nch; i++ )
-	chints[i] = atoi(operatorArgv()[i]);
+	chints[i] = parameter2int(operatorArgv()[i]);
     }
   else if ( operatorID == CHPARAM || operatorID == CHNAME || operatorID == CHUNIT )
     {
@@ -97,29 +97,29 @@ void *Change(void *argument)
     {
       if ( nch%2 ) cdoAbort("Odd number of input arguments!");
       for ( i = 0; i < nch; i++ )
-	chlevels[i] = atof(operatorArgv()[i]);
+	chlevels[i] = parameter2double(operatorArgv()[i]);
     }
   else if ( operatorID == CHLEVELC )
     {
       operatorCheckArgc(3);
       
-      chcode = atoi(operatorArgv()[0]);
-      chlevels[0] = atof(operatorArgv()[1]);
-      chlevels[1] = atof(operatorArgv()[2]);
+      chcode = parameter2int(operatorArgv()[0]);
+      chlevels[0] = parameter2double(operatorArgv()[1]);
+      chlevels[1] = parameter2double(operatorArgv()[2]);
     }
   else if ( operatorID == CHLEVELV )
     {
       operatorCheckArgc(3);
       
       chname = operatorArgv()[0];
-      chlevels[0] = atof(operatorArgv()[1]);
-      chlevels[1] = atof(operatorArgv()[2]);
+      chlevels[0] = parameter2double(operatorArgv()[1]);
+      chlevels[1] = parameter2double(operatorArgv()[2]);
     }
   else if ( operatorID == CHLTYPE )                  
     {
       if ( nch%2 ) cdoAbort("Odd number of input arguments!");
       for ( i = 0; i < nch; i++ )
-	chltypes[i] = atoi(operatorArgv()[i]);
+	chltypes[i] = parameter2int(operatorArgv()[i]);
     }
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Change_e5slm.c b/src/Change_e5slm.c
index 182ac3b..8500267 100644
--- a/src/Change_e5slm.c
+++ b/src/Change_e5slm.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cloudlayer.c b/src/Cloudlayer.c
index 368b786..ff582d5 100644
--- a/src/Cloudlayer.c
+++ b/src/Cloudlayer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -21,7 +21,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 
 
 #define  SCALESLP        (101325.0)
@@ -131,10 +131,9 @@ void *Cloudlayer(void *argument)
   int varID, levelID;
   int zrev = FALSE;
   int nvars;
-  int gridsize, i;
+  int i;
   int offset;
   int nmiss;
-  int ngp = 0, ngrids;
   int aclcac_code;
   int aclcacID = -1;
   int nvars2 = 0;
@@ -154,8 +153,8 @@ void *Cloudlayer(void *argument)
     {
       operatorCheckArgc(2);
       nvars2 = 1;
-      pmin = atof(operatorArgv()[0]);
-      pmax = atof(operatorArgv()[1]);
+      pmin = parameter2double(operatorArgv()[0]);
+      pmax = parameter2double(operatorArgv()[1]);
     }
   else
     {
@@ -166,27 +165,7 @@ void *Cloudlayer(void *argument)
 
   vlistID1 = streamInqVlist(streamID1);
 
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
-
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   aclcac_code = 223;
 
@@ -195,7 +174,6 @@ void *Cloudlayer(void *argument)
     {
       gridID   = vlistInqVarGrid(vlistID1, varID);
       zaxisID  = vlistInqVarZaxis(vlistID1, varID);
-      gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
 
       code = vlistInqVarCode(vlistID1, varID);
@@ -230,7 +208,6 @@ void *Cloudlayer(void *argument)
   gridID  = vlistInqVarGrid(vlistID1, aclcacID);
   zaxisID = vlistInqVarZaxis(vlistID1, aclcacID);
 
-  gridsize = gridInqSize(gridID);
   nlevel = zaxisInqSize(zaxisID);
   nhlev  = nlevel+1;
 
diff --git a/src/Collgrid.c b/src/Collgrid.c
index 9f41da4..1546e23 100644
--- a/src/Collgrid.c
+++ b/src/Collgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Command.c b/src/Command.c
index 6f011b5..097f49d 100644
--- a/src/Command.c
+++ b/src/Command.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Comp.c b/src/Comp.c
index 713dc51..859bc71 100644
--- a/src/Comp.c
+++ b/src/Comp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Compc.c b/src/Compc.c
index e0e4ec3..6439cef 100644
--- a/src/Compc.c
+++ b/src/Compc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -63,7 +63,7 @@ void *Compc(void *argument)
   operatorID = cdoOperatorID();
 
   operatorInputArg("constant value");
-  rc = atof(operatorArgv()[0]);
+  rc = parameter2double(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Complextorect.c b/src/Complextorect.c
index f1bbe06..2452a04 100644
--- a/src/Complextorect.c
+++ b/src/Complextorect.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cond.c b/src/Cond.c
index e182385..7ce989d 100644
--- a/src/Cond.c
+++ b/src/Cond.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cond2.c b/src/Cond2.c
index 76484b3..ed30a85 100644
--- a/src/Cond2.c
+++ b/src/Cond2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Condc.c b/src/Condc.c
index ad0bf01..340bdd1 100644
--- a/src/Condc.c
+++ b/src/Condc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -54,7 +54,7 @@ void *Condc(void *argument)
   operatorID = cdoOperatorID();
 
   operatorInputArg("constant value");
-  rc = atof(operatorArgv()[0]);
+  rc = parameter2double(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Consecstat.c b/src/Consecstat.c
index a7a3207..d02b68f 100644
--- a/src/Consecstat.c
+++ b/src/Consecstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -140,7 +140,7 @@ void *Consecstat(void *argument)
   operatorID = cdoOperatorID();
 
   if ( operatorID == CONSECSUM )
-    if ( operatorArgc() > 0 ) refval = atof(operatorArgv()[0]);
+    if ( operatorArgc() > 0 ) refval = parameter2double(operatorArgv()[0]);
 
   istreamID = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Copy.c b/src/Copy.c
index c77ddad..fd71c84 100644
--- a/src/Copy.c
+++ b/src/Copy.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Deltime.c b/src/Deltime.c
index d753e86..156f768 100644
--- a/src/Deltime.c
+++ b/src/Deltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Derivepar.c b/src/Derivepar.c
index e72f882..74ca483 100644
--- a/src/Derivepar.c
+++ b/src/Derivepar.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2007-2012 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -26,91 +26,11 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 #include "stdnametable.h"
 
-#define  C_RKBOL         (1.380658e-23)     /* Boltzmann constant in J/K   */
-#define  C_RNAVO         (6.0221367e+23)    /* Avogadro constant in 1/mol  */
-#define  C_RMD           (28.9644)          /* molecular weight of dry air */
-#define  C_RMV           (18.0153)          /* molecular weight of water vapor */
-#define  C_R             (C_RKBOL * C_RNAVO)
-#define  C_RV            (1000. * C_R / C_RMV)
-
-#define  C_EARTH_GRAV    (9.80665)
-#define  C_RKBOL         (1.380658e-23)     /* Boltzmann constant in J/K   */
-#define  C_RNAVO         (6.0221367e+23)    /* Avogadro constant in 1/mol  */
-#define  C_RMD           (28.9644)          /* molecular weight of dry air */
-#define  C_R             (C_RKBOL * C_RNAVO)
-#define  C_EARTH_RD      (1000. * C_R / C_RMD)
-
-static double Grav          = C_EARTH_GRAV;
-static double RD            = C_EARTH_RD;
-
-static
-void MakeGeopotHeight(double *geop, double* gt, double *gq, double *ph, int nhor, int nlev)
-{
-  int i, j;
-  double vtmp;
-  double zrg;
-  double z2log2;
-  double *geopl, *gtl, *gql, *phl;
-
-  z2log2 = 2.0 * log(2.0);
-  vtmp   = (C_RV / RD) - 1.0;
-  zrg    = 1.0 / Grav;
-
-  if ( gq ) /* Humidity is present */
-    {
-      for ( j = nlev ; j > 1 ; j-- )
-        {
-          geopl = geop + nhor*(j-1);
-          gtl   = gt   + nhor*(j-1);
-          gql   = gq   + nhor*(j-1);
-          phl   = ph   + nhor*(j-1);
-#if defined(SX)
-#pragma vdir nodep
-#endif
-#if defined(_OPENMP)
-#pragma omp parallel for
-#endif
-          for ( i = 0; i < nhor; i++ )
-            geopl[i] = geopl[i+nhor] + RD * gtl[i] * (1.0 + vtmp * gql[i])
-                     * log(phl[i+nhor] / phl[i]);
-        }
-
-#if defined(SX)
-#pragma vdir nodep
-#endif
-#if defined(_OPENMP)
-#pragma omp parallel for
-#endif
-      for ( i = 0; i < nhor; i++ )
-        geop[i] = geop[i+nhor] + RD * gt[i] * (1.0 + vtmp * gq[i]) * z2log2;
-    }
-  else    /* No humidity */
-    {
-      for ( j = nlev ; j > 1 ; j-- )
-#if defined(SX)
-#pragma vdir nodep
-#endif
-        for ( i = nhor * (j-1) ; i < nhor * j ; i++ )
-          geop[i] = geop[i+nhor] + RD * gt[i] * log(ph[i+nhor] / ph[i]);
-
-#if defined(SX)
-#pragma vdir nodep
-#endif
-      for ( i = 0; i < nhor; i++ )
-        geop[i] = geop[i+nhor] + RD * gt[i] * z2log2;
-    }
 
-#if defined(SX)
-#pragma vdir nodep
-#endif
-#if defined(_OPENMP)
-#pragma omp parallel for
-#endif
-  for ( i = 0; i < nhor * (nlev+1); i++ ) geop[i] *= zrg;
-}
+void MakeGeopotHeight(double *geop, double* gt, double *gq, double *ph, int nhor, int nlev);
 
 
 void minmaxval(long nvals, double *array, int *imiss, double *minval, double *maxval)
@@ -148,19 +68,16 @@ void minmaxval(long nvals, double *array, int *imiss, double *minval, double *ma
 
 void *Derivepar(void *argument)
 {
-  int GHEIGHT, SEALEVELPRESSURE;
-  int operatorID;
   int mode;
   enum {ECHAM_MODE, WMO_MODE};
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
-  int gridsize, ngp = 0;
+  int streamID2;
+  int vlistID2;
   int recID, nrecs;
   int i, offset;
   int tsID, varID, levelID;
   int nvars;
   int zaxisIDh = -1, nzaxis;
-  int ngrids, gridID = -1, zaxisID;
+  int zaxisID;
   int nlevel;
   int nvct;
   int surfaceID = -1;
@@ -190,41 +107,20 @@ void *Derivepar(void *argument)
 
   cdoInitialize(argument);
 
-  GHEIGHT          = cdoOperatorAdd("gheight",   0, 0, NULL);
-  SEALEVELPRESSURE = cdoOperatorAdd("sealevelpressure",   0, 0, NULL);
-
-  operatorID = cdoOperatorID();
+  int GHEIGHT          = cdoOperatorAdd("gheight",   0, 0, NULL);
+  int SEALEVELPRESSURE = cdoOperatorAdd("sealevelpressure",   0, 0, NULL);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int operatorID = cdoOperatorID();
 
-  vlistID1 = streamInqVlist(streamID1);
-
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) == GRID_SPECTRAL )
-	{
-	  cdoAbort("Spectral data unsupported!");
-	}
-      else
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int vlistID1 = streamInqVlist(streamID1);
 
+  int gridID = vlistGrid(vlistID1, 0);
+  if ( gridInqType(gridID) == GRID_SPECTRAL )
+    cdoAbort("Spectral data unsupported!");
+ 
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   nzaxis  = vlistNzaxis(vlistID1);
   lhavevct = FALSE;
@@ -387,32 +283,32 @@ void *Derivepar(void *argument)
 
   if ( tempID == -1 ) cdoAbort("%s not found!", var_stdname(air_temperature));
 
-  array   = (double*) malloc(ngp*sizeof(double));
-  sgeopot = (double*) malloc(ngp*sizeof(double));
-  ps      = (double*) malloc(ngp*sizeof(double));
-  temp    = (double*) malloc(ngp*nhlevf*sizeof(double));
+  array   = (double*) malloc(gridsize*sizeof(double));
+  sgeopot = (double*) malloc(gridsize*sizeof(double));
+  ps      = (double*) malloc(gridsize*sizeof(double));
+  temp    = (double*) malloc(gridsize*nhlevf*sizeof(double));
 
-  // lwater = (double*) malloc(ngp*nhlevf*sizeof(double));
-  // iwater = (double*) malloc(ngp*nhlevf*sizeof(double));
+  // lwater = (double*) malloc(gridsize*nhlevf*sizeof(double));
+  // iwater = (double*) malloc(gridsize*nhlevf*sizeof(double));
 
-  half_press = (double*) malloc(ngp*(nhlevf+1)*sizeof(double));
+  half_press = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double));
 
   if ( operatorID == GHEIGHT )
     {
       if ( humID == -1 )
 	cdoWarning("%s not found - using algorithm without %s!", var_stdname(specific_humidity), var_stdname(specific_humidity));
       else
-	hum    = (double*) malloc(ngp*nhlevf*sizeof(double));
+	hum    = (double*) malloc(gridsize*nhlevf*sizeof(double));
 
-      gheight = (double*) malloc(ngp*(nhlevf+1)*sizeof(double));
+      gheight = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double));
     }
   
   if ( operatorID == SEALEVELPRESSURE )
     {
-      full_press   = (double*) malloc(ngp*nhlevf*sizeof(double));
+      full_press   = (double*) malloc(gridsize*nhlevf*sizeof(double));
 
       surfaceID = zaxisFromName("surface");
-      sealevelpressure = (double*) malloc(ngp*sizeof(double));
+      sealevelpressure = (double*) malloc(gridsize*sizeof(double));
     }
 
   if ( zaxisIDh != -1 && sgeopotID == -1 )
@@ -422,7 +318,7 @@ void *Derivepar(void *argument)
       else
 	cdoPrint("%s not found - using bottom layer of %s!", var_stdname(surface_geopotential), var_stdname(geopotential));
 
-      memset(sgeopot, 0, ngp*sizeof(double));
+      memset(sgeopot, 0, gridsize*sizeof(double));
     }
 
   presID = lnpsID;
@@ -482,7 +378,6 @@ void *Derivepar(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
 	  nlevel   = zaxisInqSize(zaxisID);
 	  offset   = gridsize*levelID;
@@ -492,28 +387,28 @@ void *Derivepar(void *argument)
 	    {
 	      if ( varID == sgeopotID )
 		{
-		  memcpy(sgeopot, array, ngp*sizeof(double));
+		  memcpy(sgeopot, array, gridsize*sizeof(double));
 		}
 	      else if ( varID == geopotID && sgeopotID == -1 && (levelID+1) == nhlevf )
 		{
-		  memcpy(sgeopot, array, ngp*sizeof(double));
+		  memcpy(sgeopot, array, gridsize*sizeof(double));
 		}
 	      else if ( varID == presID )
 		{
 		  if ( lnpsID != -1 )
-		    for ( i = 0; i < ngp; ++i ) ps[i] = exp(array[i]);
+		    for ( i = 0; i < gridsize; ++i ) ps[i] = exp(array[i]);
 		  else if ( psID != -1 )
-		    memcpy(ps, array, ngp*sizeof(double));
+		    memcpy(ps, array, gridsize*sizeof(double));
 		}
 	      else if ( varID == tempID )
-		memcpy(temp+offset, array, ngp*sizeof(double));
+		memcpy(temp+offset, array, gridsize*sizeof(double));
 	      else if ( varID == humID )
-		memcpy(hum+offset, array, ngp*sizeof(double));
+		memcpy(hum+offset, array, gridsize*sizeof(double));
 	      /*
 	      else if ( varID == clwcID )
-		memcpy(lwater+offset, array, ngp*sizeof(double));
+		memcpy(lwater+offset, array, gridsize*sizeof(double));
 	      else if ( varID == ciwcID )
-		memcpy(iwater+offset, array, ngp*sizeof(double));
+		memcpy(iwater+offset, array, gridsize*sizeof(double));
 	      */
 	    }
 	}
@@ -521,12 +416,12 @@ void *Derivepar(void *argument)
       if ( zaxisIDh != -1 )
 	{
 	  /* check range of ps_prog */
-	  minmaxval(ngp, ps, NULL, &minval, &maxval);
+	  minmaxval(gridsize, ps, NULL, &minval, &maxval);
 	  if ( minval < MIN_PS || maxval > MAX_PS )
 	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
 
 	  /* check range of surface geopot */
-	  minmaxval(ngp, sgeopot, NULL, &minval, &maxval);
+	  minmaxval(gridsize, sgeopot, NULL, &minval, &maxval);
 	  if ( minval < MIN_FIS || maxval > MAX_FIS )
 	    cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval);
 	}
@@ -535,11 +430,10 @@ void *Derivepar(void *argument)
       nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       for ( levelID = 0; levelID < nlevel; levelID++ )
 	{
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  offset   = gridsize*levelID;
 	  single2  = temp + offset;
 
-	  minmaxval(ngp, single2, NULL, &minval, &maxval);
+	  minmaxval(gridsize, single2, NULL, &minval, &maxval);
 	  if ( minval < MIN_T || maxval > MAX_T )
 	    cdoWarning("Input temperature at level %d out of range (min=%g max=%g)!",
 		       levelID+1, minval, maxval);
@@ -551,13 +445,12 @@ void *Derivepar(void *argument)
 	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      offset   = gridsize*levelID;
 	      single2  = hum + offset;
 
 	      // corr_hum(gridsize, single2, MIN_Q);
 
-	      minmaxval(ngp, single2, NULL, &minval, &maxval);
+	      minmaxval(gridsize, single2, NULL, &minval, &maxval);
 	      if ( minval < -0.1 || maxval > MAX_Q )
 		cdoWarning("Input humidity at level %d out of range (min=%g max=%g)!",
 			   levelID+1, minval, maxval);
@@ -566,10 +459,10 @@ void *Derivepar(void *argument)
 
       if ( operatorID == GHEIGHT )
 	{
-	  presh(NULL, half_press, vct, ps, nhlevf, ngp);
+	  presh(NULL, half_press, vct, ps, nhlevf, gridsize);
 	  
-	  memcpy(gheight+ngp*nhlevf, sgeopot, ngp*sizeof(double));
-	  MakeGeopotHeight(gheight, temp, hum, half_press, ngp, nhlevf);
+	  memcpy(gheight+gridsize*nhlevf, sgeopot, gridsize*sizeof(double));
+	  MakeGeopotHeight(gheight, temp, hum, half_press, gridsize, nhlevf);
 
 	  nmissout = 0;
 	  varID = 0;
@@ -577,14 +470,14 @@ void *Derivepar(void *argument)
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
 	      streamDefRecord(streamID2, varID, levelID);
-	      streamWriteRecord(streamID2, gheight+levelID*ngp, nmissout);
+	      streamWriteRecord(streamID2, gheight+levelID*gridsize, nmissout);
 	    }
 	}
       else if ( operatorID == SEALEVELPRESSURE )
 	{
-	  presh(full_press, half_press, vct, ps, nhlevf, ngp);
+	  presh(full_press, half_press, vct, ps, nhlevf, gridsize);
 
-	  extra_P(sealevelpressure, half_press+ngp*(nhlevf), full_press+ngp*(nhlevf-1), sgeopot, temp+ngp*(nhlevf-1), ngp);
+	  extra_P(sealevelpressure, half_press+gridsize*(nhlevf), full_press+gridsize*(nhlevf-1), sgeopot, temp+gridsize*(nhlevf-1), gridsize);
 
 	  streamDefRecord(streamID2, 0, 0);
 	  streamWriteRecord(streamID2, sealevelpressure, 0);
diff --git a/src/Detrend.c b/src/Detrend.c
index 0c900a0..1a55b57 100644
--- a/src/Detrend.c
+++ b/src/Detrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -65,30 +65,6 @@ void detrend(long nts, double missval1, double *array1, double *array2)
 }
 
 
-void taxisInqDTinfo(int taxisID, dtinfo_t *dtinfo)
-{
-  dtinfo->v.date = taxisInqVdate(taxisID);
-  dtinfo->v.time = taxisInqVtime(taxisID);
-  if ( taxisHasBounds(taxisID) )
-    {
-      taxisInqVdateBounds(taxisID, &(dtinfo->b[0].date), &(dtinfo->b[1].date));
-      taxisInqVtimeBounds(taxisID, &(dtinfo->b[0].time), &(dtinfo->b[1].time));
-    }
-}
-
-
-void taxisDefDTinfo(int taxisID, dtinfo_t dtinfo)
-{
-  taxisDefVdate(taxisID, dtinfo.v.date);
-  taxisDefVtime(taxisID, dtinfo.v.time);
-  if ( taxisHasBounds(taxisID) )
-    {
-      taxisDefVdateBounds(taxisID, dtinfo.b[0].date, dtinfo.b[1].date);
-      taxisDefVtimeBounds(taxisID, dtinfo.b[0].time, dtinfo.b[1].time);
-    }
-}
-
-
 void *Detrend(void *argument)
 {
   int gridsize;
@@ -104,7 +80,7 @@ void *Detrend(void *argument)
   int nvars, nlevel;
   double missval;
   field_t ***vars = NULL;
-  dtinfo_t *dtinfo = NULL;
+  dtlist_type *dtlist = dtlist_new();
   typedef struct
   {
     double *array1;
@@ -135,11 +111,10 @@ void *Detrend(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  dtinfo = (dtinfo_t*) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
 	  vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
 	}
 
-      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
 
       vars[tsID] = field_malloc(vlistID1, FIELD_NONE);
 
@@ -200,7 +175,7 @@ void *Detrend(void *argument)
 
   for ( tsID = 0; tsID < nts; tsID++ )
     {
-      taxisDefDTinfo(taxisID2, dtinfo[tsID]);
+      dtlist_taxisDefTimestep(dtlist, taxisID2, tsID);
       streamDefTimestep(streamID2, tsID);
 
       for ( varID = 0; varID < nvars; varID++ )
@@ -223,7 +198,8 @@ void *Detrend(void *argument)
     }
 
   if ( vars  ) free(vars);
-  if ( dtinfo ) free(dtinfo);
+
+  dtlist_delete(dtlist);
 
   streamClose(streamID2);
   streamClose(streamID1);
diff --git a/src/Diff.c b/src/Diff.c
index 2cc813c..03b2573 100644
--- a/src/Diff.c
+++ b/src/Diff.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -68,7 +68,7 @@ void *Diff(void *argument)
 
   operatorID = cdoOperatorID();
 
-  if ( operatorArgc() == 1 ) abslim = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) abslim = parameter2double(operatorArgv()[0]);
   if ( abslim < -1.e33 || abslim > 1.e+33 ) cdoAbort("Abs. limit out of range\n");
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Distgrid.c b/src/Distgrid.c
index 63da588..fae6d70 100644
--- a/src/Distgrid.c
+++ b/src/Distgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -126,7 +126,6 @@ void *Distgrid(void *argument)
   int nrecs, ngrids;
   int tsID, recID, levelID;
   int vlistID1;
-  char *rstr;
   char filesuffix[32];
   char filename[8192];
   const char *refname;
@@ -147,13 +146,8 @@ void *Distgrid(void *argument)
   operatorInputArg("nxblocks, [nyblocks]");
   if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
   if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
-  nxblocks = (int)strtol(operatorArgv()[0], &rstr, 10);
-  if ( *rstr != 0 ) cdoAbort("Integer parameter string contains invalid characters: %s", operatorArgv()[0]);
-  if ( operatorArgc() == 2 )
-    {
-      nyblocks = (int)strtol(operatorArgv()[1], &rstr, 10);
-      if ( *rstr != 0 ) cdoAbort("Integer parameter string contains invalid characters: %s", operatorArgv()[1]);
-    }
+  nxblocks = parameter2int(operatorArgv()[0]);
+  if ( operatorArgc() == 2 ) nyblocks = parameter2int(operatorArgv()[1]);
 
   if ( nxblocks <= 0 ) cdoAbort("nxblocks has to be greater than 0!");
   if ( nyblocks <= 0 ) cdoAbort("nyblocks has to be greater than 0!");
diff --git a/src/Duplicate.c b/src/Duplicate.c
index a6951a8..aef844b 100644
--- a/src/Duplicate.c
+++ b/src/Duplicate.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -44,7 +44,7 @@ void *Duplicate(void *argument)
   cdoInitialize(argument);
 
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
-  else if ( operatorArgc() == 1 ) ndup = atoi(operatorArgv()[0]);
+  else if ( operatorArgc() == 1 ) ndup = parameter2int(operatorArgv()[0]);
 
   if ( cdoVerbose ) cdoPrint("ndup = %d\n", ndup);
 
diff --git a/src/EOFs.c b/src/EOFs.c
index 11c96cf..4293cf8 100644
--- a/src/EOFs.c
+++ b/src/EOFs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -28,8 +28,9 @@
  * number of contributing values during summation.
  */
 
-//#define OLD_IMPLEMENTATION
-#define WEIGHTS 1
+#if defined(_OPENMP)
+#include <omp.h>
+#endif
 
 #include <limits.h>  // LONG_MAX
 #include <cdi.h>
@@ -39,150 +40,238 @@
 #include "grid.h"
 #include "statistic.h"
 
-enum T_EIGEN_MODE {JACOBI, DANIELSON_LANCZOS};
-
 // NO MISSING VALUE SUPPORT ADDED SO FAR
 
-void *EOFs(void * argument)
+static
+void scale_eigvec_grid(double *restrict out, int tsID, int npack, const int *restrict pack, const double *restrict weight, double **covar, double sum_w)
 {
-  char *envstr;
+  for ( int i = 0; i < npack; ++i )
+    out[pack[i]] = covar[tsID][i] / sqrt(weight[pack[i]]/sum_w);
+}
+
+static
+void scale_eigvec_time(double *restrict out, int tsID, int nts, int npack, const int *restrict pack, const double *restrict weight,
+		       double **covar, double **data, double missval, double sum_w)
+{
+#if defined(_OPENMP)
+#pragma omp parallel for shared(tsID, data, out)
+#endif
+  for ( int i = 0; i < npack; ++i )
+    {
+      double sum = 0;
+      for ( int j = 0; j < nts; ++j )
+	sum += data[j][i] * covar[tsID][j];
+      
+      out[pack[i]] = sum;
+    }
+  /*
+  for ( int j = 0; j < nts; ++j )
+    {
+      for ( int i = 0; i < npack; ++i )
+	out[pack[i]] += data[j][i] * covar[tsID][j];
+    }
+  */
+
+  // Normalizing
+  double sum = 0;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) reduction(+:sum)	\
+  shared(out,weight,pack,npack)
+#endif
+  for ( int i = 0; i < npack; ++i )
+    {
+      // do not need to account for weights as eigenvectors are non-weighted                                   
+      sum += weight[pack[i]] * out[pack[i]] * out[pack[i]];
+    }
+
+  if ( sum > 0 )
+    {
+      sum = sqrt(sum/sum_w);
+#if defined(_OPENMP)
+#pragma omp parallel for default(none)  shared(npack,pack,sum,out)
+#endif
+      for ( int i = 0; i < npack; ++i ) out[pack[i]] /= sum;
+    }
+  else
+    {
+#if defined(_OPENMP)
+#pragma omp parallel for default(none)  shared(npack,pack,out,missval)
+#endif
+      for ( int i = 0; i < npack; ++i ) out[pack[i]] = missval;
+    }
+}
 
+
+enum T_EIGEN_MODE get_eigenmode(void)
+{
+  enum T_EIGEN_MODE eigen_mode = JACOBI;
+
+  char *envstr = getenv("CDO_SVD_MODE");  
+  if ( envstr )
+    {
+      if ( !strncmp(envstr, "danielson_lanczos", 17) ) 
+	eigen_mode = DANIELSON_LANCZOS;
+      else if ( !strncmp(envstr, "jacobi", 6) )
+	eigen_mode = JACOBI;
+      else
+	{
+	  cdoWarning("Unknown environmental setting %s for CDO_SVD_MODE. Available options are", envstr);
+	  cdoWarning("  - 'jacobi' for a one-sided parallelized jacobi algorithm");
+	  cdoWarning("  - 'danielson_lanzcos' for the D/L algorithm");
+	}
+    }
+
+  if ( cdoVerbose ) 
+    cdoPrint("Using CDO_SVD_MODE '%s' from %s",
+	     eigen_mode==JACOBI?"jacobi":"danielson_lanczos",
+	     envstr?"Environment":" default");  
+
+#if defined(_OPENMP)
+  if ( omp_get_max_threads() > 1 && eigen_mode == DANIELSON_LANCZOS )  {
+    cdoWarning("Requested parallel computation with %i Threads ",omp_get_max_threads());
+    cdoWarning("  but environmental setting CDO_SVD_MODE causes sequential ");
+    cdoWarning("  Singular value decomposition");
+  }
+#endif 
+
+  return eigen_mode;
+}
+
+
+enum T_WEIGHT_MODE get_weightmode(void)
+{  
+  enum T_WEIGHT_MODE weight_mode = WEIGHT_ON;
+
+  char *envstr = getenv("CDO_WEIGHT_MODE");
+  if ( envstr )
+    {
+      if ( !strncmp(envstr, "off", 3) ) 
+	weight_mode = WEIGHT_OFF;
+      else if ( !strncmp(envstr, "on", 2) )
+	weight_mode = WEIGHT_ON;
+      else
+	cdoWarning("Unknown environmental setting %s for CDO_WEIGHT_MODE. Available options are: on/off", envstr);
+    }
+
+  if ( cdoVerbose ) 
+    cdoPrint("Using CDO_WEIGHT_MODE '%s' from %s",
+	     weight_mode==WEIGHT_OFF?"off":"on",
+	     envstr?"Environment":" default");  
+
+  return weight_mode;
+}
+
+
+void *EOFs(void * argument)
+{
   enum {EOF_, EOF_TIME, EOF_SPATIAL};
 
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2, streamID3;
-  long gridsize;
-  long i, ii, j, i1, i2, j1, j2;
-  int vdate = 0, vtime = 0;
-  int nrecs, nvars, nlevs=0 ;
+  int i, j, j1, j2;
+  int nlevs = 0 ;
   int nmiss;
   int tsID;
   int varID, recID, levelID;
-  int vlistID1, vlistID2 = -1, vlistID3 = -1;
-  int taxisID1, taxisID2, taxisID3;
-  int gridID1, gridID2, gridID3;
-  int ngrids;
-  int reached_eof;
-  int npack=0, nts=0;
-  int *pack, *miss;
-  int *datacountv;
-  int ***datacounts;
-  int n_eig, n=0;
-  int grid_space=0, time_space=0;
-  int missval_warning=0;
-  int timer_init = 0, timer_alloc = 0, timer_read = 0, timer_cov = 0, timer_eig = 0, timer_post = 0, timer_write = 0, timer_finish = 0;
+  int nts = 0;
+  int n = 0;
+  int grid_space = 0, time_space = 0;
+  int timer_cov = 0, timer_eig = 0;
 
   int calendar = CALENDAR_STANDARD;
   juldate_t juldate;
 
-  double *weight;
-  double sum_w;
   double sum;
-  double missval=0;
+  double missval = 0;
   double xvals, yvals;
-  double **cov, *eigv;
 
-  double *df1p, *df2p;
-  double **datafieldv = NULL;
-  double ****datafields = NULL;
-  double ****eigenvectors = NULL, ****eigenvalues = NULL;
-  double *in = NULL;
-
-  enum T_EIGEN_MODE eigen_mode = JACOBI;
+  typedef struct {
+    int init;
+    int first_call;
+    double *eig_val;
+    double *covar_array;
+    double **covar;
+    double **data;
+  }
+  eofdata_t;
 
   if ( cdoTimer )
     {
-      timer_init = timer_new("Timeof init");
-      timer_alloc= timer_new("Timeof alloc");
-      timer_read = timer_new("Timeof read");
       timer_cov  = timer_new("Timeof cov");
       timer_eig  = timer_new("Timeof eig");
-      timer_post = timer_new("Timeof post");
-      timer_write= timer_new("Timeof write");
-      timer_finish=timer_new("Timeof finish");
-
-      timer_start(timer_init);
     }
   
   cdoInitialize(argument);
 
-  cdoOperatorAdd("eof",       EOF_,       0, NULL);
-  cdoOperatorAdd("eoftime",   EOF_TIME,   0, NULL);
-  cdoOperatorAdd("eofspatial",EOF_SPATIAL,0, NULL);
+  cdoOperatorAdd("eof",        EOF_,        0, NULL);
+  cdoOperatorAdd("eoftime",    EOF_TIME,    0, NULL);
+  cdoOperatorAdd("eofspatial", EOF_SPATIAL, 0, NULL);
 
-  operatorID  = cdoOperatorID();
-  operfunc    = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
 
   operatorInputArg("Number of eigen functions to write out");
-  n_eig       = atoi(operatorArgv()[0]);
-
-  envstr = getenv("CDO_SVD_MODE");
-  
-  if ( envstr && !strncmp(envstr,"danielson_lanczos",17) ) 
-    eigen_mode = DANIELSON_LANCZOS;
-  else if ( envstr && ! strncmp(envstr,"jacobi",6 ) )
-    eigen_mode = JACOBI;
-  else if ( envstr ) {
-    cdoWarning("Unknown environmental setting %s for CDO_SVD_MODE. Available options are",envstr);
-    cdoWarning("  - 'jacobi' for a one-sided parallelized jacobi algorithm");
-    cdoWarning("  - 'danielson_lanzcos' for the D/L algorithm");
-    envstr=NULL;
-  }
-
-  if ( cdoVerbose ) 
-    cdoPrint("Using CDO_SVD_MODE '%s' from %s",
-	     eigen_mode==JACOBI?"jacobi":"danielson_lanczos",
-	     envstr?"Environment":" default");
+  int n_eig      = parameter2int(operatorArgv()[0]);
   
+  enum T_EIGEN_MODE eigen_mode = get_eigenmode();
+  enum T_WEIGHT_MODE weight_mode = get_weightmode();
+
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int vlistID1  = streamInqVlist(streamID1);
+  int taxisID1  = vlistInqTaxis(vlistID1);
+  int gridID1   = vlistInqVarGrid(vlistID1, 0);
+  int gridsize  = vlistGridsizeMax(vlistID1);
+  int nvars     = vlistNvars(vlistID1);
+  int nrecs     = vlistNrecs(vlistID1);
+
+  int ngrids = vlistNgrids(vlistID1);
+  for ( int index = 1; index < ngrids; index++ )
+    if ( vlistGrid(vlistID1, 0) != vlistGrid(vlistID1, index))
+      {
+	cdoAbort("Too many different grids!");
+      }
+
+  double *weight = (double *) malloc(gridsize*sizeof(double));
+  for ( i = 0; i < gridsize; ++i ) weight[i] = 1.;
+
+  if ( weight_mode == WEIGHT_ON )
+    {
+      int wstatus = gridWeights(gridID1, weight);
+      if ( wstatus != 0  )
+	{
+	  weight_mode = WEIGHT_OFF;
+	  cdoWarning("Using constant grid cell area weights!");
+	}
+    }
 
-  streamID1   = streamOpenRead(cdoStreamName(0));
-  vlistID1    = streamInqVlist(streamID1);
-  taxisID1    = vlistInqTaxis(vlistID1);
-  gridID1     = vlistInqVarGrid(vlistID1, 0);
-  gridsize    = vlistGridsizeMax(vlistID1);
-  nvars       = vlistNvars(vlistID1);
-  nrecs       = vlistNrecs(vlistID1);
-
-  weight      = (double*) malloc(gridsize*sizeof(double));
-  if ( WEIGHTS )
-    gridWeights(gridID1, &weight[0]);
-  else
-    for(i=0;i<gridsize;i++) 
-      weight[i]=1;
-
-  /*  eigenvalues */
+  /* eigenvalues */
 
-  reached_eof = 0;
-  tsID        = 0;
+  tsID = 0;
 
   /* COUNT NUMBER OF TIMESTEPS if EOF_ or EOF_TIME */
   if ( operfunc == EOF_ || operfunc == EOF_TIME )
     {
-      if ( cdoVerbose ) 
-	cdoPrint("Counting timesteps in ifile");
-      
-      while ( TRUE )
-        {
-          if ( reached_eof ) continue;
-          nrecs = streamInqTimestep(streamID1, tsID);
-          if ( nrecs == 0 ) {
-              reached_eof = 1;
-              break;
-            }
-          tsID++;
-        }
+      if ( cdoVerbose ) cdoPrint("Counting timesteps in ifile");
+
+      nts = vlistNtsteps(vlistID1);
+      if ( nts == -1 )
+	{
+	  while ( TRUE )
+	    {
+	      nrecs = streamInqTimestep(streamID1, tsID);
+	      if ( nrecs == 0 )  break;
+	      tsID++;
+	    }
 
-      if ( cdoVerbose ) 
-	cdoPrint("Counted %i timeSteps",tsID);
+	  nts = tsID;
+	  if ( cdoVerbose ) cdoPrint("Counted %i timeSteps", nts);
+	}
 
-      nts         = tsID;
-      reached_eof = 0;
-      //TODO close on streamID1 ??  streamClose(streamID1);
       streamClose(streamID1);
-      streamID1   = streamOpenRead(cdoStreamName(0));
-      vlistID1    = streamInqVlist(streamID1);
-      taxisID1    = vlistInqTaxis(vlistID1);
+
+      streamID1 = streamOpenRead(cdoStreamName(0));
+      vlistID1  = streamInqVlist(streamID1);
+      taxisID1  = vlistInqTaxis(vlistID1);
+
       if ( nts < gridsize || operfunc == EOF_TIME )
 	{
 	  time_space = 1;
@@ -215,8 +304,7 @@ void *EOFs(void * argument)
     }
   else if ( grid_space )
     {
-      if ( ((double)gridsize)*gridsize > (double)LONG_MAX )
-	cdoAbort("Grid space to large!");
+      if ( ((double)gridsize)*gridsize > (double)LONG_MAX ) cdoAbort("Grid space too large!");
 
       if ( n_eig > gridsize )
         {
@@ -233,432 +321,180 @@ void *EOFs(void * argument)
     cdoPrint("Calculating %i eigenvectors and %i eigenvalues in %s",
 	     n_eig,n,grid_space==1?"grid_space" : "time_space");
 
-  if ( cdoTimer ) timer_stop(timer_init);
-  
-  if ( cdoTimer ) timer_start(timer_alloc);
-
   /* allocation of temporary fields and output structures */
-  in           = (double*) malloc(gridsize*sizeof(double));
-  datafields   = (double ****) malloc(nvars*sizeof(double ***));
-  datacounts   = (int ***) malloc(nvars*sizeof(int **));
-  eigenvectors = (double ****) malloc(nvars*sizeof(double ***));
-  eigenvalues  = (double ****) malloc(nvars*sizeof(double ***));
+  int npack = -1;
+  int *pack            = (int *) malloc(gridsize*sizeof(int));
+  double *in           = (double *) malloc(gridsize*sizeof(double));
+  eofdata_t **eofdata  = (eofdata_t **) malloc(nvars*sizeof(eofdata_t*));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
-      gridID1             = vlistInqVarGrid(vlistID1, varID);
-      gridsize            = vlistGridsizeMax(vlistID1);
-      nlevs               = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      missval             = vlistInqVarMissval(vlistID1, varID);
+      gridID1  = vlistInqVarGrid(vlistID1, varID);
+      gridsize = vlistGridsizeMax(vlistID1);
+      nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+      missval  = vlistInqVarMissval(vlistID1, varID);
 
-      datafields[varID]   = (double ***) malloc(nlevs*sizeof(double **));
-      datacounts[varID]   = (int* *) malloc(nlevs*sizeof(int* ));
-      eigenvectors[varID] = (double ***) malloc(nlevs*sizeof(double **));
-      eigenvalues[varID]  = (double ***) malloc(nlevs*sizeof(double **));
+      eofdata[varID] = (eofdata_t *) malloc(nlevs*sizeof(eofdata_t));
 
       for ( levelID = 0; levelID < nlevs; ++levelID )
         {
-          if ( grid_space )
-            {
-              datafields[varID][levelID]            = (double **) malloc(1*sizeof(double *));
-              //datafields[varID][levelID][0].grid    = gridID1;
-              //datafields[varID][levelID][0].nmiss   = 0;
-              //datafields[varID][levelID][0].missval = missval;
-              datafields[varID][levelID][0]     = (double*) malloc(gridsize*gridsize*sizeof(double));
-
-              datacounts[varID][levelID]            = (int*) malloc(gridsize*gridsize*sizeof(int));
-	      for ( i = 0; i<gridsize*gridsize; i++ )
-		{
-		  datacounts[varID][levelID][i] = 0;
-		  datafields[varID][levelID][0][i] = 0;            
-		}
-	    }
-          else if ( time_space )
-            {
-              datafields[varID][levelID] = (double **) malloc(nts*sizeof(double *));
-              for ( tsID = 0; tsID < nts; tsID++ )
-                {
-                  //datafields[varID][levelID][tsID].grid    = gridID1;
-                  //datafields[varID][levelID][tsID].nmiss   = 0;
-                  //datafields[varID][levelID][tsID].missval = missval;
-                  datafields[varID][levelID][tsID]    = (double*) malloc(gridsize*sizeof(double));
-                  for ( i = 0; i < gridsize; ++i )
-                    datafields[varID][levelID][tsID][i] = 0;
-                }
-              datacounts[varID][levelID] = (int*) malloc(gridsize*sizeof(int));	      
-	      for(i=0;i<gridsize;i++)
-		datacounts[varID][levelID][i] = 0;
-            }
-
-          eigenvectors[varID][levelID] = (double **) malloc(n_eig*sizeof(double *));
-          eigenvalues[varID][levelID]  = (double **) malloc(n*sizeof(double *));
-
-          for ( i = 0; i < n; i++ )
-            {
-              if ( i < n_eig )
-                {
-                  eigenvectors[varID][levelID][i] = (double*) malloc(gridsize*sizeof(double));
-                  for ( ii = 0; ii < gridsize; ++ii )
-                    eigenvectors[varID][levelID][i][ii] = missval;
-                }
-
-              eigenvalues[varID][levelID][i] = (double*) malloc(1*sizeof(double));
-              eigenvalues[varID][levelID][i][0]  = missval;
-            }
+	  eofdata[varID][levelID].init = 0;
+	  eofdata[varID][levelID].first_call = TRUE;
+	  eofdata[varID][levelID].eig_val = NULL;
+	  eofdata[varID][levelID].covar_array = NULL;
+	  eofdata[varID][levelID].covar = NULL;
+	  eofdata[varID][levelID].data = NULL;
+
+	  if ( time_space )
+	    eofdata[varID][levelID].data = (double **) malloc(nts*sizeof(double *));
         }
     }
 
   if ( cdoVerbose )
     cdoPrint("Allocated eigenvalue/eigenvector structures with nts=%i gridsize=%i", nts, gridsize);
 
-  if ( cdoTimer ) timer_stop(timer_alloc);
-  if ( cdoTimer ) timer_start(timer_read);
+  int ipack, jpack;
+  double *covar_array = NULL;
+  double **covar = NULL;
+  double sum_w = 1.;
+
   tsID = 0;
 
   /* read the data and create covariance matrices for each var & level */
   while ( TRUE )
     {
-      if ( reached_eof ) continue;
       nrecs = streamInqTimestep(streamID1, tsID);
-      if ( nrecs == 0 )
-        {
-          reached_eof = 1;
-          break;
-        }
-
-      vdate = taxisInqVdate(taxisID1);
-      vtime = taxisInqVtime(taxisID1);
+      if ( nrecs == 0 ) break;
 
       for ( recID = 0; recID < nrecs; recID++ )
         {
-          int i2;
-
           streamInqRecord(streamID1, &varID, &levelID);
-          gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-
-          missval = vlistInqVarMissval(vlistID1, varID);
           streamReadRecord(streamID1, in, &nmiss);
 
-          if ( grid_space )
-            {
-	      // This could be done in parallel to save lots of time
-#if defined(_OPENMP)
-#pragma omp parallel for private(i1,i2) default(shared)
-#endif
-              for ( i1 = 0; i1 < gridsize; i1++ )
-                {
-                  for ( i2 = i1; i2 < gridsize; i2++ )
-                    {
-                      if ( nmiss == 0 ||
-			   (( ! DBL_IS_EQUAL(in[i1], missval) ) &&
-			    ( ! DBL_IS_EQUAL(in[i2], missval) )) )
-                        {
-                          datafields[varID][levelID][0][i1*gridsize+i2] += in[i1]*in[i2];
-                          datacounts[varID][levelID][i1*gridsize+i2]++;
-                        }
-                      else if ( missval_warning == 0 )
-                        {
-			  cdoWarning("Missing value support not checked for this operator!\n");
-			  missval_warning = 1; 
-			}
-                    }
-                }
-            }
-          else if ( time_space )
+	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+          missval = vlistInqVarMissval(vlistID1, varID);
+	  if ( npack == -1 )
 	    {
-	      for ( i=0; i<gridsize; ++i )
+	      npack = 0;
+	      for ( i = 0; i < gridsize; ++i )
 		{
-		  if ( ! DBL_IS_EQUAL(in[i], missval ) )
-		    {
-		      datafields[varID][levelID][tsID][i] = in[i];
-		      datacounts[varID][levelID][i]++;
-		    }
-		  else
-		    {
-		      if ( missval_warning == 0 )
-			{
-			  cdoWarning("Missing Value Support not Checked for this Operator!");
-			  cdoWarning("Does not work with changing locations of missing values in time.");
-			  missval_warning = 1;
-			}
-		      datafields[varID][levelID][tsID][i] = 0;
-		    }
+		  if ( !DBL_IS_EQUAL(weight[i], 0) && !DBL_IS_EQUAL(weight[i], missval) &&
+		       !DBL_IS_EQUAL(in[i], missval) )
+		    pack[npack++] = i;
 		}
-	    }
-        }
-      tsID++;
-    }
-
-  if ( tsID == 1 )
-    cdoAbort("File consists of only one timestep!");
-
-  if ( grid_space )
-    for ( i1 = 0; i1 < gridsize; ++i1 )
-      for ( i2 = 0; i2 < i1; ++i2 )
-        {
-          datafields[varID][levelID][0][i1*gridsize+i2] = datafields[varID][levelID][0][i2*gridsize+i1];
-          datacounts[varID][levelID][i1*gridsize+i2]    = datacounts[varID][levelID][i2*gridsize+i1];
-        }
-
-  /*
-  pack = (int*) malloc(gridsize*sizeof(int)); //TODO
-  miss = (int*) malloc(gridsize*sizeof(int));
-  */
-
-  if ( cdoTimer ) timer_stop(timer_read);
-
-  for ( varID = 0; varID < nvars; varID++ )
-    {
-      char vname[256];
-      vlistInqVarName(vlistID1, varID, vname);
-      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-      nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-
-      if ( cdoVerbose )
-	cdoPrint("Calculating cov matrices for %i levels of var%i (%s)", nlevs, varID, vname);
-
-      for ( levelID = 0; levelID < nlevs; levelID++ )
-        {
-	  if ( cdoTimer ) timer_start(timer_cov);
-
-	  if ( cdoVerbose ) cdoPrint("processing level %i",levelID);
 
-          int i2;
-
-	  datafieldv = datafields[varID][levelID];
-	  datacountv = datacounts[varID][levelID];
-
-          cov   = NULL; // TODO covariance matrix / eigenvectors after solving
-          eigv  = NULL; // TODO eigenvalues
-	  pack  = NULL;
-	  miss  = NULL;
-          npack = 0;    // TODO already set to 0
-          sum_w = 0;
-
-          if ( grid_space )
-            {
-	      pack = (int*) malloc(gridsize*sizeof(int));
-	      miss = (int*) malloc(gridsize*sizeof(int));
-
-              for ( i1 = 0; i1 < gridsize; i1++ )
-                {
-		  if ( datacountv[i1*gridsize + i1] > 1 ) 
-		    pack[npack++] = i1;
-		  else
-		    miss[i1] = 1;
-                }
-
-              for ( i1 = 0; i1 < npack; i1++ )
-                sum_w += weight[pack[i1]];
+	      if ( weight_mode == WEIGHT_ON )
+		{
+		  sum_w = 0;
+		  for ( i = 0; i < npack; i++ )  sum_w += weight[pack[i]];
+		}
+	    }
 
-	      n = npack;
-	      if ( npack )
+	  ipack = 0;
+	  for ( i = 0; i < gridsize; ++i )
+	    {
+	      if ( !DBL_IS_EQUAL(weight[i], 0) && !DBL_IS_EQUAL(weight[i], missval) &&
+		   !DBL_IS_EQUAL(in[i], missval) && pack[ipack++] != i )
+		{
+		  cdoAbort("Missing values unsupported!");
+		}
+	      else if ( DBL_IS_EQUAL(in[i], missval) && pack[ipack] == i )
 		{
-		  cov = (double **) malloc(npack*sizeof(double *));
-		  for (i1 = 0; i1 < npack; i1++ )
-		    cov[i1] = (double*) malloc(npack*sizeof(double));
-		  eigv = (double*) malloc(npack*sizeof(double));
+		  cdoAbort("Missing values unsupported!");
 		}
+	    }
 
-              for (i1 = 0; i1 < npack; i1++)
-		for (i2 = i1; i2 < npack; i2++ )
-		  if ( datacountv[pack[i1]*gridsize+pack[i2]] )
-		    cov[i2][i1] = cov[i1][i2] =
-		      datafieldv[0][pack[i1]*gridsize+pack[i2]]*   // covariance
-		      sqrt(weight[pack[i1]]) * sqrt (weight[pack[i2]]) / sum_w /       // weights
-		      (datacountv[pack[i1]*gridsize+pack[i2]]);   // number of data contributing
-            }
-          else if ( time_space )
+	  if ( grid_space )
             {
-              sum_w = 0;
-
-	      pack = (int*) malloc(gridsize*sizeof(int));
-	      miss = (int*) malloc(gridsize*sizeof(int));
-
-              for ( i = 0; i < gridsize; i++ )
-                {
-		  if ( datacountv[i] )
+	      if ( !eofdata[varID][levelID].init )
+		{
+		  n = npack;
+		  double *covar_array = (double *) malloc(npack*npack*sizeof(double));
+		  covar = (double **) malloc(npack*sizeof(double *));
+		  for ( i = 0; i < npack; ++i ) covar[i] = covar_array + npack*i;
+		  for ( i = 0; i < npack; ++i )
 		    {
-		      pack[npack] = i;
-		      npack++;
-		      sum_w += weight[i];
+		      for ( j = 0; j < npack; ++j ) covar[i][j] = 0;
 		    }
-		}
-
-	      if ( cdoVerbose )
-		cdoPrint("allocating cov with %i x %i elements | npack=%i",nts,nts,npack);
-
-              cov = (double**) malloc(nts*sizeof(double*));
-              for ( j1 = 0; j1 < nts; j1++)
-                cov[j1] = (double*) malloc(nts*sizeof(double));
-	      eigv = (double*) malloc(nts*sizeof(double));
-
-#if defined(_OPENMP)
-#pragma omp parallel for private(j1,j2,i,sum, df1p, df2p) default(shared) schedule(dynamic)
-#endif
-              for ( j1 = 0; j1 < nts; j1++ )
-		for ( j2 = j1; j2 < nts; j2++ )
-		  {
-		    sum = 0;
-		    df1p = datafieldv[j1];
-		    df2p = datafieldv[j2];
-		    for ( i = 0; i < npack; i++ )
-		      {
-			sum += weight[pack[i]]*df1p[pack[i]]*df2p[pack[i]];
-		      }
-		    cov[j2][j1] = cov[j1][j2] = sum / sum_w / nts;
-		  }
-
-	      if ( cdoVerbose )
-		cdoPrint("finished calculation of cov-matrix for var %s",&vname[0]);
-            }
-
-	  if ( cdoTimer ) timer_stop(timer_cov);
-
-          /* SOLVE THE EIGEN PROBLEM */
-	  if ( cdoTimer ) timer_start(timer_eig);
-	  
-	  if ( eigen_mode == JACOBI ) 
-	    // TODO: use return status (>0 okay, -1 did not converge at all) 
-	    parallel_eigen_solution_of_symmetric_matrix(&cov[0],&eigv[0],n,n,__func__);
-	  else 
-	    eigen_solution_of_symmetric_matrix(&cov[0],&eigv[0],n,n,__func__);
-
-	  if ( cdoTimer ) timer_stop(timer_eig);
-	  /* NOW: cov contains the eigenvectors, eigv the eigenvalues */
-	  
-	  if ( cdoTimer ) timer_start(timer_post);
-          for (i = 0; i < n; i++) 
-            eigenvalues[varID][levelID][i][0] = eigv[i]*sum_w;
-
-          for ( i = 0; i < n_eig; i++ )
-            {
-	      double *eigenvec = eigenvectors[varID][levelID][i];
 
-              if ( grid_space )
+		  eofdata[varID][levelID].covar_array = covar_array;
+		  eofdata[varID][levelID].covar       = covar;
+		}
+	      else
 		{
-		  for(j = 0; j < npack; j++)
-		    eigenvec[pack[j]] = 
-#ifdef OLD_IMPLEMENTATION
-		      cov[i][j] / sqrt(weight[pack[j]]);
-#else
-		      cov[i][j] /*/ sqrt(weight[pack[j]])*/;
-#endif
+		  covar = eofdata[varID][levelID].covar;
 		}
-              else if ( time_space )
-                {
 #if defined(_OPENMP)
-#pragma omp parallel for private(i2,j,sum) shared(datafieldv,eigenvec)
+#pragma omp parallel for private(ipack, jpack) default(shared)
 #endif
-                  for ( i2 = 0; i2 < npack; i2++ )
-                    {
-                      sum = 0;
-                      for ( j = 0; j < nts; j++ )
-                        sum += datafieldv[j][pack[i2]] * cov[i][j];
-
-                      eigenvec[pack[i2]] = sum;
-                    }
-                  // NORMALIZING
-                  sum = 0;
+	      for ( ipack = 0; ipack < npack; ++ipack )
+		{
+		  for ( jpack = ipack; jpack < npack; ++jpack )
+		    covar[ipack][jpack] += in[pack[ipack]] * in[pack[jpack]];
+		}
+	    }
+          else if ( time_space )
+	    {
+	      double *data = (double *) malloc(npack*sizeof(double));
+	      eofdata[varID][levelID].data[tsID] = data;
 
-#if defined(_OPENMP)
-#pragma omp parallel for private(i2) default(none) reduction(+:sum)	\
-  shared(eigenvec,weight,pack,npack)
-#endif
-                  for ( i2 = 0; i2 < npack; i2++ )
-		    {
-		      /* 
-		      ** do not need to account for weights as eigenvectors are non-weighted                                   
-		      */ 
-#ifdef OLD_IMPLEMENTATION
-		      sum += weight[pack[i2]] *
-#else
-		      sum += /*weight[pack[i2]] **/
-#endif
-			eigenvec[pack[i2]] *
-			eigenvec[pack[i2]];
-		    }
+	      for ( ipack = 0; ipack < npack; ipack++ )
+		data[ipack] = in[pack[ipack]];
+	    }
 
-                  if ( sum > 0 )
-                    {
-                      sum = sqrt(sum);
-#if defined(_OPENMP)
-#pragma omp parallel for private(i2) default(none) \
-  shared(npack,pack,sum,eigenvec)
-#endif
-                      for( i2 = 0; i2 < npack; i2++ )
-                        eigenvec[pack[i2]] /= sum;
-                    }
-                  else
-		    {
-#if defined(_OPENMP)
-#pragma omp parallel for private(i2) default(none) \
-  shared(npack,pack,eigenvec,missval)
-#endif
-		      for( i2 = 0; i2 < npack; i2++ )
-			eigenvec[pack[i2]] = missval;
-		    }
-                } // else if ( time_space )
-            } // for ( i = 0; i < n_eig; i++ )
-	  if ( cdoTimer ) timer_stop(timer_post);
+	  eofdata[varID][levelID].init = 1;
+        }
 
-	  if ( eigv ) free(eigv);
-	  for ( i=0; i<n; i++ )
-	    if ( cov[i] ) free(cov[i]);
-	  if ( cov ) free(cov);
-	  if ( miss ) free(miss);
-	  if ( pack ) free(pack);
+      tsID++;
+    }
 
-        } // for ( levelID = 0; levelID < nlevs; levelID++ )
-    } // for ( varID = 0; varID < nvars; varID++ )
+  if ( grid_space ) nts = tsID;
 
+  if ( tsID == 1 ) cdoAbort("File consists of only one timestep!");
 
   /* write files with eigenvalues (ID3) and eigenvectors (ID2) */
 
   /* eigenvalues */
-  streamID2   = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2   = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
-  vlistID2    = vlistDuplicate(vlistID1);
-  taxisID2    = taxisDuplicate(taxisID1);
+  int vlistID2    = vlistDuplicate(vlistID1);
+  int taxisID2    = taxisDuplicate(taxisID1);
   taxisDefRdate(taxisID2, 0);
   taxisDefRtime(taxisID2, 0);
   vlistDefTaxis(vlistID2, taxisID2);
-  gridID2     = gridCreate(GRID_LONLAT, 1);
+  int gridID2     = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID2, 1);
   gridDefYsize(gridID2, 1);
   xvals    = 0;
   yvals    = 0;
   gridDefXvals(gridID2, &xvals);
   gridDefYvals(gridID2, &yvals);
-  ngrids   = vlistNgrids(vlistID2);
   for ( i = 0; i < ngrids; i++ )
     vlistChangeGridIndex(vlistID2, i, gridID2);
 
   /*  eigenvectors */
-  streamID3   = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+  int streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
 
-  vlistID3    = vlistDuplicate(vlistID1);
-  taxisID3    = taxisDuplicate(taxisID1);
-  gridID3     = gridDuplicate(gridID1);
+  int vlistID3  = vlistDuplicate(vlistID1);
+  int taxisID3  = taxisDuplicate(taxisID1);
   taxisDefRdate(taxisID3, 0);
   taxisDefRtime(taxisID3, 0);
   vlistDefTaxis(vlistID3, taxisID3);
 
-
-  if ( cdoVerbose )
-    cdoPrint("Initialized streams");
-
-  if ( cdoTimer ) timer_start(timer_write);
-
-  if ( cdoVerbose ) cdoPrint("starting to write results");
-
   streamDefVlist(streamID2, vlistID2);
   streamDefVlist(streamID3, vlistID3);
 
-  vdate = 10101;
-  vtime = 0;
+  int vdate = 10101;
+  int vtime = 0;
   juldate = juldate_encode(calendar, vdate, vtime);
-  for ( tsID = 0; tsID < n; tsID++ )
+
+  double *out = in;
+  double *eig_val = NULL;
+
+  int nts_out = nts;
+  if ( npack < nts ) nts_out = npack;
+
+  for ( tsID = 0; tsID < nts_out; tsID++ )
     {
       juldate = juldate_add_seconds(60, juldate);
       juldate_decode(calendar, juldate, &vdate, &vtime);
@@ -675,96 +511,173 @@ void *EOFs(void * argument)
         }
 
       for ( varID = 0; varID < nvars; varID++ )
-        {
-          nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-          for ( levelID = 0; levelID < nlevs; levelID++ )
-            {
+	{
+	  char vname[256];
+	  vlistInqVarName(vlistID1, varID, vname);
+	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+	  nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+
+	  for ( levelID = 0; levelID < nlevs; levelID++ )
+	    {
+	      double **data = eofdata[varID][levelID].data;
+
+	      if ( eofdata[varID][levelID].first_call )
+		{
+		  eofdata[varID][levelID].first_call = FALSE;
+
+		  if ( cdoVerbose )
+		    cdoPrint("Calculating covar matrices for %i levels of var%i (%s)", nlevs, varID, vname);
+		  
+		  if ( cdoTimer ) timer_start(timer_cov);
+
+		  if ( cdoVerbose ) cdoPrint("processing level %i",levelID);
+		  
+		  if ( grid_space )
+		    {
+		      if ( npack )
+			{
+			  eig_val = (double *) malloc(npack*sizeof(double));
+			  eofdata[varID][levelID].eig_val = eig_val;
+			}
+
+		      covar = eofdata[varID][levelID].covar;
+
+		      for ( ipack = 0; ipack < npack; ++ipack )
+			{
+			  i = pack[ipack];
+			  for ( jpack = 0; jpack < npack; ++jpack)
+			    {
+			      if ( jpack < ipack )
+				{
+				  covar[ipack][jpack] = covar[jpack][ipack];
+				}
+			      else
+				{
+				  j = pack[jpack];
+				  covar[ipack][jpack] = 
+				    covar[ipack][jpack] *   // covariance
+				    sqrt(weight[i]) * sqrt(weight[j]) / sum_w /       // weights
+				    nts;   // number of data contributing
+				}
+			    }
+			}
+		    }
+		  else if ( time_space )
+		    {		      
+		      if ( cdoVerbose )
+			cdoPrint("allocating covar with %i x %i elements | npack=%i", nts, nts, npack);
+
+		      covar_array = (double *) malloc(nts*nts*sizeof(double));
+		      covar = (double **) malloc(nts*sizeof(double *));
+		      for ( i = 0; i < nts; ++i ) covar[i] = covar_array + nts*i;
+
+		      eig_val = (double *) malloc(nts*sizeof(double));
+		      eofdata[varID][levelID].eig_val     = eig_val;
+		      eofdata[varID][levelID].covar_array = covar_array;
+		      eofdata[varID][levelID].covar       = covar;
+
+#if defined(_OPENMP)
+#pragma omp parallel for private(j1, j2, i, sum) default(shared) schedule(dynamic)
+#endif
+		      for ( j1 = 0; j1 < nts; j1++ )
+			{
+			  for ( j2 = 0; j2 < j1; j2++ ) covar[j1][j2] = covar[j2][j1];
+			  for ( j2 = j1; j2 < nts; j2++ )
+			    {
+			      sum = 0;
+			      double *df1p = data[j1];
+			      double *df2p = data[j2];
+			      for ( i = 0; i < npack; i++ )
+				sum += weight[pack[i]]*df1p[i]*df2p[i];
+			      covar[j1][j2] = sum / sum_w / nts;
+			    }
+			}
+		      
+		      if ( cdoVerbose )
+			cdoPrint("finished calculation of covar-matrix for var %s", vname);
+		    }
+
+		  if ( cdoTimer ) timer_stop(timer_cov);
+
+		  /* SOLVE THE EIGEN PROBLEM */
+		  if ( cdoTimer ) timer_start(timer_eig);
+
+		  if ( eigen_mode == JACOBI ) 
+		    // TODO: use return status (>0 okay, -1 did not converge at all) 
+		    parallel_eigen_solution_of_symmetric_matrix(covar, eig_val, n, __func__);
+		  else 
+		    eigen_solution_of_symmetric_matrix(covar, eig_val, n, __func__);
+
+		  if ( cdoTimer ) timer_stop(timer_eig);
+		  /* NOW: covar contains the eigenvectors, eig_val the eigenvalues */
+
+		  for ( i = 0; i < gridsize; ++i ) out[i] = missval;
+	  
+		  // for ( i = 0; i < n; i++ ) eig_val[i] *= sum_w;
+		} // first_call
+	      else
+		{
+		  covar   = eofdata[varID][levelID].covar;
+		  eig_val = eofdata[varID][levelID].eig_val;
+		}
+
               if ( tsID < n_eig )
                 {
+		  if      ( grid_space ) scale_eigvec_grid(out, tsID, npack, pack, weight, covar, sum_w);
+		  else if ( time_space ) scale_eigvec_time(out, tsID, nts, npack, pack, weight, covar, data, missval, sum_w);
+
                   nmiss = 0;
-                  for ( i = 0; i < gridsize; i++ )
-                    if ( DBL_IS_EQUAL(eigenvectors[varID][levelID][tsID][i], missval) ) nmiss++;
+                  for ( i = 0; i < gridsize; i++ ) if ( DBL_IS_EQUAL(out[i], missval) ) nmiss++;
 
                   streamDefRecord(streamID3, varID, levelID);
-                  streamWriteRecord(streamID3, eigenvectors[varID][levelID][tsID], nmiss);
-                }
+                  streamWriteRecord(streamID3, out, nmiss);
+		} // loop n_eig
 
-              if ( DBL_IS_EQUAL(eigenvalues[varID][levelID][tsID][0], missval) ) nmiss = 1;
-              else nmiss = 0;
+	      nmiss = 0;
+              if ( DBL_IS_EQUAL(eig_val[tsID], missval) ) nmiss = 1;
               streamDefRecord(streamID2, varID, levelID);
-              streamWriteRecord(streamID2, eigenvalues[varID][levelID][tsID], nmiss);
-
-            }
-        }
+              streamWriteRecord(streamID2, &eig_val[tsID], nmiss);
+	    } // loop nlevs
+	} // loop nvars
     }
 
-  if ( cdoVerbose ) cdoPrint("stopping timers");
-
-  if ( cdoTimer ) timer_stop(timer_write);
-
-  if ( cdoTimer ) timer_start(timer_finish);
-
-  if ( cdoVerbose ) cdoPrint("freeing pointers");
-  
   for ( varID = 0; varID < nvars; varID++)
     {
-      nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      gridsize =  gridInqSize(vlistInqVarGrid(vlistID1, varID));
+      nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       
-      for(levelID = 0; levelID < nlevs; levelID++)
-        {
-	  int n_use = time_space == 1? nts : gridsize;
-          for(i = 0; i < n_use; i++)
-            {
-              if ( i < n_eig ) 
-                if (eigenvectors[varID][levelID][i])
-		  free(eigenvectors[varID][levelID][i]);
-	      if (eigenvalues[varID][levelID][i])
-		free(eigenvalues[varID][levelID][i]);
+      for( levelID = 0; levelID < nlevs; levelID++ )
+        { 	  
+	  if ( eofdata[varID][levelID].eig_val ) free(eofdata[varID][levelID].eig_val);
+	  if ( eofdata[varID][levelID].covar_array ) free(eofdata[varID][levelID].covar_array);
+	  if ( eofdata[varID][levelID].covar ) free(eofdata[varID][levelID].covar);
+	  if ( time_space && eofdata[varID][levelID].data )
+	    {
+	      for ( tsID = 0; tsID < nts; tsID++ )
+		if ( eofdata[varID][levelID].data[tsID] ) free(eofdata[varID][levelID].data[tsID]);
+	      free(eofdata[varID][levelID].data);
 	    }
-	  if ( grid_space ) 
-	    free(datafields[varID][levelID][0]);
-	  else if ( time_space )
-	    for (tsID=0; tsID<nts; tsID++ )
-	      free(datafields[varID][levelID][tsID]);
-          free(eigenvectors[varID][levelID]);
-          free(eigenvalues[varID][levelID]);
-          free(datacounts[varID][levelID]);
-	  free(datafields[varID][levelID]);
-        }
-      free(eigenvectors[varID]);
-      free(eigenvalues[varID]);
-      free(datafields[varID]);
-      free(datacounts[varID]);
-
+	}
+      
+      free(eofdata[varID]);
     }
 
-  free(eigenvectors);
-  free(eigenvalues);
-  free(datafields);
-  free(datacounts);
+  free(eofdata);
   free(in);
+  free(pack);
   free(weight);
 
-
   streamClose(streamID3);
   streamClose(streamID2);
   streamClose(streamID1);
 
-  //  vlistDestroy(vlistID1);
-  //  vlistDestroy(vlistID2);
-  //  vlistDestroy(vlistID3);
+  vlistDestroy(vlistID2);
+  vlistDestroy(vlistID3);
 
-  gridDestroy(gridID1);
   gridDestroy(gridID2);
-  gridDestroy(gridID3);
 
-  //  taxisDestroy(taxisID1);
   //  taxisDestroy(taxisID2);
   //  taxisDestroy(taxisID3);
 
-  if ( cdoTimer ) timer_stop(timer_finish);
-
   cdoFinish();
 
   return (0);
diff --git a/src/EcaIndices.c b/src/EcaIndices.c
index 7c0af95..4318705 100755
--- a/src/EcaIndices.c
+++ b/src/EcaIndices.c
@@ -315,7 +315,7 @@ void *EcaCsu(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_csu", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argT = atof(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
 
   request.var1.name     = CSU_NAME;
   request.var1.longname = CSU_LONGNAME;
@@ -352,8 +352,8 @@ void *EcaCwdi(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_cwdi", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
-  if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
+  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
+  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
   
   longname = (char*) malloc(strlen(CWDI_LONGNAME) + 80);
   sprintf(longname, CWDI_LONGNAME, argN, argT);
@@ -394,7 +394,7 @@ void *EcaCwfi(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_cwfi", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
 
   longname = (char*) malloc(strlen(CWFI_LONGNAME) + 40);
   sprintf(longname, CWFI_LONGNAME, argN);
@@ -494,9 +494,9 @@ void *EcaGsl(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_gsl", 0, 10, NULL);
   
-  if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
-  if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
-  if ( operatorArgc() > 2 ) minLandFraction = atof(operatorArgv()[2]);
+  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
+  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
+  if ( operatorArgc() > 2 ) minLandFraction = parameter2double(operatorArgv()[2]);
 
   longname = (char*) malloc(strlen(GSL_LONGNAME) + 160);
   sprintf(longname, GSL_LONGNAME, argN, argT, argN, argT);
@@ -536,11 +536,11 @@ void *EcaHd(void *argument)
 
   if ( operatorArgc() > 0 ) 
     {
-      argX = atof(operatorArgv()[0]);
+      argX = parameter2double(operatorArgv()[0]);
       argA = argX;
     }
   if ( operatorArgc() > 1 ) 
-    argA = atof(operatorArgv()[1]);
+    argA = parameter2double(operatorArgv()[1]);
   
   request.var1.name     = HD_NAME;
   request.var1.longname = HD_LONGNAME;
@@ -573,8 +573,8 @@ void *EcaHwdi(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_hwdi", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
-  if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
+  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
+  if ( operatorArgc() > 1 ) argT = parameter2double(operatorArgv()[1]);
   
   longname = (char*) malloc(strlen(HWDI_LONGNAME) + 80);
   sprintf(longname, HWDI_LONGNAME, argN, argT);
@@ -615,7 +615,7 @@ void *EcaHwfi(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_hwfi", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argN = parameter2int(operatorArgv()[0]);
 
   longname = (char*) malloc(strlen(HWFI_LONGNAME) + 40);
   sprintf(longname, HWFI_LONGNAME, argN);
@@ -682,7 +682,7 @@ void *EcaSu(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_su", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argT = atof(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
   longname = (char*) malloc(strlen(SU_LONGNAME) + 40);
   sprintf(longname, SU_LONGNAME, argT);
 
@@ -817,7 +817,7 @@ void *EcaTr(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_tr", 0, 31, NULL);
 
-  if ( operatorArgc() > 0 ) argT = atof(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argT = parameter2double(operatorArgv()[0]);
   longname = (char*) malloc(strlen(TR_LONGNAME) + 40);
   sprintf(longname, TR_LONGNAME, argT);
  
@@ -905,7 +905,7 @@ void *EcaCdd(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_cdd", 0, 31, NULL);
 
-  if ( operatorArgc() == 1 ) threshold = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) threshold = parameter2double(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
   sprintf(lnamebuffer, CDD_LONGNAME, threshold);
@@ -944,7 +944,7 @@ void *EcaCwd(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_cwd", 0, 31, NULL);
 
-  if ( operatorArgc() == 1 ) threshold = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) threshold = parameter2double(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
   sprintf(lnamebuffer, CWD_LONGNAME, threshold);
@@ -997,7 +997,7 @@ void *EcaPd(void *argument)
       if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
       if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
-      threshold = atof(operatorArgv()[0]);
+      threshold = parameter2double(operatorArgv()[0]);
 
       if ( threshold < 0 ) cdoAbort("Parameter out of range: threshold = %d", threshold);
 
@@ -1259,7 +1259,7 @@ void *EcaRr1(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_rr1", 0, 31, NULL);
 
-  if ( operatorArgc() == 1 ) threshold = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) threshold = parameter2double(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
   sprintf(lnamebuffer, RR1_LONGNAME, threshold);
@@ -1325,7 +1325,7 @@ void *EcaRx5day(void *argument)
   ECA_REQUEST_1 request;
   
   cdoInitialize(argument);
-  if ( operatorArgc() > 0 ) argX = atof(operatorArgv()[0]);
+  if ( operatorArgc() > 0 ) argX = parameter2double(operatorArgv()[0]);
   
   longname = (char*) malloc(strlen(RX5DAY_LONGNAME2) + 40);
   sprintf(longname, RX5DAY_LONGNAME2, argX);
@@ -1367,7 +1367,7 @@ void *EcaSdii(void *argument)
   cdoInitialize(argument);
   cdoOperatorAdd("eca_sdii", 0, 31, NULL);
 
-  if ( operatorArgc() == 1 ) threshold = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) threshold = parameter2double(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
 
   sprintf(lnamebuffer, SDII_LONGNAME, threshold);
@@ -1429,7 +1429,7 @@ void *Strwin(void *argument)
   cdoOperatorAdd("strwin", 0, 31, NULL);
 
   if ( operatorArgc() > 0 )
-    maxWind = atof(operatorArgv()[0]);
+    maxWind = parameter2double(operatorArgv()[0]);
 
   longname = (char*) malloc(strlen(STRWIN_LONGNAME) + 40);
   sprintf(longname, STRWIN_LONGNAME, maxWind);
diff --git a/src/Echam5ini.c b/src/Echam5ini.c
index b86ddad..c6c61e4 100644
--- a/src/Echam5ini.c
+++ b/src/Echam5ini.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Enlarge.c b/src/Enlarge.c
index 5e2a424..9be8095 100644
--- a/src/Enlarge.c
+++ b/src/Enlarge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Enlargegrid.c b/src/Enlargegrid.c
index efd8fcb..674fa6d 100644
--- a/src/Enlargegrid.c
+++ b/src/Enlargegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ensstat.c b/src/Ensstat.c
index 71fd226..8f5d570 100644
--- a/src/Ensstat.c
+++ b/src/Ensstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -40,31 +40,22 @@
 
 void *Ensstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
   int i;
   int varID, recID;
-  int gridsize = 0;
   int gridID;
   int nrecs, nrecs0;
   int levelID;
-  int tsID;
-  int streamID = 0, streamID2;
-  int vlistID, vlistID1, vlistID2;
+  int streamID = 0;
   int nmiss;
-  int taxisID1, taxisID2;
+  int fileID;
   double missval;
-  double *array2 = NULL;
-  field_t *field;
-  int fileID, nfiles;
-  const char *ofilename;
   typedef struct
   {
     int streamID;
     int vlistID;
+    double missval;
     double *array;
   } ens_file_t;
-  ens_file_t *ef = NULL;
   int pn = 0;
 
   cdoInitialize(argument);
@@ -80,75 +71,99 @@ void *Ensstat(void *argument)
   cdoOperatorAdd("ensvar1", func_var1, 0, NULL);
   cdoOperatorAdd("enspctl", func_pctl, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
+  int argc = operatorArgc();
+  int nargc = argc;
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
-      pn = atoi(operatorArgv()[0]);
+      pn = parameter2int(operatorArgv()[0]);
       
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
+      argc--;
+    }
+
+  int count_data = FALSE;
+  if ( argc == 1 )
+    {
+      if ( strcmp("count", operatorArgv()[nargc-1]) == 0 ) count_data = TRUE;
+      else cdoAbort("Unknown parameter: >%s<", operatorArgv()[nargc-1]); 
     }
     
-  nfiles = cdoStreamCnt() - 1;
+  int nfiles = cdoStreamCnt() - 1;
 
-  if ( cdoVerbose )
-    cdoPrint("Ensemble over %d files.", nfiles);
+  if ( cdoVerbose ) cdoPrint("Ensemble over %d files.", nfiles);
 
-  ofilename = cdoStreamName(nfiles)->args;
+  const char *ofilename = cdoStreamName(nfiles)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  ef = (ens_file_t*) malloc(nfiles*sizeof(ens_file_t));
+  ens_file_t *ef = (ens_file_t *) malloc(nfiles*sizeof(ens_file_t));
 
-  field = (field_t*) malloc(ompNumThreads*sizeof(field_t));
+  field_t *field = (field_t *) malloc(ompNumThreads*sizeof(field_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
       field_init(&field[i]);
       field[i].size   = nfiles;
       field[i].ptr    = (double*) malloc(nfiles*sizeof(double));
       field[i].weight = (double*) malloc(nfiles*sizeof(double));
-      for ( fileID = 0; fileID < nfiles; fileID++ )
-	field[i].weight[fileID] = 1;
+      for ( fileID = 0; fileID < nfiles; fileID++ ) field[i].weight[fileID] = 1;
     }
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
-      streamID = streamOpenRead(cdoStreamName(fileID));
-
-      vlistID = streamInqVlist(streamID);
-
-      ef[fileID].streamID = streamID;
-      ef[fileID].vlistID = vlistID;
+      ef[fileID].streamID = streamOpenRead(cdoStreamName(fileID));
+      ef[fileID].vlistID  = streamInqVlist(ef[fileID].streamID);
     }
 
   /* check that the contents is always the same */
   for ( fileID = 1; fileID < nfiles; fileID++ )
     vlistCompare(ef[0].vlistID, ef[fileID].vlistID, CMP_ALL);
 
-  vlistID1 = ef[0].vlistID;
-  vlistID2 = vlistDuplicate(vlistID1);
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int vlistID1 = ef[0].vlistID;
+  int vlistID2 = vlistDuplicate(vlistID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
-
-  streamDefVlist(streamID2, vlistID2);
-	  
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     ef[fileID].array = (double*) malloc(gridsize*sizeof(double));
 
-  array2 = (double*) malloc(gridsize*sizeof(double));
+  double *array2 = (double *) malloc(gridsize*sizeof(double));
+
+  int nvars = vlistNvars(vlistID2);
+  double *count2 = NULL;
+  if ( count_data )
+    {
+      count2 = (double *) malloc(gridsize*sizeof(double));
+      for ( varID = 0; varID < nvars; ++varID )
+	{
+	  char name[CDI_MAX_NAME];
+	  vlistInqVarName(vlistID2, varID, name);
+	  strcat(name, "_count");
+	  gridID = vlistInqVarGrid(vlistID2, varID);
+	  int zaxisID = vlistInqVarZaxis(vlistID2, varID);
+	  int tsteptype = vlistInqVarTsteptype(vlistID2, varID);
+	  int cvarID = vlistDefVar(vlistID2, gridID, zaxisID, tsteptype);
+	  vlistDefVarName(vlistID2, cvarID, name);
+	  vlistDefVarDatatype(vlistID2, cvarID, DATATYPE_INT16);
+	  if ( cvarID != (varID+nvars) ) cdoAbort("Internal error, varIDs do not match!");
+	}
+    }
+
+  int streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
 
-  tsID = 0;
+  int tsID = 0;
   do
     {
       nrecs0 = streamInqTimestep(ef[0].streamID, tsID);
@@ -183,6 +198,7 @@ void *Ensstat(void *argument)
 	      streamID = ef[fileID].streamID;
 	      streamInqRecord(streamID, &varID, &levelID);
 	      streamReadRecord(streamID, ef[fileID].array, &nmiss);
+              ef[fileID].missval = vlistInqVarMissval(ef[fileID].vlistID, varID);
 	    }
 
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
@@ -193,7 +209,7 @@ void *Ensstat(void *argument)
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared) private(i, fileID)
 #endif
-	  for ( i = 0; i < gridsize; i++ )
+	  for ( i = 0; i < gridsize; ++i )
 	    {
 	      int ompthID = cdo_omp_get_thread_num();
 
@@ -202,9 +218,12 @@ void *Ensstat(void *argument)
 	      for ( fileID = 0; fileID < nfiles; fileID++ )
 		{
 		  field[ompthID].ptr[fileID] = ef[fileID].array[i];
-		  if ( DBL_IS_EQUAL(field[ompthID].ptr[fileID], missval) )
-		    field[ompthID].nmiss++;
-		}
+		  if ( DBL_IS_EQUAL(field[ompthID].ptr[fileID], ef[fileID].missval) )
+                    {
+                      field[ompthID].ptr[fileID] = missval;
+                      field[ompthID].nmiss++;
+                    }
+                }
 
 	      if ( operfunc == func_pctl )
 	        array2[i] = fldpctl(field[ompthID], pn);
@@ -218,10 +237,18 @@ void *Ensstat(void *argument)
 #endif
 		  nmiss++;
 		}
+
+	      if ( count_data ) count2[i] = nfiles - field[ompthID].nmiss;
 	    }
 
 	  streamDefRecord(streamID2, varID, levelID);
 	  streamWriteRecord(streamID2, array2, nmiss);
+
+	  if ( count_data )
+	    {
+	      streamDefRecord(streamID2, varID+nvars, levelID);
+	      streamWriteRecord(streamID2, count2, 0);
+	    }
 	}
 
       tsID++;
@@ -229,10 +256,7 @@ void *Ensstat(void *argument)
   while ( nrecs0 > 0 );
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
-    {
-      streamID = ef[fileID].streamID;
-      streamClose(streamID);
-    }
+    streamClose(ef[fileID].streamID);
 
   streamClose(streamID2);
 
@@ -241,6 +265,7 @@ void *Ensstat(void *argument)
 
   if ( ef ) free(ef);
   if ( array2 ) free(array2);
+  if ( count2 ) free(count2);
 
   for ( i = 0; i < ompNumThreads; i++ )
     {
diff --git a/src/Ensstat3.c b/src/Ensstat3.c
index fd14e87..fa4db7c 100644
--- a/src/Ensstat3.c
+++ b/src/Ensstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -101,7 +101,7 @@ void *Ensstat3(void *argument)
 
   if ( operfunc == func_roc ) {
     operatorInputArg("Number of eigen functions to write out");
-    nbins       = atoi(operatorArgv()[0]);
+    nbins       = parameter2int(operatorArgv()[0]);
   }
   
   nfiles = cdoStreamCnt() - 1;
diff --git a/src/Ensval.c b/src/Ensval.c
index dd5f180..1e0439f 100644
--- a/src/Ensval.c
+++ b/src/Ensval.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -111,7 +111,7 @@ void *Ensval(void *argument)
   else if ( operfunc == BRS )  {
     operatorInputArg("Threshold for Brier score?");
     operatorCheckArgc(1);
-    brs_thresh = atof(operatorArgv()[0]);
+    brs_thresh = parameter2double(operatorArgv()[0]);
     nostreams = 4;
 
     fprintf(stderr,"brs_thres %10.6f\n",brs_thresh);
diff --git a/src/Eof3d.c b/src/Eof3d.c
index 016f87a..21f3ce4 100644
--- a/src/Eof3d.c
+++ b/src/Eof3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -40,36 +40,23 @@
 #include "statistic.h"
 
 
-enum T_EIGEN_MODE {JACOBI, DANIELSON_LANCZOS};
+enum T_EIGEN_MODE get_eigenmode(void);
+enum T_WEIGHT_MODE get_weightmode(void);
 
-#define WEIGHTS 1
 
 // NO MISSING VALUE SUPPORT ADDED SO FAR
 
 void *EOF3d(void * argument)
 {
-  char *envstr;
-
   enum {EOF3D_, EOF3D_TIME, EOF3D_SPATIAL};
 
-  int **datacounts;
-  int gridsize, temp_size = 0;
-  int gridID1, gridID2, gridID3;
+  int temp_size = 0;
   int i, i2, j, j1, j2, eofID, varID, recID, levelID, tsID;
   int missval_warning=0;
-  int nmiss,ngrids,n_eig,nrecs,nvars,n=0,nlevs=0,npack=0,nts=0;
+  int nmiss,ngrids,n=0,nlevs=0,npack=0,nts=0;
   int offset;
-  int operatorID, operfunc;
-  int *pack;
-  int reached_eof;
-  int streamID1, streamID2, streamID3;
-  int taxisID1, taxisID2, taxisID3;
-  int timer_init = 0, timer_alloc = 0, timer_read = 0, timer_cov = 0;
-  int timer_eig = 0, timer_post = 0, timer_write = 0, timer_finish = 0;
+  int timer_cov = 0, timer_eig = 0;
   int *varID2;
-  int vdate=0, vtime=0;
-  int vlistID1, vlistID2 = -1, vlistID3 = -1;
-  int zaxisID2;
 
   int calendar = CALENDAR_STANDARD;
   juldate_t juldate;
@@ -78,152 +65,78 @@ void *EOF3d(void * argument)
   double sum_w, sum;
   double **cov = NULL;                                /* TODO: covariance matrix / eigenvectors after solving */
   double *eigv;
-  double *weight;
   double *xvals, *yvals, *zvals;
   double *df1p, *df2p;
 
-  field_t **datafields;
-  field_t **eigenvectors, **eigenvalues;
-  field_t in;
-
-  enum T_EIGEN_MODE eigen_mode = JACOBI;
-
-
-  if ( cdoTimer ) {
-    timer_init = timer_new("Timeof init");
-    timer_alloc= timer_new("Timeof alloc");
-    timer_read = timer_new("Timeof read");
-    timer_cov  = timer_new("Timeof cov");
-    timer_eig  = timer_new("Timeof eig");
-    timer_post = timer_new("Timeof post");
-    timer_write= timer_new("Timeof write");
-    timer_finish=timer_new("Timeof finish");
 
-    timer_start(timer_init);
-  }
+  if ( cdoTimer )
+    {
+      timer_cov  = timer_new("Timeof cov");
+      timer_eig  = timer_new("Timeof eig");
+    }
 
   cdoInitialize(argument);
-  cdoOperatorAdd("eof3d",       EOF3D_,       0, NULL);
-  cdoOperatorAdd("eof3dtime",   EOF3D_TIME,   0, NULL);
-  cdoOperatorAdd("eof3dspatial",EOF3D_SPATIAL,0, NULL);
+  cdoOperatorAdd("eof3d",        EOF3D_,        0, NULL);
+  cdoOperatorAdd("eof3dtime",    EOF3D_TIME,    0, NULL);
+  cdoOperatorAdd("eof3dspatial", EOF3D_SPATIAL, 0, NULL);
 
-  operatorID  = cdoOperatorID();
-  operfunc    = cdoOperatorF1(operatorID);
+  int operatorID  = cdoOperatorID();
+  int operfunc    = cdoOperatorF1(operatorID);
 
   operatorInputArg("Number of eigen functions to write out");
-  n_eig       = atoi(operatorArgv()[0]);
-
-  envstr = getenv("CDO_SVD_MODE");
-
-  if ( envstr &&! strncmp(envstr,"danielson_lanczos",17) )
-    eigen_mode = DANIELSON_LANCZOS;
-  else if ( envstr && ! strncmp(envstr,"jacobi",6) )
-    eigen_mode = JACOBI;
-  else if ( envstr ) {
-    cdoWarning("Unknown environmental setting %s for CDO_SVD_MODE. Available options are",envstr);
-    cdoWarning("  - 'jacobi' for a one-sided parallelized jacobi algorithm");
-    cdoWarning("  - 'danielson_lanzcos' for the D/L algorithm");
-  }
-
-  if ( cdoVerbose ) 
-    cdoPrint("Set eigen_mode to %s\n",eigen_mode == JACOBI? "jacobi" : "danielson_lanczos");
-
-#if defined(_OPENMP)
-  if ( omp_get_max_threads() > 1 && eigen_mode == DANIELSON_LANCZOS )  {
-    cdoWarning("Requested parallel computation with %i Threads ",omp_get_max_threads());
-    cdoWarning("  but environmental setting CDO_SVD_MODE causes sequential ");
-    cdoWarning("  Singular value decomposition");
-  }
-#endif 
-
-  streamID1   = streamOpenRead(cdoStreamName(0));
-  vlistID1    = streamInqVlist(streamID1);
-  taxisID1    = vlistInqTaxis(vlistID1);
-  gridID1     = vlistInqVarGrid(vlistID1, 0);
-  gridsize    = vlistGridsizeMax(vlistID1);
-  nvars       = vlistNvars(vlistID1);
-  nrecs       = vlistNrecs(vlistID1);
-  taxisID1    = vlistInqTaxis(vlistID1);
-  weight      = (double*) malloc(gridsize*sizeof(double));
-  if ( WEIGHTS )
-      gridWeights(gridID1, &weight[0]);
-  else
-    for(i=0;i<gridsize;i++)
-      weight[i]=1;
-
-
-  /*  eigenvalues */
-  streamID2   = streamOpenWrite(cdoStreamName(1), cdoFiletype());
-
-  taxisID2    = taxisDuplicate(taxisID1);
-
-  gridID2     = gridCreate(GRID_LONLAT, 1);
-  gridDefXsize(gridID2, 1);
-  gridDefYsize(gridID2, 1);
-  xvals       = (double*) malloc(1*sizeof(double));
-  yvals       = (double*) malloc(1*sizeof(double));
-  zvals       = (double*) malloc(1*sizeof(double));
-  xvals[0]    = 0;
-  yvals[0]    = 0;
-  zvals[0]    = 0;
-  gridDefXvals(gridID2, xvals);
-  gridDefYvals(gridID2, yvals);
-
-  zaxisID2 = zaxisCreate(ZAXIS_GENERIC,1);
-  zaxisDefLevels(zaxisID2,zvals);
-  zaxisDefName(zaxisID2,"zaxis_Reduced");
-  zaxisDefLongname(zaxisID2,"Reduced zaxis from EOF3D - only one eigen value per 3D eigen vector");
-
-  vlistID2 = vlistCreate();
-  taxisDefRdate(taxisID2, 0);
-  taxisDefRtime(taxisID2, 0);
-  vlistDefTaxis(vlistID2, taxisID2);
+  int n_eig       = parameter2int(operatorArgv()[0]);
 
-  varID2 = (int*) malloc(nvars*sizeof(int));
-  for ( varID=0; varID<nvars; varID++ )
-    varID2[varID] = vlistDefVar(vlistID2, gridID2, zaxisID2, TSTEP_INSTANT);
-  ngrids      = vlistNgrids(vlistID2);
-  for ( i = 0; i < ngrids; i++ )
-    vlistChangeGridIndex(vlistID2, i, gridID2);
+  enum T_EIGEN_MODE eigen_mode = get_eigenmode();
+  enum T_WEIGHT_MODE weight_mode = get_weightmode();
 
-  /*  eigenvectors */
-  streamID3   = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+  int streamID1  = streamOpenRead(cdoStreamName(0));
+  int vlistID1   = streamInqVlist(streamID1);
+  int taxisID1   = vlistInqTaxis(vlistID1);
+  int gridID1    = vlistInqVarGrid(vlistID1, 0);
+  long gridsize  = vlistGridsizeMax(vlistID1);
+  int nvars      = vlistNvars(vlistID1);
+  int nrecs      = vlistNrecs(vlistID1);
 
-  vlistID3    = vlistDuplicate(vlistID1);
-  taxisID3    = taxisDuplicate(taxisID1);
-  gridID3     = gridDuplicate(gridID1);
-  taxisDefRdate(taxisID3, 0);
-  taxisDefRtime(taxisID3, 0);
-  vlistDefTaxis(vlistID3, taxisID3);
-  
+  double *weight = (double *) malloc(gridsize*sizeof(double));
+  for ( i = 0; i < gridsize; ++i ) weight[i] = 1.;
 
-  if ( cdoVerbose )
-    cdoPrint("Initialized streams");
+  if ( weight_mode == WEIGHT_ON )
+    {
+      int wstatus = gridWeights(gridID1, weight);
+      if ( wstatus != 0  )
+	{
+	  weight_mode = WEIGHT_OFF;
+	  cdoWarning("Using constant grid cell area weights!");
+	}
+    }
 
   /*  eigenvalues */
 
-  reached_eof = 0;
-  tsID        = 0;
-
   if ( operfunc == EOF3D_SPATIAL )
     cdoAbort("Operator not Implemented - use eof3d or eof3dtime instead");
 
+  tsID = 0;
 
   /* COUNT NUMBER OF TIMESTEPS if EOF3D_ or EOF3D_TIME */
-  while ( TRUE )
+  nts = vlistNtsteps(vlistID1);
+  if ( nts == -1 )
     {
-      if ( reached_eof ) continue;
-      nrecs = streamInqTimestep(streamID1, tsID);
-      if ( nrecs == 0 ) {
-	reached_eof = 1;
-	break;
-      }
-      tsID++;
+      while ( TRUE )
+	{
+	  nrecs = streamInqTimestep(streamID1, tsID);
+	  if ( nrecs == 0 )  break;
+	  tsID++;
+	}
+      
+      nts = tsID;
+      if ( cdoVerbose ) cdoPrint("Counted %i timeSteps", nts);
     }
 
-  nts         = tsID;
-  reached_eof = 0;
-  streamID1   = streamOpenRead(cdoStreamName(0));
+  streamClose(streamID1);
+
+  streamID1 = streamOpenRead(cdoStreamName(0));
+  vlistID1  = streamInqVlist(streamID1);
+  taxisID1  = vlistInqTaxis(vlistID1);
 
   /* reset the requested number of eigen-function to the maximum if neccessary */
   if ( n_eig > nts )
@@ -233,20 +146,17 @@ void *EOF3d(void * argument)
       cdoWarning("Setting n_eig to %i.", nts);
       n_eig = nts;
     }
-  n = nts;
 
-  if ( cdoVerbose ) 
-    cdoPrint("counted %i timesteps",n);
+  n = nts;
 
-  if ( cdoTimer ) timer_stop(timer_init);
-  if ( cdoTimer ) timer_start(timer_alloc);
+  if ( cdoVerbose )  cdoPrint("counted %i timesteps",n);
 
   /* allocation of temporary fields and output structures */
-  in.ptr       = (double*) malloc(gridsize*sizeof(double));
-  datafields   = (field_t**) malloc(nvars*sizeof(field_t*));
-  datacounts   = (int**) malloc(nvars*sizeof(int*));
-  eigenvectors = (field_t**) malloc(nvars*sizeof(field_t*));
-  eigenvalues  = (field_t**) malloc(nvars*sizeof(field_t*));
+  double *in       = (double *) malloc(gridsize*sizeof(double));
+  int **datacounts = (int **) malloc(nvars*sizeof(int*));
+  double ***datafields   = (double ***) malloc(nvars*sizeof(double **));
+  double ***eigenvectors = (double ***) malloc(nvars*sizeof(double **));
+  double ***eigenvalues  = (double ***) malloc(nvars*sizeof(double **));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -257,42 +167,30 @@ void *EOF3d(void * argument)
       missval             = vlistInqVarMissval(vlistID1, varID);
 
       datacounts[varID]   = (int*) malloc(nlevs*sizeof(int));
-      eigenvectors[varID] = (field_t*) malloc(nlevs*sizeof(field_t));
-      datafields[varID]   = (field_t*) malloc(nts*sizeof(field_t));
+      datafields[varID]   = (double **) malloc(nts*sizeof(double *));
 
       for ( tsID = 0; tsID < nts; tsID++ )
 	{
-	  datafields[varID][tsID].grid    = gridID1;
-	  datafields[varID][tsID].nmiss   = 0;
-	  datafields[varID][tsID].missval = missval;
-	  datafields[varID][tsID].ptr     = (double*) malloc(temp_size*sizeof(double));
-	  for ( i = 0; i < temp_size; ++i )
-	    datafields[varID][tsID].ptr[i] = 0;
+	  datafields[varID][tsID] = (double *) malloc(temp_size*sizeof(double));
+	  for ( i = 0; i < temp_size; ++i ) datafields[varID][tsID][i] = 0;
 	}
-      datacounts[varID] = (int*) malloc(temp_size*sizeof(int));	      
-      for(i=0;i<temp_size;i++)
-	datacounts[varID][i] = 0;
+      datacounts[varID] = (int *) malloc(temp_size*sizeof(int));	      
+      for( i = 0; i < temp_size; i++) datacounts[varID][i] = 0;
       
-      eigenvectors[varID] = (field_t*) malloc(n_eig*sizeof(field_t));
-      eigenvalues[varID]  = (field_t*) malloc(nts*sizeof(field_t));
+      eigenvectors[varID] = (double **) malloc(n_eig*sizeof(double *));
+      eigenvalues[varID]  = (double **) malloc(nts*sizeof(double *));
 
       for ( i = 0; i < n; i++ )
 	{
 	  if ( i < n_eig )
 	    {
-	      eigenvectors[varID][i].grid    = gridID2;
-	      eigenvectors[varID][i].nmiss   = 0;
-	      eigenvectors[varID][i].missval = missval;
-	      eigenvectors[varID][i].ptr     = (double*) malloc(temp_size*sizeof(double));
+	      eigenvectors[varID][i] = (double *) malloc(temp_size*sizeof(double));
 	      for ( i2 = 0; i2 < temp_size; ++i2 )
-		eigenvectors[varID][i].ptr[i2] = missval;
+		eigenvectors[varID][i][i2] = missval;
 	    }
 	  
-	  eigenvalues[varID][i].grid    = gridID3;
-	  eigenvalues[varID][i].nmiss   = 0;
-	  eigenvalues[varID][i].missval = missval;
-	  eigenvalues[varID][i].ptr     = (double*) malloc(1*sizeof(double));
-	  eigenvalues[varID][i].ptr[0]  = missval;
+	  eigenvalues[varID][i]    = (double *) malloc(1*sizeof(double));
+	  eigenvalues[varID][i][0] = missval;
 	}
     }
 
@@ -300,39 +198,29 @@ void *EOF3d(void * argument)
     cdoPrint("allocated eigenvalue/eigenvector with nts=%i, n=%i, gridsize=%i for processing in %s",
 	     nts,n,gridsize,"time_space");
   
-  if ( cdoTimer ) timer_stop(timer_alloc);
-
-  if ( cdoTimer ) timer_start(timer_read);
   tsID = 0;
 
   /* read the data and create covariance matrices for each var & level */
   while ( TRUE )
     {
-      if ( reached_eof ) continue;
       nrecs = streamInqTimestep(streamID1, tsID);
-      if ( nrecs == 0 )
-        {
-          reached_eof = 1;
-          break;
-        }
-
-      vdate = taxisInqVdate(taxisID1);
-      vtime = taxisInqVtime(taxisID1);
+      if ( nrecs == 0 ) break;
 
       for ( recID = 0; recID < nrecs; recID++ )
         {
           streamInqRecord(streamID1, &varID, &levelID);
+
           gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 
-          missval  = in.missval = vlistInqVarMissval(vlistID1, varID);
-          streamReadRecord(streamID1, in.ptr, &in.nmiss);
+          missval = vlistInqVarMissval(vlistID1, varID);
+          streamReadRecord(streamID1, in, &nmiss);
 
 	  offset = gridsize * levelID;
-	  for ( i=0; i<gridsize; ++i )
+	  for ( i = 0; i < gridsize; ++i )
 	    {
-	      if ( ! DBL_IS_EQUAL(in.ptr[i], missval ) )
+	      if ( ! DBL_IS_EQUAL(in[i], missval ) )
 		{
-		  datafields[varID][tsID].ptr[offset + i] = in.ptr[i];
+		  datafields[varID][tsID][offset + i] = in[i];
 		  datacounts[varID][offset + i]++;
 		}
 	      else
@@ -343,7 +231,7 @@ void *EOF3d(void * argument)
 		      cdoWarning("Does not work with changing locations of missing values in time.");
 		      missval_warning = 1;
 		    }
-		  datafields[varID][tsID].ptr[i+offset] = 0;
+		  datafields[varID][tsID][i+offset] = 0;
 		}
 	    }
         }
@@ -353,9 +241,7 @@ void *EOF3d(void * argument)
   if ( cdoVerbose ) 
     cdoPrint("Read data for %i variables",nvars);
   
-  pack = (int*) malloc(temp_size*sizeof(int)); //TODO
-
-  if ( cdoTimer ) timer_stop(timer_read);
+  int *pack = (int*) malloc(temp_size*sizeof(int)); //TODO
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -370,23 +256,26 @@ void *EOF3d(void * argument)
 	cdoPrint("Calculating covariance matrix and SVD for var%i (%s)",varID,vname);
       }
 
-      npack        = 0;    // TODO already set to 0
-      sum_w        = 0;
+      npack = 0;    // TODO already set to 0
 
       if ( cdoTimer ) timer_start(timer_cov);
       
-      // sum_w = 0;
-      sum_w = 1;
       for ( i = 0; i < temp_size ; i++ )
 	{
 	  if ( datacounts[varID][i] > 1)
 	    {
 	      pack[npack] = i;
 	      npack++;
-	      //  sum_w += weight[i%gridsize];
 	    }
 	}
 
+      sum_w = 1;
+      if ( weight_mode == WEIGHT_ON )
+	{
+	  sum_w = 0;
+	  for ( i = 0; i < npack; i++ )  sum_w += weight[pack[i]];
+	}
+
       if ( npack < 1 ) {
 	char vname[64];
 	vlistInqVarName(vlistID1,varID,&vname[0]);
@@ -395,10 +284,10 @@ void *EOF3d(void * argument)
       }
 
 	  
-      cov = (double**) malloc(nts*sizeof(double*));
+      cov = (double **) malloc(nts*sizeof(double*));
       for ( j1 = 0; j1 < nts; j1++)
-	cov[j1] = (double*) malloc(nts*sizeof(double));
-      eigv = (double*) malloc(n*sizeof(double));
+	cov[j1] = (double *) malloc(nts*sizeof(double));
+      eigv = (double *) malloc(n*sizeof(double));
 
       if ( cdoVerbose )  {
 	cdoPrint("varID %i allocated eigv and cov with nts=%i and n=%i",varID,nts,n);
@@ -413,15 +302,14 @@ void *EOF3d(void * argument)
 	for ( j2 = j1; j2 < nts; j2++ )
 	  {
 	    sum = 0;
-	    df1p = datafields[varID][j1].ptr;
-	    df2p = datafields[varID][j2].ptr;
+	    df1p = datafields[varID][j1];
+	    df2p = datafields[varID][j2];
 	    for ( i = 0; i < npack; i++ )
-	      //  sum += df1p[pack[i]]*df2p[pack[i]];
 	      sum += weight[pack[i]%gridsize]*df1p[pack[i]]*df2p[pack[i]];
 	    cov[j2][j1] = cov[j1][j2] = sum / sum_w / nts;
 	  }
-      if ( cdoVerbose ) 
-	cdoPrint("calculated cov-matrix");
+      
+      if ( cdoVerbose ) cdoPrint("calculated cov-matrix");
 
       /* SOLVE THE EIGEN PROBLEM */
       if ( cdoTimer ) timer_stop(timer_cov);
@@ -433,23 +321,22 @@ void *EOF3d(void * argument)
 	cdoPrint("Processed correlation matrix for var %2i | npack: %4i",varID,n);
 
       if ( eigen_mode == JACOBI ) 
-	parallel_eigen_solution_of_symmetric_matrix(&cov[0],&eigv[0],n,n,__func__);
+	parallel_eigen_solution_of_symmetric_matrix(cov, eigv, n, __func__);
       else 
-	eigen_solution_of_symmetric_matrix(&cov[0],&eigv[0],n,n,__func__);
+	eigen_solution_of_symmetric_matrix(cov, eigv, n, __func__);
       /* NOW: cov contains the eigenvectors, eigv the eigenvalues */
 
       if ( cdoVerbose ) 
 	cdoPrint("Processed SVD decomposition for var %i from %i x %i matrix",varID,n,n);
 
       for( eofID=0; eofID<n; eofID++ )
-	eigenvalues[varID][eofID].ptr[0] = eigv[eofID];
+	eigenvalues[varID][eofID][0] = eigv[eofID];
       
       if ( cdoTimer ) timer_stop(timer_eig);
-      if ( cdoTimer ) timer_start(timer_post);
 
       for ( eofID = 0; eofID < n_eig; eofID++ )
 	{
-	  double *eigenvec = eigenvectors[varID][eofID].ptr;
+	  double *eigenvec = eigenvectors[varID][eofID];
 
 #if defined(_OPENMP)
 #pragma omp parallel for private(i,j,sum) shared(datafields, eigenvec)
@@ -458,7 +345,8 @@ void *EOF3d(void * argument)
 	    {
 	      sum = 0;
 	      for ( j = 0; j < nts; j++ )
-		sum += datafields[varID][j].ptr[pack[i]] * cov[eofID][j];
+		sum += datafields[varID][j][pack[i]] * cov[eofID][j];
+
 	      eigenvec[pack[i]] = sum;
 	    }
 	  // NORMALIZING
@@ -469,8 +357,8 @@ void *EOF3d(void * argument)
   shared(eigenvec,weight,pack,npack,gridsize)
 #endif 
 	  for ( i = 0; i < npack; i++ )
-	    // sum +=  weight[pack[i]%gridsize] *
-	    sum += eigenvec[pack[i]] * eigenvec[pack[i]];
+	    sum +=  weight[pack[i]%gridsize] *
+	            eigenvec[pack[i]] * eigenvec[pack[i]];
 
 	  if ( sum > 0 )
 	    {
@@ -493,8 +381,6 @@ void *EOF3d(void * argument)
 	    }
 	}     /* for ( eofID = 0; eofID < n_eig; eofID++ )     */
 
-      if ( cdoTimer ) timer_stop(timer_post);
-
       if ( eigv ) free(eigv);
       for ( i=0; i<n; i++ )
 	if ( cov[i] ) 
@@ -503,15 +389,53 @@ void *EOF3d(void * argument)
 
   /* write files with eigenvalues (ID3) and eigenvectors (ID2) */
 
+  /*  eigenvalues */
+  int streamID2   = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  int taxisID2    = taxisDuplicate(taxisID1);
+
+  int gridID2     = gridCreate(GRID_LONLAT, 1);
+  gridDefXsize(gridID2, 1);
+  gridDefYsize(gridID2, 1);
+  xvals       = (double*) malloc(1*sizeof(double));
+  yvals       = (double*) malloc(1*sizeof(double));
+  zvals       = (double*) malloc(1*sizeof(double));
+  xvals[0]    = 0;
+  yvals[0]    = 0;
+  zvals[0]    = 0;
+  gridDefXvals(gridID2, xvals);
+  gridDefYvals(gridID2, yvals);
+
+  int zaxisID2 = zaxisCreate(ZAXIS_GENERIC,1);
+  zaxisDefLevels(zaxisID2,zvals);
+  zaxisDefName(zaxisID2,"zaxis_Reduced");
+  zaxisDefLongname(zaxisID2,"Reduced zaxis from EOF3D - only one eigen value per 3D eigen vector");
+
+  int vlistID2 = vlistCreate();
+  taxisDefRdate(taxisID2, 0);
+  taxisDefRtime(taxisID2, 0);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  varID2 = (int*) malloc(nvars*sizeof(int));
+  for ( varID=0; varID<nvars; varID++ )
+    varID2[varID] = vlistDefVar(vlistID2, gridID2, zaxisID2, TSTEP_INSTANT);
+  ngrids      = vlistNgrids(vlistID2);
+  for ( i = 0; i < ngrids; i++ )
+    vlistChangeGridIndex(vlistID2, i, gridID2);
 
-  if ( cdoTimer ) timer_start(timer_write);
+  int streamID3   = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+
+  int vlistID3    = vlistDuplicate(vlistID1);
+  int taxisID3    = taxisDuplicate(taxisID1);
+  taxisDefRdate(taxisID3, 0);
+  taxisDefRtime(taxisID3, 0);
+  vlistDefTaxis(vlistID3, taxisID3);
 
-  cdoPrint("Started writing");
   streamDefVlist(streamID2, vlistID2);
   streamDefVlist(streamID3, vlistID3);
 
-  vdate = 10101;
-  vtime = 0;
+  int vdate = 10101;
+  int vtime = 0;
   juldate = juldate_encode(calendar, vdate, vtime);
   for ( tsID = 0; tsID < n; tsID++ )
     {
@@ -539,49 +463,47 @@ void *EOF3d(void * argument)
                 {
                   nmiss = 0;
                   for ( i = 0; i < gridsize; i++ )
-                    if ( DBL_IS_EQUAL(eigenvectors[varID][tsID].ptr[offset + i], missval) ) nmiss++;
+                    if ( DBL_IS_EQUAL(eigenvectors[varID][tsID][offset + i], missval) ) nmiss++;
 
                   streamDefRecord(streamID3, varID, levelID);
-                  streamWriteRecord(streamID3, &eigenvectors[varID][tsID].ptr[offset], nmiss);
+                  streamWriteRecord(streamID3, &eigenvectors[varID][tsID][offset], nmiss);
                 }
 	    }
-	  if ( DBL_IS_EQUAL(eigenvalues[varID][tsID].ptr[i], missval) ) nmiss = 1;
+	  if ( DBL_IS_EQUAL(eigenvalues[varID][tsID][i], missval) ) nmiss = 1;
 	  else nmiss = 0;
 	  streamDefRecord(streamID2, varID, 0);
-	  streamWriteRecord(streamID2, eigenvalues[varID][tsID].ptr,nmiss);
+	  streamWriteRecord(streamID2, eigenvalues[varID][tsID],nmiss);
         } // for ( varID = 0; ... )
     } // for ( tsID = 0; ... )
 
-  if ( cdoTimer ) timer_stop(timer_write);
-  
-  if ( cdoTimer ) timer_start(timer_finish);
-
-  cdoPrint("Started cleanup in eof3d");
-  
   for ( varID = 0; varID < nvars; varID++)
     {
-      for(i = 0; i < nts; i++)
+      for( i = 0; i < nts; i++)
 	{
+	  free(datafields[varID][tsID]);
 	  if ( i < n_eig )
-	    free(eigenvectors[varID][i].ptr);
-	  free(eigenvalues[varID][i].ptr);
+	    free(eigenvectors[varID][i]);
+	  free(eigenvalues[varID][i]);
 	}
+
+      free(datafields[varID]);
+      free(datacounts[varID]);
       free(eigenvectors[varID]);
       free(eigenvalues[varID]);
-      free(datacounts[varID]);
     }
 
-  free(eigenvectors);
-  free(eigenvalues);
   free(datafields);
   free(datacounts);
-  free(in.ptr);
+  free(eigenvectors);
+  free(eigenvalues);
+  free(in);
+
+  free(pack);
+  free(weight);
 
   streamClose(streamID3);
   streamClose(streamID2);
   streamClose(streamID1);
-
-  if ( cdoTimer ) timer_stop(timer_finish);
   
   cdoFinish();
  
diff --git a/src/Eofcoeff.c b/src/Eofcoeff.c
index 283e2ec..7b9160b 100644
--- a/src/Eofcoeff.c
+++ b/src/Eofcoeff.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+ Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
diff --git a/src/Eofcoeff3d.c b/src/Eofcoeff3d.c
index 5c32ece..ca8ba72 100644
--- a/src/Eofcoeff3d.c
+++ b/src/Eofcoeff3d.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+ Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
diff --git a/src/Exprf.c b/src/Exprf.c
index fee67ff..6e81869 100644
--- a/src/Exprf.c
+++ b/src/Exprf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -43,13 +43,12 @@ Constansts: M_PI, M_E
 
 void *Expr(void *argument)
 {
-  int EXPR, EXPRF, AEXPR, AEXPRF;
   int operatorID;
   char *exprs = NULL;
   const char *exprf = NULL;
   int streamID1, streamID2 = CDI_UNDEFID;
   int offset;
-  int nrecs, nvars, nvars2;
+  int nrecs, nvars, nvars1, nvars2;
   int gridID, zaxisID;
   int tsID, recID, varID, levelID;
   int vlistID1, vlistID2;
@@ -69,18 +68,20 @@ void *Expr(void *argument)
   yylex_init(&scanner);
   yyset_extra(&parse_arg, scanner);
 
-  EXPR   = cdoOperatorAdd("expr",   0, 0, "expressions");
-  EXPRF  = cdoOperatorAdd("exprf",  0, 0, "expr script filename");
-  AEXPR  = cdoOperatorAdd("aexpr",  0, 0, "expressions");
-  AEXPRF = cdoOperatorAdd("aexprf", 0, 0, "expr script filename");
 
-  UNUSED(AEXPRF);
+# define REPLACES_VARIABLES(id) cdoOperatorF1(id)
+# define READS_COMMAND_LINE(id) cdoOperatorF2(id)
+
+  cdoOperatorAdd("expr",   1, 1, "expressions");
+  cdoOperatorAdd("exprf",  1, 0, "expr script filename");
+  cdoOperatorAdd("aexpr",  0, 1, "expressions");
+  cdoOperatorAdd("aexprf", 0, 0, "expr script filename");
 
   operatorID = cdoOperatorID();
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
-  if ( operatorID == EXPR || operatorID == AEXPR )
+  if ( READS_COMMAND_LINE(operatorID) )
     {
       size_t slen;
 
@@ -126,12 +127,18 @@ void *Expr(void *argument)
 
   vlistID1 = streamInqVlist(streamID1);
 
-  nvars = vlistNvars(vlistID1);
+  nvars1 = vlistNvars(vlistID1);
 
-  if ( operatorID == EXPR || operatorID == EXPRF )
-    vlistID2 = vlistCreate();
+  if ( REPLACES_VARIABLES(operatorID) )
+    {
+      vlistID2 = vlistCreate();
+      nvars = 0;
+    }
   else
-    vlistID2 = vlistDuplicate(vlistID1);
+    {
+      vlistID2 = vlistDuplicate(vlistID1);
+      nvars = nvars1;
+    }
 
   parse_arg.init = 1;
   parse_arg.vlistID1 = vlistID1;
@@ -142,8 +149,10 @@ void *Expr(void *argument)
   parse_arg.gridID2  = -1;
   parse_arg.zaxisID2 = -1;
   parse_arg.tsteptype2  = -1;
-  for ( varID = 0; varID < nvars; varID++ )
-    parse_arg.var_needed[varID] = FALSE;
+   
+  /* Set all input variables to 'needed' if replacing is switched off */
+  for ( varID = 0; varID < nvars1; varID++ )
+    parse_arg.var_needed[varID] = ! REPLACES_VARIABLES(operatorID);
 
   yy_scan_string(exprs, scanner);
   yyparse(&parse_arg, scanner);
@@ -156,7 +165,7 @@ void *Expr(void *argument)
   if ( cdoVerbose ) vlistPrint(vlistID2);
 
   if ( cdoVerbose )
-    for ( varID = 0; varID < nvars; varID++ )
+    for ( varID = 0; varID < nvars1; varID++ )
       if ( parse_arg.var_needed[varID] )
 	printf("Needed var: %d %s\n", varID, parse_arg.var[varID]);
 
@@ -168,10 +177,10 @@ void *Expr(void *argument)
 
   streamDefVlist(streamID2, vlistID2);
 
-  parse_arg.vardata1 = (double**) malloc(nvars*sizeof(double*));
+  parse_arg.vardata1 = (double**) malloc(nvars1*sizeof(double*));
   parse_arg.vardata2 = (double**) malloc(nvars2*sizeof(double*));
 
-  for ( varID = 0; varID < nvars; varID++ )
+  for ( varID = 0; varID < nvars1; varID++ )
     {
       gridID  = vlistInqVarGrid(vlistID1, varID);
       zaxisID = vlistInqVarZaxis(vlistID1, varID);
@@ -185,7 +194,12 @@ void *Expr(void *argument)
 	parse_arg.vardata1[varID] = NULL;
     }
 
-  for ( varID = 0; varID < nvars2; varID++ )
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      parse_arg.vardata2[varID] = parse_arg.vardata1[varID];
+    }
+
+  for ( varID = nvars; varID < nvars2; varID++ )
     {
       gridID  = vlistInqVarGrid(vlistID2, varID);
       zaxisID = vlistInqVarZaxis(vlistID2, varID);
@@ -228,7 +242,7 @@ void *Expr(void *argument)
 	    }
 	}
 
-      for ( varID = 0; varID < nvars2; varID++ )
+      for ( varID = nvars; varID < nvars2; varID++ )
 	{
 	  gridID   = vlistInqVarGrid(vlistID2, varID);
 	  zaxisID  = vlistInqVarZaxis(vlistID2, varID);
diff --git a/src/FC.c b/src/FC.c
index 7b3b966..2082b14 100644
--- a/src/FC.c
+++ b/src/FC.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Filedes.c b/src/Filedes.c
index cd2af09..d9c12c4 100644
--- a/src/Filedes.c
+++ b/src/Filedes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -324,12 +324,12 @@ void *Filedes(void *argument)
       int opt = 0;
       if ( operatorID == GRIDDES ) opt = 1;
       for ( index = 0; index < ngrids; index++ )
-	gridPrint(vlistGrid(vlistID, index), opt);
+	gridPrint(vlistGrid(vlistID, index), index+1, opt);
     }
   else if ( operatorID == ZAXISDES )
     {
       for ( index = 0; index < nzaxis; index++ )
-	zaxisPrint(vlistZaxis(vlistID, index));
+	zaxisPrint(vlistZaxis(vlistID, index), index+1);
     }
   else if ( operatorID == VCT || operatorID == VCT2 )
     {
diff --git a/src/Fillmiss.c b/src/Fillmiss.c
index 96a6c3e..c90806d 100644
--- a/src/Fillmiss.c
+++ b/src/Fillmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Filter.c b/src/Filter.c
index 7238773..08b0bf2 100644
--- a/src/Filter.c
+++ b/src/Filter.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -47,18 +47,18 @@ void getTimeInc(double jdelta, int vdate0, int vdate1, int *incperiod, int *incu
 
 static
 void create_fmasc(int nts, double fdata, double fmin, double fmax, int *fmasc)
-{
-  double dimin, dimax;
-  int i, imin, imax;
-  
-  dimin = nts*fmin / fdata;
-  dimax = nts*fmax / fdata;
+{  
+  double dimin = nts*fmin / fdata;
+  double dimax = nts*fmax / fdata;
 
-  imin = dimin<0 ? 0 : (int)floor(dimin);  
-  imax = ceil(dimax)>nts/2 ? nts/2 : (int) ceil(dimax);  
+  int imin = dimin<0 ? 0 : (int)floor(dimin);  
+  int imax = ceil(dimax)>nts/2 ? nts/2 : (int) ceil(dimax);
+
+  if ( imin < 0 || imin >= nts ) cdoAbort("Parameter fmin=%g out of bounds (1-%d)!", nts);
+  if ( imax < 0 || imax >= nts ) cdoAbort("Parameter fmax=%g out of bounds (1-%d)!", nts);
 
   fmasc[imin] = 1;
-  for ( i = imin+1; i <= imax; i++ )  
+  for ( int i = imin+1; i <= imax; i++ )  
     fmasc[i] = fmasc[nts-i] = 1; 
 }
 
@@ -125,8 +125,6 @@ void *Filter(void *argument)
   enum {BANDPASS, HIGHPASS, LOWPASS};
   char *tunits[] = {"second", "minute", "hour", "day", "month", "year"};
   int iunits[] = {31536000, 525600, 8760, 365, 12, 1};
-  int operatorID;
-  int operfunc;
   int gridsize;
   int nrecs;
   int gridID, varID, levelID, recID;
@@ -134,18 +132,15 @@ void *Filter(void *argument)
   int i;
   int nts;
   int nalloc = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2, taxisID1, taxisID2;
   int nmiss;
   int nvars, nlevel;
-  dtinfo_t *dtinfo = NULL;
   int incperiod0, incunit0, incunit, calendar;
   int year0, month0, day0;
   double fdata = 0;
   field_t ***vars = NULL;
   double fmin = 0, fmax = 0;
-  int *fmasc;
   int use_fftw = FALSE;
+  dtlist_type *dtlist = dtlist_new();
   typedef struct
   {
     double *array1;
@@ -165,8 +160,8 @@ void *Filter(void *argument)
   cdoOperatorAdd("highpass",  HIGHPASS,  0, NULL);
   cdoOperatorAdd("lowpass" ,  LOWPASS,   0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
 
   if ( CDO_Use_FFTW )
     {
@@ -180,13 +175,13 @@ void *Filter(void *argument)
       
   if ( cdoVerbose && use_fftw  == FALSE ) cdoPrint("Using intrinsic FFT function!");
   
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   calendar = taxisInqCalendar(taxisID1);  
@@ -199,11 +194,10 @@ void *Filter(void *argument)
       if ( tsID >= nalloc )
         {
           nalloc += NALLOC_INC;
-          dtinfo = (dtinfo_t*) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
           vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
         }
                        
-      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
    
       vars[tsID] = field_malloc(vlistID1, FIELD_NONE);
            
@@ -221,21 +215,23 @@ void *Filter(void *argument)
       /* get and check time increment */                   
       if ( tsID > 0 )
         {    
-          juldate_t juldate0, juldate;
-          double jdelta;
           int incperiod = 0;
           int year, month, day;
+	  int vdate0 = dtlist_get_vdate(dtlist, tsID-1);
+	  int vdate  = dtlist_get_vdate(dtlist, tsID);
+	  int vtime0 = dtlist_get_vtime(dtlist, tsID-1);
+	  int vtime  = dtlist_get_vtime(dtlist, tsID);
 
-          cdiDecodeDate(dtinfo[tsID].v.date,   &year,  &month,  &day);
-          cdiDecodeDate(dtinfo[tsID-1].v.date, &year0, &month0, &day0);               
+          cdiDecodeDate(vdate0, &year0, &month0, &day0);               
+          cdiDecodeDate(vdate,  &year,  &month,  &day);
 
-          juldate0 = juldate_encode(calendar, dtinfo[tsID-1].v.date, dtinfo[tsID-1].v.time);        
-          juldate  = juldate_encode(calendar, dtinfo[tsID].v.date, dtinfo[tsID].v.time);         
-          jdelta   = juldate_to_seconds(juldate_sub(juldate, juldate0));
+          juldate_t juldate0 = juldate_encode(calendar, vdate0, vtime0);        
+          juldate_t juldate  = juldate_encode(calendar, vdate,  vtime);         
+          double jdelta   = juldate_to_seconds(juldate_sub(juldate, juldate0));
           
           if ( tsID == 1 ) 
             {           
-              getTimeInc(jdelta, dtinfo[tsID-1].v.date, dtinfo[tsID].v.date, &incperiod0, &incunit0);
+              getTimeInc(jdelta, vdate0, vdate, &incperiod0, &incunit0);
               incperiod = incperiod0; 
               if ( incperiod == 0 ) cdoAbort("Time step must be different from zero!");
               incunit = incunit0;
@@ -243,12 +239,13 @@ void *Filter(void *argument)
               fdata = 1.*iunits[incunit]/incperiod;
             }
           else 
-            getTimeInc(jdelta, dtinfo[tsID-1].v.date, dtinfo[tsID].v.date, &incperiod, &incunit);        
+            getTimeInc(jdelta, vdate0, vdate, &incperiod, &incunit);        
 
-          if ( incunit0 < 4 && month == 2 && day == 29 && 
+          if ( calendar != CALENDAR_360DAYS && calendar != CALENDAR_365DAYS && calendar != CALENDAR_366DAYS &&
+	       incunit0 < 4 && month == 2 && day == 29 && 
                ( day0 != day || month0 != month || year0 != year ) )
             {
-              cdoWarning("Filtering of multi-year times series only works properly with 365-day-calendar.");
+              cdoWarning("Filtering of multi-year times series doesn't works properly with a standard calendar.");
               cdoWarning("  Please delete the day %i-02-29 (cdo del29feb)", year);
             }
 
@@ -285,7 +282,7 @@ void *Filter(void *argument)
 	}
     }
 
-  fmasc  = (int*) calloc(nts, sizeof(int));
+  int *fmasc = (int*) calloc(nts, sizeof(int));
 
   switch(operfunc)
     {
@@ -293,15 +290,15 @@ void *Filter(void *argument)
       {
         operatorInputArg("lower and upper bound of frequency band");
         operatorCheckArgc(2);
-        fmin = atof(operatorArgv()[0]);
-        fmax = atof(operatorArgv()[1]);
+        fmin = parameter2double(operatorArgv()[0]);
+        fmax = parameter2double(operatorArgv()[1]);
         break;
       }
     case HIGHPASS:
       {              
         operatorInputArg("lower bound of frequency pass");
         operatorCheckArgc(1);
-        fmin = atof(operatorArgv()[0]);
+        fmin = parameter2double(operatorArgv()[0]);
         fmax = fdata;
         break;
       }
@@ -310,10 +307,12 @@ void *Filter(void *argument)
         operatorInputArg("upper bound of frequency pass");
         operatorCheckArgc(1);
         fmin = 0;
-        fmax = atof(operatorArgv()[0]);
+        fmax = parameter2double(operatorArgv()[0]);
         break;
       }
     }
+
+  if ( cdoVerbose ) cdoPrint("fmin=%g  fmax=%g", fmin, fmax);
   
   create_fmasc(nts, fdata, fmin, fmax, fmasc);
 
@@ -394,13 +393,13 @@ void *Filter(void *argument)
       free(ompmem);
     }
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
   
   streamDefVlist(streamID2, vlistID2);
  
   for ( tsID = 0; tsID < nts; tsID++ )
     {
-      taxisDefDTinfo(taxisID2, dtinfo[tsID]);
+      dtlist_taxisDefTimestep(dtlist, taxisID2, tsID);
       streamDefTimestep(streamID2, tsID);
     
       for ( varID = 0; varID < nvars; varID++ )
@@ -424,7 +423,8 @@ void *Filter(void *argument)
     }
 
   if ( vars   ) free(vars);
-  if ( dtinfo ) free(dtinfo);
+
+  dtlist_delete(dtlist);
 
   streamClose(streamID2);
   streamClose(streamID1);
diff --git a/src/Fldrms.c b/src/Fldrms.c
index 4cf3aba..bce8302 100644
--- a/src/Fldrms.c
+++ b/src/Fldrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Fldstat.c b/src/Fldstat.c
index 1adf609..f8aa2e7 100644
--- a/src/Fldstat.c
+++ b/src/Fldstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -89,21 +89,14 @@ void print_location_LL(int operfunc, int vlistID, int varID, int levelID, int gr
 
 void *Fldstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
   int gridID2, lastgrid = -1;
-  int index, ngrids;
+  int index;
   int recID, nrecs;
-  int tsID, varID, levelID;
-  int lim;
+  int varID, levelID;
   int needWeights = FALSE;
   int nmiss;
-  double slon, slat;
   double sglval;
   field_t field;
-  int taxisID1, taxisID2;
   int pn = 0;
 
   cdoInitialize(argument);
@@ -119,58 +112,90 @@ void *Fldstat(void *argument)
   cdoOperatorAdd("fldvar1", func_var1, 0, NULL);
   cdoOperatorAdd("fldpctl", func_pctl, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
-      pn = atoi(operatorArgv()[0]);
+      pn = parameter2int(operatorArgv()[0]);
       
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
     }
 
+  int useweights = TRUE;
+
   if ( operfunc == func_mean || operfunc == func_avg ||
        operfunc == func_var  || operfunc == func_std ||
        operfunc == func_var1 || operfunc == func_std1 )
-    needWeights = TRUE;
+    {
+      needWeights = TRUE;
+      unsigned npar = operatorArgc();
+      if ( npar > 0 )
+	{
+	  char **parnames = operatorArgv();
+
+	  if ( cdoVerbose )
+	    for ( unsigned i = 0; i < npar; i++ )
+	      cdoPrint("key %u = %s", i+1, parnames[i]);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+	  if ( strcmp(parnames[0], "noweights") == 0 ) useweights = FALSE;
+	  else cdoAbort("Parameter >%s< unsupported! Supported parameter are: noweights", parnames[0]);
+	}
+    }
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
+
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  slon = 0;
-  slat = 0;
-  gridID2 = gridCreate(GRID_LONLAT, 1);
-  gridDefXsize(gridID2, 1);
-  gridDefYsize(gridID2, 1);
-  gridDefXvals(gridID2, &slon);
-  gridDefYvals(gridID2, &slat);
+  if ( CDO_Reduce_Dim )
+    {
+      gridID2 = gridCreate(GRID_GENERIC, 1);
+      gridDefXsize(gridID2, 0);
+      gridDefYsize(gridID2, 0);
+    }
+  else
+    {
+      double slon = 0;
+      double slat = 0;
+      gridID2 = gridCreate(GRID_LONLAT, 1);
+      gridDefXsize(gridID2, 1);
+      gridDefYsize(gridID2, 1);
+      gridDefXvals(gridID2, &slon);
+      gridDefYvals(gridID2, &slat);
+    }
 
-  ngrids = vlistNgrids(vlistID1);
+  int ngrids = vlistNgrids(vlistID1);
 
   for ( index = 0; index < ngrids; index++ )
     vlistChangeGridIndex(vlistID2, index, gridID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
   field_init(&field);
 
-  lim = vlistGridsizeMax(vlistID1);
+  int lim = vlistGridsizeMax(vlistID1);
   field.ptr    = (double*) malloc(lim*sizeof(double));
   field.weight = NULL;
   if ( needWeights )
-    field.weight = (double*) malloc(lim*sizeof(double));
+    {
+      field.weight = (double*) malloc(lim*sizeof(double));
+      if ( !useweights )
+	{
+	  cdoPrint("Using constant grid cell area weights!");
+	  for ( int i = 0; i < lim; ++i ) field.weight[i] = 1;
+	}
+    }
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
@@ -199,14 +224,14 @@ void *Fldstat(void *argument)
 	    {
 	      lastgrid = field.grid;
 	      field.weight[0] = 1;
-	      if ( field.size > 1 )
+	      if ( useweights && field.size > 1 )
 		{
-		  int wstatus = gridWeights(field.grid, field.weight);
+		  int wstatus = wstatus = gridWeights(field.grid, field.weight);
 		  if ( wstatus != 0 && tsID == 0 && levelID == 0 )
 		    {
 		      char varname[CDI_MAX_NAME];
 		      vlistInqVarName(vlistID1, varID, varname);
-		      cdoWarning("Using constant grid cell area weights for variable %s!", varname);
+		      cdoWarning("Grid cell bounds not available, using constant grid cell area weights for variable %s!", varname);
 		    }
 		}
 	    }
diff --git a/src/Fldstat2.c b/src/Fldstat2.c
index ca1ea03..78f2afd 100644
--- a/src/Fldstat2.c
+++ b/src/Fldstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Fourier.c b/src/Fourier.c
index 3634dd2..c223529 100644
--- a/src/Fourier.c
+++ b/src/Fourier.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -56,7 +56,7 @@ void *Fourier(void *argument)
   cdoInitialize(argument);
 
   operatorInputArg("the sign of the exponent (-1 for normal or 1 for reverse transformation)!");
-  sign = atoi(operatorArgv()[0]);
+  sign = parameter2int(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Gengrid.c b/src/Gengrid.c
index 3935371..ecd020a 100644
--- a/src/Gengrid.c
+++ b/src/Gengrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Gradsdes.c b/src/Gradsdes.c
index 2516040..47ebaa2 100644
--- a/src/Gradsdes.c
+++ b/src/Gradsdes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -31,8 +31,6 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "grid.h"
-//#include <string.h> // necessary for compatability? GNU basename
-#include "libgen.h" // posix basename POSIX.1-2001
 
 
 /*
@@ -355,6 +353,8 @@ void dumpmap()
         }
     }
 
+  UNUSED(nbytes);
+
   fclose(mapfp);
 
   printf("hinum: %d\n", indx.hinum);
@@ -935,38 +935,26 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
   fclose(mapfp);
 }
 
-
+/*
 static
 void write_map_grib2(const char *ctlfile, int map_version, int nrecords, int *intnum, float *fltnum, off_t *bignum)
 {
-    // to be implemented
 }
+*/
 
 void *Gradsdes(void *argument)
 {
-  int GRADSDES, DUMPMAP;
-  int operatorID;
-  int streamID = 0;
   int gridID = -1;
   int gridtype = -1;
-  int nvars, ngrids;
-  int nvarsout;
-  int ntsteps;
   int index;
-  int vlistID, tsID, varID;
+  int varID;
   int recID, levelID;
-  int filetype, byteorder;
-  int taxisID, nrecs;
+  int nrecs;
   int vdate, vtime;
-  const char *datfile;
-  char ctlfile[1024];
-  char idxfile[1024];
+  char *idxfile = NULL;
   char varname[CDI_MAX_NAME];
-  FILE *gdp;
   int yrev = FALSE;
   int zrev = FALSE;
-  int xsize = 0, ysize = 0;
-  int res;
   int xyheader = 0;
   int nrecords = 0;
   int bigendian = FALSE, littleendian = FALSE;
@@ -984,11 +972,8 @@ void *Gradsdes(void *argument)
   int nmiss;
   int prec;
   int map_version = 2;
-  int nrecsout = 0;
   int maxrecs = 0;
   int monavg = -1;
-  int *vars = NULL;
-  int *recoffset = NULL;
   int *intnum = NULL;
   float *fltnum = NULL;
   off_t *bignum = NULL;
@@ -997,16 +982,17 @@ void *Gradsdes(void *argument)
 
   cdoInitialize(argument);
 
-  GRADSDES  = cdoOperatorAdd("gradsdes",  0, 0, NULL);
-  DUMPMAP   = cdoOperatorAdd("dumpmap",   0, 0, NULL);
+  int GRADSDES = cdoOperatorAdd("gradsdes",  0, 0, NULL);
+  int DUMPMAP  = cdoOperatorAdd("dumpmap",   0, 0, NULL);
+
+  UNUSED(GRADSDES);
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
-  strcpy(ctlfile, cdoStreamName(0)->args);
-  char relpath_sign = '^';
-  if ( ctlfile[0] == '/' )
-    relpath_sign = '\0';
-  datfile = cdoStreamName(0)->args;
+  const char *datfile = cdoStreamName(0)->args;
+  size_t len = strlen(datfile);
+  char *ctlfile = (char *) malloc(len+10);
+  strcpy(ctlfile, datfile);
 
   if ( cdoStreamName(0)->args[0] == '-' )
     cdoAbort("This operator does not work with pipes!");
@@ -1014,7 +1000,6 @@ void *Gradsdes(void *argument)
   if ( operatorID == DUMPMAP )
     {
       dumpmap();
-
       goto END_LABEL;
     }
 
@@ -1022,7 +1007,7 @@ void *Gradsdes(void *argument)
 
   if ( operatorArgc() == 1 )
     {
-      map_version = atoi(operatorArgv()[0]);
+      map_version = parameter2int(operatorArgv()[0]);
       if ( map_version != 1 && map_version != 2 && map_version != 4 )
         cdoAbort("map_version=%d unsupported!", map_version);
     }
@@ -1037,17 +1022,16 @@ void *Gradsdes(void *argument)
     cdoAbort("GrADS GRIB map version %d requires size of off_t to be 8! The size of off_t is %ld.",
              map_version, sizeof(off_t));
 
+  int streamID = streamOpenRead(cdoStreamName(0));
 
-  streamID = streamOpenRead(cdoStreamName(0));
-
-  vlistID = streamInqVlist(streamID);
+  int vlistID = streamInqVlist(streamID);
 
-  nvars   = vlistNvars(vlistID);
-  ntsteps = vlistNtsteps(vlistID);
-  ngrids  = vlistNgrids(vlistID);
+  int nvars   = vlistNvars(vlistID);
+  int ntsteps = vlistNtsteps(vlistID);
+  int ngrids  = vlistNgrids(vlistID);
 
-  filetype  = streamInqFiletype(streamID);
-  byteorder = streamInqByteorder(streamID);
+  int filetype  = streamInqFiletype(streamID);
+  int byteorder = streamInqByteorder(streamID);
 
   if ( filetype == FILETYPE_NC2 || filetype == FILETYPE_NC4 ) filetype = FILETYPE_NC;
 
@@ -1080,10 +1064,10 @@ void *Gradsdes(void *argument)
     cdoAbort("No Lon/Lat, Gaussian or Lambert grid found (%s data unsupported)!", gridNamePtr(gridtype));
 
   /* select all variables with used gridID */
-  vars = (int*) malloc(nvars*sizeof(int));
-  recoffset = (int*) malloc(nvars*sizeof(int));
-  nvarsout = 0;
-  nrecsout = 0;
+  int *vars = (int*) malloc(nvars*sizeof(int));
+  int *recoffset = (int*) malloc(nvars*sizeof(int));
+  int nvarsout = 0;
+  int nrecsout = 0;
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( vlistInqVarGrid(vlistID, varID) == gridID )
@@ -1146,19 +1130,28 @@ void *Gradsdes(void *argument)
   repl_filetypeext(ctlfile, filetypeext(filetype), ".ctl");
 
   /* open ctl file*/
-  gdp = fopen(ctlfile, "w");
+  FILE *gdp = fopen(ctlfile, "w");
   if ( gdp == NULL ) cdoAbort("Open failed on %s", ctlfile);
 
   /* VERSION */
+  fprintf(gdp, "* Generated by CDO operator gradsdes\n");
+  fprintf(gdp, "*\n");
+  /*
 #if defined(VERSION)
   fprintf(gdp, "* Generated by CDO version %s\n", VERSION);
   fprintf(gdp, "*\n");
 #endif
-
+  */
   /* DSET */
-  if ( relpath_sign ) 
-      datfile = basename((char *) datfile);
-  fprintf(gdp, "DSET  %c%s\n", relpath_sign, datfile);
+  if ( datfile[0] == '/' )
+    fprintf(gdp, "DSET  %s\n", datfile);
+  else
+    {
+      datfile = strrchr(datfile, '/');
+      if ( datfile == 0 ) datfile = cdoStreamName(0)->args;
+      else                datfile++;
+      fprintf(gdp, "DSET  ^%s\n", datfile);
+    }
 
   /*
    * DTYPE Print file type
@@ -1166,8 +1159,7 @@ void *Gradsdes(void *argument)
    */
   if ( filetype == FILETYPE_GRB ||  filetype == FILETYPE_GRB2 )
     {
-
-      strcpy(idxfile, ctlfile);
+      idxfile = strdup(ctlfile);
       char *pidxfile = idxfile;
 
       // print GRIB[12] file type
@@ -1176,19 +1168,23 @@ void *Gradsdes(void *argument)
         {
           fprintf(gdp, "DTYPE  GRIB\n");
           repl_filetypeext(idxfile, ".ctl", ".gmp");
-          write_map_grib1(idxfile, map_version, nrecords, intnum, fltnum, bignum);
         }
       else if ( filetype == FILETYPE_GRB2 )
         {
           fprintf(gdp, "DTYPE  GRIB2\n");
           repl_filetypeext(pidxfile, ".ctl", ".idx");
-          // TODO: write_map_grib2();
         }
 
       // print file name of index file
-      if ( relpath_sign ) 
-          pidxfile = basename((char *) pidxfile);
-      fprintf(gdp, "INDEX  %c%s\n", relpath_sign, pidxfile);
+      if ( datfile[0] == '/' )
+        fprintf(gdp, "INDEX  %s\n", pidxfile);
+      else
+        {
+          pidxfile = strrchr(pidxfile, '/');
+          if ( pidxfile == 0 ) pidxfile = idxfile;
+          else                 pidxfile++;
+          fprintf(gdp, "INDEX  ^%s\n", pidxfile);
+        }
 
       gridsize = vlistGridsizeMax(vlistID);
       array = (double*) malloc(gridsize*sizeof(double));
@@ -1203,11 +1199,11 @@ void *Gradsdes(void *argument)
 
   /* TIME */
 
-  taxisID = vlistInqTaxis(vlistID);
+  int taxisID = vlistInqTaxis(vlistID);
 
   if ( taxisInqCalendar(taxisID) == CALENDAR_365DAYS ) cal365day = 1;
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID, tsID)) )
     {
       vdate = taxisInqVdate(taxisID);
@@ -1280,7 +1276,7 @@ void *Gradsdes(void *argument)
           if ( iddd < 0 ) iddd *= -1;
           if ( idyy > 0 ) idmm += idyy*12;
 
-          if ( idmn == 0 && idhh == 0 && (iddd == 0 || idd > 27 ) &&
+          if ( /*idmn == 0 && idhh == 0 &&*/ (iddd == 0 || iddd == 1 || idd > 27 ) &&
                idmm > 0 && (mdt == 0 || idmm == mdt) )
             {
               mdt = idmm;
@@ -1290,7 +1286,7 @@ void *Gradsdes(void *argument)
             {
               monavg = FALSE;
             }
-          /*
+          /*          
           printf("monavg %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
                  tsID, monavg, mdt, imm , imms, idmm, iyy, iyys, idyy, idd, idds, iddd);
           */
@@ -1363,17 +1359,17 @@ void *Gradsdes(void *argument)
         }
     }
 
-  sprintf (Time, "%02d:%02dZ%02d%s%04d", ihh0, imn0, idd0, cmons[imm0-1], iyy0);
-  sprintf (Incr, "%d%s", dt, IncrKey[iik]);
+  sprintf(Time, "%02d:%02dZ%02d%s%04d", ihh0, imn0, idd0, cmons[imm0-1], iyy0);
+  sprintf(Incr, "%d%s", dt, IncrKey[iik]);
 
-  fprintf (gdp, "TDEF %d LINEAR %s %s\n", tsID, Time, Incr);
+  fprintf(gdp, "TDEF %d LINEAR %s %s\n", tsID, Time, Incr);
 
   /* TITLE */
 
-  xsize  = gridInqXsize(gridID);
-  ysize  = gridInqYsize(gridID);
+  int xsize  = gridInqXsize(gridID);
+  int ysize  = gridInqYsize(gridID);
 
-  res = 0;
+  int res = 0;
   if ( gridtype == GRID_GAUSSIAN ) res = nlat2ntr(ysize);
 
   if ( res )
@@ -1394,16 +1390,19 @@ void *Gradsdes(void *argument)
   /* INDEX file */
   if ( filetype == FILETYPE_GRB )
     {
+      write_map_grib1(idxfile, map_version, nrecords, intnum, fltnum, bignum);
     }
   if ( filetype == FILETYPE_GRB2 )
     {
       cdoAbort("\nThe fileformat GRIB2 is not fully supported yet\nfor the gradsdes operator.\nThe .ctl file %s was generated.\nYou can add the necessary .idx file by running\n\tgribmap -i %s", ctlfile, ctlfile);
-      write_map_grib2(idxfile, map_version, nrecords, intnum, fltnum, bignum);
+      // write_map_grib2(idxfile, map_version, nrecords, intnum, fltnum, bignum);
     }
 
-
   streamClose(streamID);
 
+  if ( ctlfile ) free(ctlfile);
+  if ( idxfile ) free(idxfile);
+
   if ( vars ) free(vars);
   if ( recoffset ) free(recoffset);
   if ( array ) free(array);
diff --git a/src/Gridboxstat.c b/src/Gridboxstat.c
index 6e774e8..ccc4e97 100644
--- a/src/Gridboxstat.c
+++ b/src/Gridboxstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -55,17 +55,8 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
   double xvals2_0 = 0;
   double area_norm;  
 
- 
   gridtype  = gridInqType(gridID1);
   gridsize1 = gridInqSize(gridID1);
- 
-  if ( cdoVerbose )
-    {
-      if ( ! circular )
-        fprintf(stderr, "grid is not circular\n");
-      else
-        fprintf(stderr, "grid is circular\n");
-    }
 
   if ( xinc < 1 || yinc < 1 )
     cdoAbort("xinc and yinc must not be smaller than 1!");
@@ -257,211 +248,149 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
                         }
                      
                       if ( gridHasBounds )
-                        {/* 
-                         =====================================================================
-                         ** O L D
-                         */
-                          if ( FALSE )
-                            {
-                              /* upper left cell */
-                              if ( y1 == y2*yinc && x1 == x2*xinc)
-                                {
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {
-                                      add = 4*g1_add + corner;
-                                      if ( grid1_corner_lon[add] < on_up )
-                                        on_up = grid1_corner_lon[add];
-                                      if (grid1_corner_lat[add] > ax_le )
-                                        ax_le = grid1_corner_lat[add];
-                                    }
-                                }
-                              
-                              /* upper right cell */
-                              if ( ( y1 == y2*yinc ) && ( x1 == (x2+1)*xinc - 1 ) )
-                                {    
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {
-                                      add = 4*g1_add + corner;
-                                      if ( grid1_corner_lon[add] > ox_up )
-                                        ox_up = grid1_corner_lon[add];
-                                      if (grid1_corner_lat[add] > ax_ri )
-                                        ax_ri = grid1_corner_lat[add];
-                                    }
-                                }
-                              
-                              /* lower right cell */
-                              if ( ( y1 == (y2+1)*yinc -1 ) && (x1 == (x2+1)*xinc -1) )
-                                {
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {                             
-                                  add = 4*g1_add + corner;
-                                      if ( grid1_corner_lon[add] > ox_lo )
-                                        ox_lo = grid1_corner_lon[add];
-                                      if ( grid1_corner_lat[add] < an_ri )
-                                        an_ri = grid1_corner_lat[add];
-                                    }
-                                }
-                              
-                              /* lower left cell */
-                              if ( ( y1 == (y2+1)*yinc -1 ) && ( x1 == x2*xinc ) )
-                                {    
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {
-                                      add = 4*g1_add + corner;
-                                      if ( grid1_corner_lon[add] < on_lo )
-                                    on_lo = grid1_corner_lon[add];
-                                      if ( grid1_corner_lat[add] < an_le )
-                                        an_le = grid1_corner_lat[add];
-                                    }
-                                }
-                            }  /* O  L  D */
-                          //=================================================================
-                          else /* N  E  W */
-                            {
-                              int c_flag[4], corner2, g1_add2, g1_add3;
-                              double lon, lat, lon2, lat2, lon3, lat3;
-                              /* upper left cell */
-                              if ( y1 == y2*yinc && x1 == x2*xinc)
-                                {                                 
-                                  c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {                                      
-                                      add = 4*g1_add + corner;
-                                      lon = grid1_corner_lon[add];
-                                      lat = grid1_corner_lat[add]; 
-                                      g1_add2 = g1_add+1;
-                                      if ( g1_add+nlon1 > gridsize1 ) 
-                                        {
-                                          cdoWarning("Can't find cell below upper left");
-                                          continue; 
-                                        }
-                                      g1_add3 = g1_add+nlon1;
-                                      for ( corner2 = 0; corner2 < 4; corner2++ )
-                                        {                                          
-                                          lon2 = grid1_corner_lon[4*g1_add2+corner2];
-                                          lat2 = grid1_corner_lat[4*g1_add2+corner2];
-                                          lon3 = grid1_corner_lon[4*g1_add3+corner2];
-                                          lat3 = grid1_corner_lat[4*g1_add3+corner2];
-                                          if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
-                                              (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
-                                            c_flag[corner] = 1;
-                                        }
-                                    }
-                                  for ( corner = 0; corner<4; corner++ )
-                                    if ( !c_flag[corner] ) break;                                 
-                                  on_up = grid1_corner_lon[4*g1_add + corner];
-                                  ax_le = grid1_corner_lat[4*g1_add + corner];                                  
-                                  if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
-                                    cdoWarning("found two matching corners!");                                  
-                                }
+                        {
+			  int c_flag[4], corner2, g1_add2, g1_add3;
+			  double lon, lat, lon2, lat2, lon3, lat3;
+			  /* upper left cell */
+			  if ( y1 == y2*yinc && x1 == x2*xinc)
+			    {                                 
+			      c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
+			      for ( corner = 0; corner < 4; corner++ )
+				{                                      
+				  add = 4*g1_add + corner;
+				  lon = grid1_corner_lon[add];
+				  lat = grid1_corner_lat[add]; 
+				  g1_add2 = g1_add+1;
+				  if ( g1_add+nlon1 > gridsize1 ) 
+				    {
+				      cdoWarning("Can't find cell below upper left");
+				      continue; 
+				    }
+				  g1_add3 = g1_add+nlon1;
+				  for ( corner2 = 0; corner2 < 4; corner2++ )
+				    {                                          
+				      lon2 = grid1_corner_lon[4*g1_add2+corner2];
+				      lat2 = grid1_corner_lat[4*g1_add2+corner2];
+				      lon3 = grid1_corner_lon[4*g1_add3+corner2];
+				      lat3 = grid1_corner_lat[4*g1_add3+corner2];
+				      if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
+					  (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
+					c_flag[corner] = 1;
+				    }
+				}
+			      for ( corner = 0; corner<4; corner++ )
+				if ( !c_flag[corner] ) break;                                 
+			      on_up = grid1_corner_lon[4*g1_add + corner];
+			      ax_le = grid1_corner_lat[4*g1_add + corner];                                  
+			      if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
+				cdoWarning("found two matching corners!");                                  
+			    }
                               
-                              /* upper right cell */
-                              if ( ( y1 == y2*yinc ) && ( x1 == (x2+1)*xinc - 1 ) )
-                                {
-                                  c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {                                      
-                                      add = 4*g1_add + corner;
-                                      lon = grid1_corner_lon[add];
-                                      lat = grid1_corner_lat[add]; 
-                                      g1_add2 = g1_add-1;                                      
-                                      if ( g1_add+nlon1 > gridsize1 ) 
-                                        {
-                                          cdoWarning("Can't find cell below upper left");
-                                          continue; 
-                                        }
-                                      g1_add3 = g1_add+nlon1;
-                                      for ( corner2 = 0; corner2 < 4; corner2++ )
-                                        {                                          
-                                          lon2 = grid1_corner_lon[4*g1_add2+corner2];
-                                          lat2 = grid1_corner_lat[4*g1_add2+corner2];
-                                          lon3 = grid1_corner_lon[4*g1_add3+corner2];
-                                          lat3 = grid1_corner_lat[4*g1_add3+corner2];
-                                         if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
-					     (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
-                                             c_flag[corner] = 1;
-                                        } 
-                                    }                                 
-                                  for ( corner = 0; corner<4; corner++ )
-                                    if ( !c_flag[corner] ) break;                                 
-                                  ox_up = grid1_corner_lon[4*g1_add + corner];
-                                  ax_ri = grid1_corner_lat[4*g1_add + corner];                                  
-                                  if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
-                                    cdoWarning("found two matching corners!");                                     
-                                }
+			  /* upper right cell */
+			  if ( ( y1 == y2*yinc ) && ( x1 == (x2+1)*xinc - 1 ) )
+			    {
+			      c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
+			      for ( corner = 0; corner < 4; corner++ )
+				{                                      
+				  add = 4*g1_add + corner;
+				  lon = grid1_corner_lon[add];
+				  lat = grid1_corner_lat[add]; 
+				  g1_add2 = g1_add-1;                                      
+				  if ( g1_add+nlon1 > gridsize1 ) 
+				    {
+				      cdoWarning("Can't find cell below upper left");
+				      continue; 
+				    }
+				  g1_add3 = g1_add+nlon1;
+				  for ( corner2 = 0; corner2 < 4; corner2++ )
+				    {                                          
+				      lon2 = grid1_corner_lon[4*g1_add2+corner2];
+				      lat2 = grid1_corner_lat[4*g1_add2+corner2];
+				      lon3 = grid1_corner_lon[4*g1_add3+corner2];
+				      lat3 = grid1_corner_lat[4*g1_add3+corner2];
+				      if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
+					  (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
+					c_flag[corner] = 1;
+				    } 
+				}                                 
+			      for ( corner = 0; corner<4; corner++ )
+				if ( !c_flag[corner] ) break;                                 
+			      ox_up = grid1_corner_lon[4*g1_add + corner];
+			      ax_ri = grid1_corner_lat[4*g1_add + corner];                                  
+			      if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
+				cdoWarning("found two matching corners!");                                     
+			    }
                             
-                            
-                              
-                              /* lower right cell */
-                              if ( ( y1 == (y2+1)*yinc -1 ) && (x1 == (x2+1)*xinc -1) )
-                                {                                  
-                                  c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {                                      
-                                      add = 4*g1_add + corner;
-                                      lon = grid1_corner_lon[add];
-                                      lat = grid1_corner_lat[add]; 
-                                      g1_add2 = g1_add-1;
-                                      if ( g1_add-nlon1 < 0 ) 
-                                        {
-                                          cdoWarning("Can't find cell above lower right left");
-                                          continue; 
-                                        }
-                                      g1_add3 = g1_add-nlon1;
-                                      for ( corner2 = 0; corner2 < 4; corner2++ )
-                                        {                                          
-                                          lon2 = grid1_corner_lon[4*g1_add2+corner2];
-                                          lat2 = grid1_corner_lat[4*g1_add2+corner2];
-                                          lon3 = grid1_corner_lon[4*g1_add3+corner2];
-                                          lat3 = grid1_corner_lat[4*g1_add3+corner2];
-                                          if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
-					      (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
-                                            c_flag[corner] = 1;
-                                        } 
-                                    }                                  
-                                  for ( corner = 0; corner<4; corner++ )
-                                    if ( !c_flag[corner] ) break;                                 
-                                  ox_lo = grid1_corner_lon[4*g1_add + corner];
-                                  an_ri = grid1_corner_lat[4*g1_add + corner];                                  
-                                  if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
-                                    cdoWarning("found two matching corners!");        
-                                }
                               
-                              /* lower left cell */
-                              if ( ( y1 == (y2+1)*yinc -1 ) && ( x1 == x2*xinc ) )
-                                {    
-                                  c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
-                                  for ( corner = 0; corner < 4; corner++ )
-                                    {                                      
-                                      add = 4*g1_add + corner;
-                                      lon = grid1_corner_lon[add];
-                                      lat = grid1_corner_lat[add]; 
-                                      g1_add2 = g1_add+1;
-                                      if ( g1_add-nlon1 < 0 ) 
-                                        {
-                                          cdoWarning("Can't find cell above lower right left");
-                                          continue; 
-                                        }
-                                      g1_add3 = g1_add-nlon1;
-                                      for ( corner2 = 0; corner2 < 4; corner2++ )
-                                        {                                          
-                                          lon2 = grid1_corner_lon[4*g1_add2+corner2];
-                                          lat2 = grid1_corner_lat[4*g1_add2+corner2];
-                                          lon3 = grid1_corner_lon[4*g1_add3+corner2];
-                                          lat3 = grid1_corner_lat[4*g1_add3+corner2];
-                                          if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
-					      (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
-                                            c_flag[corner] = 1;
-                                        }
-                                    }                                 
-                                  for ( corner = 0; corner<4; corner++ )
-                                    if ( !c_flag[corner] ) break;                                 
-                                  on_lo = grid1_corner_lon[4*g1_add + corner];
-                                  an_le = grid1_corner_lat[4*g1_add + corner];                                  
-                                  if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
-                                    cdoWarning("found two matching corners!");                                      
-                                }
-                            }/* else to if(fast) */
+			  /* lower right cell */
+			  if ( ( y1 == (y2+1)*yinc -1 ) && (x1 == (x2+1)*xinc -1) )
+			    {                                  
+			      c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
+			      for ( corner = 0; corner < 4; corner++ )
+				{                                      
+				  add = 4*g1_add + corner;
+				  lon = grid1_corner_lon[add];
+				  lat = grid1_corner_lat[add]; 
+				  g1_add2 = g1_add-1;
+				  if ( g1_add-nlon1 < 0 ) 
+				    {
+				      cdoWarning("Can't find cell above lower right left");
+				      continue; 
+				    }
+				  g1_add3 = g1_add-nlon1;
+				  for ( corner2 = 0; corner2 < 4; corner2++ )
+				    {                                          
+				      lon2 = grid1_corner_lon[4*g1_add2+corner2];
+				      lat2 = grid1_corner_lat[4*g1_add2+corner2];
+				      lon3 = grid1_corner_lon[4*g1_add3+corner2];
+				      lat3 = grid1_corner_lat[4*g1_add3+corner2];
+				      if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
+					  (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
+					c_flag[corner] = 1;
+				    } 
+				}                                  
+			      for ( corner = 0; corner<4; corner++ )
+				if ( !c_flag[corner] ) break;                                 
+			      ox_lo = grid1_corner_lon[4*g1_add + corner];
+			      an_ri = grid1_corner_lat[4*g1_add + corner];                                  
+			      if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
+				cdoWarning("found two matching corners!");        
+			    }
+			  
+			  /* lower left cell */
+			  if ( ( y1 == (y2+1)*yinc -1 ) && ( x1 == x2*xinc ) )
+			    {    
+			      c_flag[0] = c_flag[1] = c_flag[2] = c_flag[3] = 0;
+			      for ( corner = 0; corner < 4; corner++ )
+				{                                      
+				  add = 4*g1_add + corner;
+				  lon = grid1_corner_lon[add];
+				  lat = grid1_corner_lat[add]; 
+				  g1_add2 = g1_add+1;
+				  if ( g1_add-nlon1 < 0 ) 
+				    {
+				      cdoWarning("Can't find cell above lower right left");
+				      continue; 
+				    }
+				  g1_add3 = g1_add-nlon1;
+				  for ( corner2 = 0; corner2 < 4; corner2++ )
+				    {                                          
+				      lon2 = grid1_corner_lon[4*g1_add2+corner2];
+				      lat2 = grid1_corner_lat[4*g1_add2+corner2];
+				      lon3 = grid1_corner_lon[4*g1_add3+corner2];
+				      lat3 = grid1_corner_lat[4*g1_add3+corner2];
+				      if ((IS_EQUAL(lon2, lon) && IS_EQUAL(lat2, lat))  ||
+					  (IS_EQUAL(lon3, lon) && IS_EQUAL(lat3, lat)) )
+					c_flag[corner] = 1;
+				    }
+				}                                 
+			      for ( corner = 0; corner<4; corner++ )
+				if ( !c_flag[corner] ) break;                                 
+			      on_lo = grid1_corner_lon[4*g1_add + corner];
+			      an_le = grid1_corner_lat[4*g1_add + corner];                                  
+			      if ( c_flag[0] + c_flag[1] + c_flag[2] + c_flag[3] < 3 )
+				cdoWarning("found two matching corners!");                                      
+			    }
                         }/* if ( gridHasBounds) */                  
                     }/* for ( x1 = x2*xinc; x1 < xinc*(x2+1) ; x1++ ) */
                 }/* for ( y1 = y2*yinc; y1 < yinc*(y2+1); y1++ ) */
@@ -647,8 +576,8 @@ void *Gridboxstat(void *argument)
 
   operatorInputArg("xinc, yinc");
   operatorCheckArgc(2);
-  xinc = atoi(operatorArgv()[0]);
-  yinc = atoi(operatorArgv()[1]);
+  xinc = parameter2int(operatorArgv()[0]);
+  yinc = parameter2int(operatorArgv()[1]);
 
   cdoOperatorAdd("gridboxmin",  func_min,  0, NULL);
   cdoOperatorAdd("gridboxmax",  func_max,  0, NULL);
diff --git a/src/Gridcell.c b/src/Gridcell.c
index f5ca490..8a6acfb 100644
--- a/src/Gridcell.c
+++ b/src/Gridcell.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "grid.h"
-
+#include "constants.h"
 
 static
 double orthodrome(double px1, double py1, double px2, double py2)
@@ -52,8 +52,6 @@ void *Gridcell(void *argument)
   int tsID, varID, levelID, taxisID;
   long i, gridsize;
   double *array = NULL;
-  double  EarthRadius = 6371000; /* default radius of the earth in m */
-  double PlanetRadius = EarthRadius;
 
   cdoInitialize(argument);
 
@@ -223,22 +221,8 @@ void *Gridcell(void *argument)
 
 	  gridInqXunits(gridID, units);
 
-	  if ( memcmp(units, "degree", 6) == 0 )
-	    {
-	      for ( i = 0; i < gridsize; ++i )
-		{
-		  xv[i] *= DEG2RAD;
-		  yv[i] *= DEG2RAD;
-		}
-	    }
-	  else if ( memcmp(units, "radian", 6) == 0 )
-	    {
-	      /* No conversion necessary */
-	    }
-	  else
-	    {
-	      cdoWarning("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
-	    }
+	  grid_to_radian(units, gridsize, yv, "grid longitudes");
+	  grid_to_radian(units, gridsize, yv, "grid latitudes");
 
 	  if ( operatorID == GRIDDX )
 	    {
diff --git a/src/Gridsearch.c b/src/Gridsearch.c
index 14b9ba7..d7adfd0 100644
--- a/src/Gridsearch.c
+++ b/src/Gridsearch.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Harmonic.c b/src/Harmonic.c
index 2e104a1..4c2936a 100644
--- a/src/Harmonic.c
+++ b/src/Harmonic.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -58,8 +58,8 @@ void *Harmonic(void *argument)
 
   operatorCheckArgc(2);
 
-  n_out = atoi(operatorArgv()[0]);
-  n     = atoi(operatorArgv()[1]);
+  n_out = parameter2int(operatorArgv()[0]);
+  n     = parameter2int(operatorArgv()[1]);
 
   if ( n_out > 9 ) cdoAbort("Maximum number of wave numbers is 9!");
 
diff --git a/src/Hi.c b/src/Hi.c
old mode 100644
new mode 100755
diff --git a/src/Histogram.c b/src/Histogram.c
index fbc8c56..a32ff74 100644
--- a/src/Histogram.c
+++ b/src/Histogram.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Importamsr.c b/src/Importamsr.c
index 019ac87..ef0f26b 100644
--- a/src/Importamsr.c
+++ b/src/Importamsr.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -163,11 +163,8 @@ static
 int getDate(const char *name)
 {
   int date = 0;
-  size_t len;
   char *pname;
 
-  len = strlen(name);
-
   pname = strchr(name, '_');
 
   if ( pname ) date = atoi(pname+1);
diff --git a/src/Importbinary.c b/src/Importbinary.c
index 995926f..5d09fe8 100644
--- a/src/Importbinary.c
+++ b/src/Importbinary.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -246,10 +246,10 @@ void *Importbinary(void *argument)
   if ( nvars == 0 ) cdoAbort("No variables found!");
 
   gridID = define_grid(&pfi);
-  if ( cdoVerbose ) gridPrint(gridID, 1);
+  if ( cdoVerbose ) gridPrint(gridID, gridID, 1);
 
   zaxisID = define_level(&pfi, 0);
-  if ( cdoVerbose ) zaxisPrint(zaxisID);
+  if ( cdoVerbose ) zaxisPrint(zaxisID, zaxisID);
 
   zaxisIDsfc = zaxisCreate(ZAXIS_SURFACE, 1);
   zaxisDefLevels(zaxisIDsfc, &sfclevel);
@@ -349,9 +349,11 @@ void *Importbinary(void *argument)
       pvar++;
     }
 
+  int calendar = CALENDAR_STANDARD;
+
   taxisID = taxisCreate(TAXIS_RELATIVE);
 
-  taxisDefCalendar(taxisID, CALENDAR_STANDARD);
+  taxisDefCalendar(taxisID, calendar);
 
   vlistDefTaxis(vlistID, taxisID);
 
diff --git a/src/Importcmsaf.c b/src/Importcmsaf.c
index f13af84..331d167 100644
--- a/src/Importcmsaf.c
+++ b/src/Importcmsaf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Importobs.c b/src/Importobs.c
index 5176e2f..bb1ef68 100644
--- a/src/Importobs.c
+++ b/src/Importobs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -91,11 +91,8 @@ static
 int getDate(const char *name)
 {
   int date = 0;
-  size_t len;
   char *pname;
 
-  len = strlen(name);
-
   pname = strchr(name, '_');
 
   if ( pname ) date = atoi(pname+1);
diff --git a/src/Info.c b/src/Info.c
index e86193f..4d2b585 100644
--- a/src/Info.c
+++ b/src/Info.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -242,10 +242,7 @@ void printMap(int nlon, int nlat, double *array, double missval, double min, dou
 
 void *Info(void *argument)
 {
-  int INFO, INFOP, INFON, INFOC, MAP;
-  int operatorID;
   int i;
-  int indf, indg;
   int varID, recID;
   int gridsize = 0;
   int gridID, zaxisID;
@@ -253,9 +250,6 @@ void *Info(void *argument)
   int vdate, vtime;
   int nrecs;
   int levelID;
-  int tsID, taxisID;
-  int streamID = 0;
-  int vlistID;
   int nmiss;
   int number;
   int ivals = 0, nvals = 0;
@@ -264,36 +258,38 @@ void *Info(void *argument)
   char paramstr[32];
   char vdatestr[32], vtimestr[32];
   double missval;
-  double *array = NULL;
   double level;
   double arrmin = 0, arrmax = 0, arrmean = 0, arrvar = 0;
 
   cdoInitialize(argument);
 
-  INFO  = cdoOperatorAdd("info",  0, 0, NULL);
-  INFOP = cdoOperatorAdd("infop", 0, 0, NULL);
-  INFON = cdoOperatorAdd("infon", 0, 0, NULL);
-  INFOC = cdoOperatorAdd("infoc", 0, 0, NULL);
-  MAP   = cdoOperatorAdd("map",   0, 0, NULL);
+  int INFO  = cdoOperatorAdd("info",  0, 0, NULL);
+  int INFOP = cdoOperatorAdd("infop", 0, 0, NULL);
+  int INFON = cdoOperatorAdd("infon", 0, 0, NULL);
+  int INFOC = cdoOperatorAdd("infoc", 0, 0, NULL);
+  int MAP   = cdoOperatorAdd("map",   0, 0, NULL);
 
-  operatorID = cdoOperatorID();
+  UNUSED(INFO);
+  UNUSED(INFOP);
 
-  for ( indf = 0; indf < cdoStreamCnt(); indf++ )
+  int operatorID = cdoOperatorID();
+
+  for ( int indf = 0; indf < cdoStreamCnt(); indf++ )
     {
-      streamID = streamOpenRead(cdoStreamName(indf));
+      int streamID = streamOpenRead(cdoStreamName(indf));
 
-      vlistID = streamInqVlist(streamID);
+      int vlistID = streamInqVlist(streamID);
+      int taxisID = vlistInqTaxis(vlistID);
 
       if ( vlistNvars(vlistID) == 0 ) continue;
 
       gridsize = vlistGridsizeMax(vlistID);
       if ( vlistNumber(vlistID) != CDI_REAL ) gridsize *= 2;
 
-      array = (double*) malloc(gridsize*sizeof(double));
+      double *array = (double*) malloc(gridsize*sizeof(double));
 
-      indg = 0;
-      tsID = 0;
-      taxisID = vlistInqTaxis(vlistID);
+      int indg = 0;
+      int tsID = 0;
       while ( (nrecs = streamInqTimestep(streamID, tsID)) )
 	{
 	  vdate = taxisInqVdate(taxisID);
@@ -487,6 +483,7 @@ void *Info(void *argument)
 	    }
 	  tsID++;
 	}
+
       streamClose(streamID);
 
       if ( array ) free(array);
diff --git a/src/Input.c b/src/Input.c
index d544352..0ca9d38 100644
--- a/src/Input.c
+++ b/src/Input.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -81,7 +81,7 @@ void *Input(void *argument)
   int vlistID = -1;
   int nmiss = 0;
   int i;
-  int code = 0, code0 = 0, level = 0, date = 0, time = 0, nlon = 0, nlat = 0;
+  int code = 0, level = 0, date = 0, time = 0, nlon = 0, nlat = 0;
   int output_filetype = FILETYPE_GRB;
   int rval;
   int ihead[8];
@@ -157,7 +157,6 @@ void *Input(void *argument)
 	  
 	  if ( nrecs == 0 )
 	    {
-	      code0 = code;
 	      levels[0] = level;
 	      gridsize0 = gridsize;
 
@@ -204,7 +203,6 @@ void *Input(void *argument)
 
 	  if ( nrecs == 0 )
 	    {
-	      code0 = code;
 	      levels[0] = level;
 	      gridsize0 = gridsize;
 	  
diff --git a/src/Intgrid.c b/src/Intgrid.c
index f86a3f4..d72abe8 100644
--- a/src/Intgrid.c
+++ b/src/Intgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -345,8 +345,8 @@ void *Intgrid(void *argument)
     {
       operatorInputArg("longitude and latitude");
       operatorCheckArgc(2);
-      slon = atof(operatorArgv()[0]);
-      slat = atof(operatorArgv()[1]);
+      slon = parameter2double(operatorArgv()[0]);
+      slat = parameter2double(operatorArgv()[1]);
       gridID2 = gridCreate(GRID_LONLAT, 1);
       gridDefXsize(gridID2, 1);
       gridDefYsize(gridID2, 1);
@@ -357,8 +357,8 @@ void *Intgrid(void *argument)
     {
       operatorInputArg("xinc, yinc");
       operatorCheckArgc(2);
-      xinc = atoi(operatorArgv()[0]);
-      yinc = atoi(operatorArgv()[1]);
+      xinc = parameter2int(operatorArgv()[0]);
+      yinc = parameter2int(operatorArgv()[1]);
     }
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Intgridtraj.c b/src/Intgridtraj.c
index 2d95a8d..2c3a196 100644
--- a/src/Intgridtraj.c
+++ b/src/Intgridtraj.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Intlevel.c b/src/Intlevel.c
index e9ad253..200052a 100644
--- a/src/Intlevel.c
+++ b/src/Intlevel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -32,8 +32,8 @@
 
 
 static
-void interp_lev(int gridsize, double missval, double *vardata1, double *vardata2,
-		int nlev2, int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
+void vert_interp_lev(int gridsize, double missval, double *vardata1, double *vardata2,
+		     int nlev2, int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
 {
   int i, ilev;
   int idx1, idx2;
@@ -91,12 +91,12 @@ void interp_lev(int gridsize, double missval, double *vardata1, double *vardata2
 }
 
 static
-void gen_weights(int expol, int nlev1, double *lev1, int nlev2, double *lev2,
-		 int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
+void vert_gen_weights(int expol, int nlev1, double *lev1, int nlev2, double *lev2,
+		      int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
 {
   int i1, i2;
-  double val1, val2 = 0;
   int    idx1 = 0, idx2 = 0;
+  double val1, val2 = 0;
 
   for ( i2 = 0; i2 < nlev2; ++i2 )
     {
@@ -104,7 +104,7 @@ void gen_weights(int expol, int nlev1, double *lev1, int nlev2, double *lev2,
 	{
 	  if ( lev1[i1-1] < lev1[i1] )
 	    {
-	      idx1 = i1 - 1;
+	      idx1 = i1-1;
 	      idx2 = i1;
 	    }
 	  else
@@ -162,16 +162,11 @@ void gen_weights(int expol, int nlev1, double *lev1, int nlev2, double *lev2,
 
 void *Intlevel(void *argument)
 {
-  int INTLEVEL, INTLEVELX;
-  int operatorID;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
   int gridsize;
   int recID, nrecs;
   int i, offset;
   int tsID, varID, levelID;
   int nvars;
-  int nzaxis;
   int nmiss;
   int zaxisID1 = -1, zaxisID2;
   int gridID, zaxisID;
@@ -185,17 +180,18 @@ void *Intlevel(void *argument)
   double *lev1 = NULL, *lev2 = NULL;
   double *single1, *single2;
   double **vardata1 = NULL, **vardata2 = NULL;
-  int taxisID1, taxisID2;
   int *lev_idx1, *lev_idx2;
   double *lev_wgt1, *lev_wgt2;
   LIST *flist = listNew(FLT_LIST);
 
   cdoInitialize(argument);
 
-  INTLEVEL   = cdoOperatorAdd("intlevel",  0, 0, NULL);
-  INTLEVELX  = cdoOperatorAdd("intlevelx", 0, 0, NULL);
+  int INTLEVEL   = cdoOperatorAdd("intlevel",  0, 0, NULL);
+  int INTLEVELX  = cdoOperatorAdd("intlevelx", 0, 0, NULL);
+
+  UNUSED(INTLEVEL);
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   if ( operatorID == INTLEVELX ) expol = TRUE;
 
@@ -206,16 +202,16 @@ void *Intlevel(void *argument)
 
   if ( cdoVerbose ) for ( i = 0; i < nlev2; ++i ) printf("lev2 %d: %g\n", i, lev2[i]);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  nzaxis  = vlistNzaxis(vlistID1);
+  int nzaxis  = vlistNzaxis(vlistID1);
   for ( i = 0; i < nzaxis; i++ )
     {
       zaxisID = vlistZaxis(vlistID1, i);
@@ -278,7 +274,7 @@ void *Intlevel(void *argument)
   lev_wgt1 = (double*) malloc(nlev2*sizeof(double));
   lev_wgt2 = (double*) malloc(nlev2*sizeof(double));
 
-  gen_weights(expol, nlev1+2, lev1, nlev2, lev2, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
+  vert_gen_weights(expol, nlev1+2, lev1, nlev2, lev2, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
   zaxisID2 = zaxisCreate(zaxisInqType(zaxisID1), nlev2);
   zaxisDefLevels(zaxisID2, lev2);
@@ -301,7 +297,7 @@ void *Intlevel(void *argument)
     if ( zaxisID1 == vlistZaxis(vlistID1, i) )
       vlistChangeZaxisIndex(vlistID2, i, zaxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
@@ -369,8 +365,8 @@ void *Intlevel(void *argument)
 	      missval  = vlistInqVarMissval(vlistID1, varID);
 	      gridsize = gridInqSize(gridID);
 
-	      interp_lev(gridsize, missval, vardata1[varID], vardata2[varID],
-			 nlev2, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
+	      vert_interp_lev(gridsize, missval, vardata1[varID], vardata2[varID],
+			      nlev2, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
 	      for ( levelID = 0; levelID < nlev2; levelID++ )
 		{
diff --git a/src/Intlevel3d.c b/src/Intlevel3d.c
index faf59db..c0c95ae 100644
--- a/src/Intlevel3d.c
+++ b/src/Intlevel3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,168 +29,12 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "list.h"
+#include "after_vertint.h"
 
-/*
- * 3d vertical interpolation routine (see interp_lev() in src/Intlevel.c)
- */
-static
-void interp_lev3d(int gridsize, double missval, double *vardata1, double *vardata2,
-	     	  int nlev2, int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
-{
-  int i, ilev;
-  int idx1, idx2;
-  double wgt1, wgt2;
-  double w1, w2;
-  double var1L1, var1L2, *var2;
-
-  for ( ilev = 0; ilev < nlev2; ilev++ )
-    {
-      var2 = vardata2+(ilev*gridsize);
-
-      for ( i = 0; i < gridsize; i++ )
-	{
-          idx1 = lev_idx1[ilev*gridsize+i];
-          idx2 = lev_idx2[ilev*gridsize+i];
-          wgt1 = lev_wgt1[ilev*gridsize+i];
-          wgt2 = lev_wgt2[ilev*gridsize+i];
-
-          /* upper/lower values from input field */
-          var1L1 = *(vardata1+idx1);
-          var1L2 = *(vardata1+idx2);
-
-          /* if (cdoVerbose) printf("i:%d level %d: idx1=%d idx2=%d (ilev*gridsize+i:%d) wgt1=%g wgt2=%g var1L1:%g var1L2:%g ",
-           *                         i,       ilev, idx1,   idx2,    ilev*gridsize+i,    wgt1,   wgt2,   var1L1,   var1L2);
-           */
-
-	  w1 = wgt1;
-	  w2 = wgt2;
-	  if ( DBL_IS_EQUAL(var1L1, missval)  ) w1 = 0;
-	  if ( DBL_IS_EQUAL(var1L2, missval)  ) w2 = 0;
-
-	  if ( IS_EQUAL(w1, 0) && IS_EQUAL(w2, 0) )
-	    {
-	      var2[i] = missval;
-	    }
-	  else if ( IS_EQUAL(w1, 0) )
-	    {
-	      if ( w2 >= 0.5 )
-		var2[i] = var1L2;
-	      else
-		var2[i] = missval;	      
-	    }
-	  else if ( IS_EQUAL(w2, 0) )
-	    {
-	      if ( w1 >= 0.5 )
-		var2[i] = var1L1;
-	      else
-		var2[i] = missval;	      
-	    }
-	  else
-	    {
-	      var2[i] = var1L1*w1 + var1L2*w2;
-	    }
-	}
-    }
-}
 
-/*
- * Create weights for the 3d vertical coordinate
- *
- * The resulting index sets lev_idx1 and lev_idx2 contain absolute numbers,i.e.
- * wrt. the given gridsize. They can directly be used to read values from 3d
- * data fields.
- *
- * 3d version of gen_weights() (src/Intlevel.c)
- */
-static
-void gen_weights3d(int expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
-                   int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
-{
-  int i,i1, i2;
-  double val1, val2 = 0;
-  int    idx1 = 0, idx2 = 0;
-
-  for ( i = 0; i < gridsize; i++ )
-    {
-      for ( i2 = 0; i2 < nlev2; i2++ )
-        {
-          /* Because 2 levels were added to the source vertical coordinate (one on
-           * top, one at the bottom), its loop starts at 1 */
-          for ( i1 = 1; i1 < nlev1; i1++ )
-            {
-              if ( lev1[(i1-1)*gridsize+i] < lev1[i1*gridsize+i] )
-                {
-                  idx1 = (i1 - 1)*gridsize+i;
-                  idx2 = i1*gridsize+i;
-                }
-              else
-                {
-                  idx1 = i1*gridsize+i;
-                  idx2 = (i1-1)*gridsize+i;
-                }
-              val1 = lev1[idx1];
-              val2 = lev1[idx2];
-
-              if ( lev2[i2*gridsize+i] > val1 && lev2[i2*gridsize+i] <= val2 ) break;
-            }
-
-          if ( i1 == nlev1 ) 
-            {
-              if ( expol )
-                cdoAbort("Level %g at index %d not found! Use extrapolation", lev2[i2*gridsize],i2);
-              else
-                cdoAbort("Level %g at index %d not found!");
-            }
-
-          if ( i1-1 == 0 ) /* destination levels ios not covert by the first two input z levels */
-            {
-              lev_idx1[i2*gridsize+i] = gridsize+i;
-              lev_idx2[i2*gridsize+i] = gridsize+i;
-              lev_wgt1[i2*gridsize+i] = 0;
-              if ( expol || IS_EQUAL(lev2[i2*gridsize+i], val2) )
-                lev_wgt2[i2*gridsize+i] = 1;
-              else
-                lev_wgt2[i2*gridsize+i] = 0;
-            }
-          else if ( i1 == nlev1-1 ) /* destination level is beyond the last value of the input z field */
-            {
-              lev_idx1[i2*gridsize+i] = (nlev1-2)*gridsize+i;
-              lev_idx2[i2*gridsize+i] = (nlev1-2)*gridsize+i;
-              if ( expol || IS_EQUAL(lev2[i2*gridsize+i], val2) )
-                lev_wgt1[i2*gridsize+i] = 1;
-              else
-                lev_wgt1[i2*gridsize+i] = 0;
-              lev_wgt2[i2*gridsize+i] = 0;
-            }
-          else /* target z values has two bounday values in input z field */
-            {
-              lev_idx1[i2*gridsize+i] = idx1;
-              lev_idx2[i2*gridsize+i] = idx2;
-              lev_wgt1[i2*gridsize+i] = (lev1[idx2]        - lev2[i2*gridsize+i]) / (lev1[idx2] - lev1[idx1]);
-              lev_wgt2[i2*gridsize+i] = (lev2[i2*gridsize+i] - lev1[idx1])        / (lev1[idx2] - lev1[idx1]);
-
-            }
-  /*         if (cdoVerbose)
-   *         {
-   *           printf("i:%d i2:%d\ti2*gridsize+i:%d\tlev2[i2*gridsize+i]:%g\tidx1:%d\tidx2:%d\tlev1[idx1]:%g\tlev1[idx2]:%g\t",
-   *                   i, i2, i2*gridsize+i,         lev2[i2*gridsize+i],    idx1,    idx2,    lev1[idx1],    lev1[idx2]);
-   *           printf("\tlev_wgt1:%g\tlev_wgt2:%g\n", lev_wgt1[i2*gridsize+i], lev_wgt2[i2*gridsize+i]);
-   *         }
-   */
-          /* backshift of the indices because if the two additional levels in input vertical coordinate */
-          lev_idx1[i2*gridsize+i] -= gridsize;
-          lev_idx2[i2*gridsize+i] -= gridsize;
-
-        }
-    }
-}
 
 void *Intlevel3d(void *argument)
 {
-  int INTLEVEL3D, INTLEVELX3D;
-  int operatorID;
-  int streamID0, streamID1, streamID2,streamID3;
-  int vlistID0, vlistID1, vlistID2, vlistID3;
   int gridsize,gridSize,gridsizei,gridsizeo;
   int recID, nrecs;
   int i, offset;
@@ -200,7 +44,7 @@ void *Intlevel3d(void *argument)
   int nmiss;
 
   int nlonIn, nlatIn, nlonOut, nlatOut;
-  double *lonIn, *latIn, *lonOut, *latOut;
+  //double *lonIn, *latIn, *lonOut, *latOut;
 
   int zaxisID1 = -1, zaxisID3;
   int gridID3 = -1, gridID, zaxisID;
@@ -223,10 +67,10 @@ void *Intlevel3d(void *argument)
 
   cdoInitialize(argument);
 
-  INTLEVEL3D  = cdoOperatorAdd("intlevel3d",  0, 0, NULL);
-  INTLEVELX3D = cdoOperatorAdd("intlevelx3d",  0, 0, NULL);
+  int INTLEVEL3D  = cdoOperatorAdd("intlevel3d",  0, 0, NULL);
+  int INTLEVELX3D = cdoOperatorAdd("intlevelx3d",  0, 0, NULL);
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   if      ( operatorID == INTLEVEL3D )  expol = FALSE;
   else if ( operatorID == INTLEVELX3D ) expol = TRUE;
@@ -237,16 +81,16 @@ void *Intlevel3d(void *argument)
   operatorInputArg("filename for vertical source coordinates variable");
   operatorCheckArgc(1);
   argument_t *fileargument = file_argument_new(operatorArgv()[0]);
-  streamID0 = streamOpenRead(fileargument);                     /*  3d vertical input coordinate */
+  int streamID0 = streamOpenRead(fileargument);                     /*  3d vertical input coordinate */
   file_argument_free(fileargument);
-  streamID1 = streamOpenRead(cdoStreamName(0));                 /*  input data */
-  streamID2 = streamOpenRead(cdoStreamName(1));                 /*  3d target vertical coordinate */
-  streamID3 = streamOpenWrite(cdoStreamName(2),cdoFiletype());  /*  output stream */
-
-  vlistID0 = streamInqVlist(streamID0);
-  vlistID1 = streamInqVlist(streamID1); taxisID1 = vlistInqTaxis(vlistID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = vlistDuplicate(vlistID1);  taxisID3 = taxisDuplicate(taxisID1);
+  int streamID1 = streamOpenRead(cdoStreamName(0));                 /*  input data */
+  int streamID2 = streamOpenRead(cdoStreamName(1));                 /*  3d target vertical coordinate */
+  int streamID3 = streamOpenWrite(cdoStreamName(2),cdoFiletype());  /*  output stream */
+
+  int vlistID0 = streamInqVlist(streamID0);
+  int vlistID1 = streamInqVlist(streamID1); taxisID1 = vlistInqTaxis(vlistID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = vlistDuplicate(vlistID1);  taxisID3 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID3, taxisID1);
 
   /*
@@ -264,11 +108,12 @@ void *Intlevel3d(void *argument)
 
     nlonIn  = gridInqXsize(gridID);
     nlatIn  = gridInqYsize(gridID);
+    /*
     lonIn   = (double*) malloc(nlonIn*sizeof(double));
     latIn   = (double*) malloc(nlatIn*sizeof(double));
     gridInqXvals(gridID, lonIn);
     gridInqYvals(gridID, latIn);
-
+    */
     zlevels_in = (double*) malloc(gridsize*(nlevel+2)*sizeof(double));
     nlevi      = nlevel;   /* number of input levels for later use */
     gridsizei  = gridsize; /* horizontal gridsize of input z coordinate */
@@ -299,11 +144,12 @@ void *Intlevel3d(void *argument)
 
     nlonOut = gridInqXsize(gridID);
     nlatOut = gridInqYsize(gridID);
+    /*
     lonOut  = (double*) malloc(nlonOut*sizeof(double));
     latOut  = (double*) malloc(nlatOut*sizeof(double));
     gridInqXvals(gridID, lonOut);
     gridInqYvals(gridID, latOut);
-
+    */
     zlevels_out = (double*) malloc(gridsize*nlevel*sizeof(double));
     nlevo       = nlevel;  /* number of output levels for later use */
     gridsizeo   = gridsize;/* horizontal gridsize of output z coordinate */
@@ -347,9 +193,9 @@ void *Intlevel3d(void *argument)
 
    /* input and output vertical coordinates must have exactly the same horizontal grid */
    if ( nlonIn != nlonOut || 
-        nlatIn != nlatOut ||
+        nlatIn != nlatOut /*||
         memcmp(lonIn,lonOut,nlonIn*sizeof(double)) ||
-        memcmp(latIn,latOut,nlatIn*sizeof(double)) )
+        memcmp(latIn,latOut,nlatIn*sizeof(double))*/ )
      {
        /* i =0; printf ( "lonIn:%g latIn:%g lonOut:%g latOut:%g\n",lonIn[i],latIn[i],lonOut[i],latOut[i] ); */
        cdoAbort("Input and output vertical coordinates do NOT exactly have the same horizontal grid.");
@@ -429,7 +275,7 @@ void *Intlevel3d(void *argument)
   lev_wgt1 = (double*) malloc(nlevo*gridSize*sizeof(double));
   lev_wgt2 = (double*) malloc(nlevo*gridSize*sizeof(double));
 
-  gen_weights3d(expol, nlevi+2, gridSize, zlevels_in, nlevo, zlevels_out, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
+  vert_gen_weights3d(expol, nlevi+2, gridSize, zlevels_in, nlevo, zlevels_out, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
   /*
    * Copy z-axis information to output z-axis
@@ -497,15 +343,16 @@ void *Intlevel3d(void *argument)
         {
           nlonIn  = gridInqXsize(gridID);
           nlatIn  = gridInqYsize(gridID);
+	  /*
           lonIn   = (double*) malloc(nlonIn*sizeof(double));
           latIn   = (double*) malloc(nlatIn*sizeof(double));
           gridInqXvals(gridID, lonIn);
           gridInqYvals(gridID, latIn);
-
+	  */
           if ( nlonIn != nlonOut || 
-               nlatIn != nlatOut ||
+               nlatIn != nlatOut /*||
                memcmp(lonIn,lonOut,nlonIn*sizeof(double)) ||
-               memcmp(latIn,latOut,nlatIn*sizeof(double)) )
+               memcmp(latIn,latOut,nlatIn*sizeof(double))*/ )
             {
               varinterp[varID] = FALSE;
               vardata2[varID]  = vardata1[varID];
@@ -562,8 +409,8 @@ void *Intlevel3d(void *argument)
 	      missval  = vlistInqVarMissval(vlistID1, varID);
 	      gridsize = gridInqSize(gridID);
 
-	      interp_lev3d(gridsize, missval, vardata1[varID], vardata2[varID],
-			 nlevo, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
+	      vert_interp_lev3d(gridsize, missval, vardata1[varID], vardata2[varID],
+				nlevo, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
 	      for ( levelID = 0; levelID < nlevo; levelID++ )
 		{
diff --git a/src/Intntime.c b/src/Intntime.c
index 8e211df..ee5efab 100644
--- a/src/Intntime.c
+++ b/src/Intntime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -57,7 +57,7 @@ void *Intntime(void *argument)
   operatorInputArg("number of timesteps between 2 timesteps");
   if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
 
-  numts = atoi(operatorArgv()[0]);
+  numts = parameter2int(operatorArgv()[0]);
   if ( numts < 2 ) cdoAbort("parameter must be greater than 1!");
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Inttime.c b/src/Inttime.c
index 5497a6c..a341d25 100644
--- a/src/Inttime.c
+++ b/src/Inttime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Intyear.c b/src/Intyear.c
index 4ab00b6..f2c2601 100644
--- a/src/Intyear.c
+++ b/src/Intyear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Invert.c b/src/Invert.c
index 61ab9fe..9744af2 100644
--- a/src/Invert.c
+++ b/src/Invert.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -314,42 +314,31 @@ void invertLatData(double *array1, double *array2, int gridID1)
 
 void *Invert(void *argument)
 {
-  int INVERTLAT, INVERTLON, INVERTLATDES, INVERTLONDES, INVERTLATDATA, INVERTLONDATA;
-  int operatorID;
-  int operfunc1, operfunc2;
-  int streamID1, streamID2;
   int nrecs;
-  int tsID, recID, varID, levelID;
-  int gridsize;
-  int vlistID1, vlistID2;
+  int recID, varID, levelID;
   int gridID1;
   int nmiss;
-  double *array1, *array2;
-  int taxisID1, taxisID2;
 
   cdoInitialize(argument);
 
-  INVERTLAT     = cdoOperatorAdd("invertlat",     func_all, 0, NULL);
-  INVERTLON     = cdoOperatorAdd("invertlon",     func_all, 0, NULL);
-  INVERTLATDES  = cdoOperatorAdd("invertlatdes",  func_hrd, 0, NULL);
-  INVERTLONDES  = cdoOperatorAdd("invertlondes",  func_hrd, 0, NULL);
-  INVERTLATDATA = cdoOperatorAdd("invertlatdata", func_fld, 0, NULL);
-  INVERTLONDATA = cdoOperatorAdd("invertlondata", func_fld, 0, NULL);
-
-  operatorID = cdoOperatorID();
-  operfunc1 = cdoOperatorF1(operatorID);
-  if ( operatorID == INVERTLAT || operatorID == INVERTLATDES || operatorID == INVERTLATDATA )
-    operfunc2 = func_lat;
-  else
-    operfunc2 = func_lon;
+  cdoOperatorAdd("invertlat",     func_all, func_lat, NULL);
+  cdoOperatorAdd("invertlon",     func_all, func_lon, NULL);
+  cdoOperatorAdd("invertlatdes",  func_hrd, func_lat, NULL);
+  cdoOperatorAdd("invertlondes",  func_hrd, func_lon, NULL);
+  cdoOperatorAdd("invertlatdata", func_fld, func_lat, NULL);
+  cdoOperatorAdd("invertlondata", func_fld, func_lon, NULL);
+
+  int operatorID = cdoOperatorID();
+  int operfunc1 = cdoOperatorF1(operatorID);
+  int operfunc2 = cdoOperatorF2(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   if ( operfunc1 == func_all || operfunc1 == func_hrd )
@@ -360,16 +349,16 @@ void *Invert(void *argument)
 	invertLonDes(vlistID2);
     }
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double*) malloc(gridsize*sizeof(double));
-  array2 = (double*) malloc(gridsize*sizeof(double));
+  double *array1 = (double*) malloc(gridsize*sizeof(double));
+  double *array2 = (double*) malloc(gridsize*sizeof(double));
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Invertlev.c b/src/Invertlev.c
index 7418a6e..03ba316 100644
--- a/src/Invertlev.c
+++ b/src/Invertlev.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -90,59 +90,46 @@ void invertLevDes(int vlistID)
 
 void *Invertlev(void *argument)
 {
-  int INVERTLEV;
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2;
-  int nrecs, nvars;
-  int tsID, recID, varID, levelID;
-  int gridsize;
-  int vlistID1, vlistID2;
+  int nrecs;
+  int recID, varID, levelID;
   int nmiss;
-  int **varnmiss;
-  double *array;
-  double **vardata;
-  int taxisID1, taxisID2;
-  int lcopy = FALSE;
   int nlev, nlevel;
   int gridID, zaxisID, zaxistype, offset;
+  int lcopy = FALSE;
   int linvert = FALSE;
 
   cdoInitialize(argument);
 
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
-  INVERTLEV     = cdoOperatorAdd("invertlev",     func_all, 0, NULL);
+  cdoOperatorAdd("invertlev",     func_all, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  if ( operfunc == func_all || operfunc == func_hrd )
-    {
-      invertLevDes(vlistID2);
-    }
+  if ( operfunc == func_all || operfunc == func_hrd ) invertLevDes(vlistID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double*) malloc(gridsize*sizeof(double));
+  double *array = (double*) malloc(gridsize*sizeof(double));
 
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
 
-  vardata  = (double**) malloc(nvars*sizeof(double*));
-  varnmiss = (int**) malloc(nvars*sizeof(int*));
+  double **vardata  = (double**) malloc(nvars*sizeof(double*));
+  int **varnmiss = (int**) malloc(nvars*sizeof(int*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -167,7 +154,7 @@ void *Invertlev(void *argument)
 
   if ( linvert == FALSE ) cdoWarning("No variables with invertable levels found!");
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Isosurface.c b/src/Isosurface.c
index 2b1f201..18ea01a 100644
--- a/src/Isosurface.c
+++ b/src/Isosurface.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -105,7 +105,7 @@ void *Isosurface(void *argument)
 
   operatorCheckArgc(1);
 
-  isoval = atof(operatorArgv()[0]);
+  isoval = parameter2double(operatorArgv()[0]);
 
   if ( cdoVerbose ) cdoPrint("Isoval: %g\n", isoval);
 
diff --git a/src/Kvl.c b/src/Kvl.c
index 113ec86..f8c3845 100644
--- a/src/Kvl.c
+++ b/src/Kvl.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Log.c b/src/Log.c
index 911542f..e2e7a81 100644
--- a/src/Log.c
+++ b/src/Log.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -26,8 +26,7 @@ void dumplogo(const char *logfilename, int dumptype);
 
 void *Log(void *argument)
 {
-  int DUMPLOGS, DAYLOGS, MONLOGS, DUMPLOGO;
-  int SNAMELOGO, SCALLLOGO, SMEMLOGO, STIMELOGO, SPERCLOGO;
+  int DUMPLOGS, DAYLOGS, MONLOGS;
   int operatorID, operfunc;
   int dumptype;
 
@@ -36,12 +35,12 @@ void *Log(void *argument)
   DUMPLOGS  = cdoOperatorAdd("dumplogs",   0, 0, NULL);
   DAYLOGS   = cdoOperatorAdd("daylogs",    0, 0, NULL);
   MONLOGS   = cdoOperatorAdd("monlogs",    0, 0, NULL);
-  DUMPLOGO  = cdoOperatorAdd("dumplogo",   1, 0, NULL);
-  SNAMELOGO = cdoOperatorAdd("snamelogo",  1, 1, NULL);
-  SCALLLOGO = cdoOperatorAdd("scalllogo",  1, 2, NULL);
-  SMEMLOGO  = cdoOperatorAdd("smemlogo",   1, 3, NULL);
-  STIMELOGO = cdoOperatorAdd("stimelogo",  1, 4, NULL);
-  SPERCLOGO = cdoOperatorAdd("sperclogo",  1, 5, NULL);
+              cdoOperatorAdd("dumplogo",   1, 0, NULL);
+              cdoOperatorAdd("snamelogo",  1, 1, NULL);
+              cdoOperatorAdd("scalllogo",  1, 2, NULL);
+              cdoOperatorAdd("smemlogo",   1, 3, NULL);
+              cdoOperatorAdd("stimelogo",  1, 4, NULL);
+              cdoOperatorAdd("sperclogo",  1, 5, NULL);
 
   operatorID = cdoOperatorID();
   operfunc   = cdoOperatorF1(operatorID);
diff --git a/src/Makefile.am b/src/Makefile.am
index c07c403..14d521e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,160 @@
 ## Process this file with automake to produce Makefile.in
+noinst_LTLIBRARIES = libcdo.la
+libcdo_la_SOURCES =            \
+               cdo_int.h       \
+               compare.h       \
+               cdo_pthread.c   \
+               cdo_vlist.c     \
+               cdo_getopt.c    \
+               cdo_getopt.h    \
+               cdo_history.c   \
+               after_sptrans.c \
+               after_fctrans.c \
+               after_dvtrans.c \
+               after_vertint.c \
+               after_vertint.h \
+               after_namelist.c\
+               afterburnerlib.c\
+               afterburner.h   \
+               vct_l191.h      \
+               constants.h     \
+               constants.c     \
+               color.c         \
+               color.h         \
+               commandline.c   \
+               const.h         \
+               counter.h       \
+               datetime.c      \
+               datetime.h      \
+               dmemory.h       \
+               dtypes.h        \
+               ecacore.c       \
+               ecacore.h       \
+               ecautil.c       \
+               ecautil.h       \
+               error.h         \
+               etopo.h         \
+               temp.h          \
+               mask.h          \
+               exception.c     \
+               expr.c          \
+               expr.h          \
+               expr_lex.c      \
+               expr_yacc.c     \
+               expr_yacc.h     \
+               features.c      \
+               field.c         \
+               field.h         \
+               field2.c        \
+               fieldc.c        \
+               fieldmem.c      \
+               fieldmer.c      \
+               fieldzon.c      \
+               functs.h        \
+               gradsdeslib.c   \
+               gradsdeslib.h   \
+               grid.c          \
+               grid.h          \
+               grid_area.c     \
+               grid_gme.c      \
+               grid_lcc.c      \
+               grid_rot.c      \
+               gridreference.c \
+               griddes.c       \
+               griddes.h       \
+               griddes_h5.c    \
+               griddes_nc.c    \
+               hetaeta.c       \
+               hetaeta.h       \
+               institution.c   \
+               interpol.c      \
+               interpol.h      \
+               job.c           \
+               juldate.c       \
+               kvlist.c        \
+               kvlist.h        \
+               list.c          \
+               list.h          \
+	       merge_sort2.c   \
+	       merge_sort2.h   \
+               modules.c       \
+               modules.h       \
+               namelist.c      \
+               namelist.h      \
+               normal.c        \
+               nth_element.c   \
+               nth_element.h   \
+               operator_help.h \
+               par_io.c        \
+               par_io.h        \
+               percentiles.c   \
+               percentiles.h   \
+               pipe.c          \
+               pipe.h          \
+               pragma_omp_atomic_update.h \
+               printinfo.h     \
+               process.c       \
+               process.h       \
+               pstream.c       \
+               pstream.h       \
+               pstream_write.h \
+               pstream_int.h   \
+               pthread_debug.c \
+               pthread_debug.h \
+               readline.c      \
+               realtime.c      \
+               remap.h         \
+               remaplib.c      \
+               remapsort.c     \
+               remap_scrip_io.c \
+               remap_search_reg2d.c \
+               remap_search_latbins.c \
+               remap_store_link.c \
+               remap_store_link.h \
+               remap_store_link_cnsrv.c \
+               remap_store_link_cnsrv.h \
+               remap_conserv.c \
+               remap_conserv_scrip.c \
+               remap_distwgt_scrip.c \
+               remap_bicubic_scrip.c \
+               remap_bilinear_scrip.c \
+               stdnametable.c  \
+               stdnametable.h  \
+               specspace.c     \
+               specspace.h     \
+               statistic.c     \
+               statistic.h     \
+               table.c         \
+               text.c          \
+               text.h          \
+               timebase.h      \
+               timer.c         \
+               userlog.c       \
+               util.c          \
+               util.h          \
+               zaxis.c
+libcdo_la_SOURCES +=           \
+               clipping/clipping.c           \
+               clipping/clipping.h           \
+               clipping/area.c               \
+               clipping/area.h               \
+               clipping/ensure_array_size.c  \
+               clipping/ensure_array_size.h  \
+               clipping/geometry.h           \
+               clipping/grid.h               \
+               clipping/points.h             \
+               clipping/dep_list.h           \
+               clipping/grid_cell.c          \
+               clipping/grid_cell.h          \
+               clipping/intersection.c       \
+               clipping/utils.c              \
+               clipping/utils.h 
 #
 bin_PROGRAMS = cdo
 #
 cdo_SOURCES  = cdo.c
 cdo_SOURCES += Adisit.c        \
+               Afterburner.c   \
                Arith.c         \
                Arithc.c        \
                Arithdays.c     \
@@ -158,7 +309,8 @@ cdo_SOURCES += Adisit.c        \
                Vardup.c        \
                Vargen.c        \
                Varrms.c        \
-               Vertint.c       \
+               Vertintml.c     \
+               Vertintap.c     \
                Vertstat.c      \
                Vertwind.c      \
                Wct.c           \
@@ -180,143 +332,8 @@ cdo_SOURCES += Adisit.c        \
                Yseaspctl.c     \
                Yseasstat.c     \
                Zonstat.c       \
-               cdo.h           \
-               cdo_int.h       \
-               cdo_pthread.c   \
-               cdo_vlist.c     \
-               cdo_getopt.c    \
-               cdo_getopt.h    \
-               color.c         \
-               color.h         \
-               commandline.c   \
-               const.h         \
-               counter.h       \
-               dmemory.h       \
-               dtypes.h        \
-               ecacore.c       \
-               ecacore.h       \
-               ecautil.c       \
-               ecautil.h       \
-               error.h         \
-               etopo.h         \
-               temp.h          \
-               mask.h          \
-               exception.c     \
-               expr.c          \
-               expr.h          \
-               expr_lex.c      \
-               expr_yacc.c     \
-               expr_yacc.h     \
-               features.c      \
-               field.c         \
-               field.h         \
-               field2.c        \
-               fieldc.c        \
-               fieldmem.c      \
-               fieldmer.c      \
-               fieldzon.c      \
-               fouriertrans.c  \
-               functs.h        \
-               gradsdeslib.c   \
-               gradsdeslib.h   \
-               grid.c          \
-               grid.h          \
-               grid_area.c     \
-               grid_gme.c      \
-               grid_lcc.c      \
-               grid_rot.c      \
-               gridreference.c \
-               griddes.c       \
-               griddes.h       \
-               griddes_h5.c    \
-               griddes_nc.c    \
-               hetaeta.c       \
-               hetaeta.h       \
-               history.c       \
-               institution.c   \
-               interpol.c      \
-               interpol.h      \
-               job.c           \
-               juldate.c       \
-               kvlist.c        \
-               kvlist.h        \
-               legendre.c      \
-               list.c          \
-               list.h          \
-	       merge_sort2.c   \
-	       merge_sort2.h   \
-               modules.c       \
-               modules.h       \
-               namelist.c      \
-               namelist.h      \
-               normal.c        \
-               nth_element.c   \
-               nth_element.h   \
-               operator_help.h \
-               par_io.c        \
-               par_io.h        \
-               percentiles.c   \
-               percentiles.h   \
-               pipe.c          \
-               pipe.h          \
-               pragma_omp_atomic_update.h \
-               printinfo.h     \
-               process.c       \
-               process.h       \
-               pstream.c       \
-               pstream.h       \
-               pstream_int.h   \
-               pthread_debug.c \
-               pthread_debug.h \
-               readline.c      \
-               realtime.c      \
-               remap.h         \
-               remaplib.c      \
-               remapsort.c     \
-               remap_scrip_io.c \
-               remap_search_reg2d.c \
-               remap_search_latbins.c \
-               remap_store_link.c \
-               remap_store_link.h \
-               remap_conserv.c \
-               remap_conserv_scrip.c \
-               remap_distwgt_scrip.c \
-               remap_bicubic_scrip.c \
-               remap_bilinear_scrip.c \
-               stdnametable.c  \
-               stdnametable.h  \
-               specspace.c     \
-               specspace.h     \
-               statistic.c     \
-               statistic.h     \
-               table.c         \
-               text.c          \
-               text.h          \
-               timebase.h      \
-               timer.c         \
-               userlog.c       \
-               util.c          \
-               util.h          \
-               vinterp.c       \
-               vinterp.h       \
-               zaxis.c
+               cdo.h
 
-cdo_SOURCES += clipping/clipping.c           \
-               clipping/clipping.h           \
-               clipping/area.c               \
-               clipping/area.h               \
-               clipping/ensure_array_size.c  \
-               clipping/ensure_array_size.h  \
-               clipping/geometry_tools.c     \
-               clipping/geometry.h           \
-               clipping/grid.h               \
-               clipping/points.h             \
-               clipping/dep_list.h           \
-               clipping/grid_cell.c          \
-               clipping/grid_cell.h          \
-               clipping/intersection.c       \
-               clipping/utils.c              \
-               clipping/utils.h 
 
 if ENABLE_MAGICS
 cdo_SOURCES += Magplot.c       \
@@ -335,13 +352,14 @@ cdo_SOURCES += Magplot.c       \
 endif
 
 cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
-cdo_LDADD    = $(top_builddir)/libcdi/src/libcdi.la
+cdo_LDADD    = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
 cdo_LDFLAGS  =
 
 if ENABLE_ALL_STATIC
 cdo_LDFLAGS  += -all-static
 endif
 
+libcdo_la_CPPFLAGS = $(cdo_CPPFLAGS)
 noinst_PROGRAMS  = cdotest
 cdotest_SOURCES  = cdo_int.h	\
 	           cdotest.c
diff --git a/src/Makefile.in b/src/Makefile.in
index 76f099b..49af461 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -14,6 +14,7 @@
 
 @SET_MAKE@
 
+
 VPATH = @srcdir@
 am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
@@ -112,19 +113,69 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libcdo_la_LIBADD =
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libcdo_la_OBJECTS = libcdo_la-cdo_pthread.lo libcdo_la-cdo_vlist.lo \
+	libcdo_la-cdo_getopt.lo libcdo_la-cdo_history.lo \
+	libcdo_la-after_sptrans.lo libcdo_la-after_fctrans.lo \
+	libcdo_la-after_dvtrans.lo libcdo_la-after_vertint.lo \
+	libcdo_la-after_namelist.lo libcdo_la-afterburnerlib.lo \
+	libcdo_la-constants.lo libcdo_la-color.lo \
+	libcdo_la-commandline.lo libcdo_la-datetime.lo \
+	libcdo_la-ecacore.lo libcdo_la-ecautil.lo \
+	libcdo_la-exception.lo libcdo_la-expr.lo libcdo_la-expr_lex.lo \
+	libcdo_la-expr_yacc.lo libcdo_la-features.lo \
+	libcdo_la-field.lo libcdo_la-field2.lo libcdo_la-fieldc.lo \
+	libcdo_la-fieldmem.lo libcdo_la-fieldmer.lo \
+	libcdo_la-fieldzon.lo libcdo_la-gradsdeslib.lo \
+	libcdo_la-grid.lo libcdo_la-grid_area.lo libcdo_la-grid_gme.lo \
+	libcdo_la-grid_lcc.lo libcdo_la-grid_rot.lo \
+	libcdo_la-gridreference.lo libcdo_la-griddes.lo \
+	libcdo_la-griddes_h5.lo libcdo_la-griddes_nc.lo \
+	libcdo_la-hetaeta.lo libcdo_la-institution.lo \
+	libcdo_la-interpol.lo libcdo_la-job.lo libcdo_la-juldate.lo \
+	libcdo_la-kvlist.lo libcdo_la-list.lo libcdo_la-merge_sort2.lo \
+	libcdo_la-modules.lo libcdo_la-namelist.lo libcdo_la-normal.lo \
+	libcdo_la-nth_element.lo libcdo_la-par_io.lo \
+	libcdo_la-percentiles.lo libcdo_la-pipe.lo \
+	libcdo_la-process.lo libcdo_la-pstream.lo \
+	libcdo_la-pthread_debug.lo libcdo_la-readline.lo \
+	libcdo_la-realtime.lo libcdo_la-remaplib.lo \
+	libcdo_la-remapsort.lo libcdo_la-remap_scrip_io.lo \
+	libcdo_la-remap_search_reg2d.lo \
+	libcdo_la-remap_search_latbins.lo \
+	libcdo_la-remap_store_link.lo \
+	libcdo_la-remap_store_link_cnsrv.lo libcdo_la-remap_conserv.lo \
+	libcdo_la-remap_conserv_scrip.lo \
+	libcdo_la-remap_distwgt_scrip.lo \
+	libcdo_la-remap_bicubic_scrip.lo \
+	libcdo_la-remap_bilinear_scrip.lo libcdo_la-stdnametable.lo \
+	libcdo_la-specspace.lo libcdo_la-statistic.lo \
+	libcdo_la-table.lo libcdo_la-text.lo libcdo_la-timer.lo \
+	libcdo_la-userlog.lo libcdo_la-util.lo libcdo_la-zaxis.lo \
+	clipping/libcdo_la-clipping.lo clipping/libcdo_la-area.lo \
+	clipping/libcdo_la-ensure_array_size.lo \
+	clipping/libcdo_la-grid_cell.lo \
+	clipping/libcdo_la-intersection.lo clipping/libcdo_la-utils.lo
+libcdo_la_OBJECTS = $(am_libcdo_la_OBJECTS)
+AM_V_lt = $(am__v_lt_ at AM_V@)
+am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
-am__cdo_SOURCES_DIST = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c \
-	Arithlat.c CDItest.c CDIread.c CDIwrite.c Cat.c Change.c \
-	Change_e5slm.c Cloudlayer.c Collgrid.c Command.c Comp.c \
-	Compc.c Complextorect.c Cond.c Cond2.c Condc.c Consecstat.c \
-	Copy.c Deltime.c Derivepar.c Detrend.c Diff.c Distgrid.c \
-	Duplicate.c EOFs.c Eof3d.c EcaIndices.c Echam5ini.c Enlarge.c \
-	Enlargegrid.c Ensstat.c Ensstat3.c Ensval.c Eofcoeff.c \
-	Eofcoeff3d.c Exprf.c FC.c Filedes.c Fillmiss.c Filter.c \
-	Fldrms.c Fldstat.c Fldstat2.c Fourier.c Gengrid.c Gradsdes.c \
-	Gridboxstat.c Gridcell.c Gridsearch.c Harmonic.c Hi.c \
-	Histogram.c Importamsr.c Importbinary.c Importcmsaf.c \
+am__cdo_SOURCES_DIST = cdo.c Adisit.c Afterburner.c Arith.c Arithc.c \
+	Arithdays.c Arithlat.c CDItest.c CDIread.c CDIwrite.c Cat.c \
+	Change.c Change_e5slm.c Cloudlayer.c Collgrid.c Command.c \
+	Comp.c Compc.c Complextorect.c Cond.c Cond2.c Condc.c \
+	Consecstat.c Copy.c Deltime.c Derivepar.c Detrend.c Diff.c \
+	Distgrid.c Duplicate.c EOFs.c Eof3d.c EcaIndices.c Echam5ini.c \
+	Enlarge.c Enlargegrid.c Ensstat.c Ensstat3.c Ensval.c \
+	Eofcoeff.c Eofcoeff3d.c Exprf.c FC.c Filedes.c Fillmiss.c \
+	Filter.c Fldrms.c Fldstat.c Fldstat2.c Fourier.c Gengrid.c \
+	Gradsdes.c Gridboxstat.c Gridcell.c Gridsearch.c Harmonic.c \
+	Hi.c Histogram.c Importamsr.c Importbinary.c Importcmsaf.c \
 	Importobs.c Info.c Input.c Intgrid.c Intgridtraj.c Intlevel.c \
 	Intlevel3d.c Intntime.c Inttime.c Intyear.c Invert.c \
 	Invertlev.c Isosurface.c Kvl.c Log.c Maskbox.c Mastrfu.c \
@@ -141,46 +192,16 @@ am__cdo_SOURCES_DIST = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c \
 	Subtrend.c Tee.c Templates.c Test.c Tests.c Timcount.c \
 	Timpctl.c Timselpctl.c Timselstat.c Timsort.c Timstat.c \
 	Timstat2.c Timstat3.c Tinfo.c Tocomplex.c Transpose.c Trend.c \
-	Trms.c Tstepcount.c Vardup.c Vargen.c Varrms.c Vertint.c \
-	Vertstat.c Vertwind.c Wct.c Wind.c Writegrid.c Writerandom.c \
-	YAR.c Yearmonstat.c Ydayarith.c Ydaypctl.c Ydaystat.c \
-	Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c Ymonarith.c \
-	Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c Zonstat.c cdo.h \
-	cdo_int.h cdo_pthread.c cdo_vlist.c cdo_getopt.c cdo_getopt.h \
-	color.c color.h commandline.c const.h counter.h dmemory.h \
-	dtypes.h ecacore.c ecacore.h ecautil.c ecautil.h error.h \
-	etopo.h temp.h mask.h exception.c expr.c expr.h expr_lex.c \
-	expr_yacc.c expr_yacc.h features.c field.c field.h field2.c \
-	fieldc.c fieldmem.c fieldmer.c fieldzon.c fouriertrans.c \
-	functs.h gradsdeslib.c gradsdeslib.h grid.c grid.h grid_area.c \
-	grid_gme.c grid_lcc.c grid_rot.c gridreference.c griddes.c \
-	griddes.h griddes_h5.c griddes_nc.c hetaeta.c hetaeta.h \
-	history.c institution.c interpol.c interpol.h job.c juldate.c \
-	kvlist.c kvlist.h legendre.c list.c list.h merge_sort2.c \
-	merge_sort2.h modules.c modules.h namelist.c namelist.h \
-	normal.c nth_element.c nth_element.h operator_help.h par_io.c \
-	par_io.h percentiles.c percentiles.h pipe.c pipe.h \
-	pragma_omp_atomic_update.h printinfo.h process.c process.h \
-	pstream.c pstream.h pstream_int.h pthread_debug.c \
-	pthread_debug.h readline.c realtime.c remap.h remaplib.c \
-	remapsort.c remap_scrip_io.c remap_search_reg2d.c \
-	remap_search_latbins.c remap_store_link.c remap_store_link.h \
-	remap_conserv.c remap_conserv_scrip.c remap_distwgt_scrip.c \
-	remap_bicubic_scrip.c remap_bilinear_scrip.c stdnametable.c \
-	stdnametable.h specspace.c specspace.h statistic.c statistic.h \
-	table.c text.c text.h timebase.h timer.c userlog.c util.c \
-	util.h vinterp.c vinterp.h zaxis.c clipping/clipping.c \
-	clipping/clipping.h clipping/area.c clipping/area.h \
-	clipping/ensure_array_size.c clipping/ensure_array_size.h \
-	clipping/geometry_tools.c clipping/geometry.h clipping/grid.h \
-	clipping/points.h clipping/dep_list.h clipping/grid_cell.c \
-	clipping/grid_cell.h clipping/intersection.c clipping/utils.c \
-	clipping/utils.h Magplot.c Magvector.c Maggraph.c \
+	Trms.c Tstepcount.c Vardup.c Vargen.c Varrms.c Vertintml.c \
+	Vertintap.c Vertstat.c Vertwind.c Wct.c Wind.c Writegrid.c \
+	Writerandom.c YAR.c Yearmonstat.c Ydayarith.c Ydaypctl.c \
+	Ydaystat.c Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c \
+	Ymonarith.c Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c \
+	Zonstat.c cdo.h Magplot.c Magvector.c Maggraph.c \
 	template_parser.h template_parser.c results_template_parser.h \
 	results_template_parser.c magics_template_parser.h \
 	magics_template_parser.c StringUtilities.h StringUtilities.c \
 	CdoMagicsMapper.h CdoMagicsMapper.c
-am__dirstamp = $(am__leading_dot)dirstamp
 @ENABLE_MAGICS_TRUE at am__objects_1 = cdo-Magplot.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-Magvector.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-Maggraph.$(OBJEXT) \
@@ -190,13 +211,13 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @ENABLE_MAGICS_TRUE@	cdo-StringUtilities.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-CdoMagicsMapper.$(OBJEXT)
 am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
-	cdo-Arith.$(OBJEXT) cdo-Arithc.$(OBJEXT) \
-	cdo-Arithdays.$(OBJEXT) cdo-Arithlat.$(OBJEXT) \
-	cdo-CDItest.$(OBJEXT) cdo-CDIread.$(OBJEXT) \
-	cdo-CDIwrite.$(OBJEXT) cdo-Cat.$(OBJEXT) cdo-Change.$(OBJEXT) \
-	cdo-Change_e5slm.$(OBJEXT) cdo-Cloudlayer.$(OBJEXT) \
-	cdo-Collgrid.$(OBJEXT) cdo-Command.$(OBJEXT) \
-	cdo-Comp.$(OBJEXT) cdo-Compc.$(OBJEXT) \
+	cdo-Afterburner.$(OBJEXT) cdo-Arith.$(OBJEXT) \
+	cdo-Arithc.$(OBJEXT) cdo-Arithdays.$(OBJEXT) \
+	cdo-Arithlat.$(OBJEXT) cdo-CDItest.$(OBJEXT) \
+	cdo-CDIread.$(OBJEXT) cdo-CDIwrite.$(OBJEXT) cdo-Cat.$(OBJEXT) \
+	cdo-Change.$(OBJEXT) cdo-Change_e5slm.$(OBJEXT) \
+	cdo-Cloudlayer.$(OBJEXT) cdo-Collgrid.$(OBJEXT) \
+	cdo-Command.$(OBJEXT) cdo-Comp.$(OBJEXT) cdo-Compc.$(OBJEXT) \
 	cdo-Complextorect.$(OBJEXT) cdo-Cond.$(OBJEXT) \
 	cdo-Cond2.$(OBJEXT) cdo-Condc.$(OBJEXT) \
 	cdo-Consecstat.$(OBJEXT) cdo-Copy.$(OBJEXT) \
@@ -261,66 +282,19 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
 	cdo-Transpose.$(OBJEXT) cdo-Trend.$(OBJEXT) cdo-Trms.$(OBJEXT) \
 	cdo-Tstepcount.$(OBJEXT) cdo-Vardup.$(OBJEXT) \
 	cdo-Vargen.$(OBJEXT) cdo-Varrms.$(OBJEXT) \
-	cdo-Vertint.$(OBJEXT) cdo-Vertstat.$(OBJEXT) \
-	cdo-Vertwind.$(OBJEXT) cdo-Wct.$(OBJEXT) cdo-Wind.$(OBJEXT) \
-	cdo-Writegrid.$(OBJEXT) cdo-Writerandom.$(OBJEXT) \
-	cdo-YAR.$(OBJEXT) cdo-Yearmonstat.$(OBJEXT) \
-	cdo-Ydayarith.$(OBJEXT) cdo-Ydaypctl.$(OBJEXT) \
-	cdo-Ydaystat.$(OBJEXT) cdo-Ydrunpctl.$(OBJEXT) \
-	cdo-Ydrunstat.$(OBJEXT) cdo-Yhourarith.$(OBJEXT) \
-	cdo-Yhourstat.$(OBJEXT) cdo-Ymonarith.$(OBJEXT) \
-	cdo-Ymonpctl.$(OBJEXT) cdo-Ymonstat.$(OBJEXT) \
-	cdo-Yseaspctl.$(OBJEXT) cdo-Yseasstat.$(OBJEXT) \
-	cdo-Zonstat.$(OBJEXT) cdo-cdo_pthread.$(OBJEXT) \
-	cdo-cdo_vlist.$(OBJEXT) cdo-cdo_getopt.$(OBJEXT) \
-	cdo-color.$(OBJEXT) cdo-commandline.$(OBJEXT) \
-	cdo-ecacore.$(OBJEXT) cdo-ecautil.$(OBJEXT) \
-	cdo-exception.$(OBJEXT) cdo-expr.$(OBJEXT) \
-	cdo-expr_lex.$(OBJEXT) cdo-expr_yacc.$(OBJEXT) \
-	cdo-features.$(OBJEXT) cdo-field.$(OBJEXT) \
-	cdo-field2.$(OBJEXT) cdo-fieldc.$(OBJEXT) \
-	cdo-fieldmem.$(OBJEXT) cdo-fieldmer.$(OBJEXT) \
-	cdo-fieldzon.$(OBJEXT) cdo-fouriertrans.$(OBJEXT) \
-	cdo-gradsdeslib.$(OBJEXT) cdo-grid.$(OBJEXT) \
-	cdo-grid_area.$(OBJEXT) cdo-grid_gme.$(OBJEXT) \
-	cdo-grid_lcc.$(OBJEXT) cdo-grid_rot.$(OBJEXT) \
-	cdo-gridreference.$(OBJEXT) cdo-griddes.$(OBJEXT) \
-	cdo-griddes_h5.$(OBJEXT) cdo-griddes_nc.$(OBJEXT) \
-	cdo-hetaeta.$(OBJEXT) cdo-history.$(OBJEXT) \
-	cdo-institution.$(OBJEXT) cdo-interpol.$(OBJEXT) \
-	cdo-job.$(OBJEXT) cdo-juldate.$(OBJEXT) cdo-kvlist.$(OBJEXT) \
-	cdo-legendre.$(OBJEXT) cdo-list.$(OBJEXT) \
-	cdo-merge_sort2.$(OBJEXT) cdo-modules.$(OBJEXT) \
-	cdo-namelist.$(OBJEXT) cdo-normal.$(OBJEXT) \
-	cdo-nth_element.$(OBJEXT) cdo-par_io.$(OBJEXT) \
-	cdo-percentiles.$(OBJEXT) cdo-pipe.$(OBJEXT) \
-	cdo-process.$(OBJEXT) cdo-pstream.$(OBJEXT) \
-	cdo-pthread_debug.$(OBJEXT) cdo-readline.$(OBJEXT) \
-	cdo-realtime.$(OBJEXT) cdo-remaplib.$(OBJEXT) \
-	cdo-remapsort.$(OBJEXT) cdo-remap_scrip_io.$(OBJEXT) \
-	cdo-remap_search_reg2d.$(OBJEXT) \
-	cdo-remap_search_latbins.$(OBJEXT) \
-	cdo-remap_store_link.$(OBJEXT) cdo-remap_conserv.$(OBJEXT) \
-	cdo-remap_conserv_scrip.$(OBJEXT) \
-	cdo-remap_distwgt_scrip.$(OBJEXT) \
-	cdo-remap_bicubic_scrip.$(OBJEXT) \
-	cdo-remap_bilinear_scrip.$(OBJEXT) cdo-stdnametable.$(OBJEXT) \
-	cdo-specspace.$(OBJEXT) cdo-statistic.$(OBJEXT) \
-	cdo-table.$(OBJEXT) cdo-text.$(OBJEXT) cdo-timer.$(OBJEXT) \
-	cdo-userlog.$(OBJEXT) cdo-util.$(OBJEXT) cdo-vinterp.$(OBJEXT) \
-	cdo-zaxis.$(OBJEXT) clipping/cdo-clipping.$(OBJEXT) \
-	clipping/cdo-area.$(OBJEXT) \
-	clipping/cdo-ensure_array_size.$(OBJEXT) \
-	clipping/cdo-geometry_tools.$(OBJEXT) \
-	clipping/cdo-grid_cell.$(OBJEXT) \
-	clipping/cdo-intersection.$(OBJEXT) \
-	clipping/cdo-utils.$(OBJEXT) $(am__objects_1)
+	cdo-Vertintml.$(OBJEXT) cdo-Vertintap.$(OBJEXT) \
+	cdo-Vertstat.$(OBJEXT) cdo-Vertwind.$(OBJEXT) \
+	cdo-Wct.$(OBJEXT) cdo-Wind.$(OBJEXT) cdo-Writegrid.$(OBJEXT) \
+	cdo-Writerandom.$(OBJEXT) cdo-YAR.$(OBJEXT) \
+	cdo-Yearmonstat.$(OBJEXT) cdo-Ydayarith.$(OBJEXT) \
+	cdo-Ydaypctl.$(OBJEXT) cdo-Ydaystat.$(OBJEXT) \
+	cdo-Ydrunpctl.$(OBJEXT) cdo-Ydrunstat.$(OBJEXT) \
+	cdo-Yhourarith.$(OBJEXT) cdo-Yhourstat.$(OBJEXT) \
+	cdo-Ymonarith.$(OBJEXT) cdo-Ymonpctl.$(OBJEXT) \
+	cdo-Ymonstat.$(OBJEXT) cdo-Yseaspctl.$(OBJEXT) \
+	cdo-Yseasstat.$(OBJEXT) cdo-Zonstat.$(OBJEXT) $(am__objects_1)
 cdo_OBJECTS = $(am_cdo_OBJECTS)
-cdo_DEPENDENCIES = $(top_builddir)/libcdi/src/libcdi.la
-AM_V_lt = $(am__v_lt_ at AM_V@)
-am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 = 
+cdo_DEPENDENCIES = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
 cdo_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(cdo_LDFLAGS) $(LDFLAGS) -o $@
@@ -364,8 +338,9 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(cdo_SOURCES) $(cdotest_SOURCES)
-DIST_SOURCES = $(am__cdo_SOURCES_DIST) $(cdotest_SOURCES)
+SOURCES = $(libcdo_la_SOURCES) $(cdo_SOURCES) $(cdotest_SOURCES)
+DIST_SOURCES = $(libcdo_la_SOURCES) $(am__cdo_SOURCES_DIST) \
+	$(cdotest_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -434,6 +409,7 @@ ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
 ENABLE_IEG = @ENABLE_IEG@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
+ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
 ENABLE_NETCDF = @ENABLE_NETCDF@
 ENABLE_SERVICE = @ENABLE_SERVICE@
 EXEEXT = @EXEEXT@
@@ -563,18 +539,53 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libcdo.la
+libcdo_la_SOURCES = cdo_int.h compare.h cdo_pthread.c cdo_vlist.c \
+	cdo_getopt.c cdo_getopt.h cdo_history.c after_sptrans.c \
+	after_fctrans.c after_dvtrans.c after_vertint.c \
+	after_vertint.h after_namelist.c afterburnerlib.c \
+	afterburner.h vct_l191.h constants.h constants.c color.c \
+	color.h commandline.c const.h counter.h datetime.c datetime.h \
+	dmemory.h dtypes.h ecacore.c ecacore.h ecautil.c ecautil.h \
+	error.h etopo.h temp.h mask.h exception.c expr.c expr.h \
+	expr_lex.c expr_yacc.c expr_yacc.h features.c field.c field.h \
+	field2.c fieldc.c fieldmem.c fieldmer.c fieldzon.c functs.h \
+	gradsdeslib.c gradsdeslib.h grid.c grid.h grid_area.c \
+	grid_gme.c grid_lcc.c grid_rot.c gridreference.c griddes.c \
+	griddes.h griddes_h5.c griddes_nc.c hetaeta.c hetaeta.h \
+	institution.c interpol.c interpol.h job.c juldate.c kvlist.c \
+	kvlist.h list.c list.h merge_sort2.c merge_sort2.h modules.c \
+	modules.h namelist.c namelist.h normal.c nth_element.c \
+	nth_element.h operator_help.h par_io.c par_io.h percentiles.c \
+	percentiles.h pipe.c pipe.h pragma_omp_atomic_update.h \
+	printinfo.h process.c process.h pstream.c pstream.h \
+	pstream_write.h pstream_int.h pthread_debug.c pthread_debug.h \
+	readline.c realtime.c remap.h remaplib.c remapsort.c \
+	remap_scrip_io.c remap_search_reg2d.c remap_search_latbins.c \
+	remap_store_link.c remap_store_link.h remap_store_link_cnsrv.c \
+	remap_store_link_cnsrv.h remap_conserv.c remap_conserv_scrip.c \
+	remap_distwgt_scrip.c remap_bicubic_scrip.c \
+	remap_bilinear_scrip.c stdnametable.c stdnametable.h \
+	specspace.c specspace.h statistic.c statistic.h table.c text.c \
+	text.h timebase.h timer.c userlog.c util.c util.h zaxis.c \
+	clipping/clipping.c clipping/clipping.h clipping/area.c \
+	clipping/area.h clipping/ensure_array_size.c \
+	clipping/ensure_array_size.h clipping/geometry.h \
+	clipping/grid.h clipping/points.h clipping/dep_list.h \
+	clipping/grid_cell.c clipping/grid_cell.h \
+	clipping/intersection.c clipping/utils.c clipping/utils.h
 #
-cdo_SOURCES = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c Arithlat.c \
-	CDItest.c CDIread.c CDIwrite.c Cat.c Change.c Change_e5slm.c \
-	Cloudlayer.c Collgrid.c Command.c Comp.c Compc.c \
-	Complextorect.c Cond.c Cond2.c Condc.c Consecstat.c Copy.c \
-	Deltime.c Derivepar.c Detrend.c Diff.c Distgrid.c Duplicate.c \
-	EOFs.c Eof3d.c EcaIndices.c Echam5ini.c Enlarge.c \
-	Enlargegrid.c Ensstat.c Ensstat3.c Ensval.c Eofcoeff.c \
-	Eofcoeff3d.c Exprf.c FC.c Filedes.c Fillmiss.c Filter.c \
-	Fldrms.c Fldstat.c Fldstat2.c Fourier.c Gengrid.c Gradsdes.c \
-	Gridboxstat.c Gridcell.c Gridsearch.c Harmonic.c Hi.c \
-	Histogram.c Importamsr.c Importbinary.c Importcmsaf.c \
+cdo_SOURCES = cdo.c Adisit.c Afterburner.c Arith.c Arithc.c \
+	Arithdays.c Arithlat.c CDItest.c CDIread.c CDIwrite.c Cat.c \
+	Change.c Change_e5slm.c Cloudlayer.c Collgrid.c Command.c \
+	Comp.c Compc.c Complextorect.c Cond.c Cond2.c Condc.c \
+	Consecstat.c Copy.c Deltime.c Derivepar.c Detrend.c Diff.c \
+	Distgrid.c Duplicate.c EOFs.c Eof3d.c EcaIndices.c Echam5ini.c \
+	Enlarge.c Enlargegrid.c Ensstat.c Ensstat3.c Ensval.c \
+	Eofcoeff.c Eofcoeff3d.c Exprf.c FC.c Filedes.c Fillmiss.c \
+	Filter.c Fldrms.c Fldstat.c Fldstat2.c Fourier.c Gengrid.c \
+	Gradsdes.c Gridboxstat.c Gridcell.c Gridsearch.c Harmonic.c \
+	Hi.c Histogram.c Importamsr.c Importbinary.c Importcmsaf.c \
 	Importobs.c Info.c Input.c Intgrid.c Intgridtraj.c Intlevel.c \
 	Intlevel3d.c Intntime.c Inttime.c Intyear.c Invert.c \
 	Invertlev.c Isosurface.c Kvl.c Log.c Maskbox.c Mastrfu.c \
@@ -591,44 +602,16 @@ cdo_SOURCES = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c Arithlat.c \
 	Subtrend.c Tee.c Templates.c Test.c Tests.c Timcount.c \
 	Timpctl.c Timselpctl.c Timselstat.c Timsort.c Timstat.c \
 	Timstat2.c Timstat3.c Tinfo.c Tocomplex.c Transpose.c Trend.c \
-	Trms.c Tstepcount.c Vardup.c Vargen.c Varrms.c Vertint.c \
-	Vertstat.c Vertwind.c Wct.c Wind.c Writegrid.c Writerandom.c \
-	YAR.c Yearmonstat.c Ydayarith.c Ydaypctl.c Ydaystat.c \
-	Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c Ymonarith.c \
-	Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c Zonstat.c cdo.h \
-	cdo_int.h cdo_pthread.c cdo_vlist.c cdo_getopt.c cdo_getopt.h \
-	color.c color.h commandline.c const.h counter.h dmemory.h \
-	dtypes.h ecacore.c ecacore.h ecautil.c ecautil.h error.h \
-	etopo.h temp.h mask.h exception.c expr.c expr.h expr_lex.c \
-	expr_yacc.c expr_yacc.h features.c field.c field.h field2.c \
-	fieldc.c fieldmem.c fieldmer.c fieldzon.c fouriertrans.c \
-	functs.h gradsdeslib.c gradsdeslib.h grid.c grid.h grid_area.c \
-	grid_gme.c grid_lcc.c grid_rot.c gridreference.c griddes.c \
-	griddes.h griddes_h5.c griddes_nc.c hetaeta.c hetaeta.h \
-	history.c institution.c interpol.c interpol.h job.c juldate.c \
-	kvlist.c kvlist.h legendre.c list.c list.h merge_sort2.c \
-	merge_sort2.h modules.c modules.h namelist.c namelist.h \
-	normal.c nth_element.c nth_element.h operator_help.h par_io.c \
-	par_io.h percentiles.c percentiles.h pipe.c pipe.h \
-	pragma_omp_atomic_update.h printinfo.h process.c process.h \
-	pstream.c pstream.h pstream_int.h pthread_debug.c \
-	pthread_debug.h readline.c realtime.c remap.h remaplib.c \
-	remapsort.c remap_scrip_io.c remap_search_reg2d.c \
-	remap_search_latbins.c remap_store_link.c remap_store_link.h \
-	remap_conserv.c remap_conserv_scrip.c remap_distwgt_scrip.c \
-	remap_bicubic_scrip.c remap_bilinear_scrip.c stdnametable.c \
-	stdnametable.h specspace.c specspace.h statistic.c statistic.h \
-	table.c text.c text.h timebase.h timer.c userlog.c util.c \
-	util.h vinterp.c vinterp.h zaxis.c clipping/clipping.c \
-	clipping/clipping.h clipping/area.c clipping/area.h \
-	clipping/ensure_array_size.c clipping/ensure_array_size.h \
-	clipping/geometry_tools.c clipping/geometry.h clipping/grid.h \
-	clipping/points.h clipping/dep_list.h clipping/grid_cell.c \
-	clipping/grid_cell.h clipping/intersection.c clipping/utils.c \
-	clipping/utils.h $(am__append_1)
+	Trms.c Tstepcount.c Vardup.c Vargen.c Varrms.c Vertintml.c \
+	Vertintap.c Vertstat.c Vertwind.c Wct.c Wind.c Writegrid.c \
+	Writerandom.c YAR.c Yearmonstat.c Ydayarith.c Ydaypctl.c \
+	Ydaystat.c Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c \
+	Ymonarith.c Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c \
+	Zonstat.c cdo.h $(am__append_1)
 cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
-cdo_LDADD = $(top_builddir)/libcdi/src/libcdi.la
+cdo_LDADD = libcdo.la $(top_builddir)/libcdi/src/libcdi.la
 cdo_LDFLAGS = $(am__append_2)
+libcdo_la_CPPFLAGS = $(cdo_CPPFLAGS)
 cdotest_SOURCES = cdo_int.h	\
 	           cdotest.c
 
@@ -692,6 +675,38 @@ $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 
 distclean-hdr:
 	-rm -f config.h stamp-h1
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+clipping/$(am__dirstamp):
+	@$(MKDIR_P) clipping
+	@: > clipping/$(am__dirstamp)
+clipping/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) clipping/$(DEPDIR)
+	@: > clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-clipping.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-area.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-ensure_array_size.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-grid_cell.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-intersection.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+clipping/libcdo_la-utils.lo: clipping/$(am__dirstamp) \
+	clipping/$(DEPDIR)/$(am__dirstamp)
+
+libcdo.la: $(libcdo_la_OBJECTS) $(libcdo_la_DEPENDENCIES) $(EXTRA_libcdo_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(LINK)  $(libcdo_la_OBJECTS) $(libcdo_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
 	@$(NORMAL_INSTALL)
 	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -750,26 +765,6 @@ clean-noinstPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
-clipping/$(am__dirstamp):
-	@$(MKDIR_P) clipping
-	@: > clipping/$(am__dirstamp)
-clipping/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) clipping/$(DEPDIR)
-	@: > clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-clipping.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-area.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-ensure_array_size.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-geometry_tools.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-grid_cell.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-intersection.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
-clipping/cdo-utils.$(OBJEXT): clipping/$(am__dirstamp) \
-	clipping/$(DEPDIR)/$(am__dirstamp)
 
 cdo$(EXEEXT): $(cdo_OBJECTS) $(cdo_DEPENDENCIES) $(EXTRA_cdo_DEPENDENCIES) 
 	@rm -f cdo$(EXEEXT)
@@ -782,11 +777,13 @@ cdotest$(EXEEXT): $(cdotest_OBJECTS) $(cdotest_DEPENDENCIES) $(EXTRA_cdotest_DEP
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
 	-rm -f clipping/*.$(OBJEXT)
+	-rm -f clipping/*.lo
 
 distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Adisit.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Afterburner.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arith.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arithc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arithdays.Po at am__quote@
@@ -946,7 +943,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vardup.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vargen.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Varrms.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vertint.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vertintap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vertintml.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vertstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Vertwind.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Wct.Po at am__quote@
@@ -969,89 +967,94 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yseasstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Zonstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo_getopt.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo_pthread.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo_vlist.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-color.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-commandline.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-ecacore.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-ecautil.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-exception.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-expr.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-expr_lex.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-expr_yacc.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-features.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-field.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-field2.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldc.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldmem.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldmer.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldzon.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fouriertrans.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-gradsdeslib.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_area.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_gme.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_lcc.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_rot.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-griddes.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-griddes_h5.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-griddes_nc.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-gridreference.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-hetaeta.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-history.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-institution.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-interpol.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-job.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-juldate.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-kvlist.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-legendre.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-list.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-magics_template_parser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-merge_sort2.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-modules.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-namelist.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-normal.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-nth_element.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-par_io.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-percentiles.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-pipe.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-process.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-pstream.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-pthread_debug.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-readline.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-realtime.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_bicubic_scrip.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_bilinear_scrip.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_conserv.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_conserv_scrip.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_distwgt_scrip.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_scrip_io.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_search_latbins.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_search_reg2d.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_store_link.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remaplib.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remapsort.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-results_template_parser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-specspace.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-statistic.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-stdnametable.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-table.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-template_parser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-text.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-timer.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-userlog.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-util.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-vinterp.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-zaxis.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdotest-cdotest.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-area.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-clipping.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-ensure_array_size.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-geometry_tools.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-grid_cell.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-intersection.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/cdo-utils.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-after_dvtrans.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-after_fctrans.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-after_namelist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-after_sptrans.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-after_vertint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-afterburnerlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_getopt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_history.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_pthread.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-cdo_vlist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-color.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-commandline.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-constants.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-datetime.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-ecacore.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-ecautil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-exception.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-expr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-expr_lex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-expr_yacc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-features.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-field.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-field2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldmem.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldmer.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-fieldzon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-gradsdeslib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid_area.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid_gme.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid_lcc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-grid_rot.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-griddes.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-griddes_h5.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-griddes_nc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-gridreference.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-hetaeta.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-institution.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-interpol.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-job.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-juldate.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-kvlist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-list.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-merge_sort2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-modules.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-namelist.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-normal.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-nth_element.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-par_io.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-percentiles.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-pipe.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-process.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-pstream.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-pthread_debug.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-readline.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-realtime.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_bicubic_scrip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_bilinear_scrip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_conserv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_conserv_scrip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_distwgt_scrip.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_scrip_io.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_search_latbins.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_search_reg2d.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_store_link.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remap_store_link_cnsrv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remaplib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-remapsort.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-specspace.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-statistic.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-stdnametable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-table.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-text.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-timer.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-userlog.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcdo_la-zaxis.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-area.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-clipping.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-ensure_array_size.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-grid_cell.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-intersection.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at clipping/$(DEPDIR)/libcdo_la-utils.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -1077,6 +1080,594 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+libcdo_la-cdo_pthread.lo: cdo_pthread.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_pthread.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_pthread.Tpo -c -o libcdo_la-cdo_pthread.lo `test -f 'cdo_pthread.c' || echo '$(srcdir)/'`cdo_pthread.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_pthread.Tpo $(DEPDIR)/libcdo_la-cdo_pthread.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_pthread.c' object='libcdo_la-cdo_pthread.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_pthread.lo `test -f 'cdo_pthread.c' || echo '$(srcdir)/'`cdo_pthread.c
+
+libcdo_la-cdo_vlist.lo: cdo_vlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_vlist.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_vlist.Tpo -c -o libcdo_la-cdo_vlist.lo `test -f 'cdo_vlist.c' || echo '$(srcdir)/'`cdo_vlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_vlist.Tpo $(DEPDIR)/libcdo_la-cdo_vlist.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_vlist.c' object='libcdo_la-cdo_vlist.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_vlist.lo `test -f 'cdo_vlist.c' || echo '$(srcdir)/'`cdo_vlist.c
+
+libcdo_la-cdo_getopt.lo: cdo_getopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_getopt.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_getopt.Tpo -c -o libcdo_la-cdo_getopt.lo `test -f 'cdo_getopt.c' || echo '$(srcdir)/'`cdo_getopt.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_getopt.Tpo $(DEPDIR)/libcdo_la-cdo_getopt.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_getopt.c' object='libcdo_la-cdo_getopt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_getopt.lo `test -f 'cdo_getopt.c' || echo '$(srcdir)/'`cdo_getopt.c
+
+libcdo_la-cdo_history.lo: cdo_history.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-cdo_history.lo -MD -MP -MF $(DEPDIR)/libcdo_la-cdo_history.Tpo -c -o libcdo_la-cdo_history.lo `test -f 'cdo_history.c' || echo '$(srcdir)/'`cdo_history.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-cdo_history.Tpo $(DEPDIR)/libcdo_la-cdo_history.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_history.c' object='libcdo_la-cdo_history.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-cdo_history.lo `test -f 'cdo_history.c' || echo '$(srcdir)/'`cdo_history.c
+
+libcdo_la-after_sptrans.lo: after_sptrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-after_sptrans.lo -MD -MP -MF $(DEPDIR)/libcdo_la-after_sptrans.Tpo -c -o libcdo_la-after_sptrans.lo `test -f 'after_sptrans.c' || echo '$(srcdir)/'`after_sptrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-after_sptrans.Tpo $(DEPDIR)/libcdo_la-after_sptrans.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='after_sptrans.c' object='libcdo_la-after_sptrans.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-after_sptrans.lo `test -f 'after_sptrans.c' || echo '$(srcdir)/'`after_sptrans.c
+
+libcdo_la-after_fctrans.lo: after_fctrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-after_fctrans.lo -MD -MP -MF $(DEPDIR)/libcdo_la-after_fctrans.Tpo -c -o libcdo_la-after_fctrans.lo `test -f 'after_fctrans.c' || echo '$(srcdir)/'`after_fctrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-after_fctrans.Tpo $(DEPDIR)/libcdo_la-after_fctrans.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='after_fctrans.c' object='libcdo_la-after_fctrans.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-after_fctrans.lo `test -f 'after_fctrans.c' || echo '$(srcdir)/'`after_fctrans.c
+
+libcdo_la-after_dvtrans.lo: after_dvtrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-after_dvtrans.lo -MD -MP -MF $(DEPDIR)/libcdo_la-after_dvtrans.Tpo -c -o libcdo_la-after_dvtrans.lo `test -f 'after_dvtrans.c' || echo '$(srcdir)/'`after_dvtrans.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-after_dvtrans.Tpo $(DEPDIR)/libcdo_la-after_dvtrans.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='after_dvtrans.c' object='libcdo_la-after_dvtrans.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-after_dvtrans.lo `test -f 'after_dvtrans.c' || echo '$(srcdir)/'`after_dvtrans.c
+
+libcdo_la-after_vertint.lo: after_vertint.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-after_vertint.lo -MD -MP -MF $(DEPDIR)/libcdo_la-after_vertint.Tpo -c -o libcdo_la-after_vertint.lo `test -f 'after_vertint.c' || echo '$(srcdir)/'`after_vertint.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-after_vertint.Tpo $(DEPDIR)/libcdo_la-after_vertint.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='after_vertint.c' object='libcdo_la-after_vertint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-after_vertint.lo `test -f 'after_vertint.c' || echo '$(srcdir)/'`after_vertint.c
+
+libcdo_la-after_namelist.lo: after_namelist.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-after_namelist.lo -MD -MP -MF $(DEPDIR)/libcdo_la-after_namelist.Tpo -c -o libcdo_la-after_namelist.lo `test -f 'after_namelist.c' || echo '$(srcdir)/'`after_namelist.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-after_namelist.Tpo $(DEPDIR)/libcdo_la-after_namelist.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='after_namelist.c' object='libcdo_la-after_namelist.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-after_namelist.lo `test -f 'after_namelist.c' || echo '$(srcdir)/'`after_namelist.c
+
+libcdo_la-afterburnerlib.lo: afterburnerlib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-afterburnerlib.lo -MD -MP -MF $(DEPDIR)/libcdo_la-afterburnerlib.Tpo -c -o libcdo_la-afterburnerlib.lo `test -f 'afterburnerlib.c' || echo '$(srcdir)/'`afterburnerlib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-afterburnerlib.Tpo $(DEPDIR)/libcdo_la-afterburnerlib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='afterburnerlib.c' object='libcdo_la-afterburnerlib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-afterburnerlib.lo `test -f 'afterburnerlib.c' || echo '$(srcdir)/'`afterburnerlib.c
+
+libcdo_la-constants.lo: constants.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-constants.lo -MD -MP -MF $(DEPDIR)/libcdo_la-constants.Tpo -c -o libcdo_la-constants.lo `test -f 'constants.c' || echo '$(srcdir)/'`constants.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-constants.Tpo $(DEPDIR)/libcdo_la-constants.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='constants.c' object='libcdo_la-constants.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-constants.lo `test -f 'constants.c' || echo '$(srcdir)/'`constants.c
+
+libcdo_la-color.lo: color.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-color.lo -MD -MP -MF $(DEPDIR)/libcdo_la-color.Tpo -c -o libcdo_la-color.lo `test -f 'color.c' || echo '$(srcdir)/'`color.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-color.Tpo $(DEPDIR)/libcdo_la-color.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='color.c' object='libcdo_la-color.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-color.lo `test -f 'color.c' || echo '$(srcdir)/'`color.c
+
+libcdo_la-commandline.lo: commandline.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-commandline.lo -MD -MP -MF $(DEPDIR)/libcdo_la-commandline.Tpo -c -o libcdo_la-commandline.lo `test -f 'commandline.c' || echo '$(srcdir)/'`commandline.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-commandline.Tpo $(DEPDIR)/libcdo_la-commandline.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='commandline.c' object='libcdo_la-commandline.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-commandline.lo `test -f 'commandline.c' || echo '$(srcdir)/'`commandline.c
+
+libcdo_la-datetime.lo: datetime.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-datetime.lo -MD -MP -MF $(DEPDIR)/libcdo_la-datetime.Tpo -c -o libcdo_la-datetime.lo `test -f 'datetime.c' || echo '$(srcdir)/'`datetime.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-datetime.Tpo $(DEPDIR)/libcdo_la-datetime.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='datetime.c' object='libcdo_la-datetime.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-datetime.lo `test -f 'datetime.c' || echo '$(srcdir)/'`datetime.c
+
+libcdo_la-ecacore.lo: ecacore.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-ecacore.lo -MD -MP -MF $(DEPDIR)/libcdo_la-ecacore.Tpo -c -o libcdo_la-ecacore.lo `test -f 'ecacore.c' || echo '$(srcdir)/'`ecacore.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-ecacore.Tpo $(DEPDIR)/libcdo_la-ecacore.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecacore.c' object='libcdo_la-ecacore.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-ecacore.lo `test -f 'ecacore.c' || echo '$(srcdir)/'`ecacore.c
+
+libcdo_la-ecautil.lo: ecautil.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-ecautil.lo -MD -MP -MF $(DEPDIR)/libcdo_la-ecautil.Tpo -c -o libcdo_la-ecautil.lo `test -f 'ecautil.c' || echo '$(srcdir)/'`ecautil.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-ecautil.Tpo $(DEPDIR)/libcdo_la-ecautil.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecautil.c' object='libcdo_la-ecautil.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-ecautil.lo `test -f 'ecautil.c' || echo '$(srcdir)/'`ecautil.c
+
+libcdo_la-exception.lo: exception.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-exception.lo -MD -MP -MF $(DEPDIR)/libcdo_la-exception.Tpo -c -o libcdo_la-exception.lo `test -f 'exception.c' || echo '$(srcdir)/'`exception.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-exception.Tpo $(DEPDIR)/libcdo_la-exception.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='exception.c' object='libcdo_la-exception.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-exception.lo `test -f 'exception.c' || echo '$(srcdir)/'`exception.c
+
+libcdo_la-expr.lo: expr.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-expr.lo -MD -MP -MF $(DEPDIR)/libcdo_la-expr.Tpo -c -o libcdo_la-expr.lo `test -f 'expr.c' || echo '$(srcdir)/'`expr.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-expr.Tpo $(DEPDIR)/libcdo_la-expr.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr.c' object='libcdo_la-expr.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-expr.lo `test -f 'expr.c' || echo '$(srcdir)/'`expr.c
+
+libcdo_la-expr_lex.lo: expr_lex.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-expr_lex.lo -MD -MP -MF $(DEPDIR)/libcdo_la-expr_lex.Tpo -c -o libcdo_la-expr_lex.lo `test -f 'expr_lex.c' || echo '$(srcdir)/'`expr_lex.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-expr_lex.Tpo $(DEPDIR)/libcdo_la-expr_lex.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_lex.c' object='libcdo_la-expr_lex.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-expr_lex.lo `test -f 'expr_lex.c' || echo '$(srcdir)/'`expr_lex.c
+
+libcdo_la-expr_yacc.lo: expr_yacc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-expr_yacc.lo -MD -MP -MF $(DEPDIR)/libcdo_la-expr_yacc.Tpo -c -o libcdo_la-expr_yacc.lo `test -f 'expr_yacc.c' || echo '$(srcdir)/'`expr_yacc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-expr_yacc.Tpo $(DEPDIR)/libcdo_la-expr_yacc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_yacc.c' object='libcdo_la-expr_yacc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-expr_yacc.lo `test -f 'expr_yacc.c' || echo '$(srcdir)/'`expr_yacc.c
+
+libcdo_la-features.lo: features.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-features.lo -MD -MP -MF $(DEPDIR)/libcdo_la-features.Tpo -c -o libcdo_la-features.lo `test -f 'features.c' || echo '$(srcdir)/'`features.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-features.Tpo $(DEPDIR)/libcdo_la-features.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='features.c' object='libcdo_la-features.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-features.lo `test -f 'features.c' || echo '$(srcdir)/'`features.c
+
+libcdo_la-field.lo: field.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-field.lo -MD -MP -MF $(DEPDIR)/libcdo_la-field.Tpo -c -o libcdo_la-field.lo `test -f 'field.c' || echo '$(srcdir)/'`field.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-field.Tpo $(DEPDIR)/libcdo_la-field.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field.c' object='libcdo_la-field.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-field.lo `test -f 'field.c' || echo '$(srcdir)/'`field.c
+
+libcdo_la-field2.lo: field2.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-field2.lo -MD -MP -MF $(DEPDIR)/libcdo_la-field2.Tpo -c -o libcdo_la-field2.lo `test -f 'field2.c' || echo '$(srcdir)/'`field2.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-field2.Tpo $(DEPDIR)/libcdo_la-field2.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field2.c' object='libcdo_la-field2.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-field2.lo `test -f 'field2.c' || echo '$(srcdir)/'`field2.c
+
+libcdo_la-fieldc.lo: fieldc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-fieldc.lo -MD -MP -MF $(DEPDIR)/libcdo_la-fieldc.Tpo -c -o libcdo_la-fieldc.lo `test -f 'fieldc.c' || echo '$(srcdir)/'`fieldc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-fieldc.Tpo $(DEPDIR)/libcdo_la-fieldc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldc.c' object='libcdo_la-fieldc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-fieldc.lo `test -f 'fieldc.c' || echo '$(srcdir)/'`fieldc.c
+
+libcdo_la-fieldmem.lo: fieldmem.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-fieldmem.lo -MD -MP -MF $(DEPDIR)/libcdo_la-fieldmem.Tpo -c -o libcdo_la-fieldmem.lo `test -f 'fieldmem.c' || echo '$(srcdir)/'`fieldmem.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-fieldmem.Tpo $(DEPDIR)/libcdo_la-fieldmem.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmem.c' object='libcdo_la-fieldmem.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-fieldmem.lo `test -f 'fieldmem.c' || echo '$(srcdir)/'`fieldmem.c
+
+libcdo_la-fieldmer.lo: fieldmer.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-fieldmer.lo -MD -MP -MF $(DEPDIR)/libcdo_la-fieldmer.Tpo -c -o libcdo_la-fieldmer.lo `test -f 'fieldmer.c' || echo '$(srcdir)/'`fieldmer.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-fieldmer.Tpo $(DEPDIR)/libcdo_la-fieldmer.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmer.c' object='libcdo_la-fieldmer.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-fieldmer.lo `test -f 'fieldmer.c' || echo '$(srcdir)/'`fieldmer.c
+
+libcdo_la-fieldzon.lo: fieldzon.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-fieldzon.lo -MD -MP -MF $(DEPDIR)/libcdo_la-fieldzon.Tpo -c -o libcdo_la-fieldzon.lo `test -f 'fieldzon.c' || echo '$(srcdir)/'`fieldzon.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-fieldzon.Tpo $(DEPDIR)/libcdo_la-fieldzon.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldzon.c' object='libcdo_la-fieldzon.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-fieldzon.lo `test -f 'fieldzon.c' || echo '$(srcdir)/'`fieldzon.c
+
+libcdo_la-gradsdeslib.lo: gradsdeslib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-gradsdeslib.lo -MD -MP -MF $(DEPDIR)/libcdo_la-gradsdeslib.Tpo -c -o libcdo_la-gradsdeslib.lo `test -f 'gradsdeslib.c' || echo '$(srcdir)/'`gradsdeslib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-gradsdeslib.Tpo $(DEPDIR)/libcdo_la-gradsdeslib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gradsdeslib.c' object='libcdo_la-gradsdeslib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-gradsdeslib.lo `test -f 'gradsdeslib.c' || echo '$(srcdir)/'`gradsdeslib.c
+
+libcdo_la-grid.lo: grid.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-grid.lo -MD -MP -MF $(DEPDIR)/libcdo_la-grid.Tpo -c -o libcdo_la-grid.lo `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-grid.Tpo $(DEPDIR)/libcdo_la-grid.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid.c' object='libcdo_la-grid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-grid.lo `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
+
+libcdo_la-grid_area.lo: grid_area.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-grid_area.lo -MD -MP -MF $(DEPDIR)/libcdo_la-grid_area.Tpo -c -o libcdo_la-grid_area.lo `test -f 'grid_area.c' || echo '$(srcdir)/'`grid_area.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-grid_area.Tpo $(DEPDIR)/libcdo_la-grid_area.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_area.c' object='libcdo_la-grid_area.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-grid_area.lo `test -f 'grid_area.c' || echo '$(srcdir)/'`grid_area.c
+
+libcdo_la-grid_gme.lo: grid_gme.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-grid_gme.lo -MD -MP -MF $(DEPDIR)/libcdo_la-grid_gme.Tpo -c -o libcdo_la-grid_gme.lo `test -f 'grid_gme.c' || echo '$(srcdir)/'`grid_gme.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-grid_gme.Tpo $(DEPDIR)/libcdo_la-grid_gme.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_gme.c' object='libcdo_la-grid_gme.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-grid_gme.lo `test -f 'grid_gme.c' || echo '$(srcdir)/'`grid_gme.c
+
+libcdo_la-grid_lcc.lo: grid_lcc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-grid_lcc.lo -MD -MP -MF $(DEPDIR)/libcdo_la-grid_lcc.Tpo -c -o libcdo_la-grid_lcc.lo `test -f 'grid_lcc.c' || echo '$(srcdir)/'`grid_lcc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-grid_lcc.Tpo $(DEPDIR)/libcdo_la-grid_lcc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_lcc.c' object='libcdo_la-grid_lcc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-grid_lcc.lo `test -f 'grid_lcc.c' || echo '$(srcdir)/'`grid_lcc.c
+
+libcdo_la-grid_rot.lo: grid_rot.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-grid_rot.lo -MD -MP -MF $(DEPDIR)/libcdo_la-grid_rot.Tpo -c -o libcdo_la-grid_rot.lo `test -f 'grid_rot.c' || echo '$(srcdir)/'`grid_rot.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-grid_rot.Tpo $(DEPDIR)/libcdo_la-grid_rot.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_rot.c' object='libcdo_la-grid_rot.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-grid_rot.lo `test -f 'grid_rot.c' || echo '$(srcdir)/'`grid_rot.c
+
+libcdo_la-gridreference.lo: gridreference.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-gridreference.lo -MD -MP -MF $(DEPDIR)/libcdo_la-gridreference.Tpo -c -o libcdo_la-gridreference.lo `test -f 'gridreference.c' || echo '$(srcdir)/'`gridreference.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-gridreference.Tpo $(DEPDIR)/libcdo_la-gridreference.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gridreference.c' object='libcdo_la-gridreference.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-gridreference.lo `test -f 'gridreference.c' || echo '$(srcdir)/'`gridreference.c
+
+libcdo_la-griddes.lo: griddes.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-griddes.lo -MD -MP -MF $(DEPDIR)/libcdo_la-griddes.Tpo -c -o libcdo_la-griddes.lo `test -f 'griddes.c' || echo '$(srcdir)/'`griddes.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-griddes.Tpo $(DEPDIR)/libcdo_la-griddes.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes.c' object='libcdo_la-griddes.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-griddes.lo `test -f 'griddes.c' || echo '$(srcdir)/'`griddes.c
+
+libcdo_la-griddes_h5.lo: griddes_h5.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-griddes_h5.lo -MD -MP -MF $(DEPDIR)/libcdo_la-griddes_h5.Tpo -c -o libcdo_la-griddes_h5.lo `test -f 'griddes_h5.c' || echo '$(srcdir)/'`griddes_h5.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-griddes_h5.Tpo $(DEPDIR)/libcdo_la-griddes_h5.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_h5.c' object='libcdo_la-griddes_h5.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-griddes_h5.lo `test -f 'griddes_h5.c' || echo '$(srcdir)/'`griddes_h5.c
+
+libcdo_la-griddes_nc.lo: griddes_nc.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-griddes_nc.lo -MD -MP -MF $(DEPDIR)/libcdo_la-griddes_nc.Tpo -c -o libcdo_la-griddes_nc.lo `test -f 'griddes_nc.c' || echo '$(srcdir)/'`griddes_nc.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-griddes_nc.Tpo $(DEPDIR)/libcdo_la-griddes_nc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_nc.c' object='libcdo_la-griddes_nc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-griddes_nc.lo `test -f 'griddes_nc.c' || echo '$(srcdir)/'`griddes_nc.c
+
+libcdo_la-hetaeta.lo: hetaeta.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-hetaeta.lo -MD -MP -MF $(DEPDIR)/libcdo_la-hetaeta.Tpo -c -o libcdo_la-hetaeta.lo `test -f 'hetaeta.c' || echo '$(srcdir)/'`hetaeta.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-hetaeta.Tpo $(DEPDIR)/libcdo_la-hetaeta.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='hetaeta.c' object='libcdo_la-hetaeta.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-hetaeta.lo `test -f 'hetaeta.c' || echo '$(srcdir)/'`hetaeta.c
+
+libcdo_la-institution.lo: institution.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-institution.lo -MD -MP -MF $(DEPDIR)/libcdo_la-institution.Tpo -c -o libcdo_la-institution.lo `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-institution.Tpo $(DEPDIR)/libcdo_la-institution.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='institution.c' object='libcdo_la-institution.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-institution.lo `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
+
+libcdo_la-interpol.lo: interpol.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-interpol.lo -MD -MP -MF $(DEPDIR)/libcdo_la-interpol.Tpo -c -o libcdo_la-interpol.lo `test -f 'interpol.c' || echo '$(srcdir)/'`interpol.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-interpol.Tpo $(DEPDIR)/libcdo_la-interpol.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='interpol.c' object='libcdo_la-interpol.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-interpol.lo `test -f 'interpol.c' || echo '$(srcdir)/'`interpol.c
+
+libcdo_la-job.lo: job.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-job.lo -MD -MP -MF $(DEPDIR)/libcdo_la-job.Tpo -c -o libcdo_la-job.lo `test -f 'job.c' || echo '$(srcdir)/'`job.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-job.Tpo $(DEPDIR)/libcdo_la-job.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='job.c' object='libcdo_la-job.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-job.lo `test -f 'job.c' || echo '$(srcdir)/'`job.c
+
+libcdo_la-juldate.lo: juldate.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-juldate.lo -MD -MP -MF $(DEPDIR)/libcdo_la-juldate.Tpo -c -o libcdo_la-juldate.lo `test -f 'juldate.c' || echo '$(srcdir)/'`juldate.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-juldate.Tpo $(DEPDIR)/libcdo_la-juldate.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='juldate.c' object='libcdo_la-juldate.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-juldate.lo `test -f 'juldate.c' || echo '$(srcdir)/'`juldate.c
+
+libcdo_la-kvlist.lo: kvlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-kvlist.lo -MD -MP -MF $(DEPDIR)/libcdo_la-kvlist.Tpo -c -o libcdo_la-kvlist.lo `test -f 'kvlist.c' || echo '$(srcdir)/'`kvlist.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-kvlist.Tpo $(DEPDIR)/libcdo_la-kvlist.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kvlist.c' object='libcdo_la-kvlist.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-kvlist.lo `test -f 'kvlist.c' || echo '$(srcdir)/'`kvlist.c
+
+libcdo_la-list.lo: list.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-list.lo -MD -MP -MF $(DEPDIR)/libcdo_la-list.Tpo -c -o libcdo_la-list.lo `test -f 'list.c' || echo '$(srcdir)/'`list.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-list.Tpo $(DEPDIR)/libcdo_la-list.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='list.c' object='libcdo_la-list.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-list.lo `test -f 'list.c' || echo '$(srcdir)/'`list.c
+
+libcdo_la-merge_sort2.lo: merge_sort2.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-merge_sort2.lo -MD -MP -MF $(DEPDIR)/libcdo_la-merge_sort2.Tpo -c -o libcdo_la-merge_sort2.lo `test -f 'merge_sort2.c' || echo '$(srcdir)/'`merge_sort2.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-merge_sort2.Tpo $(DEPDIR)/libcdo_la-merge_sort2.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='merge_sort2.c' object='libcdo_la-merge_sort2.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-merge_sort2.lo `test -f 'merge_sort2.c' || echo '$(srcdir)/'`merge_sort2.c
+
+libcdo_la-modules.lo: modules.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-modules.lo -MD -MP -MF $(DEPDIR)/libcdo_la-modules.Tpo -c -o libcdo_la-modules.lo `test -f 'modules.c' || echo '$(srcdir)/'`modules.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-modules.Tpo $(DEPDIR)/libcdo_la-modules.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='modules.c' object='libcdo_la-modules.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-modules.lo `test -f 'modules.c' || echo '$(srcdir)/'`modules.c
+
+libcdo_la-namelist.lo: namelist.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-namelist.lo -MD -MP -MF $(DEPDIR)/libcdo_la-namelist.Tpo -c -o libcdo_la-namelist.lo `test -f 'namelist.c' || echo '$(srcdir)/'`namelist.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-namelist.Tpo $(DEPDIR)/libcdo_la-namelist.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='namelist.c' object='libcdo_la-namelist.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-namelist.lo `test -f 'namelist.c' || echo '$(srcdir)/'`namelist.c
+
+libcdo_la-normal.lo: normal.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-normal.lo -MD -MP -MF $(DEPDIR)/libcdo_la-normal.Tpo -c -o libcdo_la-normal.lo `test -f 'normal.c' || echo '$(srcdir)/'`normal.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-normal.Tpo $(DEPDIR)/libcdo_la-normal.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='normal.c' object='libcdo_la-normal.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-normal.lo `test -f 'normal.c' || echo '$(srcdir)/'`normal.c
+
+libcdo_la-nth_element.lo: nth_element.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-nth_element.lo -MD -MP -MF $(DEPDIR)/libcdo_la-nth_element.Tpo -c -o libcdo_la-nth_element.lo `test -f 'nth_element.c' || echo '$(srcdir)/'`nth_element.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-nth_element.Tpo $(DEPDIR)/libcdo_la-nth_element.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nth_element.c' object='libcdo_la-nth_element.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-nth_element.lo `test -f 'nth_element.c' || echo '$(srcdir)/'`nth_element.c
+
+libcdo_la-par_io.lo: par_io.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-par_io.lo -MD -MP -MF $(DEPDIR)/libcdo_la-par_io.Tpo -c -o libcdo_la-par_io.lo `test -f 'par_io.c' || echo '$(srcdir)/'`par_io.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-par_io.Tpo $(DEPDIR)/libcdo_la-par_io.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='par_io.c' object='libcdo_la-par_io.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-par_io.lo `test -f 'par_io.c' || echo '$(srcdir)/'`par_io.c
+
+libcdo_la-percentiles.lo: percentiles.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-percentiles.lo -MD -MP -MF $(DEPDIR)/libcdo_la-percentiles.Tpo -c -o libcdo_la-percentiles.lo `test -f 'percentiles.c' || echo '$(srcdir)/'`percentiles.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-percentiles.Tpo $(DEPDIR)/libcdo_la-percentiles.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='percentiles.c' object='libcdo_la-percentiles.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-percentiles.lo `test -f 'percentiles.c' || echo '$(srcdir)/'`percentiles.c
+
+libcdo_la-pipe.lo: pipe.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-pipe.lo -MD -MP -MF $(DEPDIR)/libcdo_la-pipe.Tpo -c -o libcdo_la-pipe.lo `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-pipe.Tpo $(DEPDIR)/libcdo_la-pipe.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pipe.c' object='libcdo_la-pipe.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-pipe.lo `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c
+
+libcdo_la-process.lo: process.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-process.lo -MD -MP -MF $(DEPDIR)/libcdo_la-process.Tpo -c -o libcdo_la-process.lo `test -f 'process.c' || echo '$(srcdir)/'`process.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-process.Tpo $(DEPDIR)/libcdo_la-process.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='process.c' object='libcdo_la-process.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-process.lo `test -f 'process.c' || echo '$(srcdir)/'`process.c
+
+libcdo_la-pstream.lo: pstream.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-pstream.lo -MD -MP -MF $(DEPDIR)/libcdo_la-pstream.Tpo -c -o libcdo_la-pstream.lo `test -f 'pstream.c' || echo '$(srcdir)/'`pstream.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-pstream.Tpo $(DEPDIR)/libcdo_la-pstream.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pstream.c' object='libcdo_la-pstream.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-pstream.lo `test -f 'pstream.c' || echo '$(srcdir)/'`pstream.c
+
+libcdo_la-pthread_debug.lo: pthread_debug.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-pthread_debug.lo -MD -MP -MF $(DEPDIR)/libcdo_la-pthread_debug.Tpo -c -o libcdo_la-pthread_debug.lo `test -f 'pthread_debug.c' || echo '$(srcdir)/'`pthread_debug.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-pthread_debug.Tpo $(DEPDIR)/libcdo_la-pthread_debug.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pthread_debug.c' object='libcdo_la-pthread_debug.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-pthread_debug.lo `test -f 'pthread_debug.c' || echo '$(srcdir)/'`pthread_debug.c
+
+libcdo_la-readline.lo: readline.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-readline.lo -MD -MP -MF $(DEPDIR)/libcdo_la-readline.Tpo -c -o libcdo_la-readline.lo `test -f 'readline.c' || echo '$(srcdir)/'`readline.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-readline.Tpo $(DEPDIR)/libcdo_la-readline.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='readline.c' object='libcdo_la-readline.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-readline.lo `test -f 'readline.c' || echo '$(srcdir)/'`readline.c
+
+libcdo_la-realtime.lo: realtime.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-realtime.lo -MD -MP -MF $(DEPDIR)/libcdo_la-realtime.Tpo -c -o libcdo_la-realtime.lo `test -f 'realtime.c' || echo '$(srcdir)/'`realtime.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-realtime.Tpo $(DEPDIR)/libcdo_la-realtime.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='realtime.c' object='libcdo_la-realtime.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-realtime.lo `test -f 'realtime.c' || echo '$(srcdir)/'`realtime.c
+
+libcdo_la-remaplib.lo: remaplib.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remaplib.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remaplib.Tpo -c -o libcdo_la-remaplib.lo `test -f 'remaplib.c' || echo '$(srcdir)/'`remaplib.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remaplib.Tpo $(DEPDIR)/libcdo_la-remaplib.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remaplib.c' object='libcdo_la-remaplib.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remaplib.lo `test -f 'remaplib.c' || echo '$(srcdir)/'`remaplib.c
+
+libcdo_la-remapsort.lo: remapsort.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remapsort.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remapsort.Tpo -c -o libcdo_la-remapsort.lo `test -f 'remapsort.c' || echo '$(srcdir)/'`remapsort.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remapsort.Tpo $(DEPDIR)/libcdo_la-remapsort.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remapsort.c' object='libcdo_la-remapsort.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remapsort.lo `test -f 'remapsort.c' || echo '$(srcdir)/'`remapsort.c
+
+libcdo_la-remap_scrip_io.lo: remap_scrip_io.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_scrip_io.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_scrip_io.Tpo -c -o libcdo_la-remap_scrip_io.lo `test -f 'remap_scrip_io.c' || echo '$(srcdir)/'`remap_scrip_io.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_scrip_io.Tpo $(DEPDIR)/libcdo_la-remap_scrip_io.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_scrip_io.c' object='libcdo_la-remap_scrip_io.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_scrip_io.lo `test -f 'remap_scrip_io.c' || echo '$(srcdir)/'`remap_scrip_io.c
+
+libcdo_la-remap_search_reg2d.lo: remap_search_reg2d.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_search_reg2d.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_search_reg2d.Tpo -c -o libcdo_la-remap_search_reg2d.lo `test -f 'remap_search_reg2d.c' || echo '$(srcdir)/'`remap_search_reg2d.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_search_reg2d.Tpo $(DEPDIR)/libcdo_la-remap_search_reg2d.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_reg2d.c' object='libcdo_la-remap_search_reg2d.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_search_reg2d.lo `test -f 'remap_search_reg2d.c' || echo '$(srcdir)/'`remap_search_reg2d.c
+
+libcdo_la-remap_search_latbins.lo: remap_search_latbins.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_search_latbins.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_search_latbins.Tpo -c -o libcdo_la-remap_search_latbins.lo `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_search_latbins.Tpo $(DEPDIR)/libcdo_la-remap_search_latbins.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_latbins.c' object='libcdo_la-remap_search_latbins.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_search_latbins.lo `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
+
+libcdo_la-remap_store_link.lo: remap_store_link.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_store_link.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_store_link.Tpo -c -o libcdo_la-remap_store_link.lo `test -f 'remap_store_link.c' || echo '$(srcdir)/'`remap_store_link.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_store_link.Tpo $(DEPDIR)/libcdo_la-remap_store_link.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_store_link.c' object='libcdo_la-remap_store_link.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_store_link.lo `test -f 'remap_store_link.c' || echo '$(srcdir)/'`remap_store_link.c
+
+libcdo_la-remap_store_link_cnsrv.lo: remap_store_link_cnsrv.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_store_link_cnsrv.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_store_link_cnsrv.Tpo -c -o libcdo_la-remap_store_link_cnsrv.lo `test -f 'remap_store_link_cnsrv.c' || echo '$(srcdir)/'`remap_store_link_cnsrv.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_store_link_cnsrv.Tpo $(DEPDIR)/libcdo_la-remap_store_link_cnsrv.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_store_link_cnsrv.c' object='libcdo_la-remap_store_link_cnsrv.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_store_link_cnsrv.lo `test -f 'remap_store_link_cnsrv.c' || echo '$(srcdir)/'`remap_store_link_cnsrv.c
+
+libcdo_la-remap_conserv.lo: remap_conserv.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_conserv.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_conserv.Tpo -c -o libcdo_la-remap_conserv.lo `test -f 'remap_conserv.c' || echo '$(srcdir)/'`remap_conserv.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_conserv.Tpo $(DEPDIR)/libcdo_la-remap_conserv.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv.c' object='libcdo_la-remap_conserv.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_conserv.lo `test -f 'remap_conserv.c' || echo '$(srcdir)/'`remap_conserv.c
+
+libcdo_la-remap_conserv_scrip.lo: remap_conserv_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_conserv_scrip.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_conserv_scrip.Tpo -c -o libcdo_la-remap_conserv_scrip.lo `test -f 'remap_conserv_scrip.c' || echo '$(srcdir)/'`remap_conserv_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_conserv_scrip.Tpo $(DEPDIR)/libcdo_la-remap_conserv_scrip.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv_scrip.c' object='libcdo_la-remap_conserv_scrip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_conserv_scrip.lo `test -f 'remap_conserv_scrip.c' || echo '$(srcdir)/'`remap_conserv_scrip.c
+
+libcdo_la-remap_distwgt_scrip.lo: remap_distwgt_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_distwgt_scrip.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_distwgt_scrip.Tpo -c -o libcdo_la-remap_distwgt_scrip.lo `test -f 'remap_distwgt_scrip.c' || echo '$(srcdir)/'`remap_distwgt_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_distwgt_scrip.Tpo $(DEPDIR)/libcdo_la-remap_distwgt_scrip.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_distwgt_scrip.c' object='libcdo_la-remap_distwgt_scrip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_distwgt_scrip.lo `test -f 'remap_distwgt_scrip.c' || echo '$(srcdir)/'`remap_distwgt_scrip.c
+
+libcdo_la-remap_bicubic_scrip.lo: remap_bicubic_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_bicubic_scrip.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_bicubic_scrip.Tpo -c -o libcdo_la-remap_bicubic_scrip.lo `test -f 'remap_bicubic_scrip.c' || echo '$(srcdir)/'`remap_bicubic_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_bicubic_scrip.Tpo $(DEPDIR)/libcdo_la-remap_bicubic_scrip.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bicubic_scrip.c' object='libcdo_la-remap_bicubic_scrip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_bicubic_scrip.lo `test -f 'remap_bicubic_scrip.c' || echo '$(srcdir)/'`remap_bicubic_scrip.c
+
+libcdo_la-remap_bilinear_scrip.lo: remap_bilinear_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-remap_bilinear_scrip.lo -MD -MP -MF $(DEPDIR)/libcdo_la-remap_bilinear_scrip.Tpo -c -o libcdo_la-remap_bilinear_scrip.lo `test -f 'remap_bilinear_scrip.c' || echo '$(srcdir)/'`remap_bilinear_scrip.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-remap_bilinear_scrip.Tpo $(DEPDIR)/libcdo_la-remap_bilinear_scrip.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bilinear_scrip.c' object='libcdo_la-remap_bilinear_scrip.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-remap_bilinear_scrip.lo `test -f 'remap_bilinear_scrip.c' || echo '$(srcdir)/'`remap_bilinear_scrip.c
+
+libcdo_la-stdnametable.lo: stdnametable.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-stdnametable.lo -MD -MP -MF $(DEPDIR)/libcdo_la-stdnametable.Tpo -c -o libcdo_la-stdnametable.lo `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-stdnametable.Tpo $(DEPDIR)/libcdo_la-stdnametable.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stdnametable.c' object='libcdo_la-stdnametable.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-stdnametable.lo `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
+
+libcdo_la-specspace.lo: specspace.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-specspace.lo -MD -MP -MF $(DEPDIR)/libcdo_la-specspace.Tpo -c -o libcdo_la-specspace.lo `test -f 'specspace.c' || echo '$(srcdir)/'`specspace.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-specspace.Tpo $(DEPDIR)/libcdo_la-specspace.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='specspace.c' object='libcdo_la-specspace.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-specspace.lo `test -f 'specspace.c' || echo '$(srcdir)/'`specspace.c
+
+libcdo_la-statistic.lo: statistic.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-statistic.lo -MD -MP -MF $(DEPDIR)/libcdo_la-statistic.Tpo -c -o libcdo_la-statistic.lo `test -f 'statistic.c' || echo '$(srcdir)/'`statistic.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-statistic.Tpo $(DEPDIR)/libcdo_la-statistic.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='statistic.c' object='libcdo_la-statistic.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-statistic.lo `test -f 'statistic.c' || echo '$(srcdir)/'`statistic.c
+
+libcdo_la-table.lo: table.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-table.lo -MD -MP -MF $(DEPDIR)/libcdo_la-table.Tpo -c -o libcdo_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-table.Tpo $(DEPDIR)/libcdo_la-table.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table.c' object='libcdo_la-table.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-table.lo `test -f 'table.c' || echo '$(srcdir)/'`table.c
+
+libcdo_la-text.lo: text.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-text.lo -MD -MP -MF $(DEPDIR)/libcdo_la-text.Tpo -c -o libcdo_la-text.lo `test -f 'text.c' || echo '$(srcdir)/'`text.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-text.Tpo $(DEPDIR)/libcdo_la-text.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='text.c' object='libcdo_la-text.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-text.lo `test -f 'text.c' || echo '$(srcdir)/'`text.c
+
+libcdo_la-timer.lo: timer.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-timer.lo -MD -MP -MF $(DEPDIR)/libcdo_la-timer.Tpo -c -o libcdo_la-timer.lo `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-timer.Tpo $(DEPDIR)/libcdo_la-timer.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='timer.c' object='libcdo_la-timer.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-timer.lo `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
+
+libcdo_la-userlog.lo: userlog.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-userlog.lo -MD -MP -MF $(DEPDIR)/libcdo_la-userlog.Tpo -c -o libcdo_la-userlog.lo `test -f 'userlog.c' || echo '$(srcdir)/'`userlog.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-userlog.Tpo $(DEPDIR)/libcdo_la-userlog.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='userlog.c' object='libcdo_la-userlog.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-userlog.lo `test -f 'userlog.c' || echo '$(srcdir)/'`userlog.c
+
+libcdo_la-util.lo: util.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-util.lo -MD -MP -MF $(DEPDIR)/libcdo_la-util.Tpo -c -o libcdo_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-util.Tpo $(DEPDIR)/libcdo_la-util.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='util.c' object='libcdo_la-util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-util.lo `test -f 'util.c' || echo '$(srcdir)/'`util.c
+
+libcdo_la-zaxis.lo: zaxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcdo_la-zaxis.lo -MD -MP -MF $(DEPDIR)/libcdo_la-zaxis.Tpo -c -o libcdo_la-zaxis.lo `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcdo_la-zaxis.Tpo $(DEPDIR)/libcdo_la-zaxis.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='zaxis.c' object='libcdo_la-zaxis.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcdo_la-zaxis.lo `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
+
+clipping/libcdo_la-clipping.lo: clipping/clipping.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-clipping.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-clipping.Tpo -c -o clipping/libcdo_la-clipping.lo `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-clipping.Tpo clipping/$(DEPDIR)/libcdo_la-clipping.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/clipping.c' object='clipping/libcdo_la-clipping.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-clipping.lo `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
+
+clipping/libcdo_la-area.lo: clipping/area.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-area.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-area.Tpo -c -o clipping/libcdo_la-area.lo `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-area.Tpo clipping/$(DEPDIR)/libcdo_la-area.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/area.c' object='clipping/libcdo_la-area.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-area.lo `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
+
+clipping/libcdo_la-ensure_array_size.lo: clipping/ensure_array_size.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-ensure_array_size.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-ensure_array_size.Tpo -c -o clipping/libcdo_la-ensure_array_size.lo `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-ensure_array_size.Tpo clipping/$(DEPDIR)/libcdo_la-ensure_array_size.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/ensure_array_size.c' object='clipping/libcdo_la-ensure_array_size.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-ensure_array_size.lo `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
+
+clipping/libcdo_la-grid_cell.lo: clipping/grid_cell.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-grid_cell.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-grid_cell.Tpo -c -o clipping/libcdo_la-grid_cell.lo `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-grid_cell.Tpo clipping/$(DEPDIR)/libcdo_la-grid_cell.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/grid_cell.c' object='clipping/libcdo_la-grid_cell.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-grid_cell.lo `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
+
+clipping/libcdo_la-intersection.lo: clipping/intersection.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-intersection.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-intersection.Tpo -c -o clipping/libcdo_la-intersection.lo `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-intersection.Tpo clipping/$(DEPDIR)/libcdo_la-intersection.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/intersection.c' object='clipping/libcdo_la-intersection.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-intersection.lo `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
+
+clipping/libcdo_la-utils.lo: clipping/utils.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/libcdo_la-utils.lo -MD -MP -MF clipping/$(DEPDIR)/libcdo_la-utils.Tpo -c -o clipping/libcdo_la-utils.lo `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/libcdo_la-utils.Tpo clipping/$(DEPDIR)/libcdo_la-utils.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/utils.c' object='clipping/libcdo_la-utils.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcdo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/libcdo_la-utils.lo `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
+
 cdo-cdo.o: cdo.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo.o -MD -MP -MF $(DEPDIR)/cdo-cdo.Tpo -c -o cdo-cdo.o `test -f 'cdo.c' || echo '$(srcdir)/'`cdo.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo.Tpo $(DEPDIR)/cdo-cdo.Po
@@ -1105,6 +1696,20 @@ cdo-Adisit.obj: Adisit.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Adisit.obj `if test -f 'Adisit.c'; then $(CYGPATH_W) 'Adisit.c'; else $(CYGPATH_W) '$(srcdir)/Adisit.c'; fi`
 
+cdo-Afterburner.o: Afterburner.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Afterburner.o -MD -MP -MF $(DEPDIR)/cdo-Afterburner.Tpo -c -o cdo-Afterburner.o `test -f 'Afterburner.c' || echo '$(srcdir)/'`Afterburner.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Afterburner.Tpo $(DEPDIR)/cdo-Afterburner.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Afterburner.c' object='cdo-Afterburner.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Afterburner.o `test -f 'Afterburner.c' || echo '$(srcdir)/'`Afterburner.c
+
+cdo-Afterburner.obj: Afterburner.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Afterburner.obj -MD -MP -MF $(DEPDIR)/cdo-Afterburner.Tpo -c -o cdo-Afterburner.obj `if test -f 'Afterburner.c'; then $(CYGPATH_W) 'Afterburner.c'; else $(CYGPATH_W) '$(srcdir)/Afterburner.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Afterburner.Tpo $(DEPDIR)/cdo-Afterburner.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Afterburner.c' object='cdo-Afterburner.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Afterburner.obj `if test -f 'Afterburner.c'; then $(CYGPATH_W) 'Afterburner.c'; else $(CYGPATH_W) '$(srcdir)/Afterburner.c'; fi`
+
 cdo-Arith.o: Arith.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Arith.o -MD -MP -MF $(DEPDIR)/cdo-Arith.Tpo -c -o cdo-Arith.o `test -f 'Arith.c' || echo '$(srcdir)/'`Arith.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Arith.Tpo $(DEPDIR)/cdo-Arith.Po
@@ -3261,19 +3866,33 @@ cdo-Varrms.obj: Varrms.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Varrms.obj `if test -f 'Varrms.c'; then $(CYGPATH_W) 'Varrms.c'; else $(CYGPATH_W) '$(srcdir)/Varrms.c'; fi`
 
-cdo-Vertint.o: Vertint.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertint.o -MD -MP -MF $(DEPDIR)/cdo-Vertint.Tpo -c -o cdo-Vertint.o `test -f 'Vertint.c' || echo '$(srcdir)/'`Vertint.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertint.Tpo $(DEPDIR)/cdo-Vertint.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertint.c' object='cdo-Vertint.o' libtool=no @AMDEPBACKSLASH@
+cdo-Vertintml.o: Vertintml.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertintml.o -MD -MP -MF $(DEPDIR)/cdo-Vertintml.Tpo -c -o cdo-Vertintml.o `test -f 'Vertintml.c' || echo '$(srcdir)/'`Vertintml.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertintml.Tpo $(DEPDIR)/cdo-Vertintml.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertintml.c' object='cdo-Vertintml.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertint.o `test -f 'Vertint.c' || echo '$(srcdir)/'`Vertint.c
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertintml.o `test -f 'Vertintml.c' || echo '$(srcdir)/'`Vertintml.c
 
-cdo-Vertint.obj: Vertint.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertint.obj -MD -MP -MF $(DEPDIR)/cdo-Vertint.Tpo -c -o cdo-Vertint.obj `if test -f 'Vertint.c'; then $(CYGPATH_W) 'Vertint.c'; else $(CYGPATH_W) '$(srcdir)/Vertint.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertint.Tpo $(DEPDIR)/cdo-Vertint.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertint.c' object='cdo-Vertint.obj' libtool=no @AMDEPBACKSLASH@
+cdo-Vertintml.obj: Vertintml.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertintml.obj -MD -MP -MF $(DEPDIR)/cdo-Vertintml.Tpo -c -o cdo-Vertintml.obj `if test -f 'Vertintml.c'; then $(CYGPATH_W) 'Vertintml.c'; else $(CYGPATH_W) '$(srcdir)/Vertintml.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertintml.Tpo $(DEPDIR)/cdo-Vertintml.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertintml.c' object='cdo-Vertintml.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertint.obj `if test -f 'Vertint.c'; then $(CYGPATH_W) 'Vertint.c'; else $(CYGPATH_W) '$(srcdir)/Vertint.c'; fi`
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertintml.obj `if test -f 'Vertintml.c'; then $(CYGPATH_W) 'Vertintml.c'; else $(CYGPATH_W) '$(srcdir)/Vertintml.c'; fi`
+
+cdo-Vertintap.o: Vertintap.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertintap.o -MD -MP -MF $(DEPDIR)/cdo-Vertintap.Tpo -c -o cdo-Vertintap.o `test -f 'Vertintap.c' || echo '$(srcdir)/'`Vertintap.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertintap.Tpo $(DEPDIR)/cdo-Vertintap.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertintap.c' object='cdo-Vertintap.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertintap.o `test -f 'Vertintap.c' || echo '$(srcdir)/'`Vertintap.c
+
+cdo-Vertintap.obj: Vertintap.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertintap.obj -MD -MP -MF $(DEPDIR)/cdo-Vertintap.Tpo -c -o cdo-Vertintap.obj `if test -f 'Vertintap.c'; then $(CYGPATH_W) 'Vertintap.c'; else $(CYGPATH_W) '$(srcdir)/Vertintap.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Vertintap.Tpo $(DEPDIR)/cdo-Vertintap.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='Vertintap.c' object='cdo-Vertintap.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Vertintap.obj `if test -f 'Vertintap.c'; then $(CYGPATH_W) 'Vertintap.c'; else $(CYGPATH_W) '$(srcdir)/Vertintap.c'; fi`
 
 cdo-Vertstat.o: Vertstat.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Vertstat.o -MD -MP -MF $(DEPDIR)/cdo-Vertstat.Tpo -c -o cdo-Vertstat.o `test -f 'Vertstat.c' || echo '$(srcdir)/'`Vertstat.c
@@ -3569,1112 +4188,6 @@ cdo-Zonstat.obj: Zonstat.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Zonstat.obj `if test -f 'Zonstat.c'; then $(CYGPATH_W) 'Zonstat.c'; else $(CYGPATH_W) '$(srcdir)/Zonstat.c'; fi`
 
-cdo-cdo_pthread.o: cdo_pthread.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_pthread.o -MD -MP -MF $(DEPDIR)/cdo-cdo_pthread.Tpo -c -o cdo-cdo_pthread.o `test -f 'cdo_pthread.c' || echo '$(srcdir)/'`cdo_pthread.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_pthread.Tpo $(DEPDIR)/cdo-cdo_pthread.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_pthread.c' object='cdo-cdo_pthread.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_pthread.o `test -f 'cdo_pthread.c' || echo '$(srcdir)/'`cdo_pthread.c
-
-cdo-cdo_pthread.obj: cdo_pthread.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_pthread.obj -MD -MP -MF $(DEPDIR)/cdo-cdo_pthread.Tpo -c -o cdo-cdo_pthread.obj `if test -f 'cdo_pthread.c'; then $(CYGPATH_W) 'cdo_pthread.c'; else $(CYGPATH_W) '$(srcdir)/cdo_pthread.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_pthread.Tpo $(DEPDIR)/cdo-cdo_pthread.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_pthread.c' object='cdo-cdo_pthread.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_pthread.obj `if test -f 'cdo_pthread.c'; then $(CYGPATH_W) 'cdo_pthread.c'; else $(CYGPATH_W) '$(srcdir)/cdo_pthread.c'; fi`
-
-cdo-cdo_vlist.o: cdo_vlist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_vlist.o -MD -MP -MF $(DEPDIR)/cdo-cdo_vlist.Tpo -c -o cdo-cdo_vlist.o `test -f 'cdo_vlist.c' || echo '$(srcdir)/'`cdo_vlist.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_vlist.Tpo $(DEPDIR)/cdo-cdo_vlist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_vlist.c' object='cdo-cdo_vlist.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_vlist.o `test -f 'cdo_vlist.c' || echo '$(srcdir)/'`cdo_vlist.c
-
-cdo-cdo_vlist.obj: cdo_vlist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_vlist.obj -MD -MP -MF $(DEPDIR)/cdo-cdo_vlist.Tpo -c -o cdo-cdo_vlist.obj `if test -f 'cdo_vlist.c'; then $(CYGPATH_W) 'cdo_vlist.c'; else $(CYGPATH_W) '$(srcdir)/cdo_vlist.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_vlist.Tpo $(DEPDIR)/cdo-cdo_vlist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_vlist.c' object='cdo-cdo_vlist.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_vlist.obj `if test -f 'cdo_vlist.c'; then $(CYGPATH_W) 'cdo_vlist.c'; else $(CYGPATH_W) '$(srcdir)/cdo_vlist.c'; fi`
-
-cdo-cdo_getopt.o: cdo_getopt.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_getopt.o -MD -MP -MF $(DEPDIR)/cdo-cdo_getopt.Tpo -c -o cdo-cdo_getopt.o `test -f 'cdo_getopt.c' || echo '$(srcdir)/'`cdo_getopt.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_getopt.Tpo $(DEPDIR)/cdo-cdo_getopt.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_getopt.c' object='cdo-cdo_getopt.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_getopt.o `test -f 'cdo_getopt.c' || echo '$(srcdir)/'`cdo_getopt.c
-
-cdo-cdo_getopt.obj: cdo_getopt.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-cdo_getopt.obj -MD -MP -MF $(DEPDIR)/cdo-cdo_getopt.Tpo -c -o cdo-cdo_getopt.obj `if test -f 'cdo_getopt.c'; then $(CYGPATH_W) 'cdo_getopt.c'; else $(CYGPATH_W) '$(srcdir)/cdo_getopt.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-cdo_getopt.Tpo $(DEPDIR)/cdo-cdo_getopt.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='cdo_getopt.c' object='cdo-cdo_getopt.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo_getopt.obj `if test -f 'cdo_getopt.c'; then $(CYGPATH_W) 'cdo_getopt.c'; else $(CYGPATH_W) '$(srcdir)/cdo_getopt.c'; fi`
-
-cdo-color.o: color.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-color.o -MD -MP -MF $(DEPDIR)/cdo-color.Tpo -c -o cdo-color.o `test -f 'color.c' || echo '$(srcdir)/'`color.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-color.Tpo $(DEPDIR)/cdo-color.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='color.c' object='cdo-color.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-color.o `test -f 'color.c' || echo '$(srcdir)/'`color.c
-
-cdo-color.obj: color.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-color.obj -MD -MP -MF $(DEPDIR)/cdo-color.Tpo -c -o cdo-color.obj `if test -f 'color.c'; then $(CYGPATH_W) 'color.c'; else $(CYGPATH_W) '$(srcdir)/color.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-color.Tpo $(DEPDIR)/cdo-color.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='color.c' object='cdo-color.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-color.obj `if test -f 'color.c'; then $(CYGPATH_W) 'color.c'; else $(CYGPATH_W) '$(srcdir)/color.c'; fi`
-
-cdo-commandline.o: commandline.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-commandline.o -MD -MP -MF $(DEPDIR)/cdo-commandline.Tpo -c -o cdo-commandline.o `test -f 'commandline.c' || echo '$(srcdir)/'`commandline.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-commandline.Tpo $(DEPDIR)/cdo-commandline.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='commandline.c' object='cdo-commandline.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-commandline.o `test -f 'commandline.c' || echo '$(srcdir)/'`commandline.c
-
-cdo-commandline.obj: commandline.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-commandline.obj -MD -MP -MF $(DEPDIR)/cdo-commandline.Tpo -c -o cdo-commandline.obj `if test -f 'commandline.c'; then $(CYGPATH_W) 'commandline.c'; else $(CYGPATH_W) '$(srcdir)/commandline.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-commandline.Tpo $(DEPDIR)/cdo-commandline.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='commandline.c' object='cdo-commandline.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-commandline.obj `if test -f 'commandline.c'; then $(CYGPATH_W) 'commandline.c'; else $(CYGPATH_W) '$(srcdir)/commandline.c'; fi`
-
-cdo-ecacore.o: ecacore.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ecacore.o -MD -MP -MF $(DEPDIR)/cdo-ecacore.Tpo -c -o cdo-ecacore.o `test -f 'ecacore.c' || echo '$(srcdir)/'`ecacore.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-ecacore.Tpo $(DEPDIR)/cdo-ecacore.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecacore.c' object='cdo-ecacore.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ecacore.o `test -f 'ecacore.c' || echo '$(srcdir)/'`ecacore.c
-
-cdo-ecacore.obj: ecacore.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ecacore.obj -MD -MP -MF $(DEPDIR)/cdo-ecacore.Tpo -c -o cdo-ecacore.obj `if test -f 'ecacore.c'; then $(CYGPATH_W) 'ecacore.c'; else $(CYGPATH_W) '$(srcdir)/ecacore.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-ecacore.Tpo $(DEPDIR)/cdo-ecacore.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecacore.c' object='cdo-ecacore.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ecacore.obj `if test -f 'ecacore.c'; then $(CYGPATH_W) 'ecacore.c'; else $(CYGPATH_W) '$(srcdir)/ecacore.c'; fi`
-
-cdo-ecautil.o: ecautil.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ecautil.o -MD -MP -MF $(DEPDIR)/cdo-ecautil.Tpo -c -o cdo-ecautil.o `test -f 'ecautil.c' || echo '$(srcdir)/'`ecautil.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-ecautil.Tpo $(DEPDIR)/cdo-ecautil.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecautil.c' object='cdo-ecautil.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ecautil.o `test -f 'ecautil.c' || echo '$(srcdir)/'`ecautil.c
-
-cdo-ecautil.obj: ecautil.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ecautil.obj -MD -MP -MF $(DEPDIR)/cdo-ecautil.Tpo -c -o cdo-ecautil.obj `if test -f 'ecautil.c'; then $(CYGPATH_W) 'ecautil.c'; else $(CYGPATH_W) '$(srcdir)/ecautil.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-ecautil.Tpo $(DEPDIR)/cdo-ecautil.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ecautil.c' object='cdo-ecautil.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ecautil.obj `if test -f 'ecautil.c'; then $(CYGPATH_W) 'ecautil.c'; else $(CYGPATH_W) '$(srcdir)/ecautil.c'; fi`
-
-cdo-exception.o: exception.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-exception.o -MD -MP -MF $(DEPDIR)/cdo-exception.Tpo -c -o cdo-exception.o `test -f 'exception.c' || echo '$(srcdir)/'`exception.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-exception.Tpo $(DEPDIR)/cdo-exception.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='exception.c' object='cdo-exception.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-exception.o `test -f 'exception.c' || echo '$(srcdir)/'`exception.c
-
-cdo-exception.obj: exception.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-exception.obj -MD -MP -MF $(DEPDIR)/cdo-exception.Tpo -c -o cdo-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-exception.Tpo $(DEPDIR)/cdo-exception.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='exception.c' object='cdo-exception.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-exception.obj `if test -f 'exception.c'; then $(CYGPATH_W) 'exception.c'; else $(CYGPATH_W) '$(srcdir)/exception.c'; fi`
-
-cdo-expr.o: expr.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr.o -MD -MP -MF $(DEPDIR)/cdo-expr.Tpo -c -o cdo-expr.o `test -f 'expr.c' || echo '$(srcdir)/'`expr.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr.Tpo $(DEPDIR)/cdo-expr.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr.c' object='cdo-expr.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr.o `test -f 'expr.c' || echo '$(srcdir)/'`expr.c
-
-cdo-expr.obj: expr.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr.obj -MD -MP -MF $(DEPDIR)/cdo-expr.Tpo -c -o cdo-expr.obj `if test -f 'expr.c'; then $(CYGPATH_W) 'expr.c'; else $(CYGPATH_W) '$(srcdir)/expr.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr.Tpo $(DEPDIR)/cdo-expr.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr.c' object='cdo-expr.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr.obj `if test -f 'expr.c'; then $(CYGPATH_W) 'expr.c'; else $(CYGPATH_W) '$(srcdir)/expr.c'; fi`
-
-cdo-expr_lex.o: expr_lex.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr_lex.o -MD -MP -MF $(DEPDIR)/cdo-expr_lex.Tpo -c -o cdo-expr_lex.o `test -f 'expr_lex.c' || echo '$(srcdir)/'`expr_lex.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr_lex.Tpo $(DEPDIR)/cdo-expr_lex.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_lex.c' object='cdo-expr_lex.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr_lex.o `test -f 'expr_lex.c' || echo '$(srcdir)/'`expr_lex.c
-
-cdo-expr_lex.obj: expr_lex.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr_lex.obj -MD -MP -MF $(DEPDIR)/cdo-expr_lex.Tpo -c -o cdo-expr_lex.obj `if test -f 'expr_lex.c'; then $(CYGPATH_W) 'expr_lex.c'; else $(CYGPATH_W) '$(srcdir)/expr_lex.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr_lex.Tpo $(DEPDIR)/cdo-expr_lex.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_lex.c' object='cdo-expr_lex.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr_lex.obj `if test -f 'expr_lex.c'; then $(CYGPATH_W) 'expr_lex.c'; else $(CYGPATH_W) '$(srcdir)/expr_lex.c'; fi`
-
-cdo-expr_yacc.o: expr_yacc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr_yacc.o -MD -MP -MF $(DEPDIR)/cdo-expr_yacc.Tpo -c -o cdo-expr_yacc.o `test -f 'expr_yacc.c' || echo '$(srcdir)/'`expr_yacc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr_yacc.Tpo $(DEPDIR)/cdo-expr_yacc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_yacc.c' object='cdo-expr_yacc.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr_yacc.o `test -f 'expr_yacc.c' || echo '$(srcdir)/'`expr_yacc.c
-
-cdo-expr_yacc.obj: expr_yacc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-expr_yacc.obj -MD -MP -MF $(DEPDIR)/cdo-expr_yacc.Tpo -c -o cdo-expr_yacc.obj `if test -f 'expr_yacc.c'; then $(CYGPATH_W) 'expr_yacc.c'; else $(CYGPATH_W) '$(srcdir)/expr_yacc.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-expr_yacc.Tpo $(DEPDIR)/cdo-expr_yacc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='expr_yacc.c' object='cdo-expr_yacc.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-expr_yacc.obj `if test -f 'expr_yacc.c'; then $(CYGPATH_W) 'expr_yacc.c'; else $(CYGPATH_W) '$(srcdir)/expr_yacc.c'; fi`
-
-cdo-features.o: features.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-features.o -MD -MP -MF $(DEPDIR)/cdo-features.Tpo -c -o cdo-features.o `test -f 'features.c' || echo '$(srcdir)/'`features.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-features.Tpo $(DEPDIR)/cdo-features.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='features.c' object='cdo-features.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-features.o `test -f 'features.c' || echo '$(srcdir)/'`features.c
-
-cdo-features.obj: features.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-features.obj -MD -MP -MF $(DEPDIR)/cdo-features.Tpo -c -o cdo-features.obj `if test -f 'features.c'; then $(CYGPATH_W) 'features.c'; else $(CYGPATH_W) '$(srcdir)/features.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-features.Tpo $(DEPDIR)/cdo-features.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='features.c' object='cdo-features.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-features.obj `if test -f 'features.c'; then $(CYGPATH_W) 'features.c'; else $(CYGPATH_W) '$(srcdir)/features.c'; fi`
-
-cdo-field.o: field.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-field.o -MD -MP -MF $(DEPDIR)/cdo-field.Tpo -c -o cdo-field.o `test -f 'field.c' || echo '$(srcdir)/'`field.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-field.Tpo $(DEPDIR)/cdo-field.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field.c' object='cdo-field.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-field.o `test -f 'field.c' || echo '$(srcdir)/'`field.c
-
-cdo-field.obj: field.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-field.obj -MD -MP -MF $(DEPDIR)/cdo-field.Tpo -c -o cdo-field.obj `if test -f 'field.c'; then $(CYGPATH_W) 'field.c'; else $(CYGPATH_W) '$(srcdir)/field.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-field.Tpo $(DEPDIR)/cdo-field.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field.c' object='cdo-field.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-field.obj `if test -f 'field.c'; then $(CYGPATH_W) 'field.c'; else $(CYGPATH_W) '$(srcdir)/field.c'; fi`
-
-cdo-field2.o: field2.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-field2.o -MD -MP -MF $(DEPDIR)/cdo-field2.Tpo -c -o cdo-field2.o `test -f 'field2.c' || echo '$(srcdir)/'`field2.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-field2.Tpo $(DEPDIR)/cdo-field2.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field2.c' object='cdo-field2.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-field2.o `test -f 'field2.c' || echo '$(srcdir)/'`field2.c
-
-cdo-field2.obj: field2.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-field2.obj -MD -MP -MF $(DEPDIR)/cdo-field2.Tpo -c -o cdo-field2.obj `if test -f 'field2.c'; then $(CYGPATH_W) 'field2.c'; else $(CYGPATH_W) '$(srcdir)/field2.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-field2.Tpo $(DEPDIR)/cdo-field2.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='field2.c' object='cdo-field2.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-field2.obj `if test -f 'field2.c'; then $(CYGPATH_W) 'field2.c'; else $(CYGPATH_W) '$(srcdir)/field2.c'; fi`
-
-cdo-fieldc.o: fieldc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldc.o -MD -MP -MF $(DEPDIR)/cdo-fieldc.Tpo -c -o cdo-fieldc.o `test -f 'fieldc.c' || echo '$(srcdir)/'`fieldc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldc.Tpo $(DEPDIR)/cdo-fieldc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldc.c' object='cdo-fieldc.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldc.o `test -f 'fieldc.c' || echo '$(srcdir)/'`fieldc.c
-
-cdo-fieldc.obj: fieldc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldc.obj -MD -MP -MF $(DEPDIR)/cdo-fieldc.Tpo -c -o cdo-fieldc.obj `if test -f 'fieldc.c'; then $(CYGPATH_W) 'fieldc.c'; else $(CYGPATH_W) '$(srcdir)/fieldc.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldc.Tpo $(DEPDIR)/cdo-fieldc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldc.c' object='cdo-fieldc.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldc.obj `if test -f 'fieldc.c'; then $(CYGPATH_W) 'fieldc.c'; else $(CYGPATH_W) '$(srcdir)/fieldc.c'; fi`
-
-cdo-fieldmem.o: fieldmem.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldmem.o -MD -MP -MF $(DEPDIR)/cdo-fieldmem.Tpo -c -o cdo-fieldmem.o `test -f 'fieldmem.c' || echo '$(srcdir)/'`fieldmem.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldmem.Tpo $(DEPDIR)/cdo-fieldmem.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmem.c' object='cdo-fieldmem.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldmem.o `test -f 'fieldmem.c' || echo '$(srcdir)/'`fieldmem.c
-
-cdo-fieldmem.obj: fieldmem.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldmem.obj -MD -MP -MF $(DEPDIR)/cdo-fieldmem.Tpo -c -o cdo-fieldmem.obj `if test -f 'fieldmem.c'; then $(CYGPATH_W) 'fieldmem.c'; else $(CYGPATH_W) '$(srcdir)/fieldmem.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldmem.Tpo $(DEPDIR)/cdo-fieldmem.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmem.c' object='cdo-fieldmem.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldmem.obj `if test -f 'fieldmem.c'; then $(CYGPATH_W) 'fieldmem.c'; else $(CYGPATH_W) '$(srcdir)/fieldmem.c'; fi`
-
-cdo-fieldmer.o: fieldmer.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldmer.o -MD -MP -MF $(DEPDIR)/cdo-fieldmer.Tpo -c -o cdo-fieldmer.o `test -f 'fieldmer.c' || echo '$(srcdir)/'`fieldmer.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldmer.Tpo $(DEPDIR)/cdo-fieldmer.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmer.c' object='cdo-fieldmer.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldmer.o `test -f 'fieldmer.c' || echo '$(srcdir)/'`fieldmer.c
-
-cdo-fieldmer.obj: fieldmer.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldmer.obj -MD -MP -MF $(DEPDIR)/cdo-fieldmer.Tpo -c -o cdo-fieldmer.obj `if test -f 'fieldmer.c'; then $(CYGPATH_W) 'fieldmer.c'; else $(CYGPATH_W) '$(srcdir)/fieldmer.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldmer.Tpo $(DEPDIR)/cdo-fieldmer.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldmer.c' object='cdo-fieldmer.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldmer.obj `if test -f 'fieldmer.c'; then $(CYGPATH_W) 'fieldmer.c'; else $(CYGPATH_W) '$(srcdir)/fieldmer.c'; fi`
-
-cdo-fieldzon.o: fieldzon.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldzon.o -MD -MP -MF $(DEPDIR)/cdo-fieldzon.Tpo -c -o cdo-fieldzon.o `test -f 'fieldzon.c' || echo '$(srcdir)/'`fieldzon.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldzon.Tpo $(DEPDIR)/cdo-fieldzon.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldzon.c' object='cdo-fieldzon.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldzon.o `test -f 'fieldzon.c' || echo '$(srcdir)/'`fieldzon.c
-
-cdo-fieldzon.obj: fieldzon.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fieldzon.obj -MD -MP -MF $(DEPDIR)/cdo-fieldzon.Tpo -c -o cdo-fieldzon.obj `if test -f 'fieldzon.c'; then $(CYGPATH_W) 'fieldzon.c'; else $(CYGPATH_W) '$(srcdir)/fieldzon.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fieldzon.Tpo $(DEPDIR)/cdo-fieldzon.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fieldzon.c' object='cdo-fieldzon.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fieldzon.obj `if test -f 'fieldzon.c'; then $(CYGPATH_W) 'fieldzon.c'; else $(CYGPATH_W) '$(srcdir)/fieldzon.c'; fi`
-
-cdo-fouriertrans.o: fouriertrans.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fouriertrans.o -MD -MP -MF $(DEPDIR)/cdo-fouriertrans.Tpo -c -o cdo-fouriertrans.o `test -f 'fouriertrans.c' || echo '$(srcdir)/'`fouriertrans.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fouriertrans.Tpo $(DEPDIR)/cdo-fouriertrans.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fouriertrans.c' object='cdo-fouriertrans.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fouriertrans.o `test -f 'fouriertrans.c' || echo '$(srcdir)/'`fouriertrans.c
-
-cdo-fouriertrans.obj: fouriertrans.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-fouriertrans.obj -MD -MP -MF $(DEPDIR)/cdo-fouriertrans.Tpo -c -o cdo-fouriertrans.obj `if test -f 'fouriertrans.c'; then $(CYGPATH_W) 'fouriertrans.c'; else $(CYGPATH_W) '$(srcdir)/fouriertrans.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-fouriertrans.Tpo $(DEPDIR)/cdo-fouriertrans.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='fouriertrans.c' object='cdo-fouriertrans.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-fouriertrans.obj `if test -f 'fouriertrans.c'; then $(CYGPATH_W) 'fouriertrans.c'; else $(CYGPATH_W) '$(srcdir)/fouriertrans.c'; fi`
-
-cdo-gradsdeslib.o: gradsdeslib.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-gradsdeslib.o -MD -MP -MF $(DEPDIR)/cdo-gradsdeslib.Tpo -c -o cdo-gradsdeslib.o `test -f 'gradsdeslib.c' || echo '$(srcdir)/'`gradsdeslib.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-gradsdeslib.Tpo $(DEPDIR)/cdo-gradsdeslib.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gradsdeslib.c' object='cdo-gradsdeslib.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-gradsdeslib.o `test -f 'gradsdeslib.c' || echo '$(srcdir)/'`gradsdeslib.c
-
-cdo-gradsdeslib.obj: gradsdeslib.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-gradsdeslib.obj -MD -MP -MF $(DEPDIR)/cdo-gradsdeslib.Tpo -c -o cdo-gradsdeslib.obj `if test -f 'gradsdeslib.c'; then $(CYGPATH_W) 'gradsdeslib.c'; else $(CYGPATH_W) '$(srcdir)/gradsdeslib.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-gradsdeslib.Tpo $(DEPDIR)/cdo-gradsdeslib.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gradsdeslib.c' object='cdo-gradsdeslib.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-gradsdeslib.obj `if test -f 'gradsdeslib.c'; then $(CYGPATH_W) 'gradsdeslib.c'; else $(CYGPATH_W) '$(srcdir)/gradsdeslib.c'; fi`
-
-cdo-grid.o: grid.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid.o -MD -MP -MF $(DEPDIR)/cdo-grid.Tpo -c -o cdo-grid.o `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid.Tpo $(DEPDIR)/cdo-grid.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid.c' object='cdo-grid.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid.o `test -f 'grid.c' || echo '$(srcdir)/'`grid.c
-
-cdo-grid.obj: grid.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid.obj -MD -MP -MF $(DEPDIR)/cdo-grid.Tpo -c -o cdo-grid.obj `if test -f 'grid.c'; then $(CYGPATH_W) 'grid.c'; else $(CYGPATH_W) '$(srcdir)/grid.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid.Tpo $(DEPDIR)/cdo-grid.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid.c' object='cdo-grid.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid.obj `if test -f 'grid.c'; then $(CYGPATH_W) 'grid.c'; else $(CYGPATH_W) '$(srcdir)/grid.c'; fi`
-
-cdo-grid_area.o: grid_area.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_area.o -MD -MP -MF $(DEPDIR)/cdo-grid_area.Tpo -c -o cdo-grid_area.o `test -f 'grid_area.c' || echo '$(srcdir)/'`grid_area.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_area.Tpo $(DEPDIR)/cdo-grid_area.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_area.c' object='cdo-grid_area.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_area.o `test -f 'grid_area.c' || echo '$(srcdir)/'`grid_area.c
-
-cdo-grid_area.obj: grid_area.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_area.obj -MD -MP -MF $(DEPDIR)/cdo-grid_area.Tpo -c -o cdo-grid_area.obj `if test -f 'grid_area.c'; then $(CYGPATH_W) 'grid_area.c'; else $(CYGPATH_W) '$(srcdir)/grid_area.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_area.Tpo $(DEPDIR)/cdo-grid_area.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_area.c' object='cdo-grid_area.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_area.obj `if test -f 'grid_area.c'; then $(CYGPATH_W) 'grid_area.c'; else $(CYGPATH_W) '$(srcdir)/grid_area.c'; fi`
-
-cdo-grid_gme.o: grid_gme.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_gme.o -MD -MP -MF $(DEPDIR)/cdo-grid_gme.Tpo -c -o cdo-grid_gme.o `test -f 'grid_gme.c' || echo '$(srcdir)/'`grid_gme.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_gme.Tpo $(DEPDIR)/cdo-grid_gme.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_gme.c' object='cdo-grid_gme.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_gme.o `test -f 'grid_gme.c' || echo '$(srcdir)/'`grid_gme.c
-
-cdo-grid_gme.obj: grid_gme.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_gme.obj -MD -MP -MF $(DEPDIR)/cdo-grid_gme.Tpo -c -o cdo-grid_gme.obj `if test -f 'grid_gme.c'; then $(CYGPATH_W) 'grid_gme.c'; else $(CYGPATH_W) '$(srcdir)/grid_gme.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_gme.Tpo $(DEPDIR)/cdo-grid_gme.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_gme.c' object='cdo-grid_gme.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_gme.obj `if test -f 'grid_gme.c'; then $(CYGPATH_W) 'grid_gme.c'; else $(CYGPATH_W) '$(srcdir)/grid_gme.c'; fi`
-
-cdo-grid_lcc.o: grid_lcc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_lcc.o -MD -MP -MF $(DEPDIR)/cdo-grid_lcc.Tpo -c -o cdo-grid_lcc.o `test -f 'grid_lcc.c' || echo '$(srcdir)/'`grid_lcc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_lcc.Tpo $(DEPDIR)/cdo-grid_lcc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_lcc.c' object='cdo-grid_lcc.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_lcc.o `test -f 'grid_lcc.c' || echo '$(srcdir)/'`grid_lcc.c
-
-cdo-grid_lcc.obj: grid_lcc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_lcc.obj -MD -MP -MF $(DEPDIR)/cdo-grid_lcc.Tpo -c -o cdo-grid_lcc.obj `if test -f 'grid_lcc.c'; then $(CYGPATH_W) 'grid_lcc.c'; else $(CYGPATH_W) '$(srcdir)/grid_lcc.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_lcc.Tpo $(DEPDIR)/cdo-grid_lcc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_lcc.c' object='cdo-grid_lcc.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_lcc.obj `if test -f 'grid_lcc.c'; then $(CYGPATH_W) 'grid_lcc.c'; else $(CYGPATH_W) '$(srcdir)/grid_lcc.c'; fi`
-
-cdo-grid_rot.o: grid_rot.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_rot.o -MD -MP -MF $(DEPDIR)/cdo-grid_rot.Tpo -c -o cdo-grid_rot.o `test -f 'grid_rot.c' || echo '$(srcdir)/'`grid_rot.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_rot.Tpo $(DEPDIR)/cdo-grid_rot.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_rot.c' object='cdo-grid_rot.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_rot.o `test -f 'grid_rot.c' || echo '$(srcdir)/'`grid_rot.c
-
-cdo-grid_rot.obj: grid_rot.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_rot.obj -MD -MP -MF $(DEPDIR)/cdo-grid_rot.Tpo -c -o cdo-grid_rot.obj `if test -f 'grid_rot.c'; then $(CYGPATH_W) 'grid_rot.c'; else $(CYGPATH_W) '$(srcdir)/grid_rot.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-grid_rot.Tpo $(DEPDIR)/cdo-grid_rot.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='grid_rot.c' object='cdo-grid_rot.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_rot.obj `if test -f 'grid_rot.c'; then $(CYGPATH_W) 'grid_rot.c'; else $(CYGPATH_W) '$(srcdir)/grid_rot.c'; fi`
-
-cdo-gridreference.o: gridreference.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-gridreference.o -MD -MP -MF $(DEPDIR)/cdo-gridreference.Tpo -c -o cdo-gridreference.o `test -f 'gridreference.c' || echo '$(srcdir)/'`gridreference.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-gridreference.Tpo $(DEPDIR)/cdo-gridreference.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gridreference.c' object='cdo-gridreference.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-gridreference.o `test -f 'gridreference.c' || echo '$(srcdir)/'`gridreference.c
-
-cdo-gridreference.obj: gridreference.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-gridreference.obj -MD -MP -MF $(DEPDIR)/cdo-gridreference.Tpo -c -o cdo-gridreference.obj `if test -f 'gridreference.c'; then $(CYGPATH_W) 'gridreference.c'; else $(CYGPATH_W) '$(srcdir)/gridreference.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-gridreference.Tpo $(DEPDIR)/cdo-gridreference.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gridreference.c' object='cdo-gridreference.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-gridreference.obj `if test -f 'gridreference.c'; then $(CYGPATH_W) 'gridreference.c'; else $(CYGPATH_W) '$(srcdir)/gridreference.c'; fi`
-
-cdo-griddes.o: griddes.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes.o -MD -MP -MF $(DEPDIR)/cdo-griddes.Tpo -c -o cdo-griddes.o `test -f 'griddes.c' || echo '$(srcdir)/'`griddes.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes.Tpo $(DEPDIR)/cdo-griddes.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes.c' object='cdo-griddes.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes.o `test -f 'griddes.c' || echo '$(srcdir)/'`griddes.c
-
-cdo-griddes.obj: griddes.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes.obj -MD -MP -MF $(DEPDIR)/cdo-griddes.Tpo -c -o cdo-griddes.obj `if test -f 'griddes.c'; then $(CYGPATH_W) 'griddes.c'; else $(CYGPATH_W) '$(srcdir)/griddes.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes.Tpo $(DEPDIR)/cdo-griddes.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes.c' object='cdo-griddes.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes.obj `if test -f 'griddes.c'; then $(CYGPATH_W) 'griddes.c'; else $(CYGPATH_W) '$(srcdir)/griddes.c'; fi`
-
-cdo-griddes_h5.o: griddes_h5.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes_h5.o -MD -MP -MF $(DEPDIR)/cdo-griddes_h5.Tpo -c -o cdo-griddes_h5.o `test -f 'griddes_h5.c' || echo '$(srcdir)/'`griddes_h5.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes_h5.Tpo $(DEPDIR)/cdo-griddes_h5.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_h5.c' object='cdo-griddes_h5.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes_h5.o `test -f 'griddes_h5.c' || echo '$(srcdir)/'`griddes_h5.c
-
-cdo-griddes_h5.obj: griddes_h5.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes_h5.obj -MD -MP -MF $(DEPDIR)/cdo-griddes_h5.Tpo -c -o cdo-griddes_h5.obj `if test -f 'griddes_h5.c'; then $(CYGPATH_W) 'griddes_h5.c'; else $(CYGPATH_W) '$(srcdir)/griddes_h5.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes_h5.Tpo $(DEPDIR)/cdo-griddes_h5.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_h5.c' object='cdo-griddes_h5.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes_h5.obj `if test -f 'griddes_h5.c'; then $(CYGPATH_W) 'griddes_h5.c'; else $(CYGPATH_W) '$(srcdir)/griddes_h5.c'; fi`
-
-cdo-griddes_nc.o: griddes_nc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes_nc.o -MD -MP -MF $(DEPDIR)/cdo-griddes_nc.Tpo -c -o cdo-griddes_nc.o `test -f 'griddes_nc.c' || echo '$(srcdir)/'`griddes_nc.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes_nc.Tpo $(DEPDIR)/cdo-griddes_nc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_nc.c' object='cdo-griddes_nc.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes_nc.o `test -f 'griddes_nc.c' || echo '$(srcdir)/'`griddes_nc.c
-
-cdo-griddes_nc.obj: griddes_nc.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-griddes_nc.obj -MD -MP -MF $(DEPDIR)/cdo-griddes_nc.Tpo -c -o cdo-griddes_nc.obj `if test -f 'griddes_nc.c'; then $(CYGPATH_W) 'griddes_nc.c'; else $(CYGPATH_W) '$(srcdir)/griddes_nc.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-griddes_nc.Tpo $(DEPDIR)/cdo-griddes_nc.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='griddes_nc.c' object='cdo-griddes_nc.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-griddes_nc.obj `if test -f 'griddes_nc.c'; then $(CYGPATH_W) 'griddes_nc.c'; else $(CYGPATH_W) '$(srcdir)/griddes_nc.c'; fi`
-
-cdo-hetaeta.o: hetaeta.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-hetaeta.o -MD -MP -MF $(DEPDIR)/cdo-hetaeta.Tpo -c -o cdo-hetaeta.o `test -f 'hetaeta.c' || echo '$(srcdir)/'`hetaeta.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-hetaeta.Tpo $(DEPDIR)/cdo-hetaeta.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='hetaeta.c' object='cdo-hetaeta.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-hetaeta.o `test -f 'hetaeta.c' || echo '$(srcdir)/'`hetaeta.c
-
-cdo-hetaeta.obj: hetaeta.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-hetaeta.obj -MD -MP -MF $(DEPDIR)/cdo-hetaeta.Tpo -c -o cdo-hetaeta.obj `if test -f 'hetaeta.c'; then $(CYGPATH_W) 'hetaeta.c'; else $(CYGPATH_W) '$(srcdir)/hetaeta.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-hetaeta.Tpo $(DEPDIR)/cdo-hetaeta.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='hetaeta.c' object='cdo-hetaeta.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-hetaeta.obj `if test -f 'hetaeta.c'; then $(CYGPATH_W) 'hetaeta.c'; else $(CYGPATH_W) '$(srcdir)/hetaeta.c'; fi`
-
-cdo-history.o: history.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-history.o -MD -MP -MF $(DEPDIR)/cdo-history.Tpo -c -o cdo-history.o `test -f 'history.c' || echo '$(srcdir)/'`history.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-history.Tpo $(DEPDIR)/cdo-history.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='history.c' object='cdo-history.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-history.o `test -f 'history.c' || echo '$(srcdir)/'`history.c
-
-cdo-history.obj: history.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-history.obj -MD -MP -MF $(DEPDIR)/cdo-history.Tpo -c -o cdo-history.obj `if test -f 'history.c'; then $(CYGPATH_W) 'history.c'; else $(CYGPATH_W) '$(srcdir)/history.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-history.Tpo $(DEPDIR)/cdo-history.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='history.c' object='cdo-history.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-history.obj `if test -f 'history.c'; then $(CYGPATH_W) 'history.c'; else $(CYGPATH_W) '$(srcdir)/history.c'; fi`
-
-cdo-institution.o: institution.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-institution.o -MD -MP -MF $(DEPDIR)/cdo-institution.Tpo -c -o cdo-institution.o `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-institution.Tpo $(DEPDIR)/cdo-institution.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='institution.c' object='cdo-institution.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-institution.o `test -f 'institution.c' || echo '$(srcdir)/'`institution.c
-
-cdo-institution.obj: institution.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-institution.obj -MD -MP -MF $(DEPDIR)/cdo-institution.Tpo -c -o cdo-institution.obj `if test -f 'institution.c'; then $(CYGPATH_W) 'institution.c'; else $(CYGPATH_W) '$(srcdir)/institution.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-institution.Tpo $(DEPDIR)/cdo-institution.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='institution.c' object='cdo-institution.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-institution.obj `if test -f 'institution.c'; then $(CYGPATH_W) 'institution.c'; else $(CYGPATH_W) '$(srcdir)/institution.c'; fi`
-
-cdo-interpol.o: interpol.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-interpol.o -MD -MP -MF $(DEPDIR)/cdo-interpol.Tpo -c -o cdo-interpol.o `test -f 'interpol.c' || echo '$(srcdir)/'`interpol.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-interpol.Tpo $(DEPDIR)/cdo-interpol.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='interpol.c' object='cdo-interpol.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-interpol.o `test -f 'interpol.c' || echo '$(srcdir)/'`interpol.c
-
-cdo-interpol.obj: interpol.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-interpol.obj -MD -MP -MF $(DEPDIR)/cdo-interpol.Tpo -c -o cdo-interpol.obj `if test -f 'interpol.c'; then $(CYGPATH_W) 'interpol.c'; else $(CYGPATH_W) '$(srcdir)/interpol.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-interpol.Tpo $(DEPDIR)/cdo-interpol.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='interpol.c' object='cdo-interpol.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-interpol.obj `if test -f 'interpol.c'; then $(CYGPATH_W) 'interpol.c'; else $(CYGPATH_W) '$(srcdir)/interpol.c'; fi`
-
-cdo-job.o: job.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-job.o -MD -MP -MF $(DEPDIR)/cdo-job.Tpo -c -o cdo-job.o `test -f 'job.c' || echo '$(srcdir)/'`job.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-job.Tpo $(DEPDIR)/cdo-job.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='job.c' object='cdo-job.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-job.o `test -f 'job.c' || echo '$(srcdir)/'`job.c
-
-cdo-job.obj: job.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-job.obj -MD -MP -MF $(DEPDIR)/cdo-job.Tpo -c -o cdo-job.obj `if test -f 'job.c'; then $(CYGPATH_W) 'job.c'; else $(CYGPATH_W) '$(srcdir)/job.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-job.Tpo $(DEPDIR)/cdo-job.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='job.c' object='cdo-job.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-job.obj `if test -f 'job.c'; then $(CYGPATH_W) 'job.c'; else $(CYGPATH_W) '$(srcdir)/job.c'; fi`
-
-cdo-juldate.o: juldate.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-juldate.o -MD -MP -MF $(DEPDIR)/cdo-juldate.Tpo -c -o cdo-juldate.o `test -f 'juldate.c' || echo '$(srcdir)/'`juldate.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-juldate.Tpo $(DEPDIR)/cdo-juldate.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='juldate.c' object='cdo-juldate.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-juldate.o `test -f 'juldate.c' || echo '$(srcdir)/'`juldate.c
-
-cdo-juldate.obj: juldate.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-juldate.obj -MD -MP -MF $(DEPDIR)/cdo-juldate.Tpo -c -o cdo-juldate.obj `if test -f 'juldate.c'; then $(CYGPATH_W) 'juldate.c'; else $(CYGPATH_W) '$(srcdir)/juldate.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-juldate.Tpo $(DEPDIR)/cdo-juldate.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='juldate.c' object='cdo-juldate.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-juldate.obj `if test -f 'juldate.c'; then $(CYGPATH_W) 'juldate.c'; else $(CYGPATH_W) '$(srcdir)/juldate.c'; fi`
-
-cdo-kvlist.o: kvlist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-kvlist.o -MD -MP -MF $(DEPDIR)/cdo-kvlist.Tpo -c -o cdo-kvlist.o `test -f 'kvlist.c' || echo '$(srcdir)/'`kvlist.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-kvlist.Tpo $(DEPDIR)/cdo-kvlist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kvlist.c' object='cdo-kvlist.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-kvlist.o `test -f 'kvlist.c' || echo '$(srcdir)/'`kvlist.c
-
-cdo-kvlist.obj: kvlist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-kvlist.obj -MD -MP -MF $(DEPDIR)/cdo-kvlist.Tpo -c -o cdo-kvlist.obj `if test -f 'kvlist.c'; then $(CYGPATH_W) 'kvlist.c'; else $(CYGPATH_W) '$(srcdir)/kvlist.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-kvlist.Tpo $(DEPDIR)/cdo-kvlist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kvlist.c' object='cdo-kvlist.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-kvlist.obj `if test -f 'kvlist.c'; then $(CYGPATH_W) 'kvlist.c'; else $(CYGPATH_W) '$(srcdir)/kvlist.c'; fi`
-
-cdo-legendre.o: legendre.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-legendre.o -MD -MP -MF $(DEPDIR)/cdo-legendre.Tpo -c -o cdo-legendre.o `test -f 'legendre.c' || echo '$(srcdir)/'`legendre.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-legendre.Tpo $(DEPDIR)/cdo-legendre.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='legendre.c' object='cdo-legendre.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-legendre.o `test -f 'legendre.c' || echo '$(srcdir)/'`legendre.c
-
-cdo-legendre.obj: legendre.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-legendre.obj -MD -MP -MF $(DEPDIR)/cdo-legendre.Tpo -c -o cdo-legendre.obj `if test -f 'legendre.c'; then $(CYGPATH_W) 'legendre.c'; else $(CYGPATH_W) '$(srcdir)/legendre.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-legendre.Tpo $(DEPDIR)/cdo-legendre.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='legendre.c' object='cdo-legendre.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-legendre.obj `if test -f 'legendre.c'; then $(CYGPATH_W) 'legendre.c'; else $(CYGPATH_W) '$(srcdir)/legendre.c'; fi`
-
-cdo-list.o: list.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-list.o -MD -MP -MF $(DEPDIR)/cdo-list.Tpo -c -o cdo-list.o `test -f 'list.c' || echo '$(srcdir)/'`list.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-list.Tpo $(DEPDIR)/cdo-list.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='list.c' object='cdo-list.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-list.o `test -f 'list.c' || echo '$(srcdir)/'`list.c
-
-cdo-list.obj: list.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-list.obj -MD -MP -MF $(DEPDIR)/cdo-list.Tpo -c -o cdo-list.obj `if test -f 'list.c'; then $(CYGPATH_W) 'list.c'; else $(CYGPATH_W) '$(srcdir)/list.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-list.Tpo $(DEPDIR)/cdo-list.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='list.c' object='cdo-list.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-list.obj `if test -f 'list.c'; then $(CYGPATH_W) 'list.c'; else $(CYGPATH_W) '$(srcdir)/list.c'; fi`
-
-cdo-merge_sort2.o: merge_sort2.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-merge_sort2.o -MD -MP -MF $(DEPDIR)/cdo-merge_sort2.Tpo -c -o cdo-merge_sort2.o `test -f 'merge_sort2.c' || echo '$(srcdir)/'`merge_sort2.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-merge_sort2.Tpo $(DEPDIR)/cdo-merge_sort2.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='merge_sort2.c' object='cdo-merge_sort2.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-merge_sort2.o `test -f 'merge_sort2.c' || echo '$(srcdir)/'`merge_sort2.c
-
-cdo-merge_sort2.obj: merge_sort2.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-merge_sort2.obj -MD -MP -MF $(DEPDIR)/cdo-merge_sort2.Tpo -c -o cdo-merge_sort2.obj `if test -f 'merge_sort2.c'; then $(CYGPATH_W) 'merge_sort2.c'; else $(CYGPATH_W) '$(srcdir)/merge_sort2.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-merge_sort2.Tpo $(DEPDIR)/cdo-merge_sort2.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='merge_sort2.c' object='cdo-merge_sort2.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-merge_sort2.obj `if test -f 'merge_sort2.c'; then $(CYGPATH_W) 'merge_sort2.c'; else $(CYGPATH_W) '$(srcdir)/merge_sort2.c'; fi`
-
-cdo-modules.o: modules.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-modules.o -MD -MP -MF $(DEPDIR)/cdo-modules.Tpo -c -o cdo-modules.o `test -f 'modules.c' || echo '$(srcdir)/'`modules.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-modules.Tpo $(DEPDIR)/cdo-modules.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='modules.c' object='cdo-modules.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-modules.o `test -f 'modules.c' || echo '$(srcdir)/'`modules.c
-
-cdo-modules.obj: modules.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-modules.obj -MD -MP -MF $(DEPDIR)/cdo-modules.Tpo -c -o cdo-modules.obj `if test -f 'modules.c'; then $(CYGPATH_W) 'modules.c'; else $(CYGPATH_W) '$(srcdir)/modules.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-modules.Tpo $(DEPDIR)/cdo-modules.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='modules.c' object='cdo-modules.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-modules.obj `if test -f 'modules.c'; then $(CYGPATH_W) 'modules.c'; else $(CYGPATH_W) '$(srcdir)/modules.c'; fi`
-
-cdo-namelist.o: namelist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-namelist.o -MD -MP -MF $(DEPDIR)/cdo-namelist.Tpo -c -o cdo-namelist.o `test -f 'namelist.c' || echo '$(srcdir)/'`namelist.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-namelist.Tpo $(DEPDIR)/cdo-namelist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='namelist.c' object='cdo-namelist.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-namelist.o `test -f 'namelist.c' || echo '$(srcdir)/'`namelist.c
-
-cdo-namelist.obj: namelist.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-namelist.obj -MD -MP -MF $(DEPDIR)/cdo-namelist.Tpo -c -o cdo-namelist.obj `if test -f 'namelist.c'; then $(CYGPATH_W) 'namelist.c'; else $(CYGPATH_W) '$(srcdir)/namelist.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-namelist.Tpo $(DEPDIR)/cdo-namelist.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='namelist.c' object='cdo-namelist.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-namelist.obj `if test -f 'namelist.c'; then $(CYGPATH_W) 'namelist.c'; else $(CYGPATH_W) '$(srcdir)/namelist.c'; fi`
-
-cdo-normal.o: normal.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-normal.o -MD -MP -MF $(DEPDIR)/cdo-normal.Tpo -c -o cdo-normal.o `test -f 'normal.c' || echo '$(srcdir)/'`normal.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-normal.Tpo $(DEPDIR)/cdo-normal.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='normal.c' object='cdo-normal.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-normal.o `test -f 'normal.c' || echo '$(srcdir)/'`normal.c
-
-cdo-normal.obj: normal.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-normal.obj -MD -MP -MF $(DEPDIR)/cdo-normal.Tpo -c -o cdo-normal.obj `if test -f 'normal.c'; then $(CYGPATH_W) 'normal.c'; else $(CYGPATH_W) '$(srcdir)/normal.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-normal.Tpo $(DEPDIR)/cdo-normal.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='normal.c' object='cdo-normal.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-normal.obj `if test -f 'normal.c'; then $(CYGPATH_W) 'normal.c'; else $(CYGPATH_W) '$(srcdir)/normal.c'; fi`
-
-cdo-nth_element.o: nth_element.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-nth_element.o -MD -MP -MF $(DEPDIR)/cdo-nth_element.Tpo -c -o cdo-nth_element.o `test -f 'nth_element.c' || echo '$(srcdir)/'`nth_element.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-nth_element.Tpo $(DEPDIR)/cdo-nth_element.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nth_element.c' object='cdo-nth_element.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-nth_element.o `test -f 'nth_element.c' || echo '$(srcdir)/'`nth_element.c
-
-cdo-nth_element.obj: nth_element.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-nth_element.obj -MD -MP -MF $(DEPDIR)/cdo-nth_element.Tpo -c -o cdo-nth_element.obj `if test -f 'nth_element.c'; then $(CYGPATH_W) 'nth_element.c'; else $(CYGPATH_W) '$(srcdir)/nth_element.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-nth_element.Tpo $(DEPDIR)/cdo-nth_element.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='nth_element.c' object='cdo-nth_element.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-nth_element.obj `if test -f 'nth_element.c'; then $(CYGPATH_W) 'nth_element.c'; else $(CYGPATH_W) '$(srcdir)/nth_element.c'; fi`
-
-cdo-par_io.o: par_io.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-par_io.o -MD -MP -MF $(DEPDIR)/cdo-par_io.Tpo -c -o cdo-par_io.o `test -f 'par_io.c' || echo '$(srcdir)/'`par_io.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-par_io.Tpo $(DEPDIR)/cdo-par_io.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='par_io.c' object='cdo-par_io.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-par_io.o `test -f 'par_io.c' || echo '$(srcdir)/'`par_io.c
-
-cdo-par_io.obj: par_io.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-par_io.obj -MD -MP -MF $(DEPDIR)/cdo-par_io.Tpo -c -o cdo-par_io.obj `if test -f 'par_io.c'; then $(CYGPATH_W) 'par_io.c'; else $(CYGPATH_W) '$(srcdir)/par_io.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-par_io.Tpo $(DEPDIR)/cdo-par_io.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='par_io.c' object='cdo-par_io.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-par_io.obj `if test -f 'par_io.c'; then $(CYGPATH_W) 'par_io.c'; else $(CYGPATH_W) '$(srcdir)/par_io.c'; fi`
-
-cdo-percentiles.o: percentiles.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-percentiles.o -MD -MP -MF $(DEPDIR)/cdo-percentiles.Tpo -c -o cdo-percentiles.o `test -f 'percentiles.c' || echo '$(srcdir)/'`percentiles.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-percentiles.Tpo $(DEPDIR)/cdo-percentiles.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='percentiles.c' object='cdo-percentiles.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-percentiles.o `test -f 'percentiles.c' || echo '$(srcdir)/'`percentiles.c
-
-cdo-percentiles.obj: percentiles.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-percentiles.obj -MD -MP -MF $(DEPDIR)/cdo-percentiles.Tpo -c -o cdo-percentiles.obj `if test -f 'percentiles.c'; then $(CYGPATH_W) 'percentiles.c'; else $(CYGPATH_W) '$(srcdir)/percentiles.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-percentiles.Tpo $(DEPDIR)/cdo-percentiles.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='percentiles.c' object='cdo-percentiles.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-percentiles.obj `if test -f 'percentiles.c'; then $(CYGPATH_W) 'percentiles.c'; else $(CYGPATH_W) '$(srcdir)/percentiles.c'; fi`
-
-cdo-pipe.o: pipe.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pipe.o -MD -MP -MF $(DEPDIR)/cdo-pipe.Tpo -c -o cdo-pipe.o `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pipe.Tpo $(DEPDIR)/cdo-pipe.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pipe.c' object='cdo-pipe.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pipe.o `test -f 'pipe.c' || echo '$(srcdir)/'`pipe.c
-
-cdo-pipe.obj: pipe.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pipe.obj -MD -MP -MF $(DEPDIR)/cdo-pipe.Tpo -c -o cdo-pipe.obj `if test -f 'pipe.c'; then $(CYGPATH_W) 'pipe.c'; else $(CYGPATH_W) '$(srcdir)/pipe.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pipe.Tpo $(DEPDIR)/cdo-pipe.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pipe.c' object='cdo-pipe.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pipe.obj `if test -f 'pipe.c'; then $(CYGPATH_W) 'pipe.c'; else $(CYGPATH_W) '$(srcdir)/pipe.c'; fi`
-
-cdo-process.o: process.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-process.o -MD -MP -MF $(DEPDIR)/cdo-process.Tpo -c -o cdo-process.o `test -f 'process.c' || echo '$(srcdir)/'`process.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-process.Tpo $(DEPDIR)/cdo-process.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='process.c' object='cdo-process.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-process.o `test -f 'process.c' || echo '$(srcdir)/'`process.c
-
-cdo-process.obj: process.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-process.obj -MD -MP -MF $(DEPDIR)/cdo-process.Tpo -c -o cdo-process.obj `if test -f 'process.c'; then $(CYGPATH_W) 'process.c'; else $(CYGPATH_W) '$(srcdir)/process.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-process.Tpo $(DEPDIR)/cdo-process.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='process.c' object='cdo-process.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-process.obj `if test -f 'process.c'; then $(CYGPATH_W) 'process.c'; else $(CYGPATH_W) '$(srcdir)/process.c'; fi`
-
-cdo-pstream.o: pstream.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pstream.o -MD -MP -MF $(DEPDIR)/cdo-pstream.Tpo -c -o cdo-pstream.o `test -f 'pstream.c' || echo '$(srcdir)/'`pstream.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pstream.Tpo $(DEPDIR)/cdo-pstream.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pstream.c' object='cdo-pstream.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pstream.o `test -f 'pstream.c' || echo '$(srcdir)/'`pstream.c
-
-cdo-pstream.obj: pstream.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pstream.obj -MD -MP -MF $(DEPDIR)/cdo-pstream.Tpo -c -o cdo-pstream.obj `if test -f 'pstream.c'; then $(CYGPATH_W) 'pstream.c'; else $(CYGPATH_W) '$(srcdir)/pstream.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pstream.Tpo $(DEPDIR)/cdo-pstream.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pstream.c' object='cdo-pstream.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pstream.obj `if test -f 'pstream.c'; then $(CYGPATH_W) 'pstream.c'; else $(CYGPATH_W) '$(srcdir)/pstream.c'; fi`
-
-cdo-pthread_debug.o: pthread_debug.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pthread_debug.o -MD -MP -MF $(DEPDIR)/cdo-pthread_debug.Tpo -c -o cdo-pthread_debug.o `test -f 'pthread_debug.c' || echo '$(srcdir)/'`pthread_debug.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pthread_debug.Tpo $(DEPDIR)/cdo-pthread_debug.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pthread_debug.c' object='cdo-pthread_debug.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pthread_debug.o `test -f 'pthread_debug.c' || echo '$(srcdir)/'`pthread_debug.c
-
-cdo-pthread_debug.obj: pthread_debug.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-pthread_debug.obj -MD -MP -MF $(DEPDIR)/cdo-pthread_debug.Tpo -c -o cdo-pthread_debug.obj `if test -f 'pthread_debug.c'; then $(CYGPATH_W) 'pthread_debug.c'; else $(CYGPATH_W) '$(srcdir)/pthread_debug.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-pthread_debug.Tpo $(DEPDIR)/cdo-pthread_debug.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='pthread_debug.c' object='cdo-pthread_debug.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-pthread_debug.obj `if test -f 'pthread_debug.c'; then $(CYGPATH_W) 'pthread_debug.c'; else $(CYGPATH_W) '$(srcdir)/pthread_debug.c'; fi`
-
-cdo-readline.o: readline.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-readline.o -MD -MP -MF $(DEPDIR)/cdo-readline.Tpo -c -o cdo-readline.o `test -f 'readline.c' || echo '$(srcdir)/'`readline.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-readline.Tpo $(DEPDIR)/cdo-readline.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='readline.c' object='cdo-readline.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-readline.o `test -f 'readline.c' || echo '$(srcdir)/'`readline.c
-
-cdo-readline.obj: readline.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-readline.obj -MD -MP -MF $(DEPDIR)/cdo-readline.Tpo -c -o cdo-readline.obj `if test -f 'readline.c'; then $(CYGPATH_W) 'readline.c'; else $(CYGPATH_W) '$(srcdir)/readline.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-readline.Tpo $(DEPDIR)/cdo-readline.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='readline.c' object='cdo-readline.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-readline.obj `if test -f 'readline.c'; then $(CYGPATH_W) 'readline.c'; else $(CYGPATH_W) '$(srcdir)/readline.c'; fi`
-
-cdo-realtime.o: realtime.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-realtime.o -MD -MP -MF $(DEPDIR)/cdo-realtime.Tpo -c -o cdo-realtime.o `test -f 'realtime.c' || echo '$(srcdir)/'`realtime.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-realtime.Tpo $(DEPDIR)/cdo-realtime.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='realtime.c' object='cdo-realtime.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-realtime.o `test -f 'realtime.c' || echo '$(srcdir)/'`realtime.c
-
-cdo-realtime.obj: realtime.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-realtime.obj -MD -MP -MF $(DEPDIR)/cdo-realtime.Tpo -c -o cdo-realtime.obj `if test -f 'realtime.c'; then $(CYGPATH_W) 'realtime.c'; else $(CYGPATH_W) '$(srcdir)/realtime.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-realtime.Tpo $(DEPDIR)/cdo-realtime.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='realtime.c' object='cdo-realtime.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-realtime.obj `if test -f 'realtime.c'; then $(CYGPATH_W) 'realtime.c'; else $(CYGPATH_W) '$(srcdir)/realtime.c'; fi`
-
-cdo-remaplib.o: remaplib.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remaplib.o -MD -MP -MF $(DEPDIR)/cdo-remaplib.Tpo -c -o cdo-remaplib.o `test -f 'remaplib.c' || echo '$(srcdir)/'`remaplib.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remaplib.Tpo $(DEPDIR)/cdo-remaplib.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remaplib.c' object='cdo-remaplib.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remaplib.o `test -f 'remaplib.c' || echo '$(srcdir)/'`remaplib.c
-
-cdo-remaplib.obj: remaplib.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remaplib.obj -MD -MP -MF $(DEPDIR)/cdo-remaplib.Tpo -c -o cdo-remaplib.obj `if test -f 'remaplib.c'; then $(CYGPATH_W) 'remaplib.c'; else $(CYGPATH_W) '$(srcdir)/remaplib.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remaplib.Tpo $(DEPDIR)/cdo-remaplib.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remaplib.c' object='cdo-remaplib.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remaplib.obj `if test -f 'remaplib.c'; then $(CYGPATH_W) 'remaplib.c'; else $(CYGPATH_W) '$(srcdir)/remaplib.c'; fi`
-
-cdo-remapsort.o: remapsort.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remapsort.o -MD -MP -MF $(DEPDIR)/cdo-remapsort.Tpo -c -o cdo-remapsort.o `test -f 'remapsort.c' || echo '$(srcdir)/'`remapsort.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remapsort.Tpo $(DEPDIR)/cdo-remapsort.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remapsort.c' object='cdo-remapsort.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remapsort.o `test -f 'remapsort.c' || echo '$(srcdir)/'`remapsort.c
-
-cdo-remapsort.obj: remapsort.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remapsort.obj -MD -MP -MF $(DEPDIR)/cdo-remapsort.Tpo -c -o cdo-remapsort.obj `if test -f 'remapsort.c'; then $(CYGPATH_W) 'remapsort.c'; else $(CYGPATH_W) '$(srcdir)/remapsort.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remapsort.Tpo $(DEPDIR)/cdo-remapsort.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remapsort.c' object='cdo-remapsort.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remapsort.obj `if test -f 'remapsort.c'; then $(CYGPATH_W) 'remapsort.c'; else $(CYGPATH_W) '$(srcdir)/remapsort.c'; fi`
-
-cdo-remap_scrip_io.o: remap_scrip_io.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_scrip_io.o -MD -MP -MF $(DEPDIR)/cdo-remap_scrip_io.Tpo -c -o cdo-remap_scrip_io.o `test -f 'remap_scrip_io.c' || echo '$(srcdir)/'`remap_scrip_io.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_scrip_io.Tpo $(DEPDIR)/cdo-remap_scrip_io.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_scrip_io.c' object='cdo-remap_scrip_io.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_scrip_io.o `test -f 'remap_scrip_io.c' || echo '$(srcdir)/'`remap_scrip_io.c
-
-cdo-remap_scrip_io.obj: remap_scrip_io.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_scrip_io.obj -MD -MP -MF $(DEPDIR)/cdo-remap_scrip_io.Tpo -c -o cdo-remap_scrip_io.obj `if test -f 'remap_scrip_io.c'; then $(CYGPATH_W) 'remap_scrip_io.c'; else $(CYGPATH_W) '$(srcdir)/remap_scrip_io.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_scrip_io.Tpo $(DEPDIR)/cdo-remap_scrip_io.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_scrip_io.c' object='cdo-remap_scrip_io.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_scrip_io.obj `if test -f 'remap_scrip_io.c'; then $(CYGPATH_W) 'remap_scrip_io.c'; else $(CYGPATH_W) '$(srcdir)/remap_scrip_io.c'; fi`
-
-cdo-remap_search_reg2d.o: remap_search_reg2d.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_reg2d.o -MD -MP -MF $(DEPDIR)/cdo-remap_search_reg2d.Tpo -c -o cdo-remap_search_reg2d.o `test -f 'remap_search_reg2d.c' || echo '$(srcdir)/'`remap_search_reg2d.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_search_reg2d.Tpo $(DEPDIR)/cdo-remap_search_reg2d.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_reg2d.c' object='cdo-remap_search_reg2d.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_reg2d.o `test -f 'remap_search_reg2d.c' || echo '$(srcdir)/'`remap_search_reg2d.c
-
-cdo-remap_search_reg2d.obj: remap_search_reg2d.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_reg2d.obj -MD -MP -MF $(DEPDIR)/cdo-remap_search_reg2d.Tpo -c -o cdo-remap_search_reg2d.obj `if test -f 'remap_search_reg2d.c'; then $(CYGPATH_W) 'remap_search_reg2d.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_reg2d.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_search_reg2d.Tpo $(DEPDIR)/cdo-remap_search_reg2d.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_reg2d.c' object='cdo-remap_search_reg2d.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_reg2d.obj `if test -f 'remap_search_reg2d.c'; then $(CYGPATH_W) 'remap_search_reg2d.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_reg2d.c'; fi`
-
-cdo-remap_search_latbins.o: remap_search_latbins.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_latbins.o -MD -MP -MF $(DEPDIR)/cdo-remap_search_latbins.Tpo -c -o cdo-remap_search_latbins.o `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_search_latbins.Tpo $(DEPDIR)/cdo-remap_search_latbins.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_latbins.c' object='cdo-remap_search_latbins.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_latbins.o `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
-
-cdo-remap_search_latbins.obj: remap_search_latbins.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_latbins.obj -MD -MP -MF $(DEPDIR)/cdo-remap_search_latbins.Tpo -c -o cdo-remap_search_latbins.obj `if test -f 'remap_search_latbins.c'; then $(CYGPATH_W) 'remap_search_latbins.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_latbins.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_search_latbins.Tpo $(DEPDIR)/cdo-remap_search_latbins.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_search_latbins.c' object='cdo-remap_search_latbins.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_latbins.obj `if test -f 'remap_search_latbins.c'; then $(CYGPATH_W) 'remap_search_latbins.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_latbins.c'; fi`
-
-cdo-remap_store_link.o: remap_store_link.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_store_link.o -MD -MP -MF $(DEPDIR)/cdo-remap_store_link.Tpo -c -o cdo-remap_store_link.o `test -f 'remap_store_link.c' || echo '$(srcdir)/'`remap_store_link.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_store_link.Tpo $(DEPDIR)/cdo-remap_store_link.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_store_link.c' object='cdo-remap_store_link.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_store_link.o `test -f 'remap_store_link.c' || echo '$(srcdir)/'`remap_store_link.c
-
-cdo-remap_store_link.obj: remap_store_link.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_store_link.obj -MD -MP -MF $(DEPDIR)/cdo-remap_store_link.Tpo -c -o cdo-remap_store_link.obj `if test -f 'remap_store_link.c'; then $(CYGPATH_W) 'remap_store_link.c'; else $(CYGPATH_W) '$(srcdir)/remap_store_link.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_store_link.Tpo $(DEPDIR)/cdo-remap_store_link.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_store_link.c' object='cdo-remap_store_link.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_store_link.obj `if test -f 'remap_store_link.c'; then $(CYGPATH_W) 'remap_store_link.c'; else $(CYGPATH_W) '$(srcdir)/remap_store_link.c'; fi`
-
-cdo-remap_conserv.o: remap_conserv.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_conserv.o -MD -MP -MF $(DEPDIR)/cdo-remap_conserv.Tpo -c -o cdo-remap_conserv.o `test -f 'remap_conserv.c' || echo '$(srcdir)/'`remap_conserv.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_conserv.Tpo $(DEPDIR)/cdo-remap_conserv.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv.c' object='cdo-remap_conserv.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_conserv.o `test -f 'remap_conserv.c' || echo '$(srcdir)/'`remap_conserv.c
-
-cdo-remap_conserv.obj: remap_conserv.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_conserv.obj -MD -MP -MF $(DEPDIR)/cdo-remap_conserv.Tpo -c -o cdo-remap_conserv.obj `if test -f 'remap_conserv.c'; then $(CYGPATH_W) 'remap_conserv.c'; else $(CYGPATH_W) '$(srcdir)/remap_conserv.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_conserv.Tpo $(DEPDIR)/cdo-remap_conserv.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv.c' object='cdo-remap_conserv.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_conserv.obj `if test -f 'remap_conserv.c'; then $(CYGPATH_W) 'remap_conserv.c'; else $(CYGPATH_W) '$(srcdir)/remap_conserv.c'; fi`
-
-cdo-remap_conserv_scrip.o: remap_conserv_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_conserv_scrip.o -MD -MP -MF $(DEPDIR)/cdo-remap_conserv_scrip.Tpo -c -o cdo-remap_conserv_scrip.o `test -f 'remap_conserv_scrip.c' || echo '$(srcdir)/'`remap_conserv_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_conserv_scrip.Tpo $(DEPDIR)/cdo-remap_conserv_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv_scrip.c' object='cdo-remap_conserv_scrip.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_conserv_scrip.o `test -f 'remap_conserv_scrip.c' || echo '$(srcdir)/'`remap_conserv_scrip.c
-
-cdo-remap_conserv_scrip.obj: remap_conserv_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_conserv_scrip.obj -MD -MP -MF $(DEPDIR)/cdo-remap_conserv_scrip.Tpo -c -o cdo-remap_conserv_scrip.obj `if test -f 'remap_conserv_scrip.c'; then $(CYGPATH_W) 'remap_conserv_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_conserv_scrip.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_conserv_scrip.Tpo $(DEPDIR)/cdo-remap_conserv_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_conserv_scrip.c' object='cdo-remap_conserv_scrip.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_conserv_scrip.obj `if test -f 'remap_conserv_scrip.c'; then $(CYGPATH_W) 'remap_conserv_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_conserv_scrip.c'; fi`
-
-cdo-remap_distwgt_scrip.o: remap_distwgt_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_distwgt_scrip.o -MD -MP -MF $(DEPDIR)/cdo-remap_distwgt_scrip.Tpo -c -o cdo-remap_distwgt_scrip.o `test -f 'remap_distwgt_scrip.c' || echo '$(srcdir)/'`remap_distwgt_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_distwgt_scrip.Tpo $(DEPDIR)/cdo-remap_distwgt_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_distwgt_scrip.c' object='cdo-remap_distwgt_scrip.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_distwgt_scrip.o `test -f 'remap_distwgt_scrip.c' || echo '$(srcdir)/'`remap_distwgt_scrip.c
-
-cdo-remap_distwgt_scrip.obj: remap_distwgt_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_distwgt_scrip.obj -MD -MP -MF $(DEPDIR)/cdo-remap_distwgt_scrip.Tpo -c -o cdo-remap_distwgt_scrip.obj `if test -f 'remap_distwgt_scrip.c'; then $(CYGPATH_W) 'remap_distwgt_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_distwgt_scrip.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_distwgt_scrip.Tpo $(DEPDIR)/cdo-remap_distwgt_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_distwgt_scrip.c' object='cdo-remap_distwgt_scrip.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_distwgt_scrip.obj `if test -f 'remap_distwgt_scrip.c'; then $(CYGPATH_W) 'remap_distwgt_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_distwgt_scrip.c'; fi`
-
-cdo-remap_bicubic_scrip.o: remap_bicubic_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_bicubic_scrip.o -MD -MP -MF $(DEPDIR)/cdo-remap_bicubic_scrip.Tpo -c -o cdo-remap_bicubic_scrip.o `test -f 'remap_bicubic_scrip.c' || echo '$(srcdir)/'`remap_bicubic_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_bicubic_scrip.Tpo $(DEPDIR)/cdo-remap_bicubic_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bicubic_scrip.c' object='cdo-remap_bicubic_scrip.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_bicubic_scrip.o `test -f 'remap_bicubic_scrip.c' || echo '$(srcdir)/'`remap_bicubic_scrip.c
-
-cdo-remap_bicubic_scrip.obj: remap_bicubic_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_bicubic_scrip.obj -MD -MP -MF $(DEPDIR)/cdo-remap_bicubic_scrip.Tpo -c -o cdo-remap_bicubic_scrip.obj `if test -f 'remap_bicubic_scrip.c'; then $(CYGPATH_W) 'remap_bicubic_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_bicubic_scrip.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_bicubic_scrip.Tpo $(DEPDIR)/cdo-remap_bicubic_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bicubic_scrip.c' object='cdo-remap_bicubic_scrip.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_bicubic_scrip.obj `if test -f 'remap_bicubic_scrip.c'; then $(CYGPATH_W) 'remap_bicubic_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_bicubic_scrip.c'; fi`
-
-cdo-remap_bilinear_scrip.o: remap_bilinear_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_bilinear_scrip.o -MD -MP -MF $(DEPDIR)/cdo-remap_bilinear_scrip.Tpo -c -o cdo-remap_bilinear_scrip.o `test -f 'remap_bilinear_scrip.c' || echo '$(srcdir)/'`remap_bilinear_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_bilinear_scrip.Tpo $(DEPDIR)/cdo-remap_bilinear_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bilinear_scrip.c' object='cdo-remap_bilinear_scrip.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_bilinear_scrip.o `test -f 'remap_bilinear_scrip.c' || echo '$(srcdir)/'`remap_bilinear_scrip.c
-
-cdo-remap_bilinear_scrip.obj: remap_bilinear_scrip.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_bilinear_scrip.obj -MD -MP -MF $(DEPDIR)/cdo-remap_bilinear_scrip.Tpo -c -o cdo-remap_bilinear_scrip.obj `if test -f 'remap_bilinear_scrip.c'; then $(CYGPATH_W) 'remap_bilinear_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_bilinear_scrip.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-remap_bilinear_scrip.Tpo $(DEPDIR)/cdo-remap_bilinear_scrip.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='remap_bilinear_scrip.c' object='cdo-remap_bilinear_scrip.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_bilinear_scrip.obj `if test -f 'remap_bilinear_scrip.c'; then $(CYGPATH_W) 'remap_bilinear_scrip.c'; else $(CYGPATH_W) '$(srcdir)/remap_bilinear_scrip.c'; fi`
-
-cdo-stdnametable.o: stdnametable.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-stdnametable.o -MD -MP -MF $(DEPDIR)/cdo-stdnametable.Tpo -c -o cdo-stdnametable.o `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-stdnametable.Tpo $(DEPDIR)/cdo-stdnametable.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stdnametable.c' object='cdo-stdnametable.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-stdnametable.o `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
-
-cdo-stdnametable.obj: stdnametable.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-stdnametable.obj -MD -MP -MF $(DEPDIR)/cdo-stdnametable.Tpo -c -o cdo-stdnametable.obj `if test -f 'stdnametable.c'; then $(CYGPATH_W) 'stdnametable.c'; else $(CYGPATH_W) '$(srcdir)/stdnametable.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-stdnametable.Tpo $(DEPDIR)/cdo-stdnametable.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='stdnametable.c' object='cdo-stdnametable.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-stdnametable.obj `if test -f 'stdnametable.c'; then $(CYGPATH_W) 'stdnametable.c'; else $(CYGPATH_W) '$(srcdir)/stdnametable.c'; fi`
-
-cdo-specspace.o: specspace.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-specspace.o -MD -MP -MF $(DEPDIR)/cdo-specspace.Tpo -c -o cdo-specspace.o `test -f 'specspace.c' || echo '$(srcdir)/'`specspace.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-specspace.Tpo $(DEPDIR)/cdo-specspace.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='specspace.c' object='cdo-specspace.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-specspace.o `test -f 'specspace.c' || echo '$(srcdir)/'`specspace.c
-
-cdo-specspace.obj: specspace.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-specspace.obj -MD -MP -MF $(DEPDIR)/cdo-specspace.Tpo -c -o cdo-specspace.obj `if test -f 'specspace.c'; then $(CYGPATH_W) 'specspace.c'; else $(CYGPATH_W) '$(srcdir)/specspace.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-specspace.Tpo $(DEPDIR)/cdo-specspace.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='specspace.c' object='cdo-specspace.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-specspace.obj `if test -f 'specspace.c'; then $(CYGPATH_W) 'specspace.c'; else $(CYGPATH_W) '$(srcdir)/specspace.c'; fi`
-
-cdo-statistic.o: statistic.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-statistic.o -MD -MP -MF $(DEPDIR)/cdo-statistic.Tpo -c -o cdo-statistic.o `test -f 'statistic.c' || echo '$(srcdir)/'`statistic.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-statistic.Tpo $(DEPDIR)/cdo-statistic.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='statistic.c' object='cdo-statistic.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-statistic.o `test -f 'statistic.c' || echo '$(srcdir)/'`statistic.c
-
-cdo-statistic.obj: statistic.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-statistic.obj -MD -MP -MF $(DEPDIR)/cdo-statistic.Tpo -c -o cdo-statistic.obj `if test -f 'statistic.c'; then $(CYGPATH_W) 'statistic.c'; else $(CYGPATH_W) '$(srcdir)/statistic.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-statistic.Tpo $(DEPDIR)/cdo-statistic.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='statistic.c' object='cdo-statistic.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-statistic.obj `if test -f 'statistic.c'; then $(CYGPATH_W) 'statistic.c'; else $(CYGPATH_W) '$(srcdir)/statistic.c'; fi`
-
-cdo-table.o: table.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-table.o -MD -MP -MF $(DEPDIR)/cdo-table.Tpo -c -o cdo-table.o `test -f 'table.c' || echo '$(srcdir)/'`table.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-table.Tpo $(DEPDIR)/cdo-table.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table.c' object='cdo-table.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-table.o `test -f 'table.c' || echo '$(srcdir)/'`table.c
-
-cdo-table.obj: table.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-table.obj -MD -MP -MF $(DEPDIR)/cdo-table.Tpo -c -o cdo-table.obj `if test -f 'table.c'; then $(CYGPATH_W) 'table.c'; else $(CYGPATH_W) '$(srcdir)/table.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-table.Tpo $(DEPDIR)/cdo-table.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='table.c' object='cdo-table.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-table.obj `if test -f 'table.c'; then $(CYGPATH_W) 'table.c'; else $(CYGPATH_W) '$(srcdir)/table.c'; fi`
-
-cdo-text.o: text.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-text.o -MD -MP -MF $(DEPDIR)/cdo-text.Tpo -c -o cdo-text.o `test -f 'text.c' || echo '$(srcdir)/'`text.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-text.Tpo $(DEPDIR)/cdo-text.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='text.c' object='cdo-text.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-text.o `test -f 'text.c' || echo '$(srcdir)/'`text.c
-
-cdo-text.obj: text.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-text.obj -MD -MP -MF $(DEPDIR)/cdo-text.Tpo -c -o cdo-text.obj `if test -f 'text.c'; then $(CYGPATH_W) 'text.c'; else $(CYGPATH_W) '$(srcdir)/text.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-text.Tpo $(DEPDIR)/cdo-text.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='text.c' object='cdo-text.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-text.obj `if test -f 'text.c'; then $(CYGPATH_W) 'text.c'; else $(CYGPATH_W) '$(srcdir)/text.c'; fi`
-
-cdo-timer.o: timer.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-timer.o -MD -MP -MF $(DEPDIR)/cdo-timer.Tpo -c -o cdo-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-timer.Tpo $(DEPDIR)/cdo-timer.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='timer.c' object='cdo-timer.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
-
-cdo-timer.obj: timer.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-timer.obj -MD -MP -MF $(DEPDIR)/cdo-timer.Tpo -c -o cdo-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-timer.Tpo $(DEPDIR)/cdo-timer.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='timer.c' object='cdo-timer.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
-
-cdo-userlog.o: userlog.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-userlog.o -MD -MP -MF $(DEPDIR)/cdo-userlog.Tpo -c -o cdo-userlog.o `test -f 'userlog.c' || echo '$(srcdir)/'`userlog.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-userlog.Tpo $(DEPDIR)/cdo-userlog.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='userlog.c' object='cdo-userlog.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-userlog.o `test -f 'userlog.c' || echo '$(srcdir)/'`userlog.c
-
-cdo-userlog.obj: userlog.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-userlog.obj -MD -MP -MF $(DEPDIR)/cdo-userlog.Tpo -c -o cdo-userlog.obj `if test -f 'userlog.c'; then $(CYGPATH_W) 'userlog.c'; else $(CYGPATH_W) '$(srcdir)/userlog.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-userlog.Tpo $(DEPDIR)/cdo-userlog.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='userlog.c' object='cdo-userlog.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-userlog.obj `if test -f 'userlog.c'; then $(CYGPATH_W) 'userlog.c'; else $(CYGPATH_W) '$(srcdir)/userlog.c'; fi`
-
-cdo-util.o: util.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-util.o -MD -MP -MF $(DEPDIR)/cdo-util.Tpo -c -o cdo-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-util.Tpo $(DEPDIR)/cdo-util.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='util.c' object='cdo-util.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-util.o `test -f 'util.c' || echo '$(srcdir)/'`util.c
-
-cdo-util.obj: util.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-util.obj -MD -MP -MF $(DEPDIR)/cdo-util.Tpo -c -o cdo-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-util.Tpo $(DEPDIR)/cdo-util.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='util.c' object='cdo-util.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-util.obj `if test -f 'util.c'; then $(CYGPATH_W) 'util.c'; else $(CYGPATH_W) '$(srcdir)/util.c'; fi`
-
-cdo-vinterp.o: vinterp.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-vinterp.o -MD -MP -MF $(DEPDIR)/cdo-vinterp.Tpo -c -o cdo-vinterp.o `test -f 'vinterp.c' || echo '$(srcdir)/'`vinterp.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-vinterp.Tpo $(DEPDIR)/cdo-vinterp.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vinterp.c' object='cdo-vinterp.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-vinterp.o `test -f 'vinterp.c' || echo '$(srcdir)/'`vinterp.c
-
-cdo-vinterp.obj: vinterp.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-vinterp.obj -MD -MP -MF $(DEPDIR)/cdo-vinterp.Tpo -c -o cdo-vinterp.obj `if test -f 'vinterp.c'; then $(CYGPATH_W) 'vinterp.c'; else $(CYGPATH_W) '$(srcdir)/vinterp.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-vinterp.Tpo $(DEPDIR)/cdo-vinterp.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='vinterp.c' object='cdo-vinterp.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-vinterp.obj `if test -f 'vinterp.c'; then $(CYGPATH_W) 'vinterp.c'; else $(CYGPATH_W) '$(srcdir)/vinterp.c'; fi`
-
-cdo-zaxis.o: zaxis.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-zaxis.o -MD -MP -MF $(DEPDIR)/cdo-zaxis.Tpo -c -o cdo-zaxis.o `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-zaxis.Tpo $(DEPDIR)/cdo-zaxis.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='zaxis.c' object='cdo-zaxis.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-zaxis.o `test -f 'zaxis.c' || echo '$(srcdir)/'`zaxis.c
-
-cdo-zaxis.obj: zaxis.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-zaxis.obj -MD -MP -MF $(DEPDIR)/cdo-zaxis.Tpo -c -o cdo-zaxis.obj `if test -f 'zaxis.c'; then $(CYGPATH_W) 'zaxis.c'; else $(CYGPATH_W) '$(srcdir)/zaxis.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-zaxis.Tpo $(DEPDIR)/cdo-zaxis.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='zaxis.c' object='cdo-zaxis.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-zaxis.obj `if test -f 'zaxis.c'; then $(CYGPATH_W) 'zaxis.c'; else $(CYGPATH_W) '$(srcdir)/zaxis.c'; fi`
-
-clipping/cdo-clipping.o: clipping/clipping.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-clipping.o -MD -MP -MF clipping/$(DEPDIR)/cdo-clipping.Tpo -c -o clipping/cdo-clipping.o `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-clipping.Tpo clipping/$(DEPDIR)/cdo-clipping.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/clipping.c' object='clipping/cdo-clipping.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-clipping.o `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
-
-clipping/cdo-clipping.obj: clipping/clipping.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-clipping.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-clipping.Tpo -c -o clipping/cdo-clipping.obj `if test -f 'clipping/clipping.c'; then $(CYGPATH_W) 'clipping/clipping.c'; else $(CYGPATH_W) '$(srcdir)/clipping/clipping.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-clipping.Tpo clipping/$(DEPDIR)/cdo-clipping.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/clipping.c' object='clipping/cdo-clipping.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-clipping.obj `if test -f 'clipping/clipping.c'; then $(CYGPATH_W) 'clipping/clipping.c'; else $(CYGPATH_W) '$(srcdir)/clipping/clipping.c'; fi`
-
-clipping/cdo-area.o: clipping/area.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-area.o -MD -MP -MF clipping/$(DEPDIR)/cdo-area.Tpo -c -o clipping/cdo-area.o `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-area.Tpo clipping/$(DEPDIR)/cdo-area.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/area.c' object='clipping/cdo-area.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-area.o `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
-
-clipping/cdo-area.obj: clipping/area.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-area.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-area.Tpo -c -o clipping/cdo-area.obj `if test -f 'clipping/area.c'; then $(CYGPATH_W) 'clipping/area.c'; else $(CYGPATH_W) '$(srcdir)/clipping/area.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-area.Tpo clipping/$(DEPDIR)/cdo-area.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/area.c' object='clipping/cdo-area.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-area.obj `if test -f 'clipping/area.c'; then $(CYGPATH_W) 'clipping/area.c'; else $(CYGPATH_W) '$(srcdir)/clipping/area.c'; fi`
-
-clipping/cdo-ensure_array_size.o: clipping/ensure_array_size.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-ensure_array_size.o -MD -MP -MF clipping/$(DEPDIR)/cdo-ensure_array_size.Tpo -c -o clipping/cdo-ensure_array_size.o `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-ensure_array_size.Tpo clipping/$(DEPDIR)/cdo-ensure_array_size.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/ensure_array_size.c' object='clipping/cdo-ensure_array_size.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-ensure_array_size.o `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
-
-clipping/cdo-ensure_array_size.obj: clipping/ensure_array_size.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-ensure_array_size.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-ensure_array_size.Tpo -c -o clipping/cdo-ensure_array_size.obj `if test -f 'clipping/ensure_array_size.c'; then $(CYGPATH_W) 'clipping/ensure_array_size.c'; else $(CYGPATH_W) '$(srcdir)/clipping/ensure_array_size.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-ensure_array_size.Tpo clipping/$(DEPDIR)/cdo-ensure_array_size.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/ensure_array_size.c' object='clipping/cdo-ensure_array_size.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-ensure_array_size.obj `if test -f 'clipping/ensure_array_size.c'; then $(CYGPATH_W) 'clipping/ensure_array_size.c'; else $(CYGPATH_W) '$(srcdir)/clipping/ensure_array_size.c'; fi`
-
-clipping/cdo-geometry_tools.o: clipping/geometry_tools.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-geometry_tools.o -MD -MP -MF clipping/$(DEPDIR)/cdo-geometry_tools.Tpo -c -o clipping/cdo-geometry_tools.o `test -f 'clipping/geometry_tools.c' || echo '$(srcdir)/'`clipping/geometry_tools.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-geometry_tools.Tpo clipping/$(DEPDIR)/cdo-geometry_tools.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/geometry_tools.c' object='clipping/cdo-geometry_tools.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-geometry_tools.o `test -f 'clipping/geometry_tools.c' || echo '$(srcdir)/'`clipping/geometry_tools.c
-
-clipping/cdo-geometry_tools.obj: clipping/geometry_tools.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-geometry_tools.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-geometry_tools.Tpo -c -o clipping/cdo-geometry_tools.obj `if test -f 'clipping/geometry_tools.c'; then $(CYGPATH_W) 'clipping/geometry_tools.c'; else $(CYGPATH_W) '$(srcdir)/clipping/geometry_tools.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-geometry_tools.Tpo clipping/$(DEPDIR)/cdo-geometry_tools.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/geometry_tools.c' object='clipping/cdo-geometry_tools.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-geometry_tools.obj `if test -f 'clipping/geometry_tools.c'; then $(CYGPATH_W) 'clipping/geometry_tools.c'; else $(CYGPATH_W) '$(srcdir)/clipping/geometry_tools.c'; fi`
-
-clipping/cdo-grid_cell.o: clipping/grid_cell.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-grid_cell.o -MD -MP -MF clipping/$(DEPDIR)/cdo-grid_cell.Tpo -c -o clipping/cdo-grid_cell.o `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-grid_cell.Tpo clipping/$(DEPDIR)/cdo-grid_cell.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/grid_cell.c' object='clipping/cdo-grid_cell.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-grid_cell.o `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
-
-clipping/cdo-grid_cell.obj: clipping/grid_cell.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-grid_cell.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-grid_cell.Tpo -c -o clipping/cdo-grid_cell.obj `if test -f 'clipping/grid_cell.c'; then $(CYGPATH_W) 'clipping/grid_cell.c'; else $(CYGPATH_W) '$(srcdir)/clipping/grid_cell.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-grid_cell.Tpo clipping/$(DEPDIR)/cdo-grid_cell.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/grid_cell.c' object='clipping/cdo-grid_cell.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-grid_cell.obj `if test -f 'clipping/grid_cell.c'; then $(CYGPATH_W) 'clipping/grid_cell.c'; else $(CYGPATH_W) '$(srcdir)/clipping/grid_cell.c'; fi`
-
-clipping/cdo-intersection.o: clipping/intersection.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-intersection.o -MD -MP -MF clipping/$(DEPDIR)/cdo-intersection.Tpo -c -o clipping/cdo-intersection.o `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-intersection.Tpo clipping/$(DEPDIR)/cdo-intersection.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/intersection.c' object='clipping/cdo-intersection.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-intersection.o `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
-
-clipping/cdo-intersection.obj: clipping/intersection.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-intersection.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-intersection.Tpo -c -o clipping/cdo-intersection.obj `if test -f 'clipping/intersection.c'; then $(CYGPATH_W) 'clipping/intersection.c'; else $(CYGPATH_W) '$(srcdir)/clipping/intersection.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-intersection.Tpo clipping/$(DEPDIR)/cdo-intersection.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/intersection.c' object='clipping/cdo-intersection.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-intersection.obj `if test -f 'clipping/intersection.c'; then $(CYGPATH_W) 'clipping/intersection.c'; else $(CYGPATH_W) '$(srcdir)/clipping/intersection.c'; fi`
-
-clipping/cdo-utils.o: clipping/utils.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-utils.o -MD -MP -MF clipping/$(DEPDIR)/cdo-utils.Tpo -c -o clipping/cdo-utils.o `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-utils.Tpo clipping/$(DEPDIR)/cdo-utils.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/utils.c' object='clipping/cdo-utils.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-utils.o `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
-
-clipping/cdo-utils.obj: clipping/utils.c
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT clipping/cdo-utils.obj -MD -MP -MF clipping/$(DEPDIR)/cdo-utils.Tpo -c -o clipping/cdo-utils.obj `if test -f 'clipping/utils.c'; then $(CYGPATH_W) 'clipping/utils.c'; else $(CYGPATH_W) '$(srcdir)/clipping/utils.c'; fi`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) clipping/$(DEPDIR)/cdo-utils.Tpo clipping/$(DEPDIR)/cdo-utils.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='clipping/utils.c' object='clipping/cdo-utils.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o clipping/cdo-utils.obj `if test -f 'clipping/utils.c'; then $(CYGPATH_W) 'clipping/utils.c'; else $(CYGPATH_W) '$(srcdir)/clipping/utils.c'; fi`
-
 cdo-Magplot.o: Magplot.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Magplot.o -MD -MP -MF $(DEPDIR)/cdo-Magplot.Tpo -c -o cdo-Magplot.o `test -f 'Magplot.c' || echo '$(srcdir)/'`Magplot.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Magplot.Tpo $(DEPDIR)/cdo-Magplot.Po
@@ -4806,6 +4319,7 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+	-rm -rf clipping/.libs clipping/_libs
 
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -4891,7 +4405,7 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS) config.h
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) config.h
 installdirs:
 	for dir in "$(DESTDIR)$(bindir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -4932,7 +4446,7 @@ maintainer-clean-generic:
 clean: clean-am
 
 clean-am: clean-binPROGRAMS clean-generic clean-libtool \
-	clean-noinstPROGRAMS mostlyclean-am
+	clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR) clipping/$(DEPDIR)
@@ -5004,18 +4518,19 @@ uninstall-am: uninstall-binPROGRAMS
 
 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
 	clean-binPROGRAMS clean-generic clean-libtool \
-	clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
-	distclean-compile distclean-generic distclean-hdr \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-binPROGRAMS \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+	clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \
+	ctags ctags-am distclean distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/Maskbox.c b/src/Maskbox.c
index 7afdf96..a65d5a2 100644
--- a/src/Maskbox.c
+++ b/src/Maskbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Mastrfu.c b/src/Mastrfu.c
index 69eba4a..227bc88 100644
--- a/src/Mastrfu.c
+++ b/src/Mastrfu.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -32,22 +32,18 @@
 static
 void mastrfu(int gridID, int zaxisID, double *array1, double *array2, int nmiss, double missval)
 {
-  int nlev;
-  int nlat;
   int ilev, ilat, n;
-  double *plevel, *phi, *cosphi, *dummy;
   double fact =  4*atan(1.0) * 6371000 / 9.81;
-  double **field1, **field2;
   char units[CDI_MAX_NAME];
 
-  nlat = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
-  phi    = (double*) malloc(nlat*sizeof(double));
-  dummy  = (double*) malloc(nlat*sizeof(double));
-  cosphi = (double*) malloc(nlat*sizeof(double));
-  plevel = (double*) malloc(nlev*sizeof(double));
-  field1 = (double**) malloc(nlev*sizeof(double*));
-  field2 = (double**) malloc(nlev*sizeof(double*));
+  int nlat = gridInqSize(gridID);
+  int nlev = zaxisInqSize(zaxisID);
+  double *phi    = (double*) malloc(nlat*sizeof(double));
+  double *dummy  = (double*) malloc(nlat*sizeof(double));
+  double *cosphi = (double*) malloc(nlat*sizeof(double));
+  double *plevel = (double*) malloc(nlev*sizeof(double));
+  double **field1 = (double**) malloc(nlev*sizeof(double*));
+  double **field2 = (double**) malloc(nlev*sizeof(double*));
 
   zaxisInqLevels(zaxisID, plevel);
 
@@ -110,33 +106,26 @@ void mastrfu(int gridID, int zaxisID, double *array1, double *array2, int nmiss,
 
 void *Mastrfu(void *argument)
 {
-  int streamID1, streamID2;
   int nrecs;
-  int tsID, recID, varID, levelID;
-  int gridsize;
-  int nvars, code, gridID, zaxisID, nlev;
-  int vlistID1, vlistID2;
+  int recID, varID, levelID;
   int offset;
   int nmiss, nmiss1;
-  double missval;
-  double *array1, *array2;
-  int taxisID1, taxisID2;
 
   cdoInitialize(argument);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
   if ( nvars != 1 ) cdoAbort("This operator works only with one variable!");
 
-  code = vlistInqVarCode(vlistID1, 0);
+  int code = vlistInqVarCode(vlistID1, 0);
   if ( code > 0 && code != 132 ) cdoWarning("Unexpected code %d!", code);
 
-  missval = vlistInqVarMissval(vlistID1, 0);
+  double missval = vlistInqVarMissval(vlistID1, 0);
 
-  zaxisID = vlistInqVarZaxis(vlistID1, 0);
+  int zaxisID = vlistInqVarZaxis(vlistID1, 0);
   if ( zaxisInqType(zaxisID) != ZAXIS_PRESSURE &&
        zaxisInqType(zaxisID) != ZAXIS_GENERIC )
     {
@@ -145,16 +134,16 @@ void *Mastrfu(void *argument)
       cdoWarning("Unexpected vertical grid %s!", longname);
     }
 
-  gridID = vlistInqVarGrid(vlistID1, 0);
+  int gridID = vlistInqVarGrid(vlistID1, 0);
   if ( gridInqXsize(gridID) > 1 ) cdoAbort("Grid must be a zonal mean!");
 
-  gridsize = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
+  int gridsize = gridInqSize(gridID);
+  int nlev = zaxisInqSize(zaxisID);
 
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   vlistDefVarCode(vlistID2, 0, 272);
@@ -163,14 +152,14 @@ void *Mastrfu(void *argument)
   vlistDefVarUnits(vlistID2, 0, "kg/s");
   vlistDefVarDatatype(vlistID2, 0, DATATYPE_FLT32);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  array1 = (double*) malloc(gridsize*nlev*sizeof(double));
-  array2 = (double*) malloc(gridsize*nlev*sizeof(double));
+  double *array1 = (double*) malloc(gridsize*nlev*sizeof(double));
+  double *array2 = (double*) malloc(gridsize*nlev*sizeof(double));
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Math.c b/src/Math.c
index 599913f..5071b71 100644
--- a/src/Math.c
+++ b/src/Math.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -84,7 +84,7 @@ void *Math(void *argument)
   if ( operfunc == POW )
     {
       operatorInputArg("value");
-      rc = atof(operatorArgv()[0]);
+      rc = parameter2double(operatorArgv()[0]);
     }
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Merge.c b/src/Merge.c
index d158fa1..13f7133 100644
--- a/src/Merge.c
+++ b/src/Merge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -113,7 +113,7 @@ void checkDupEntry(int vlistID1, int vlistID2, const char *filename)
   if ( lev1 ) free(lev1);
   if ( lev2 ) free(lev2);
 }
-
+/*
 static
 int vlistConstVars(int vlistID)
 {
@@ -124,22 +124,19 @@ int vlistConstVars(int vlistID)
 
   return (1);
 }
-
+*/
 
 void *Merge(void *argument)
 {
-  int streamID1 = -1, streamID2 = -1;
+  int streamID1 = -1;
   int varID, varID2;
   int nrecs = 0;
   int recID, levelID, levelID2;
   int index;
-  int vlistID1 = -1, vlistID2;
   int lcopy = FALSE;
   int gridsize;
   int nmiss;
-  int taxisID1, taxisID2;
   //int skip_same_var = FALSE;
-  double *array = NULL;
 
   cdoInitialize(argument);
 
@@ -176,6 +173,7 @@ void *Merge(void *argument)
   int *streamIDs = (int*) malloc(nmerge*sizeof(int));
   int *vlistIDs  = (int*) malloc(nmerge*sizeof(int));
   int *numrecs   = (int*) malloc(nmerge*sizeof(int));
+  int *numsteps  = (int*) malloc(nmerge*sizeof(int));
 
   for ( index = 0; index < nmerge; index++ )
     {
@@ -184,11 +182,11 @@ void *Merge(void *argument)
       vlistIDs[index]  = streamInqVlist(streamID1);
     }
 
-  vlistID1 = vlistIDs[0];
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int vlistID1 = vlistIDs[0];
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
 
-  vlistID2 = vlistCreate();
+  int vlistID2 = vlistCreate();
   vlistCopy(vlistID2, vlistIDs[0]);
   for ( index = 1; index < nmerge; index++ )
     {
@@ -197,17 +195,45 @@ void *Merge(void *argument)
       vlistMerge(vlistID2, vlistIDs[index]);
     }
 
+  for ( index = 0; index < nmerge; index++ ) numsteps[index] = -1;
+
+  int numconst = 0;
+  for ( index = 0; index < nmerge; index++ )
+    {
+      streamID1 = streamIDs[index];
+      vlistID1  = vlistIDs[index];
+      numsteps[index] = vlistNtsteps(vlistID1);
+      if ( numsteps[index] == 0 ) numsteps[index] = 1;
+      if ( numsteps[index] == 1 ) numconst++; 
+    }
+
+  if ( numconst > 0 && numconst < nmerge )
+    for ( index = 0; index < nmerge; index++ )
+      {
+	if ( numsteps[index] == 1 ) 
+	  {
+	    vlistID1  = vlistIDs[index];
+	    int nvars = vlistNvars(vlistID1);
+	    for ( int varID = 0; varID < nvars; ++varID )
+	      {
+		varID2 = vlistMergedVar(vlistID1, varID);
+		vlistDefVarTsteptype(vlistID2, varID2, TSTEP_CONSTANT);
+	      }
+	  }
+      }
+
   if ( cdoVerbose ) 
     {
       for ( index = 0; index < nmerge; index++ ) vlistPrint(vlistIDs[index]);
       vlistPrint(vlistID2);
     }
        
-  streamID2 = streamOpenWrite(cdoStreamName(streamCnt-1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(streamCnt-1), cdoFiletype());
 
   vlistDefTaxis(vlistID2, taxisID2);
   streamDefVlist(streamID2, vlistID2);
 
+  double *array = NULL;
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID2);
@@ -233,7 +259,7 @@ void *Merge(void *argument)
       if ( tsID == 1 )
 	{
 	  for ( index = 0; index < nmerge; index++ )
-	    if ( numrecs[index] == 0 && vlistConstVars(vlistIDs[index]) ) vlistIDs[index] = -1;
+	    if ( numrecs[index] == 0 && numsteps[index] == 1 ) vlistIDs[index] = -1;
 	  /*
 	  for ( index = 0; index < nmerge; index++ )
 	    if ( vlistIDs[index] != -1 )
@@ -314,6 +340,7 @@ void *Merge(void *argument)
   if ( streamIDs ) free(streamIDs);
   if ( vlistIDs  ) free(vlistIDs);
   if ( numrecs   ) free(numrecs);
+  if ( numsteps  ) free(numsteps);
  
   if ( ! lcopy )
     if ( array ) free(array);
diff --git a/src/Mergegrid.c b/src/Mergegrid.c
index 827e3d7..a6fee70 100644
--- a/src/Mergegrid.c
+++ b/src/Mergegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@ void gen_index(int gridID1, int gridID2, int *index)
   int nlat1, nlon1;
   int nlat2, nlon2;
   int gridtype1, gridtype2;
-  int gridsize1, gridsize2;
+  int gridsize2;
   int i, j, k, i1, i2;
   int *xindex = NULL, *yindex = NULL;
   double *xvals1 = NULL, *yvals1 = NULL;
@@ -43,7 +43,6 @@ void gen_index(int gridID1, int gridID2, int *index)
   gridtype1 = gridInqType(gridID1);
   gridtype2 = gridInqType(gridID2);
 
-  gridsize1 = gridInqSize(gridID1);
   gridsize2 = gridInqSize(gridID2);
 
   if ( gridtype1 != gridtype2 )
diff --git a/src/Mergetime.c b/src/Mergetime.c
index 69bc8ef..f8b9113 100644
--- a/src/Mergetime.c
+++ b/src/Mergetime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Merstat.c b/src/Merstat.c
index 0334d16..1b15e20 100644
--- a/src/Merstat.c
+++ b/src/Merstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,7 +74,7 @@ void *Merstat(void *argument)
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
-      pn = atoi(operatorArgv()[0]);
+      pn = parameter2int(operatorArgv()[0]);
       
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
diff --git a/src/Monarith.c b/src/Monarith.c
index d4583ef..2d557a5 100644
--- a/src/Monarith.c
+++ b/src/Monarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Mrotuv.c b/src/Mrotuv.c
index 76577ce..b29d41e 100644
--- a/src/Mrotuv.c
+++ b/src/Mrotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Mrotuvb.c b/src/Mrotuvb.c
index f573d6b..964d2c8 100644
--- a/src/Mrotuvb.c
+++ b/src/Mrotuvb.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ninfo.c b/src/Ninfo.c
index a896776..095218c 100644
--- a/src/Ninfo.c
+++ b/src/Ninfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Nmltest.c b/src/Nmltest.c
index b5c2a8a..8cb0881 100644
--- a/src/Nmltest.c
+++ b/src/Nmltest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Output.c b/src/Output.c
index 9216d55..1d7a522 100644
--- a/src/Output.c
+++ b/src/Output.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -68,9 +68,7 @@ void *Output(void *argument)
   double missval;
   double lon, lat;
   char name[CDI_MAX_NAME];
-  int npar = 0;
   int year, month, day;
-  char **parnames = NULL;
   int *keys = NULL, nkeys = 0, k;
   int nKeys;
   int Keylen[]           = {      0,        8,      11,      4,      8,     6,     6,     6,     6,      4,      4,          6,     10,      8,      5,       2,     2 };
@@ -102,14 +100,14 @@ void *Output(void *argument)
       if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
 
       format = operatorArgv()[0];
-      if ( operatorArgc() == 2 ) nelem  = atoi(operatorArgv()[1]);
+      if ( operatorArgc() == 2 ) nelem = parameter2int(operatorArgv()[1]);
     }
   else if ( operatorID == OUTPUTTAB )
     {
       operatorInputArg("keys to print");
  
-      npar     = operatorArgc();
-      parnames = operatorArgv();
+      int npar = operatorArgc();
+      char **parnames = operatorArgv();
 
       if ( cdoVerbose )
 	for ( i = 0; i < npar; i++ )
diff --git a/src/Outputgmt.c b/src/Outputgmt.c
index 8161147..924ec68 100644
--- a/src/Outputgmt.c
+++ b/src/Outputgmt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -640,7 +640,7 @@ void *Outputgmt(void *argument)
     {
       operatorInputArg("increment");
       operatorCheckArgc(1);
-      ninc  = atoi(operatorArgv()[0]);
+      ninc = parameter2int(operatorArgv()[0]);
       if ( ninc < 1 ) cdoAbort("Increment must be greater than 0!");
     }
 
diff --git a/src/Pack.c b/src/Pack.c
index ee8693c..fba4354 100644
--- a/src/Pack.c
+++ b/src/Pack.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -84,43 +84,39 @@ void *Pack(void *argument)
   int gridsize;
   int nrecs;
   int gridID, varID, levelID, recID;
-  int tsID;
   int i;
   int nts;
   int nalloc = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2, taxisID1, taxisID2;
   int nmiss;
-  int nvars, nlevel;
+  int nlevel;
   int datatype = DATATYPE_INT16;
+  dtlist_type *dtlist = dtlist_new();
   double missval1, missval2;
   field_t ***vars = NULL;
-  dtinfo_t *dtinfo = NULL;
 
   cdoInitialize(argument);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  dtinfo = (dtinfo_t*) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
 	  vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
 	}
 
-      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
 
       vars[tsID] = field_malloc(vlistID1, FIELD_NONE);
 
@@ -235,13 +231,13 @@ void *Pack(void *argument)
 	}
     }
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
   for ( tsID = 0; tsID < nts; tsID++ )
     {
-      taxisDefDTinfo(taxisID2, dtinfo[tsID]);
+      dtlist_taxisDefTimestep(dtlist, taxisID2, tsID);
       streamDefTimestep(streamID2, tsID);
 
       for ( varID = 0; varID < nvars; varID++ )
@@ -264,7 +260,8 @@ void *Pack(void *argument)
     }
 
   if ( vars  ) free(vars);
-  if ( dtinfo ) free(dtinfo);
+
+  dtlist_delete(dtlist);
 
   streamClose(streamID2);
   streamClose(streamID1);
diff --git a/src/Pinfo.c b/src/Pinfo.c
index 7f5a700..efe805c 100644
--- a/src/Pinfo.c
+++ b/src/Pinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -57,6 +57,8 @@ void *Pinfo(void *argument)
   PINFO  = cdoOperatorAdd("pinfo",  0, 0, NULL);
   PINFOV = cdoOperatorAdd("pinfov", 0, 0, NULL);
 
+  UNUSED(PINFO);
+
   operatorID = cdoOperatorID();
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Pressure.c b/src/Pressure.c
index fb0397f..d718faf 100644
--- a/src/Pressure.c
+++ b/src/Pressure.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,21 +29,18 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 #include "list.h"
 #include "stdnametable.h"
 
 
 void *Pressure(void *argument)
 {
-  int PRESSURE_FL, PRESSURE_HL, DELTAP;
-  int operatorID;
   int mode;
   enum {ECHAM_MODE, WMO_MODE};
   int geop_code = 0, temp_code = 0, ps_code = 0, lsp_code = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
-  int gridsize, ngp = 0;
+  int streamID2;
+  int vlistID2;
   int recID, nrecs;
   int i, k, offset;
   int tsID, varID, levelID;
@@ -70,37 +67,17 @@ void *Pressure(void *argument)
 
   cdoInitialize(argument);
 
-  PRESSURE_FL = cdoOperatorAdd("pressure_fl", 0, 0, NULL);
-  PRESSURE_HL = cdoOperatorAdd("pressure_hl", 0, 0, NULL);
-  DELTAP      = cdoOperatorAdd("deltap",      0, 0, NULL);
+  int PRESSURE_FL = cdoOperatorAdd("pressure_fl", 0, 0, NULL);
+  int PRESSURE_HL = cdoOperatorAdd("pressure_hl", 0, 0, NULL);
+  int DELTAP      = cdoOperatorAdd("deltap",      0, 0, NULL);
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
-
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   nzaxis  = vlistNzaxis(vlistID1);
   lhavevct = FALSE;
@@ -211,12 +188,12 @@ void *Pressure(void *argument)
 
   nvars = vlistNvars(vlistID1);
 
-  if ( zaxisIDh != -1 && ngp > 0 )
+  if ( zaxisIDh != -1 && gridsize > 0 )
     {
-      ps_prog    = (double*) malloc(ngp*sizeof(double));
-      deltap     = (double*) malloc(ngp*nhlevf*sizeof(double));
-      full_press = (double*) malloc(ngp*nhlevf*sizeof(double));
-      half_press = (double*) malloc(ngp*nhlevh*sizeof(double));
+      ps_prog    = (double*) malloc(gridsize*sizeof(double));
+      deltap     = (double*) malloc(gridsize*nhlevf*sizeof(double));
+      full_press = (double*) malloc(gridsize*nhlevf*sizeof(double));
+      half_press = (double*) malloc(gridsize*nhlevh*sizeof(double));
     }
   else
     cdoAbort("No 3D variable with hybrid sigma pressure coordinate found!");
@@ -255,7 +232,6 @@ void *Pressure(void *argument)
     {
       gridID   = vlistInqVarGrid(vlistID1, varID);
       zaxisID  = vlistInqVarZaxis(vlistID1, varID);
-      gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
       instNum  = institutInqCenter(vlistInqVarInstitut(vlistID1, varID));
       tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID));
@@ -350,7 +326,6 @@ void *Pressure(void *argument)
   if ( gridInqType(gridID) == GRID_SPECTRAL )
     cdoAbort("%s on spectral representation not supported!", var_stdname(surface_air_pressure));
 
-  gridsize = gridInqSize(gridID);
   pdata = (double*) malloc(gridsize*sizeof(double));
 
 
@@ -391,16 +366,16 @@ void *Pressure(void *argument)
       if ( zaxisIDh != -1 )
 	{
 	  if ( lnpsID != -1 )
-	    for ( i = 0; i < ngp; i++ ) ps_prog[i] = exp(pdata[i]);
+	    for ( i = 0; i < gridsize; i++ ) ps_prog[i] = exp(pdata[i]);
 	  else if ( psID != -1 )
-	    memcpy(ps_prog, pdata, ngp*sizeof(double));
+	    memcpy(ps_prog, pdata, gridsize*sizeof(double));
 
 	  /* check range of ps_prog */
-	  minmaxval(ngp, ps_prog, NULL, &minval, &maxval);
+	  minmaxval(gridsize, ps_prog, NULL, &minval, &maxval);
 	  if ( minval < MIN_PS || maxval > MAX_PS )
 	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
 	    
-	  presh(full_press, half_press, vct, ps_prog, nhlevf, ngp);
+	  presh(full_press, half_press, vct, ps_prog, nhlevf, gridsize);
 	}
 
       if ( operatorID == PRESSURE_FL )
@@ -412,9 +387,9 @@ void *Pressure(void *argument)
 	{
 	  nlevel = nhlevf;
 	  for ( k = 0; k < nhlevf; ++k )
-	    for ( i = 0; i < ngp; ++i )
+	    for ( i = 0; i < gridsize; ++i )
 	      {
-		deltap[k*ngp+i] = half_press[(k+1)*ngp+i] - half_press[k*ngp+i];
+		deltap[k*gridsize+i] = half_press[(k+1)*gridsize+i] - half_press[k*gridsize+i];
 	      }
 
 	  pout = deltap;
diff --git a/src/Regres.c b/src/Regres.c
index 4ebe37a..9890f84 100644
--- a/src/Regres.c
+++ b/src/Regres.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Remap.c b/src/Remap.c
index 7a8fc3d..da2f6d1 100644
--- a/src/Remap.c
+++ b/src/Remap.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -213,7 +213,6 @@ int remap_non_global = FALSE;
 int remap_num_srch_bins = 180;
 int lremap_num_srch_bins = FALSE;
 int remap_extrapolate = FALSE;
-int remap_genweights = TRUE;
 int lextrapolate = FALSE;
 int max_remaps = -1;
 int sort_mode = HEAP_SORT;
@@ -317,25 +316,25 @@ void get_remap_env(void)
 
   remap_set_threshhold(remap_threshhold);
 
-  envstr = getenv("CDO_REMAP_SEARCH_RADIUS");
+  envstr = getenv("CDO_REMAP_RADIUS");
   if ( envstr )
     {
       double fval;
       fval = atof(envstr);
       if ( fval < 0 || fval > 180 )
 	{
-	  cdoAbort("CDO_REMAP_SEARCH_RADIUS=%g out of bounds (0-180)", fval);
+	  cdoAbort("CDO_REMAP_RADIUS=%g out of bounds (0-180)", fval);
 	}
       else
 	{
 	  remap_search_radius = fval;
 	  if ( cdoVerbose )
-	    cdoPrint("Set CDO_REMAP_SEARCH_RADIUS to %g", remap_search_radius);
+	    cdoPrint("Set CDO_REMAP_RADIUS to %g", remap_search_radius);
 	}
     }
   
   if ( cdoVerbose )
-    cdoPrint("remap_search_radius = %g", remap_search_radius);
+    cdoPrint("remap_radius = %g", remap_search_radius);
 
   envstr = getenv("REMAP_AREA_MIN");
   if ( envstr )
@@ -506,7 +505,7 @@ void scale_gridbox_area(long gridsize, const double *restrict array1, long grids
 }
 
 static
-int set_remapgrids(int vlistID, int ngrids, int *remapgrids)
+int set_remapgrids(int filetype, int vlistID, int ngrids, int *remapgrids)
 {
   int index, gridID, gridtype;
 
@@ -527,7 +526,12 @@ int set_remapgrids(int vlistID, int ngrids, int *remapgrids)
 	   gridtype != GRID_UNSTRUCTURED )
 	{
 	  if ( gridtype == GRID_GAUSSIAN_REDUCED )
-	    cdoAbort("Unsupported grid type: %s, use CDO option -R to convert reduced to regular grid!", gridNamePtr(gridtype));
+	    {
+	      if ( !cdoRegulargrid && filetype == FILETYPE_GRB )
+		cdoAbort("Unsupported grid type: %s, use CDO option -R to convert reduced to regular grid!", gridNamePtr(gridtype));
+	      else
+		cdoAbort("Unsupported grid type: %s, use CDO operator -setgridtype,regular to convert reduced to regular grid!", gridNamePtr(gridtype));
+	    }
 	  else if ( gridtype == GRID_GENERIC && gridInqSize(gridID) == 1 )
 	    remapgrids[index] = FALSE;
 	  else
@@ -572,8 +576,9 @@ static
 int get_norm_opt(void)
 {
   int norm_opt = NORM_OPT_FRACAREA;
-  char *envstr = getenv("CDO_REMAP_NORMALIZE_OPT");
+  char *envstr;
 
+  envstr = getenv("CDO_REMAP_NORMALIZE_OPT"); // obsolate
   if ( envstr && *envstr )
     {
       if      ( memcmp(envstr, "frac", 4) == 0 ) norm_opt = NORM_OPT_FRACAREA;
@@ -582,6 +587,15 @@ int get_norm_opt(void)
       else cdoWarning("CDO_REMAP_NORMALIZE_OPT=%s unsupported!", envstr);
     }
 
+  envstr = getenv("CDO_REMAP_NORM");
+  if ( envstr && *envstr )
+    {
+      if      ( memcmp(envstr, "frac", 4) == 0 ) norm_opt = NORM_OPT_FRACAREA;
+      else if ( memcmp(envstr, "dest", 4) == 0 ) norm_opt = NORM_OPT_DESTAREA;
+      else if ( memcmp(envstr, "none", 4) == 0 ) norm_opt = NORM_OPT_NONE;
+      else cdoWarning("CDO_REMAP_NORM=%s unsupported!", envstr);
+    }
+
   if ( cdoVerbose )
     {
       if      ( norm_opt == NORM_OPT_FRACAREA ) cdoPrint("Normalization option: frac");
@@ -644,7 +658,7 @@ void remap_set_frac_min(int gridsize, double *array, double missval, remapgrid_t
 
 
 int timer_remap, timer_remap_init, timer_remap_sort;
-int timer_remap_bil, timer_remap_nn, timer_remap_con, timer_remap_con_l1, timer_remap_con_l2;
+int timer_remap_bil, timer_remap_bic, timer_remap_dis, timer_remap_con, timer_remap_con_l1, timer_remap_con_l2;
 
 static
 void init_remap_timer(void)
@@ -653,7 +667,8 @@ void init_remap_timer(void)
   timer_remap_init   = timer_new("remap init");
   timer_remap_sort   = timer_new("remap sort");
   timer_remap_bil    = timer_new("remap bil");
-  timer_remap_nn     = timer_new("remap nn");
+  timer_remap_bic    = timer_new("remap bic");
+  timer_remap_dis    = timer_new("remap dis");
   timer_remap_con    = timer_new("remap con");
   timer_remap_con_l1 = timer_new("remap con loop1");
   timer_remap_con_l2 = timer_new("remap con loop2");
@@ -670,13 +685,13 @@ void sort_remap_add(remapvars_t *remapvars)
       ** OpenMP parallelism is supported
       */   
       sort_iter(remapvars->num_links, remapvars->num_wts,
-		remapvars->tgt_grid_add, remapvars->src_grid_add,
+		remapvars->tgt_cell_add, remapvars->src_cell_add,
 		remapvars->wts, ompNumThreads);
     }
   else
     { /* use a pure heap sort without any support of parallelism */
       sort_add(remapvars->num_links, remapvars->num_wts,
-	       remapvars->tgt_grid_add, remapvars->src_grid_add,
+	       remapvars->tgt_cell_add, remapvars->src_cell_add,
 	       remapvars->wts);
     }
   if ( cdoTimer ) timer_stop(timer_remap_sort);
@@ -685,15 +700,11 @@ void sort_remap_add(remapvars_t *remapvars)
 
 void *Remap(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2 = -1;
-  int nrecs, ngrids;
+  int streamID2 = -1;
+  int nrecs;
   int index;
   int tsID, recID, varID, levelID;
   int gridsize, gridsize2;
-  int vlistID1, vlistID2;
-  int taxisID1, taxisID2;
   int gridID1 = -1, gridID2;
   int nmiss1, nmiss2, i, j, r = -1;
   int *imask = NULL;
@@ -704,14 +715,12 @@ void *Remap(void *argument)
   int num_neighbors = 4;
   int need_gradiants = FALSE;
   int grid1sizemax;
-  int *remapgrids = NULL;
   char varname[CDI_MAX_NAME];
   double missval;
   double *array1 = NULL, *array2 = NULL;
   double *grad1_lat = NULL, *grad1_lon = NULL, *grad1_latlon = NULL;
   remap_t *remaps = NULL;
   char *remap_file = NULL;
-  int lwrite_remap;
 
   if ( cdoTimer ) init_remap_timer();
 
@@ -736,9 +745,9 @@ void *Remap(void *argument)
   cdoOperatorAdd("remapycon",    REMAPYCON,    0, NULL);
   cdoOperatorAdd("genycon",      GENYCON,      1, NULL);
 
-  operatorID   = cdoOperatorID();
-  operfunc     = cdoOperatorF1(operatorID);
-  lwrite_remap = cdoOperatorF2(operatorID);
+  int operatorID   = cdoOperatorID();
+  int operfunc     = cdoOperatorF1(operatorID);
+  int lwrite_remap = cdoOperatorF2(operatorID);
 
   remap_set_int(REMAP_WRITE_REMAP, lwrite_remap);
 
@@ -770,18 +779,21 @@ void *Remap(void *argument)
       gridID2 = cdoDefineGrid(operatorArgv()[0]);
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  if ( gridInqType(gridID2) == GRID_GENERIC ) cdoAbort("Unsupported target grid type (generic)!");
+
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int filetype = streamInqFiletype(streamID1);
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  ngrids = vlistNgrids(vlistID1);
-  remapgrids = (int*) malloc(ngrids*sizeof(int));
-  index = set_remapgrids(vlistID1, ngrids, remapgrids);
+  int ngrids = vlistNgrids(vlistID1);
+  int remapgrids[ngrids];
+  index = set_remapgrids(filetype, vlistID1, ngrids, remapgrids);
   gridID1 = vlistGrid(vlistID1, index);
 
   for ( index = 0; index < ngrids; index++ )
@@ -1074,7 +1086,7 @@ void *Remap(void *argument)
 		  else if ( map_type == MAP_TYPE_DISTWGT     ) scrip_remap_weights_distwgt(num_neighbors, &remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
 		  else if ( map_type == MAP_TYPE_CONSERV_YAC ) remap_weights_conserv(&remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
 
-		  if ( remaps[r].vars.num_links != remaps[r].vars.max_links )
+		  if ( map_type == MAP_TYPE_CONSERV && remaps[r].vars.num_links != remaps[r].vars.max_links )
 		    resize_remap_vars(&remaps[r].vars, remaps[r].vars.num_links-remaps[r].vars.max_links);
 		  
 		  if ( remaps[r].vars.sort_add ) sort_remap_add(&remaps[r].vars);
@@ -1104,13 +1116,13 @@ void *Remap(void *argument)
 
 	      if ( operfunc == REMAPLAF )
 		remap_laf(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-			  remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add, array1);
+			  remaps[r].vars.num_wts, remaps[r].vars.tgt_cell_add, remaps[r].vars.src_cell_add, array1);
 	      else if ( operfunc == REMAPSUM )
 		remap_sum(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-			  remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add, array1);
+			  remaps[r].vars.num_wts, remaps[r].vars.tgt_cell_add, remaps[r].vars.src_cell_add, array1);
 	      else
 		remap(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-		      remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add,
+		      remaps[r].vars.num_wts, remaps[r].vars.tgt_cell_add, remaps[r].vars.src_cell_add,
 		      array1, grad1_lat, grad1_lon, grad1_latlon, remaps[r].vars.links);
 	    }
 	  else
@@ -1194,7 +1206,6 @@ void *Remap(void *argument)
 
   streamClose(streamID1);
 
-  if ( remapgrids ) free(remapgrids);
   if ( imask )  free(imask);
   if ( array2 ) free(array2);
   if ( array1 ) free(array1);
diff --git a/src/Remapeta.c b/src/Remapeta.c
index 142cf63..f983ee6 100644
--- a/src/Remapeta.c
+++ b/src/Remapeta.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2007-2012 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 #include "list.h"
 #include "stdnametable.h"
 #include "hetaeta.h"
@@ -185,13 +185,13 @@ void *Remapeta(void *argument)
   int operatorID;
   int streamID1, streamID2;
   int vlistID1, vlistID2;
-  int gridsize, ngp = 0, nfis2gp = 0;
+  int nfis2gp = 0;
   int recID, nrecs;
   int i, offset, iv;
   int tsID, varID, levelID;
   int nvars, nvars3D = 0;
   int zaxisID2, zaxisIDh = -1, nzaxis, surfaceID;
-  int ngrids, gridID, zaxisID;
+  int gridID, zaxisID;
   int nlevel;
   int nvct1, nvct2 = 0;
   int sgeopotID = -1, tempID = -1, sqID = -1, psID = -1, lnpsID = -1, presID = -1;
@@ -316,31 +316,11 @@ void *Remapeta(void *argument)
   taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) == GRID_SPECTRAL )
-	{
-	  cdoAbort("Spectral data unsupported!");
-	}
-      else
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
+  gridID = vlistGrid(vlistID1, 0);
+  if ( gridInqType(gridID) == GRID_SPECTRAL )
+    cdoAbort("Spectral data unsupported!");
 
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   zaxisID2 = zaxisCreate(ZAXIS_HYBRID, nhlevf2);
   lev2 = (double*) malloc(nhlevf2*sizeof(double));
@@ -512,39 +492,39 @@ void *Remapeta(void *argument)
 
   if ( operatorID == REMAPETAS || operatorID == REMAPETAZ)
     {
-      sum1 = (double*) malloc(ngp*sizeof(double));
-      sum2 = (double*) malloc(ngp*sizeof(double));
+      sum1 = (double*) malloc(gridsize*sizeof(double));
+      sum2 = (double*) malloc(gridsize*sizeof(double));
     }
 
   if ( operatorID == REMAPETAZ )
     {
-      deltap1 = (double*) malloc(ngp*nhlevf1*sizeof(double));
-      deltap2 = (double*) malloc(ngp*nhlevf2*sizeof(double));
-      half_press1 = (double*) malloc(ngp*(nhlevf1+1)*sizeof(double));
-      half_press2 = (double*) malloc(ngp*(nhlevf2+1)*sizeof(double));
+      deltap1 = (double*) malloc(gridsize*nhlevf1*sizeof(double));
+      deltap2 = (double*) malloc(gridsize*nhlevf2*sizeof(double));
+      half_press1 = (double*) malloc(gridsize*(nhlevf1+1)*sizeof(double));
+      half_press2 = (double*) malloc(gridsize*(nhlevf2+1)*sizeof(double));
     }
 
-  array = (double*) malloc(ngp*sizeof(double));
+  array = (double*) malloc(gridsize*sizeof(double));
 
-  fis1  = (double*) malloc(ngp*sizeof(double));
-  ps1   = (double*) malloc(ngp*sizeof(double));
+  fis1  = (double*) malloc(gridsize*sizeof(double));
+  ps1   = (double*) malloc(gridsize*sizeof(double));
 
-  if ( lfis2 == FALSE ) fis2  = (double*) malloc(ngp*sizeof(double));
-  if ( lfis2 == TRUE && ngp != nfis2gp ) cdoAbort("Orographies have different grid size!");
+  if ( lfis2 == FALSE ) fis2  = (double*) malloc(gridsize*sizeof(double));
+  if ( lfis2 == TRUE && gridsize != nfis2gp ) cdoAbort("Orographies have different grid size!");
 
-  ps2   = (double*) malloc(ngp*sizeof(double));
+  ps2   = (double*) malloc(gridsize*sizeof(double));
 
   if ( ltq )
     {
-      tscor = (double*) malloc(ngp*sizeof(double));
-      pscor = (double*) malloc(ngp*sizeof(double));
-      secor = (double*) malloc(ngp*sizeof(double));
+      tscor = (double*) malloc(gridsize*sizeof(double));
+      pscor = (double*) malloc(gridsize*sizeof(double));
+      secor = (double*) malloc(gridsize*sizeof(double));
 
-      t1    = (double*) malloc(ngp*nhlevf1*sizeof(double));
-      q1    = (double*) malloc(ngp*nhlevf1*sizeof(double));
+      t1    = (double*) malloc(gridsize*nhlevf1*sizeof(double));
+      q1    = (double*) malloc(gridsize*nhlevf1*sizeof(double));
 
-      t2    = (double*) malloc(ngp*nhlevf2*sizeof(double));
-      q2    = (double*) malloc(ngp*nhlevf2*sizeof(double));
+      t2    = (double*) malloc(gridsize*nhlevf2*sizeof(double));
+      q2    = (double*) malloc(gridsize*nhlevf2*sizeof(double));
     }
 
   if ( nvars3D )
@@ -554,8 +534,8 @@ void *Remapeta(void *argument)
 
       for ( varID = 0; varID < nvars3D; ++varID )
 	{
-	  vars1[varID] = (double*) malloc(ngp*nhlevf1*sizeof(double));
-	  vars2[varID] = (double*) malloc(ngp*nhlevf2*sizeof(double));
+	  vars1[varID] = (double*) malloc(gridsize*nhlevf1*sizeof(double));
+	  vars2[varID] = (double*) malloc(gridsize*nhlevf2*sizeof(double));
 	}
     }
 
@@ -564,7 +544,7 @@ void *Remapeta(void *argument)
       if ( ltq )
 	cdoWarning("%s not found - set to zero!", var_stdname(surface_geopotential));
 
-      memset(fis1, 0, ngp*sizeof(double));
+      memset(fis1, 0, gridsize*sizeof(double));
     }
 
   presID = lnpsID;
@@ -596,7 +576,6 @@ void *Remapeta(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
 	  nlevel   = zaxisInqSize(zaxisID);
 	  offset   = gridsize*levelID;
@@ -605,18 +584,18 @@ void *Remapeta(void *argument)
 	  if ( zaxisIDh != -1 )
 	    {
 	      if ( varID == sgeopotID )
-		memcpy(fis1, array, ngp*sizeof(double));
+		memcpy(fis1, array, gridsize*sizeof(double));
 	      else if ( varID == presID )
 		{
 		  if ( lnpsID != -1 )
-		    for ( i = 0; i < ngp; ++i ) ps1[i] = exp(array[i]);
+		    for ( i = 0; i < gridsize; ++i ) ps1[i] = exp(array[i]);
 		  else if ( psID != -1 )
-		    memcpy(ps1, array, ngp*sizeof(double));
+		    memcpy(ps1, array, gridsize*sizeof(double));
 		}
 	      else if ( ltq && varID == tempID )
-		memcpy(t1+offset, array, ngp*sizeof(double));
+		memcpy(t1+offset, array, gridsize*sizeof(double));
 	      else if ( ltq && varID == sqID )
-		memcpy(q1+offset, array, ngp*sizeof(double));
+		memcpy(q1+offset, array, gridsize*sizeof(double));
 	      /* else if ( zaxisID == zaxisIDh ) */
 	      else if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel == nhlevf1 )
 		{
@@ -625,7 +604,7 @@ void *Remapeta(void *argument)
 
 		  if ( i == nvars3D ) cdoAbort("Internal error, 3D variable not found!");
 
-		  memcpy(vars1[i]+offset, array, ngp*sizeof(double));
+		  memcpy(vars1[i]+offset, array, gridsize*sizeof(double));
 		}
 	      else
 		{
@@ -643,18 +622,18 @@ void *Remapeta(void *argument)
       if ( zaxisIDh != -1 )
 	{
 	  /* check range of ps_prog */
-	  minmaxval(ngp, ps1, imiss, &minval, &maxval);
+	  minmaxval(gridsize, ps1, imiss, &minval, &maxval);
 	  if ( minval < MIN_PS || maxval > MAX_PS )
 	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
 
 	  /* check range of geop */
-	  minmaxval(ngp, fis1, imiss, &minval, &maxval);
+	  minmaxval(gridsize, fis1, imiss, &minval, &maxval);
 	  if ( minval < MIN_FIS || maxval > MAX_FIS )
 	    cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval);
 	}
 
       if ( lfis2 == FALSE )
-	for ( i = 0; i < ngp; i++ ) fis2[i] = fis1[i];
+	for ( i = 0; i < gridsize; i++ ) fis2[i] = fis1[i];
 
       if ( ltq )
 	{
@@ -662,11 +641,10 @@ void *Remapeta(void *argument)
 	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      offset   = gridsize*levelID;
 	      single2  = t1 + offset;
 
-	      minmaxval(ngp, single2, imiss, &minval, &maxval);
+	      minmaxval(gridsize, single2, imiss, &minval, &maxval);
 	      if ( minval < MIN_T || maxval > MAX_T )
 		cdoWarning("Input temperature at level %d out of range (min=%g max=%g)!",
 			   levelID+1, minval, maxval);
@@ -676,13 +654,12 @@ void *Remapeta(void *argument)
 	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      offset   = gridsize*levelID;
 	      single2  = q1 + offset;
 
 	      corr_hum(gridsize, single2, MIN_Q);
 
-	      minmaxval(ngp, single2, imiss, &minval, &maxval);
+	      minmaxval(gridsize, single2, imiss, &minval, &maxval);
 	      if ( minval < MIN_Q || maxval > MAX_Q )
 		cdoWarning("Input humidity at level %d out of range (min=%g max=%g)!",
 			   levelID+1, minval, maxval);
@@ -692,7 +669,7 @@ void *Remapeta(void *argument)
       if ( nvars3D || ltq )
 	{
 	  if ( cdoTimer ) timer_start(timer_hetaeta);
-	  hetaeta(ltq, ngp, imiss,
+	  hetaeta(ltq, gridsize, imiss,
 		  nhlevf1, a1, b1,
 		  fis1, ps1,
 		  t1, q1,
@@ -711,19 +688,19 @@ void *Remapeta(void *argument)
 	{
 	  varID   = sgeopotID;
 	  levelID = 0;
-	  setmissval(ngp, imiss, missval, fis2);
+	  setmissval(gridsize, imiss, missval, fis2);
 	  streamDefRecord(streamID2, varID, levelID);
 	  streamWriteRecord(streamID2, fis2, nmissout);
 	}
 
       if ( zaxisIDh != -1 && lnpsID != -1 )
-	for ( i = 0; i < ngp; ++i ) ps2[i] = log(ps2[i]);
+	for ( i = 0; i < gridsize; ++i ) ps2[i] = log(ps2[i]);
 
       if ( zaxisIDh != -1 && presID != -1 )
 	{
 	  varID   = presID;
 	  levelID = 0;
-	  setmissval(ngp, imiss, missval, ps2);
+	  setmissval(gridsize, imiss, missval, ps2);
 	  streamDefRecord(streamID2, varID, levelID);
 	  streamWriteRecord(streamID2, ps2, nmissout);
 	}
@@ -734,16 +711,15 @@ void *Remapeta(void *argument)
 	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	      offset   = gridsize*levelID;
 	      single2  = t2 + offset;
 
-	      minmaxval(ngp, single2, imiss, &minval, &maxval);
+	      minmaxval(gridsize, single2, imiss, &minval, &maxval);
 	      if ( minval < MIN_T || maxval > MAX_T )
 		cdoWarning("Output temperature at level %d out of range (min=%g max=%g)!",
 			   levelID+1, minval, maxval);
 
-	      if ( gridsize == ngp ) setmissval(ngp, imiss, missval, single2);
+	      setmissval(gridsize, imiss, missval, single2);
 	      streamDefRecord(streamID2, varID, levelID);
 	      streamWriteRecord(streamID2, single2, nmissout);
 	    }
@@ -752,7 +728,6 @@ void *Remapeta(void *argument)
 	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	      offset   = gridsize*levelID;
 	      single2  = q2 + offset;
 
@@ -761,12 +736,12 @@ void *Remapeta(void *argument)
 	      if ( levelID < nctop )
 		for ( i = 0; i < gridsize; ++i ) single2[i] = cconst;
 
-	      minmaxval(ngp, single2, imiss, &minval, &maxval);
+	      minmaxval(gridsize, single2, imiss, &minval, &maxval);
 	      if ( minval < MIN_Q || maxval > MAX_Q )
 		cdoWarning("Output humidity at level %d out of range (min=%g max=%g)!",
 			   levelID+1, minval, maxval);
 
-	      if ( gridsize == ngp ) setmissval(ngp, imiss, missval, single2);
+	      setmissval(gridsize, imiss, missval, single2);
 	      streamDefRecord(streamID2, varID, levelID);
 	      streamWriteRecord(streamID2, single2, nmissout);
 	    }
@@ -776,16 +751,13 @@ void *Remapeta(void *argument)
 	{
 	  varID = varids[iv];
 
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 
 	  if ( operatorID == REMAPETAS )
 	    {
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      vert_sum(sum1, vars1[iv], gridsize, nhlevf1);
 
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      vert_sum(sum2, vars2[iv], gridsize, nhlevf2);
 	    }
@@ -793,28 +765,25 @@ void *Remapeta(void *argument)
 	    {
 	      int k;
 
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 
 	      presh(NULL, half_press1, vct1, ps1, nhlevf1, gridsize);
 	      for ( k = 0; k < nhlevf1; ++k )
-		for ( i = 0; i < ngp; ++i )
+		for ( i = 0; i < gridsize; ++i )
 		  {
-		    deltap1[k*ngp+i] = half_press1[(k+1)*ngp+i] - half_press1[k*ngp+i];
-		    deltap1[k*ngp+i] = log(deltap1[k*ngp+i]);
+		    deltap1[k*gridsize+i] = half_press1[(k+1)*gridsize+i] - half_press1[k*gridsize+i];
+		    deltap1[k*gridsize+i] = log(deltap1[k*gridsize+i]);
 		  }
 	      vert_sumw(sum1, vars1[iv], gridsize, nhlevf1, deltap1);
 
-
-	      gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 
 	      presh(NULL, half_press2, vct2, ps1, nhlevf2, gridsize);
 	      for ( k = 0; k < nhlevf2; ++k )
-		for ( i = 0; i < ngp; ++i )
+		for ( i = 0; i < gridsize; ++i )
 		  {
-		    deltap2[k*ngp+i] = half_press2[(k+1)*ngp+i] - half_press2[k*ngp+i];
-		    deltap2[k*ngp+i] = log(deltap2[k*ngp+i]);
+		    deltap2[k*gridsize+i] = half_press2[(k+1)*gridsize+i] - half_press2[k*gridsize+i];
+		    deltap2[k*gridsize+i] = log(deltap2[k*gridsize+i]);
 		  }
 	      vert_sumw(sum2, vars2[iv], gridsize, nhlevf2, deltap2);
 	    }
@@ -835,7 +804,7 @@ void *Remapeta(void *argument)
 		    single2[i] = single2[i]*sum1[i]/sum2[i];
 		}
 
-	      if ( gridsize == ngp ) setmissval(ngp, imiss, missval, single2);
+	      setmissval(gridsize, imiss, missval, single2);
 	      streamDefRecord(streamID2, varID, levelID);
 	      streamWriteRecord(streamID2, single2, nmissout);
 	    }
diff --git a/src/Replace.c b/src/Replace.c
index 7b14d52..48730e8 100644
--- a/src/Replace.c
+++ b/src/Replace.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Replacevalues.c b/src/Replacevalues.c
index f5b780a..c3ef91c 100644
--- a/src/Replacevalues.c
+++ b/src/Replacevalues.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,18 +29,6 @@
 #include "pstream.h"
 #include "list.h"
 
-static
-double arg2val(char *arg)
-{
-  /*
-  if      ( strcmp(arg,"inf") == 0 )
-    return  DBL_MAX;
-  else if ( strcmp(arg,"-inf") == 0 )
-    return -DBL_MAX;
-  else
-  */
-    return atof(arg);
-}
 
 void *Replacevalues(void *argument)
 {
@@ -84,17 +72,17 @@ void *Replacevalues(void *argument)
   else if ( operatorID == SETRTOC )
     {
       operatorCheckArgc(3);
-      rmin   = arg2val(operatorArgv()[0]);
-      rmax   = arg2val(operatorArgv()[1]);
-      newval = arg2val(operatorArgv()[2]);
+      rmin   = parameter2double(operatorArgv()[0]);
+      rmax   = parameter2double(operatorArgv()[1]);
+      newval = parameter2double(operatorArgv()[2]);
     }
   else if ( operatorID == SETRTOC2 )
     {
       operatorCheckArgc(4);
-      rmin    = arg2val(operatorArgv()[0]);
-      rmax    = arg2val(operatorArgv()[1]);
-      newval  = arg2val(operatorArgv()[2]);
-      newval2 = arg2val(operatorArgv()[3]);
+      rmin    = parameter2double(operatorArgv()[0]);
+      rmax    = parameter2double(operatorArgv()[1]);
+      newval  = parameter2double(operatorArgv()[2]);
+      newval2 = parameter2double(operatorArgv()[3]);
     }
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Rhopot.c b/src/Rhopot.c
index 0df33d7..b4ebf0b 100644
--- a/src/Rhopot.c
+++ b/src/Rhopot.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -164,11 +164,10 @@ void *Rhopot(void *argument)
   int nrecs;
   int tsID, recID, varID, levelID;
   int nlevel1, nlevel2;
-  int gridsize;
-  int nvars, code, gridID, zaxisID;
+  int nvars, code, zaxisID;
   int vlistID1, vlistID2;
   int offset;
-  int ngrids, nlevel;
+  int nlevel;
   int i;
   int nmiss;
   int toID = -1, saoID = -1, thoID = -1;
@@ -181,7 +180,7 @@ void *Rhopot(void *argument)
 
   cdoInitialize(argument);
 
-  if ( operatorArgc() == 1 ) pin = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) pin = parameter2double(operatorArgv()[0]);
   
   streamID1 = streamOpenRead(cdoStreamName(0));
 
@@ -191,8 +190,6 @@ void *Rhopot(void *argument)
 
   for ( varID = 0; varID < nvars; varID++ )
     {
-      gridID  = vlistInqVarGrid(vlistID1, varID);
-
       code = vlistInqVarCode(vlistID1, varID);
 
       if ( code <= 0 )
@@ -226,17 +223,8 @@ void *Rhopot(void *argument)
     }
   if ( toID  == -1 ) cdoAbort("In-situ temperature not found!");
 
-  ngrids = vlistNgrids(vlistID1);
-  gridID = vlistGrid(vlistID1, 0);
-  gridsize = gridInqSize(gridID);
-
-  /* check gridsize */
-  for ( i = 1; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridsize != gridInqSize(gridID) )
-	cdoAbort("Grids have different size!");
-    }
+  int gridID = vlistGrid(vlistID1, 0);
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   zaxisID = vlistInqVarZaxis(vlistID1, saoID);
   nlevel1 = zaxisInqSize(zaxisID);
diff --git a/src/Rotuv.c b/src/Rotuv.c
index ca09d25..84dcb0f 100644
--- a/src/Rotuv.c
+++ b/src/Rotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -120,7 +120,7 @@ void *Rotuv(void *argument)
     {
       lvar = FALSE;
       for ( i = 0; i < nch; i++ )
-	chcodes[i] = atoi(operatorArgv()[i]);
+	chcodes[i] = parameter2int(operatorArgv()[i]);
     }
   else
     {
diff --git a/src/Runpctl.c b/src/Runpctl.c
index 3cfda6d..9958a27 100644
--- a/src/Runpctl.c
+++ b/src/Runpctl.c
@@ -30,26 +30,20 @@
 
 void *Runpctl(void *argument)
 {
+  int timestat_date = TIMESTAT_MEAN;
   int gridsize;
   int varID;
   int recID;
-  int nrecs, nrecords;
+  int nrecs;
   int levelID;
   int tsID;
   int otsID;
-  int i, j, inp, its, ndates = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
+  int i, j, inp, its;
   int nmiss;
-  int nvars, nlevels;
-  int *recVarID, *recLevelID;
+  int nlevels;
   double missval, val;
-  field_t ***vars1 = NULL;
-  dtinfo_t *dtinfo;
-  int taxisID1, taxisID2;
-  int calendar;
-  int pn;
   double *array;
+  field_t ***vars1 = NULL;
 
   cdoInitialize(argument);
 
@@ -57,34 +51,35 @@ void *Runpctl(void *argument)
 
   operatorInputArg("percentile number, number of timesteps");
   operatorCheckArgc(2);
-  pn     = atoi(operatorArgv()[0]);
-  ndates = atoi(operatorArgv()[1]);
+  int pn     = parameter2int(operatorArgv()[0]);
+  int ndates = parameter2int(operatorArgv()[1]);
 
   if ( pn < 1 || pn > 99 )
     cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  calendar = taxisInqCalendar(taxisID1);
-
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
+
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
 
-  dtinfo = (dtinfo_t*) malloc((ndates+1)*sizeof(dtinfo_t));
   vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   array = (double*) malloc(ndates*sizeof(double));
   
@@ -96,10 +91,9 @@ void *Runpctl(void *argument)
   for ( tsID = 0; tsID < ndates; tsID++ )
     {
       nrecs = streamInqTimestep(streamID1, tsID);
-      if ( nrecs == 0 )
-        cdoAbort("File has less than %d timesteps!", ndates);
+      if ( nrecs == 0 ) cdoAbort("File has less than %d timesteps!", ndates);
 
-      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
         
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -152,16 +146,8 @@ void *Runpctl(void *argument)
               vars1[0][varID][levelID].nmiss = nmiss;  
             }
         }
-     
-      datetime_avg_dtinfo(calendar, ndates, dtinfo);
 
-      if ( taxisHasBounds(taxisID2) )
-	{
-	  dtinfo[ndates].b[0] = dtinfo[0].b[0];
-	  dtinfo[ndates].b[1] = dtinfo[ndates-1].b[1];
-	}
-
-      taxisDefDTinfo(taxisID2, dtinfo[ndates]);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, ndates);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -177,19 +163,18 @@ void *Runpctl(void *argument)
 
       otsID++;
 
-      dtinfo[ndates] = dtinfo[0];
-      vars1[ndates] = vars1[0];
+      dtlist_shift(dtlist);
 
+      vars1[ndates] = vars1[0];
       for ( inp = 0; inp < ndates; inp++ )
         {
-          dtinfo[inp] = dtinfo[inp+1];
           vars1[inp] = vars1[inp+1];
         }
 
       nrecs = streamInqTimestep(streamID1, tsID);
       if ( nrecs == 0 ) break;
 
-      taxisInqDTinfo(taxisID1, &dtinfo[ndates-1]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, ndates-1);
 
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -213,6 +198,8 @@ void *Runpctl(void *argument)
   if ( recVarID   ) free(recVarID);
   if ( recLevelID ) free(recLevelID);
 
+  dtlist_delete(dtlist);
+
   streamClose(streamID2);
   streamClose(streamID1);
 
diff --git a/src/Runstat.c b/src/Runstat.c
index a4b9884..b7b583e 100644
--- a/src/Runstat.c
+++ b/src/Runstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -35,150 +35,27 @@
 #include "pstream.h"
 
 
-void datetime_avg_dtinfo(int calendar, int ndates, dtinfo_t *dtinfo)
-{
-  int vdate, vtime;
-  juldate_t juldate1, juldate2, juldatem;
-  double seconds;
-  /*
-  for ( i = 0; i < ndates; i++ )
-    fprintf(stdout, "%4d %d %d\n", i+1, dtinfo[i].v.date, dtinfo[i].v.time);
-  */
-  if ( ndates%2 == 0 )
-    {
-      /*
-      vdate = dtinfo[ndates-1].v.date;
-      vtime = dtinfo[ndates-1].v.time;
-      */
-      vdate = dtinfo[ndates/2-1].v.date;
-      vtime = dtinfo[ndates/2-1].v.time;
-      juldate1 = juldate_encode(calendar, vdate, vtime);
-
-      vdate = dtinfo[ndates/2].v.date;
-      vtime = dtinfo[ndates/2].v.time;
-      juldate2 = juldate_encode(calendar, vdate, vtime);
-
-      seconds = juldate_to_seconds(juldate_sub(juldate2, juldate1)) / 2;
-      juldatem = juldate_add_seconds((int)lround(seconds), juldate1);
-      juldate_decode(calendar, juldatem, &vdate, &vtime);
-    }
-  else
-    {
-      vdate = dtinfo[ndates/2].v.date;
-      vtime = dtinfo[ndates/2].v.time;
-    }
-
-  dtinfo[ndates].v.date = vdate;
-  dtinfo[ndates].v.time = vtime;
-  /*
-  fprintf(stdout, "res: %d %d\n\n", dtinfo[ndates].v.date, dtinfo[ndates].v.time);
-  */
-}
-
-
-void datetime_avg(int calendar, int ndates, datetime_t *datetime)
-{
-  int vdate, vtime;
-  juldate_t juldate1, juldate2, juldatem;
-  double seconds;
-  /*
-  for ( i = 0; i < ndates; i++ )
-    fprintf(stdout, "%4d %d %d\n", i+1, datetime[i].date, datetime[i].time);
-  */
-  if ( ndates%2 == 0 )
-    {
-      /*
-      vdate = datetime[ndates-1].date;
-      vtime = datetime[ndates-1].time;
-      */
-      vdate = datetime[ndates/2-1].date;
-      vtime = datetime[ndates/2-1].time;
-      juldate1 = juldate_encode(calendar, vdate, vtime);
-
-      vdate = datetime[ndates/2].date;
-      vtime = datetime[ndates/2].time;
-      juldate2 = juldate_encode(calendar, vdate, vtime);
-
-      seconds = juldate_to_seconds(juldate_sub(juldate2, juldate1)) / 2;
-      juldatem = juldate_add_seconds((int)lround(seconds), juldate1);
-      juldate_decode(calendar, juldatem, &vdate, &vtime);
-    }
-  else
-    {
-      vdate = datetime[ndates/2].date;
-      vtime = datetime[ndates/2].time;
-    }
-
-  datetime[ndates].date = vdate;
-  datetime[ndates].time = vtime;
-  /*
-  fprintf(stdout, "res: %d %d\n\n", datetime[ndates].date, datetime[ndates].time);
-  */
-}
-
-
-void get_timestat_date(int *tstat_date)
-{
-  char *envstr;
-
-  envstr = getenv("TIMESTAT_DATE");
-  if ( envstr == NULL ) envstr = getenv("RUNSTAT_DATE");
-  if ( envstr )
-    {
-      int env_date = -1;
-      char envstrl[8];
-
-      memcpy(envstrl, envstr, 8);
-      envstrl[7] = 0;
-      strtolower(envstrl);
-
-      if      ( memcmp(envstrl, "first", 5)  == 0 )  env_date = DATE_FIRST;
-      else if ( memcmp(envstrl, "last", 4)   == 0 )  env_date = DATE_LAST;
-      else if ( memcmp(envstrl, "middle", 6) == 0 )  env_date = DATE_MIDDLE;
-
-      if ( env_date >= 0 )
-	{
-	  *tstat_date = env_date;
-
-	  if ( cdoVerbose ) cdoPrint("Set TIMESTAT_DATE to %s", envstr);
-	}
-    }
-}
-
-
 void *Runstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int gridsize, gridsizemax;
+  int timestat_date = TIMESTAT_MEAN;
+  int gridsize;
   int i;
   int varID;
   int recID;
-  int nrecs, nrecords;
+  int nrecs;
   int levelID;
   int tsID;
   int otsID;
-  int inp, its, ndates = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
+  int inp, its;
   int nmiss;
-  int nvars, nlevel;
-  int *recVarID, *recLevelID;
-  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
-  int *imask;
+  int nlevel;
+  int runstat_nomiss = 0;
   double missval;
-  double divisor;
   field_t ***vars1 = NULL, ***vars2 = NULL, ***samp1 = NULL;
-  dtinfo_t *dtinfo;
-  int taxisID1, taxisID2;
-  int calendar;
-  int runstat_nomiss = 0;
-  int timestat_date = DATE_MIDDLE;
-  char *envstr;
 
   cdoInitialize(argument);
 
-  envstr = getenv("RUNSTAT_NOMISS");
+  char *envstr = getenv("RUNSTAT_NOMISS");
   if ( envstr )
     {
       char *endptr;
@@ -186,8 +63,6 @@ void *Runstat(void *argument)
       if ( envval == 1 ) runstat_nomiss = 1;
     }
 
-  get_timestat_date(&timestat_date);
-
   cdoOperatorAdd("runmin",  func_min,  0, NULL);
   cdoOperatorAdd("runmax",  func_max,  0, NULL);
   cdoOperatorAdd("runsum",  func_sum,  0, NULL);
@@ -198,39 +73,40 @@ void *Runstat(void *argument)
   cdoOperatorAdd("runstd",  func_std,  0, NULL);
   cdoOperatorAdd("runstd1", func_std1, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg("number of timesteps");
-  ndates = atoi(operatorArgv()[0]);
+  int ndates = parameter2int(operatorArgv()[0]);
 
-  lmean   = operfunc == func_mean || operfunc == func_avg;
-  lstd    = operfunc == func_std || operfunc == func_std1;
-  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
-  divisor = operfunc == func_std1 || operfunc == func_var1;
+  int lmean   = operfunc == func_mean || operfunc == func_avg;
+  int lstd    = operfunc == func_std || operfunc == func_std1;
+  int lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  double divisor = operfunc == func_std1 || operfunc == func_var1;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  calendar = taxisInqCalendar(taxisID1);
-
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
+
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
 
-  dtinfo = (dtinfo_t*) malloc((ndates+1)*sizeof(dtinfo_t));
   vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   if ( !runstat_nomiss )
     samp1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
@@ -246,15 +122,15 @@ void *Runstat(void *argument)
 	vars2[its] = field_malloc(vlistID1, FIELD_PTR);
     }
 
-  gridsizemax = vlistGridsizeMax(vlistID1);
-  imask = (int*) malloc(gridsizemax*sizeof(int));
+  int gridsizemax = vlistGridsizeMax(vlistID1);
+  int *imask = (int*) malloc(gridsizemax*sizeof(int));
 
   for ( tsID = 0; tsID < ndates; tsID++ )
     {
       nrecs = streamInqTimestep(streamID1, tsID);
       if ( nrecs == 0 ) cdoAbort("File has less then %d timesteps!", ndates);
 
-      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, tsID);
 	
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -361,17 +237,7 @@ void *Runstat(void *argument)
 	      }
 	  }
 
-      if      ( timestat_date == DATE_MIDDLE ) datetime_avg_dtinfo(calendar, ndates, dtinfo);
-      else if ( timestat_date == DATE_FIRST  ) dtinfo[ndates].v = dtinfo[0].v;
-      else if ( timestat_date == DATE_LAST   ) dtinfo[ndates].v = dtinfo[ndates-1].v;
-
-      if ( taxisHasBounds(taxisID2) )
-	{
-	  dtinfo[ndates].b[0] = dtinfo[0].b[0];
-	  dtinfo[ndates].b[1] = dtinfo[ndates-1].b[1];
-	}
-
-      taxisDefDTinfo(taxisID2, dtinfo[ndates]);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, ndates);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -387,7 +253,8 @@ void *Runstat(void *argument)
 
       otsID++;
 
-      dtinfo[ndates] = dtinfo[0];
+      dtlist_shift(dtlist);
+
       vars1[ndates] = vars1[0];
       if ( !runstat_nomiss )
 	samp1[ndates] = samp1[0];
@@ -396,7 +263,6 @@ void *Runstat(void *argument)
 
       for ( inp = 0; inp < ndates; inp++ )
 	{
-	  dtinfo[inp] = dtinfo[inp+1];
 	  vars1[inp] = vars1[inp+1];
 	  if ( !runstat_nomiss )
 	    samp1[inp] = samp1[inp+1];
@@ -407,7 +273,7 @@ void *Runstat(void *argument)
       nrecs = streamInqTimestep(streamID1, tsID);
       if ( nrecs == 0 ) break;
 
-      taxisInqDTinfo(taxisID1, &dtinfo[ndates-1]);
+      dtlist_taxisInqTimestep(dtlist, taxisID1, ndates-1);
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -477,7 +343,6 @@ void *Runstat(void *argument)
       if ( lvarstd ) field_free(vars2[its], vlistID1);
     }
 
-  free(dtinfo);
   free(vars1);
   if ( !runstat_nomiss ) free(samp1);
   if ( lvarstd ) free(vars2);
@@ -486,6 +351,8 @@ void *Runstat(void *argument)
   if ( recLevelID ) free(recLevelID);
   if ( imask )      free(imask);
 
+  dtlist_delete(dtlist);
+
   streamClose(streamID2);
   streamClose(streamID1);
 
diff --git a/src/SSOpar.c b/src/SSOpar.c
index b0df78b..69e3949 100644
--- a/src/SSOpar.c
+++ b/src/SSOpar.c
@@ -686,13 +686,12 @@ void *SSOpar(void *argument)
   int operatorID;
   int streamID1, streamID2;
   int vlistID1, vlistID2;
-  int gridsize, ngp = 0;
   int recID, nrecs;
   int i, offset, iv;
   int tsID, varID, levelID;
   int nvars;
   int zaxisID2, zaxisIDh = -1, nzaxis, surfaceID;
-  int ngrids, gridID = -1, zaxisID;
+  int zaxisID;
   int nlevel;
   int nvct;
   int geopID = -1, tempID = -1, humID = -1, psID = -1, lnpsID = -1, presID = -1, clwcID = -1, ciwcID = -1;
@@ -727,32 +726,11 @@ void *SSOpar(void *argument)
 
   vlistID1 = streamInqVlist(streamID1);
 
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) == GRID_SPECTRAL )
-	{
-	  cdoAbort("Spectral data unsupported!");
-	}
-      else
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
-
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int gridID = vlistGrid(vlistID1, 0);
+  if ( gridInqType(gridID) == GRID_SPECTRAL )
+    cdoAbort("Spectral data unsupported!");
 
+  int gridsize = vlist_check_gridsize(vlistID1);
 
   nzaxis  = vlistNzaxis(vlistID1);
   lhavevct = FALSE;
@@ -866,25 +844,25 @@ void *SSOpar(void *argument)
 
   if ( tempID == -1 ) cdoAbort("Temperature not found!");
 
-  array  = (double*) malloc(ngp*sizeof(double));
+  array  = (double*) malloc(gridsize*sizeof(double));
 
-  geop   = (double*) malloc(ngp*sizeof(double));
-  ps     = (double*) malloc(ngp*sizeof(double));
+  geop   = (double*) malloc(gridsize*sizeof(double));
+  ps     = (double*) malloc(gridsize*sizeof(double));
 
-  temp   = (double*) malloc(ngp*nhlevf*sizeof(double));
-  hum    = (double*) malloc(ngp*nhlevf*sizeof(double));
-  lwater = (double*) malloc(ngp*nhlevf*sizeof(double));
-  iwater = (double*) malloc(ngp*nhlevf*sizeof(double));
+  temp   = (double*) malloc(gridsize*nhlevf*sizeof(double));
+  hum    = (double*) malloc(gridsize*nhlevf*sizeof(double));
+  lwater = (double*) malloc(gridsize*nhlevf*sizeof(double));
+  iwater = (double*) malloc(gridsize*nhlevf*sizeof(double));
 
-  half_press   = (double*) malloc(ngp*(nhlevf+1)*sizeof(double));
-  geopotheight = (double*) malloc(ngp*(nhlevf+1)*sizeof(double));
+  half_press   = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double));
+  geopotheight = (double*) malloc(gridsize*(nhlevf+1)*sizeof(double));
 
   if ( zaxisIDh != -1 && geopID == -1 )
     {
       if ( ltq )
 	cdoWarning("Orography (surf. geopotential) not found - set to zero!");
 
-      memset(geop, 0, ngp*sizeof(double));
+      memset(geop, 0, gridsize*sizeof(double));
     }
 
   presID = lnpsID;
@@ -923,7 +901,6 @@ void *SSOpar(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
 	  nlevel   = zaxisInqSize(zaxisID);
 	  offset   = gridsize*levelID;
@@ -933,23 +910,23 @@ void *SSOpar(void *argument)
 	    {
 	      if ( varID == geopID )
 		{
-		  memcpy(geop, array, ngp*sizeof(double));
+		  memcpy(geop, array, gridsize*sizeof(double));
 		}
 	      else if ( varID == presID )
 		{
 		  if ( lnpsID != -1 )
-		    for ( i = 0; i < ngp; ++i ) ps[i] = exp(array[i]);
+		    for ( i = 0; i < gridsize; ++i ) ps[i] = exp(array[i]);
 		  else if ( psID != -1 )
-		    memcpy(ps, array, ngp*sizeof(double));
+		    memcpy(ps, array, gridsize*sizeof(double));
 		}
 	      else if ( varID == tempID )
-		memcpy(temp+offset, array, ngp*sizeof(double));
+		memcpy(temp+offset, array, gridsize*sizeof(double));
 	      else if ( varID == humID )
-		memcpy(hum+offset, array, ngp*sizeof(double));
+		memcpy(hum+offset, array, gridsize*sizeof(double));
 	      else if ( varID == clwcID )
-		memcpy(lwater+offset, array, ngp*sizeof(double));
+		memcpy(lwater+offset, array, gridsize*sizeof(double));
 	      else if ( varID == ciwcID )
-		memcpy(iwater+offset, array, ngp*sizeof(double));
+		memcpy(iwater+offset, array, gridsize*sizeof(double));
 	    }
 	}
 
@@ -957,13 +934,13 @@ void *SSOpar(void *argument)
 	{
 	  /* check range of ps_prog */
 
-	  minmaxval(ngp, ps, NULL, &minval, &maxval);
+	  minmaxval(gridsize, ps, NULL, &minval, &maxval);
 	  if ( minval < MIN_PS || maxval > MAX_PS )
 	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
 
 	  /* check range of geop */
 
-	  minmaxval(ngp, geop, NULL, &minval, &maxval);
+	  minmaxval(gridsize, geop, NULL, &minval, &maxval);
 	  if ( minval < MIN_FIS || maxval > MAX_FIS )
 	    cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval);
 	}
@@ -972,11 +949,10 @@ void *SSOpar(void *argument)
       nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       for ( levelID = 0; levelID < nlevel; levelID++ )
 	{
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  offset   = gridsize*levelID;
 	  single2  = temp + offset;
 
-	  minmaxval(ngp, single2, NULL, &minval, &maxval);
+	  minmaxval(gridsize, single2, NULL, &minval, &maxval);
 	  if ( minval < MIN_T || maxval > MAX_T )
 	    cdoWarning("Input temperature at level %d out of range (min=%g max=%g)!",
 		       levelID+1, minval, maxval);
@@ -989,7 +965,7 @@ void *SSOpar(void *argument)
       for ( levelID = 0; levelID < nlevel; levelID++ )
 	{
 	  streamDefRecord(streamID2, varID, levelID);
-	  streamWriteRecord(streamID2, geopotheight+levelID*ngp, nmissout);
+	  streamWriteRecord(streamID2, geopotheight+levelID*gridsize, nmissout);
 	}
 
       tsID++;
diff --git a/src/Seaspctl.c b/src/Seaspctl.c
index 54b220a..0df7940 100644
--- a/src/Seaspctl.c
+++ b/src/Seaspctl.c
@@ -32,27 +32,22 @@
 
 void *Seaspctl(void *argument)
 {
-  int gridsize;
-  int vdate1 = 0, vtime1 = 0;
+  int timestat_date = TIMESTAT_MEAN;
+  int vdate1 = 0;
   int vdate2 = 0, vtime2 = 0;
   int vdate3 = 0, vtime3 = 0;
-  int vdate4 = 0, vtime4 = 0;
-  int nrecs, nrecords;
+  int nrecs;
   int gridID, varID, levelID, recID;
   int tsID;
   int otsID;
   long nsets;
   int year, month, day, seas, seas0 = 0;
-  int streamID1, streamID2, streamID3, streamID4;
-  int vlistID1, vlistID2, vlistID3, vlistID4, taxisID1, taxisID2, taxisID3, taxisID4;
   int nmiss;
-  int nvars, nlevels;
-  int *recVarID, *recLevelID;
+  int nlevels;
   int newseas, oldmon = 0, newmon;
   double missval;
   field_t **vars1 = NULL;
   field_t field;
-  double pn;
   HISTOGRAM_SET *hset = NULL;
   int season_start;
 
@@ -61,44 +56,48 @@ void *Seaspctl(void *argument)
   cdoOperatorAdd("seaspctl", func_pctl, 0, NULL);
 
   operatorInputArg("percentile number");
-  pn = atof(operatorArgv()[0]);
+  double pn = parameter2double(operatorArgv()[0]);
       
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
 
   season_start = get_season_start();
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
-  streamID3 = streamOpenRead(cdoStreamName(2));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID3 = streamOpenRead(cdoStreamName(2));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = streamInqVlist(streamID3);
-  vlistID4 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = streamInqVlist(streamID3);
+  int vlistID4 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
   vlistCompare(vlistID1, vlistID3, CMP_ALL);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = vlistInqTaxis(vlistID3);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = vlistInqTaxis(vlistID3);
   /* TODO - check that time axes 2 and 3 are equal */
 
-  taxisID4 = taxisDuplicate(taxisID1);
+  int taxisID4 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID4, taxisID4);
 
-  streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
+  int streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
 
   streamDefVlist(streamID4, vlistID4);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords * sizeof(int));
-  recLevelID = (int*) malloc(nrecords * sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords * sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords * sizeof(int));
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
+
+  int gridsize = vlistGridsizeMax(vlistID1);
 
   field.ptr = (double*) malloc(gridsize*sizeof(double));
 
@@ -128,9 +127,6 @@ void *Seaspctl(void *argument)
   otsID   = 0;
   while ( TRUE )
     {
-      nsets   = 0;
-      newseas = FALSE;
-
       nrecs = streamInqTimestep(streamID2, otsID);
       if ( nrecs != streamInqTimestep(streamID3, otsID) )
         cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
@@ -148,6 +144,7 @@ void *Seaspctl(void *argument)
 	  streamReadRecord(streamID2, vars1[varID][levelID].ptr, &nmiss);
           vars1[varID][levelID].nmiss = nmiss;
         }
+
       for ( recID = 0; recID < nrecs; recID++ )
         {
           streamInqRecord(streamID3, &varID, &levelID);
@@ -159,10 +156,13 @@ void *Seaspctl(void *argument)
 	  hsetDefVarLevelBounds(hset, varID, levelID, &vars1[varID][levelID], &field);
         }
 
+      nsets   = 0;
+      newseas = FALSE;
       while ( nrecs && (nrecs = streamInqTimestep(streamID1, tsID)) )
 	{
-	  vdate1 = taxisInqVdate(taxisID1);
-	  vtime1 = taxisInqVtime(taxisID1);
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
+	  vdate1 = dtlist_get_vdate(dtlist, nsets);
+
 	  cdiDecodeDate(vdate1, &year, &month, &day);
 	  if ( month < 0 || month > 16 )
 	    cdoAbort("Month %d out of range!", month);
@@ -215,19 +215,12 @@ void *Seaspctl(void *argument)
 	      hsetAddVarLevelValues(hset, varID, levelID, &vars1[varID][levelID]);
 	    }
 
-	  vdate4 = vdate1;
-	  vtime4 = vtime1;
 	  nsets++;
 	  tsID++;
 	}
 
       if ( nrecs == 0 && nsets == 0 ) break;
 
-      if ( vdate2 != vdate4 )
-        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-      if ( vtime2 != vtime4 )
-        cdoAbort("Verification times at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-
       for ( varID = 0; varID < nvars; varID++ )
 	{
 	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -237,8 +230,7 @@ void *Seaspctl(void *argument)
             hsetGetVarLevelPercentiles(&vars1[varID][levelID], hset, varID, levelID, pn);
 	}
 
-      taxisDefVdate(taxisID4, vdate4);
-      taxisDefVtime(taxisID4, vtime4);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID4, nsets);
       streamDefTimestep(streamID4, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -267,6 +259,8 @@ void *Seaspctl(void *argument)
   free(vars1);
   hsetDestroy(hset);
 
+  dtlist_delete(dtlist);
+
   if ( field.ptr ) free(field.ptr);
 
   if ( recVarID   ) free(recVarID);
diff --git a/src/Seasstat.c b/src/Seasstat.c
index b30c6f7..d4326e0 100644
--- a/src/Seasstat.c
+++ b/src/Seasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -37,27 +37,20 @@
 
 void *Seasstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
+  int timestat_date = TIMESTAT_MEAN;
   int gridsize;
   int vdate = 0, vtime = 0;
   int vdate0 = 0, vtime0 = 0;
   int vdate1 = 0, vtime1 = 0;
-  int vdate_lb = 0, vdate_ub = 0, date_lb = 0, date_ub = 0;
-  int vtime_lb = 0, vtime_ub = 0, time_lb = 0, time_ub = 0;
-  int nrecs, nrecords;
+  int nrecs;
   int varID, levelID, recID;
   int tsID;
   int otsID;
   long nsets;
   int i;
   int year, month, day, seas, seas0 = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2, taxisID1, taxisID2;
   int nmiss;
-  int nvars, nlevel;
-  int *recVarID, *recLevelID;
-  int taxis_has_bounds = FALSE;
+  int nlevel;
   int newseas, oldmon = 0, newmon;
   int nseason = 0;
   field_t **vars1 = NULL, **vars2 = NULL, **samp1 = NULL;
@@ -75,32 +68,35 @@ void *Seasstat(void *argument)
   cdoOperatorAdd("seasvar",  func_var,  0, NULL);
   cdoOperatorAdd("seasstd",  func_std,  0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
   season_start = get_season_start();
   get_season_name(seas_name);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   if ( taxisInqType(taxisID2) == TAXIS_FORECAST ) taxisDefType(taxisID2, TAXIS_RELATIVE);
-  taxis_has_bounds = taxisHasBounds(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
+
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
@@ -120,21 +116,9 @@ void *Seasstat(void *argument)
       newseas = FALSE;
       while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
 	{
-	  vdate = taxisInqVdate(taxisID1);
-	  vtime = taxisInqVtime(taxisID1);
-
-	  if ( taxis_has_bounds )
-	    {
-	      taxisInqVdateBounds(taxisID1, &date_lb, &date_ub);
-	      taxisInqVtimeBounds(taxisID1, &time_lb, &time_ub);
-	      if ( nsets == 0 )
-		{ vdate_lb = date_lb; vtime_lb = time_lb; }
-	    }
-	  else
-	    {
-	      if ( nsets == 0 )
-		{ vdate_lb = vdate; vtime_lb = vtime; }
-	    }
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
+	  vdate = dtlist_get_vdate(dtlist, nsets);
+	  vtime = dtlist_get_vtime(dtlist, nsets);
 
 	  cdiDecodeDate(vdate, &year, &month, &day);
 	  if ( month < 1 || month > 12 )
@@ -177,11 +161,6 @@ void *Seasstat(void *argument)
 
 	  oldmon = newmon;
 
-	  if ( taxis_has_bounds )
-	    { vdate_ub = date_ub; vtime_ub = time_ub; }
-	  else
-	    { vdate_ub = vdate; vtime_ub = vtime; }
-
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
 	      streamInqRecord(streamID1, &varID, &levelID);
@@ -312,10 +291,7 @@ void *Seasstat(void *argument)
 		   vdatestr0, vtimestr0, vdatestr1, vtimestr1, nsets);
 	}
 
-      taxisDefVdate(taxisID2, vdate1);
-      taxisDefVtime(taxisID2, vtime1);
-      taxisDefVdateBounds(taxisID2, vdate_lb, vdate_ub);
-      taxisDefVtimeBounds(taxisID2, vtime_lb, vtime_ub);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, nsets);
       streamDefTimestep(streamID2, otsID);
 
       if ( nsets < 3 )
@@ -351,6 +327,8 @@ void *Seasstat(void *argument)
   if ( recVarID   ) free(recVarID);
   if ( recLevelID ) free(recLevelID);
 
+  dtlist_delete(dtlist);
+
   streamClose(streamID2);
   streamClose(streamID1);
 
diff --git a/src/Selbox.c b/src/Selbox.c
index 01f5232..8054247 100644
--- a/src/Selbox.c
+++ b/src/Selbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -431,10 +431,10 @@ void genlonlatbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11
 
   operatorCheckArgc(argc_offset+4);
 
-  xlon1 = atof(operatorArgv()[argc_offset+0]);
-  xlon2 = atof(operatorArgv()[argc_offset+1]);
-  xlat1 = atof(operatorArgv()[argc_offset+2]);
-  xlat2 = atof(operatorArgv()[argc_offset+3]);
+  xlon1 = parameter2double(operatorArgv()[argc_offset+0]);
+  xlon2 = parameter2double(operatorArgv()[argc_offset+1]);
+  xlat1 = parameter2double(operatorArgv()[argc_offset+2]);
+  xlat2 = parameter2double(operatorArgv()[argc_offset+3]);
 
   gridtype = gridInqType(gridID1);
 
@@ -598,10 +598,10 @@ int gencellgrid(int gridID1, int *gridsize2, int **cellidx)
 
   operatorCheckArgc(argc_offset+4);
 
-  xlon1 = atof(operatorArgv()[argc_offset+0]);
-  xlon2 = atof(operatorArgv()[argc_offset+1]);
-  xlat1 = atof(operatorArgv()[argc_offset+2]);
-  xlat2 = atof(operatorArgv()[argc_offset+3]);
+  xlon1 = parameter2double(operatorArgv()[argc_offset+0]);
+  xlon2 = parameter2double(operatorArgv()[argc_offset+1]);
+  xlat1 = parameter2double(operatorArgv()[argc_offset+2]);
+  xlat2 = parameter2double(operatorArgv()[argc_offset+3]);
 
   if ( xlon1 >= xlon2 ) { x = xlon1; xlon1 = xlon2; xlon2 = x; }
   if ( xlat1 >= xlat2 ) { x = xlat1; xlat1 = xlat2; xlat2 = x; }
@@ -665,10 +665,10 @@ void genindexbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11,
 
   operatorCheckArgc(argc_offset+4);
 
-  *lon11 = atoi(operatorArgv()[argc_offset+0]);
-  *lon12 = atoi(operatorArgv()[argc_offset+1]);
-  *lat1  = atoi(operatorArgv()[argc_offset+2]);
-  *lat2  = atoi(operatorArgv()[argc_offset+3]);
+  *lon11 = parameter2int(operatorArgv()[argc_offset+0]);
+  *lon12 = parameter2int(operatorArgv()[argc_offset+1]);
+  *lat1  = parameter2int(operatorArgv()[argc_offset+2]);
+  *lat2  = parameter2int(operatorArgv()[argc_offset+3]);
 
   if ( *lat1 > *lat2 )
     {
diff --git a/src/Select.c b/src/Select.c
index 8062e85..090d3d4 100644
--- a/src/Select.c
+++ b/src/Select.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,7 @@
 #include "util.h"
 //#include "list.h"
 
+double datestr_to_double(const char *datestr);
 
 #define  PML_INT         1
 #define  PML_FLT         2
@@ -72,6 +73,7 @@ static int NumParameter = sizeof(Parameter) / sizeof(Parameter[0]);
 #define PAR_CHECK_INT(name)           par_check_int(npar_##name, par_##name, flag_##name, name)
 #define PAR_CHECK_FLT(name)           par_check_flt(npar_##name, par_##name, flag_##name, name)
 #define PAR_CHECK_WORD(name)          par_check_word(npar_##name, par_##name, flag_##name, name)
+#define PAR_CHECK_DATE(name)          par_check_date(npar_##name, par_##name, flag_##name, name)
 
 #define MAX_PLIST_ENTRY  256
 #define MAX_PML_ENTRY    256
@@ -392,10 +394,8 @@ int pmlRead(pml_t *pml, int argc, char **argv)
 
 int par_check_int(int npar, int *parlist, int *flaglist, int par)
 {
-  int i, found;
-
-  found = 0;
-  for ( i = 0; i < npar; i++ )
+  int found = 0;
+  for ( int i = 0; i < npar; i++ )
     if ( par == parlist[i] ) { found = 1; flaglist[i] = TRUE;/* break;*/}
 
   return (found);
@@ -404,10 +404,8 @@ int par_check_int(int npar, int *parlist, int *flaglist, int par)
 
 int par_check_flt(int npar, double *parlist, int *flaglist, double par)
 {
-  int i, found;
-
-  found = 0;
-  for ( i = 0; i < npar; i++ )
+  int found = 0;
+  for ( int i = 0; i < npar; i++ )
     if ( fabs(par - parlist[i]) < 1.e-4 ) { found = 1; flaglist[i] = TRUE;/* break;*/}
 
   return (found);
@@ -416,11 +414,27 @@ int par_check_flt(int npar, double *parlist, int *flaglist, double par)
 
 int par_check_word(int npar, char **parlist, int *flaglist, char *par)
 {
-  int i, found;
+  int found = 0;
+  for ( int i = 0; i < npar; i++ )
+    if ( wildcardmatch(parlist[i], par) == 0 ) { found = 1; flaglist[i] = TRUE;/* break;*/}
 
-  found = 0;
-  for ( i = 0; i < npar; i++ )
-    if ( strcmp(par, parlist[i]) == 0 ) { found = 1; flaglist[i] = TRUE;/* break;*/}
+  return (found);
+}
+
+
+int par_check_date(int npar, char **parlist, int *flaglist, char *par)
+{
+  int found = 0;
+  char wcdate[512];
+
+  if ( *par == ' ' ) ++par;
+
+  for ( int i = 0; i < npar; i++ )
+    {
+      strcpy(wcdate, parlist[i]);
+      strcat(wcdate, "*");
+      if ( wildcardmatch(wcdate, par) == 0 ) { found = 1; flaglist[i] = TRUE;/* break;*/}
+    }
 
   return (found);
 }
@@ -428,9 +442,7 @@ int par_check_word(int npar, char **parlist, int *flaglist, char *par)
 
 void par_check_int_flag(int npar, int *parlist, int *flaglist, const char *txt)
 {
-  int i;
-
-  for ( i = 0; i < npar; ++i )
+  for ( int i = 0; i < npar; ++i )
     if ( flaglist[i] == FALSE )
       cdoWarning("%s >%d< not found!", txt, parlist[i]);
 }
@@ -438,9 +450,7 @@ void par_check_int_flag(int npar, int *parlist, int *flaglist, const char *txt)
 
 void par_check_flt_flag(int npar, double *parlist, int *flaglist, const char *txt)
 {
-  int i;
-
-  for ( i = 0; i < npar; ++i )
+  for ( int i = 0; i < npar; ++i )
     if ( flaglist[i] == FALSE )
       cdoWarning("%s >%g< not found!", txt, parlist[i]);
 }
@@ -448,9 +458,7 @@ void par_check_flt_flag(int npar, double *parlist, int *flaglist, const char *tx
 
 void par_check_word_flag(int npar, char **parlist, int *flaglist, const char *txt)
 {
-  int i;
-
-  for ( i = 0; i < npar; ++i )
+  for ( int i = 0; i < npar; ++i )
     if ( flaglist[i] == FALSE )
       cdoWarning("%s >%s< not found!", txt, parlist[i]);
 }
@@ -458,9 +466,7 @@ void par_check_word_flag(int npar, char **parlist, int *flaglist, const char *tx
 
 void *Select(void *argument)
 {
-  int SELECT, DELETE;
-  int operatorID;
-  int streamID1, streamID2 = CDI_UNDEFID;
+  int streamID2 = CDI_UNDEFID;
   int tsID1, tsID2, nrecs;
   int nvars, nvars2, nlevs;
   int zaxisID, levID;
@@ -470,26 +476,25 @@ void *Select(void *argument)
   int nsel;
   int vdate, vtime;
   int last_year = -999999999;
-  int copytimestep;
   char paramstr[32];
   char varname[CDI_MAX_NAME];
   char stdname[CDI_MAX_NAME];
   char **argnames = NULL;
-  int vlistID0 = -1, vlistID1 = -1, vlistID2 = -1;
+  int vlistID0 = -1, vlistID2 = -1;
   int i;
   int result = FALSE;
-  int lcopy = FALSE;
   int gridsize;
   int nmiss;
-  int streamCnt, nfiles, indf;
-  double *array = NULL;
-  int taxisID1, taxisID2 = CDI_UNDEFID;
+  int taxisID2 = CDI_UNDEFID;
   int ntsteps;
   int ltimsel = FALSE;
   int second;
   int npar;
   int *vars = NULL;
-  pml_t *pml;
+  double *array = NULL;
+  double fstartdate = -99999999999.;
+  double fenddate   = -99999999999.;
+
   PML_DEF_INT(timestep_of_year, 4096, "Timestep of year");
   PML_DEF_INT(timestep,         4096, "Timestep");
   PML_DEF_INT(year,             1024, "Year");
@@ -503,6 +508,9 @@ void *Select(void *argument)
   PML_DEF_FLT(level,            1024, "Level");
   PML_DEF_WORD(name,            1024, "Variable name");
   PML_DEF_WORD(param,           1024, "Parameter");
+  PML_DEF_WORD(startdate,          1, "Start date");
+  PML_DEF_WORD(enddate,            1, "End date");
+  PML_DEF_WORD(date,            1024, "Date");
 
   PML_INIT_INT(timestep_of_year);
   PML_INIT_INT(timestep);
@@ -517,15 +525,19 @@ void *Select(void *argument)
   PML_INIT_FLT(level);
   PML_INIT_WORD(name);
   PML_INIT_WORD(param);
+  PML_INIT_WORD(startdate);
+  PML_INIT_WORD(enddate);
+  PML_INIT_WORD(date);
 
   cdoInitialize(argument);
 
-  SELECT  = cdoOperatorAdd("select", 0, 0, "parameter list");
-  DELETE  = cdoOperatorAdd("delete", 0, 0, "parameter list");
+  int SELECT  = cdoOperatorAdd("select", 0, 0, "parameter list");
+  int DELETE  = cdoOperatorAdd("delete", 0, 0, "parameter list");
 
+  int lcopy = FALSE;
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
@@ -536,7 +548,7 @@ void *Select(void *argument)
     for ( i = 0; i < nsel; i++ )
       printf("name %d = %s\n", i+1, argnames[i]);
 
-  pml = pmlNew("SELECT");
+  pml_t *pml = pmlNew("SELECT");
 
   PML_ADD_INT(pml, timestep_of_year);
   PML_ADD_INT(pml, timestep);
@@ -551,6 +563,9 @@ void *Select(void *argument)
   PML_ADD_FLT(pml, level);
   PML_ADD_WORD(pml, name);
   PML_ADD_WORD(pml, param);
+  PML_ADD_WORD(pml, startdate);
+  PML_ADD_WORD(pml, enddate);
+  PML_ADD_WORD(pml, date);
 
   pmlRead(pml, nsel, argnames);
 
@@ -569,25 +584,28 @@ void *Select(void *argument)
   PML_NUM(pml, level);
   PML_NUM(pml, name);
   PML_NUM(pml, param);
+  PML_NUM(pml, startdate);
+  PML_NUM(pml, enddate);
+  PML_NUM(pml, date);
   /*
   pmlDelete(pml);
   */
 
-  streamCnt = cdoStreamCnt();
-  nfiles = streamCnt - 1;
+  int streamCnt = cdoStreamCnt();
+  int nfiles = streamCnt - 1;
 
   if ( !cdoVerbose && nfiles > 1 ) progressInit();
 
   tsID2 = 0;
-  for ( indf = 0; indf < nfiles; indf++ )
+  for ( int indf = 0; indf < nfiles; indf++ )
     {
       if ( !cdoVerbose && nfiles > 1 ) progressStatus(0, 1, (indf+1.)/nfiles);
       if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
 
-      streamID1 = streamOpenRead(cdoStreamName(indf));
+      int streamID1 = streamOpenRead(cdoStreamName(indf));
 
-      vlistID1 = streamInqVlist(streamID1);
-      taxisID1 = vlistInqTaxis(vlistID1);
+      int vlistID1 = streamInqVlist(streamID1);
+      int taxisID1 = vlistInqTaxis(vlistID1);
 
       if ( indf == 0 )
 	{
@@ -714,6 +732,7 @@ void *Select(void *argument)
 	  PAR_CHECK_WORD_FLAG(name);
 	  PAR_CHECK_WORD_FLAG(param);
 
+	  if ( npar_date || npar_startdate || npar_enddate ) ltimsel = TRUE;
 	  if ( npar_timestep_of_year || npar_timestep || npar_year || npar_month || npar_day || npar_hour || npar_minute ) ltimsel = TRUE;
 
 	  npar = 0;
@@ -800,8 +819,8 @@ void *Select(void *argument)
 		  if ( par_timestep[i] < 0 )
 		    {
 		      if ( cdoVerbose )
-			cdoPrint("timestep %d changed to %d", par_timestep[i], ntsteps + 1 + par_timestep[i]);
-		      par_timestep[i] = ntsteps + 1 + par_timestep[i];
+			cdoPrint("timestep %d changed to %d", par_timestep[i], par_timestep[i] + ntsteps + 1 );
+		      par_timestep[i] += ntsteps + 1;
 		    }
 		}
 	    }
@@ -812,6 +831,11 @@ void *Select(void *argument)
 	      if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
 	      array = (double*) malloc(gridsize*sizeof(double));
 	    }
+
+	  startdate = par_startdate[0];
+	  enddate   = par_enddate[0];
+	  if ( npar_startdate ) fstartdate = datestr_to_double(startdate);
+	  if ( npar_enddate   ) fenddate   = datestr_to_double(enddate);
 	}
       else
 	{
@@ -825,18 +849,26 @@ void *Select(void *argument)
 	  goto END_LABEL;
 	}
 
+      int lstop = FALSE;
       tsID1 = 0;
       while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
 	{
+	  int copytimestep = TRUE;
+
 	  if ( ltimsel == TRUE )
 	    {
 	      copytimestep = FALSE;
 	      timestep = tsID1 + 1;
 
-	      if ( operatorID == SELECT && npar_timestep > 0 && timestep > par_timestep[npar_timestep-1] ) break;
+	      if ( operatorID == SELECT && npar_timestep > 0 && timestep > par_timestep[npar_timestep-1] )
+		{
+		  lstop = TRUE;
+		  break;
+		}
 
 	      vdate = taxisInqVdate(taxisID1);
 	      vtime = taxisInqVtime(taxisID1);
+
 	      cdiDecodeDate(vdate, &year, &month, &day);
 	      cdiDecodeTime(vtime, &hour, &minute, &second);
 
@@ -851,7 +883,7 @@ void *Select(void *argument)
 	      if ( npar_timestep && PAR_CHECK_INT(timestep) ) copytimestep = TRUE;
 	      if ( npar_timestep_of_year && PAR_CHECK_INT(timestep_of_year) ) copytimestep = TRUE;
 
-	      if ( !copytimestep && npar_timestep == 0 && npar_timestep_of_year == 0 )
+	      if ( !copytimestep && npar_date == 0 && npar_timestep == 0 && npar_timestep_of_year == 0 )
 		{
 		  int lyear = 0, lmonth = 0, lday = 0, lhour = 0, lminute = 0;
 
@@ -864,12 +896,50 @@ void *Select(void *argument)
 		  if ( lyear && lmonth && lday && lhour && lminute ) copytimestep = TRUE;
 		}
 
+	      double fdate = ((double)vdate) + ((double)vtime)/1000000.;
+
+	      if ( npar_enddate )
+		{
+		  if ( fdate > fenddate )
+		    {
+		      flag_enddate[0] = TRUE;
+		      copytimestep = FALSE;
+		      if ( operatorID == SELECT )
+			{
+			  lstop = TRUE;
+			  break;
+			}
+		    }
+		  else
+		    {
+		      copytimestep = TRUE;
+		    }
+		}
+
+	      if ( npar_startdate )
+		{
+		  if ( fdate < fstartdate )
+		    {
+		      copytimestep = FALSE;
+		    }
+		  else
+		    {
+		      flag_startdate[0] = TRUE;
+		      copytimestep = TRUE;
+		    }
+		}
+
+              
+              if ( npar_date )
+                {
+                  char vdatetimestr[64];
+                  datetime2str(vdate, vtime, vdatetimestr, sizeof(vdatetimestr));
+                  date = vdatetimestr;
+                  if ( PAR_CHECK_DATE(date) ) copytimestep = TRUE;
+                }
+
 	      if ( operatorID == DELETE ) copytimestep = !copytimestep;
 	    }
-	  else
-	    {
-	      copytimestep = TRUE;
-	    }
 
 	  if ( copytimestep == TRUE )
 	    {
@@ -911,10 +981,14 @@ void *Select(void *argument)
 	}
       
       streamClose(streamID1);
+
+      if ( lstop ) break;
     }
 
  END_LABEL:
 
+  if ( !cdoVerbose && nfiles > 1 ) progressStatus(0, 1, 1);    
+
   PAR_CHECK_INT_FLAG(timestep_of_year);
   PAR_CHECK_INT_FLAG(timestep);
   PAR_CHECK_INT_FLAG(year);
@@ -922,6 +996,9 @@ void *Select(void *argument)
   PAR_CHECK_INT_FLAG(day);
   PAR_CHECK_INT_FLAG(hour);
   PAR_CHECK_INT_FLAG(minute);
+  PAR_CHECK_WORD_FLAG(startdate);
+  PAR_CHECK_WORD_FLAG(enddate);
+  PAR_CHECK_WORD_FLAG(date);
 
   if ( streamID2 != CDI_UNDEFID ) streamClose(streamID2);
 
@@ -933,6 +1010,8 @@ void *Select(void *argument)
   if ( array ) free(array);
   if ( vars ) free(vars);
 
+  if ( tsID2 == 0 ) cdoAbort("No timesteps selected!");
+
   cdoFinish();
 
   return (NULL);
diff --git a/src/Seloperator.c b/src/Seloperator.c
index a44deaa..faef11f 100644
--- a/src/Seloperator.c
+++ b/src/Seloperator.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -44,11 +44,11 @@ void *Seloperator(void *argument)
 
   operatorInputArg("code, ltype, level");
 
-  scode  = atoi(operatorArgv()[0]);
-  sltype = atoi(operatorArgv()[1]);
+  scode  = parameter2int(operatorArgv()[0]);
+  sltype = parameter2int(operatorArgv()[1]);
 
   if ( operatorArgc() == 3 )
-    slevel = atof(operatorArgv()[2]);
+    slevel = parameter2double(operatorArgv()[2]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Selrec.c b/src/Selrec.c
index 07f32ee..862d3ed 100644
--- a/src/Selrec.c
+++ b/src/Selrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Seltime.c b/src/Seltime.c
index 553f1ec..4a63a78 100644
--- a/src/Seltime.c
+++ b/src/Seltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -46,20 +46,18 @@ static
 int seaslist(LIST *ilist)
 {
   int i;
-  int nsel;
   char Seas[3];
   int seas[4] = {FALSE, FALSE, FALSE, FALSE};
   int imon[17]; /* 1-16 ! */
   int ival;
   size_t len;
-  int season_start;
 
-  season_start = get_season_start();
-  nsel = operatorArgc();
+  int season_start = get_season_start();
+  int nsel = operatorArgc();
   if ( isdigit(*operatorArgv()[0]))
     for ( i = 0; i < nsel; i++ )
       {
-	ival = atoi(operatorArgv()[i]);
+	ival = parameter2int(operatorArgv()[i]);
 	if      ( ival == 1 || ival == 13 ) seas[0] = TRUE;
 	else if ( ival == 2 || ival == 14 ) seas[1] = TRUE;
 	else if ( ival == 3 || ival == 15 ) seas[2] = TRUE;
@@ -117,21 +115,45 @@ int seaslist(LIST *ilist)
   return (nsel);
 }
 
+
+double datestr_to_double(const char *datestr)
+{
+  int year = 1, month = 1, day = 1, hour = 0, minute = 0, second = 0;
+  double fval = 0;
+
+  if ( strchr(datestr, '-') == NULL )
+    {
+      fval = parameter2double(datestr);
+    }
+  else if ( strchr(datestr, 'T') )
+    {
+      sscanf(datestr, "%d-%d-%dT%d:%d:%d", &year, &month, &day, &hour, &minute, &second);
+      fval = cdiEncodeTime(hour, minute, second);
+      if ( fabs(fval) > 0 ) fval /= 1000000;
+      fval += cdiEncodeDate(year, month, day);
+    }
+  else
+    {
+      sscanf(datestr, "%d-%d-%d", &year, &month, &day);
+      fval = cdiEncodeDate(year, month, day);
+    }
+
+  return fval;
+}
+
 static
 int datelist(LIST *flist)
 {
-  int nsel;
-  int i;
-  int status;
   int set2 = TRUE;
-  int year = 1, month = 1, day = 1, hour = 0, minute = 0, second = 0;
   double fval = 0;
 
-  nsel = operatorArgc();
+  int nsel = operatorArgc();
   if ( nsel < 1 ) cdoAbort("Too few arguments!");
-  for ( i = 0; i < nsel; i++)
+  if ( nsel > 2 ) cdoAbort("Too many arguments!");
+
+  for ( int i = 0; i < nsel; i++ )
     {
-      if      ( operatorArgv()[i][0] == '-' && operatorArgv()[i][1] == 0 )
+      if ( operatorArgv()[i][0] == '-' && operatorArgv()[i][1] == 0 )
 	{
 	  if ( i == 0 )
 	    fval = -99999999999.;
@@ -140,34 +162,16 @@ int datelist(LIST *flist)
 
 	  listSetFlt(flist, i,  fval);
 	}
-      else if ( strchr(operatorArgv()[i], '-') == NULL )
-	{
-	  fval = atof(operatorArgv()[i]);
-	  listSetFlt(flist, i, fval);
-	}
       else
 	{
-	  year = 1; month = 1; day = 1; hour = 0; minute = 0, second = 0;
+	  fval = datestr_to_double(operatorArgv()[i]);
 	  if ( strchr(operatorArgv()[i], 'T') )
-	    {
-	      status = sscanf(operatorArgv()[i], "%d-%d-%dT%d:%d:%d",
-			      &year, &month, &day, &hour, &minute, &second);
-	      fval = cdiEncodeTime(hour, minute, second);
-	      if ( fabs(fval) > 0 ) fval /= 1000000;
-	      fval += cdiEncodeDate(year, month, day);
-	      listSetFlt(flist, i, fval);
-	      set2 = FALSE;
-	    }
-	  else
-	    {
-	      status = sscanf(operatorArgv()[i], "%d-%d-%d", &year, &month, &day);
-	      fval = cdiEncodeDate(year, month, day);
-	      
-	      if ( nsel > 1 && i > 0 ) fval += 0.999;
-
-	      listSetFlt(flist, i, fval);
-	    }
+	    set2 = FALSE;
+	  else if ( nsel > 1 && i > 0 )
+	    fval += 0.999;
 	}
+
+      listSetFlt(flist, i, fval);
     }
 
   if ( nsel == 1 && set2 == TRUE )
@@ -183,36 +187,28 @@ int datelist(LIST *flist)
 
 void *Seltime(void *argument)
 {
-  int SELTIMESTEP, SELDATE, SELTIME, SELHOUR, SELDAY, SELMON, SELYEAR, SELSEAS, SELSMON;
-  int operatorID;
-  int operfunc, intval;
-  int moddat[NOPERATORS];
-  int streamID1, streamID2 = -1;
-  int tsID, tsID2, nrecs;
+  int streamID2 = -1;
+  int nrecs;
   int recID, varID, levelID;
-  int *intarr, nsel = 0, selival;
-  int vlistID1 = -1, vlistID2 = -1;
-  int taxisID1, taxisID2;
+  int nsel = 0, selival;
   int vdate, vtime;
   int copytimestep;
   int copy_nts2 = FALSE;
   int i, isel;
-  int lcopy = FALSE;
   int gridsize;
   int nmiss;
-  int lnts1;
   int ncts = 0, nts, it;
   int *selfound = NULL;
   int hour = 0, minute = 0, second = 0;
   int nts1 = 0, nts2 = 0;
   int its1 = 0, its2 = 0;
-  double selfval = 0, *fltarr;
+  double selfval = 0;
   double *array = NULL;
   LIST *ilist = listNew(INT_LIST);
   LIST *flist = listNew(FLT_LIST);
   int gridID;
-  int nvars, nlevel, ntsteps;
-  int nconst, lconstout = FALSE;
+  int nlevel;
+  int lconstout = FALSE;
   int process_nts1 = FALSE, process_nts2 = FALSE;
   int *vdate_list = NULL, *vtime_list = NULL;
   double *single;
@@ -220,16 +216,17 @@ void *Seltime(void *argument)
 
   cdoInitialize(argument);
 
-  SELTIMESTEP = cdoOperatorAdd("seltimestep", func_step,     1, "timesteps");
-  SELDATE     = cdoOperatorAdd("seldate",     func_datetime, 1, "start date and end date (format YYYY-MM-DDThh:mm:ss)");
-  SELTIME     = cdoOperatorAdd("seltime",     func_time,     1, "times (format hh:mm:ss)");
-  SELHOUR     = cdoOperatorAdd("selhour",     func_time, 10000, "hours");
-  SELDAY      = cdoOperatorAdd("selday",      func_date,     1, "days");
-  SELMON      = cdoOperatorAdd("selmon",      func_date,   100, "months");
-  SELYEAR     = cdoOperatorAdd("selyear",     func_date, 10000, "years");
-  SELSEAS     = cdoOperatorAdd("selseas",     func_date,   100, "seasons");
-  SELSMON     = cdoOperatorAdd("selsmon",     func_date,   100, "month[,nts1[,nts2]]");
+  int SELTIMESTEP = cdoOperatorAdd("seltimestep", func_step,     1, "timesteps");
+  int SELDATE     = cdoOperatorAdd("seldate",     func_datetime, 1, "start date and end date (format YYYY-MM-DDThh:mm:ss)");
+  int SELTIME     = cdoOperatorAdd("seltime",     func_time,     1, "times (format hh:mm:ss)");
+  int SELHOUR     = cdoOperatorAdd("selhour",     func_time, 10000, "hours");
+  int SELDAY      = cdoOperatorAdd("selday",      func_date,     1, "days");
+  int SELMON      = cdoOperatorAdd("selmon",      func_date,   100, "months");
+  int SELYEAR     = cdoOperatorAdd("selyear",     func_date, 10000, "years");
+  int SELSEAS     = cdoOperatorAdd("selseas",     func_date,   100, "seasons");
+  int SELSMON     = cdoOperatorAdd("selsmon",     func_date,   100, "month[,nts1[,nts2]]");
 
+  int moddat[NOPERATORS];
   moddat[SELTIMESTEP] =          1;
   /*  moddat[SELDATE]     = 1000000000; */
   moddat[SELDATE]     =          0;
@@ -241,11 +238,12 @@ void *Seltime(void *argument)
   moddat[SELSEAS]     =        100;
   moddat[SELSMON]     =        100;
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
-  operfunc = cdoOperatorF1(operatorID);
-  intval   = cdoOperatorF2(operatorID);
+  int operfunc = cdoOperatorF1(operatorID);
+  int intval   = cdoOperatorF2(operatorID);
 
+  int lcopy = FALSE;
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
   operatorInputArg(cdoOperatorEnter(operatorID));
@@ -271,7 +269,7 @@ void *Seltime(void *argument)
 	    }
 	  else
 	    {
-	      listSetInt(ilist, i, atoi(operatorArgv()[i]));
+	      listSetInt(ilist, i, parameter2int(operatorArgv()[i]));
 	    }
 	}
     }
@@ -282,8 +280,8 @@ void *Seltime(void *argument)
 
   if ( nsel < 1 ) cdoAbort("No timestep selected!");
 
-  intarr = (int *) listArrayPtr(ilist);
-  fltarr = (double *) listArrayPtr(flist);
+  int *intarr = (int *) listArrayPtr(ilist);
+  double *fltarr = (double *) listArrayPtr(flist);
 
   if ( operatorID == SELSMON )
     {
@@ -305,16 +303,16 @@ void *Seltime(void *argument)
       for ( i = 0; i < nsel; i++ ) selfound[i] = FALSE;
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
   if ( nsel == 1 && operfunc == func_step )  vlistDefNtsteps(vlistID2,  1);
   else                                       vlistDefNtsteps(vlistID2, -1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   if ( ! lcopy )
@@ -324,7 +322,7 @@ void *Seltime(void *argument)
       array = (double*) malloc(gridsize*sizeof(double));
     }
 
-  ntsteps = vlistNtsteps(vlistID1);
+  int ntsteps = vlistNtsteps(vlistID1);
 
   /* add support for negative timestep values */
   if ( operatorID == SELTIMESTEP && ntsteps > 0 )
@@ -349,12 +347,12 @@ void *Seltime(void *argument)
 	  cdoPrint("intarr entry: %d %d", i+1, intarr[i]);
     }
 
-  nvars = vlistNvars(vlistID1);
-  nconst = 0;
+  int nvars = vlistNvars(vlistID1);
+  int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
     if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
       
-  lnts1 = operatorID == SELSMON && nts1 > 0;
+  int lnts1 = operatorID == SELSMON && nts1 > 0;
 
   if ( lnts1 || nconst )
     {
@@ -370,7 +368,7 @@ void *Seltime(void *argument)
 
       vars  = (field_t ***) malloc(nts1*sizeof(field_t **));
 
-      for ( tsID = 0; tsID < nts1; tsID++ )
+      for ( int tsID = 0; tsID < nts1; tsID++ )
 	{
 	  vars[tsID] = field_malloc(vlistID1, FIELD_NONE);
 
@@ -391,8 +389,8 @@ void *Seltime(void *argument)
 	}
     }
 
-  tsID  = 0;
-  tsID2 = 0;
+  int tsID  = 0;
+  int tsID2 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       vdate = taxisInqVdate(taxisID1);
@@ -689,6 +687,8 @@ void *Seltime(void *argument)
 
   vlistDestroy(vlistID2);
 
+  if ( tsID2 == 0 ) cdoAbort("No timesteps selected!");
+
   cdoFinish();
 
   return (NULL);
diff --git a/src/Selvar.c b/src/Selvar.c
index 7dc6bb4..9a4ca6f 100644
--- a/src/Selvar.c
+++ b/src/Selvar.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -46,12 +46,7 @@
 
 void *Selvar(void *argument)
 {
-  int SELPARAM, SELCODE, SELNAME, SELLEVEL, SELLEVIDX, SELGRID, SELZAXIS, SELLTYPE; 
-  int SELTABNUM, DELPARAM, DELCODE, DELNAME, SELSTDNAME;
-  int operatorID;
-  int streamID1, streamID2;
-  int tsID, nrecs;
-  int nvars, nlevs;
+  int nlevs;
   int code, tabnum, param, gridID, zaxisID, levID;
   int grididx, zaxisidx;
   double level;
@@ -64,49 +59,49 @@ void *Selvar(void *argument)
   char varname[CDI_MAX_NAME];
   char stdname[CDI_MAX_NAME];
   char gridname[CDI_MAX_NAME];
+  char zaxistypename[CDI_MAX_NAME];
   char zaxisname[CDI_MAX_NAME];
   char **argnames = NULL;
-  int vlistID1 = -1, vlistID2 = -1;
   int isel;
   int i;
-  int npar;
-  int intlist, byname;
   int lcopy = FALSE;
   int gridsize;
   int nmiss;
   double *array = NULL;
-  int taxisID1, taxisID2;
-  int ltype;
   LIST *ilist = listNew(INT_LIST);
   LIST *flist = listNew(FLT_LIST);
 
   cdoInitialize(argument);
 
-  SELPARAM     = cdoOperatorAdd("selparam",     0, 0, "parameters");
-  SELCODE      = cdoOperatorAdd("selcode",      0, 0, "code numbers");
-  SELNAME      = cdoOperatorAdd("selname",      0, 0, "variable names");
-  SELSTDNAME   = cdoOperatorAdd("selstdname",   0, 0, "standard names");
-  SELLEVEL     = cdoOperatorAdd("sellevel",     0, 0, "levels");
-  SELLEVIDX    = cdoOperatorAdd("sellevidx",    0, 0, "index of levels");
-  SELGRID      = cdoOperatorAdd("selgrid",      0, 0, "list of grid names or numbers");
-  SELZAXIS     = cdoOperatorAdd("selzaxis",     0, 0, "list of zaxis names or numbers");
-  SELTABNUM    = cdoOperatorAdd("seltabnum",    0, 0, "table numbers");
-  DELPARAM     = cdoOperatorAdd("delparam",     0, 0, "parameter");
-  DELCODE      = cdoOperatorAdd("delcode",      0, 0, "code numbers");
-  DELNAME      = cdoOperatorAdd("delname",      0, 0, "variable names");
-  SELLTYPE     = cdoOperatorAdd("selltype",     0, 0, "GRIB level types"); 
+# define INVERTS_SELECTION(id) (cdoOperatorF2(id) & 1)
+# define TAKES_STRINGS(id) (cdoOperatorF2(id) & 2)
+# define TAKES_INTEGERS(id) (cdoOperatorF2(id) & 4)
+# define TAKES_FLOATS(id) (cdoOperatorF2(id) & 8)
+
+  int SELPARAM     = cdoOperatorAdd("selparam",     0, 2, "parameters");
+  int SELCODE      = cdoOperatorAdd("selcode",      0, 4, "code numbers");
+  int SELNAME      = cdoOperatorAdd("selname",      0, 2, "variable names");
+  int SELSTDNAME   = cdoOperatorAdd("selstdname",   0, 2, "standard names");
+  int SELLEVEL     = cdoOperatorAdd("sellevel",     0, 8, "levels");
+  int SELLEVIDX    = cdoOperatorAdd("sellevidx",    0, 4, "index of levels");
+  int SELGRID      = cdoOperatorAdd("selgrid",      0, 4|2, "list of grid names or numbers");
+  int SELZAXIS     = cdoOperatorAdd("selzaxis",     0, 4|2, "list of zaxis types or numbers");
+  int SELZAXISNAME = cdoOperatorAdd("selzaxisname", 0, 2, "list of zaxis names");
+  int SELTABNUM    = cdoOperatorAdd("seltabnum",    0, 4, "table numbers");
+  int DELPARAM     = cdoOperatorAdd("delparam",     0, 2|1, "parameter");
+  int DELCODE      = cdoOperatorAdd("delcode",      0, 1, "code numbers");
+  int DELNAME      = cdoOperatorAdd("delname",      0, 2|1, "variable names");
+  int SELLTYPE     = cdoOperatorAdd("selltype",     0, 4, "GRIB level types"); 
 
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
-  intlist = FALSE;
-  byname  = TRUE;
+  int args_are_numeric = operatorArgc() > 0 && isdigit(*operatorArgv()[0]);
 
-  if ( operatorID == SELPARAM || operatorID == DELPARAM || operatorID == SELNAME || operatorID == DELNAME || 
-       operatorID == SELSTDNAME || operatorID == SELGRID || operatorID == SELZAXIS )
+  if ( TAKES_STRINGS(operatorID) && !( TAKES_INTEGERS(operatorID) && args_are_numeric ) )
     {
       nsel     = operatorArgc();
       argnames = operatorArgv();
@@ -114,17 +109,8 @@ void *Selvar(void *argument)
       if ( cdoVerbose )
 	for ( i = 0; i < nsel; i++ )
 	  fprintf(stderr, "name %d = %s\n", i+1, argnames[i]);
-
-      if ( operatorID == SELGRID || operatorID == SELZAXIS )
-	{
-	  if ( nsel > 0 && isdigit(*argnames[0]) )
-	    {
-	      intlist = TRUE;
-	      byname  = FALSE;
-	    }
-	}
     }
-  else if ( operatorID == SELLEVEL )
+  else if ( TAKES_FLOATS(operatorID) )
     {
       nsel = args2fltlist(operatorArgc(), operatorArgv(), flist);
       fltarr = (double *) listArrayPtr(flist);
@@ -135,11 +121,6 @@ void *Selvar(void *argument)
     }
   else
     {
-      intlist = TRUE;
-    }
-
-  if ( intlist )
-    {
       nsel = args2intlist(operatorArgc(), operatorArgv(), ilist);
       intarr = (int *) listArrayPtr(ilist);
 
@@ -158,12 +139,12 @@ void *Selvar(void *argument)
   if ( nsel == 0 )
     cdoAbort("missing code argument!");
   */
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
   vlistClearFlag(vlistID1);
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
   for ( varID = 0; varID < nvars; varID++ )
     {
       vlistInqVarName(vlistID1, varID, varname);
@@ -177,7 +158,8 @@ void *Selvar(void *argument)
       zaxisidx = vlistZaxisIndex(vlistID1, zaxisID);
       nlevs    = zaxisInqSize(zaxisID);
       gridName(gridInqType(gridID), gridname);
-      zaxisName(zaxisInqType(zaxisID), zaxisname);
+      zaxisInqName(zaxisID, zaxisname);
+      zaxisName(zaxisInqType(zaxisID), zaxistypename);
 
       cdiParamToString(param, paramstr, sizeof(paramstr));
 
@@ -190,133 +172,83 @@ void *Selvar(void *argument)
 
 	  for ( isel = 0; isel < nsel; isel++ )
 	    {
+              int found = 0;
 	      if ( operatorID == SELCODE )
 		{
-		  if ( intarr[isel] == code )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == code;
 		}
 	      else if ( operatorID == SELPARAM )
 		{
-		  if ( strcmp(argnames[isel], paramstr) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = wildcardmatch(argnames[isel], paramstr) == 0;
 		}
 	      else if ( operatorID == SELNAME )
 		{
-		  if ( strcmp(argnames[isel], varname) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = wildcardmatch(argnames[isel], varname) == 0;
 		}
 	      else if ( operatorID == SELSTDNAME )
 		{
-		  if ( strcmp(argnames[isel], stdname) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = strcmp(argnames[isel], stdname) == 0;
 		}
 	      else if ( operatorID == SELLEVEL )
 		{
-		  if ( fabs(fltarr[isel] - level) < 0.0001 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = fabs(fltarr[isel] - level) < 0.0001;
 		}
 	      else if ( operatorID == SELLEVIDX )
 		{
-		  if ( intarr[isel] == (levID+1) )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == (levID+1);
 		}
-	      else if ( operatorID == SELGRID && byname == FALSE )
+	      else if ( operatorID == SELGRID && args_are_numeric )
 		{
-		  if ( intarr[isel] == (grididx+1) )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == (grididx+1);
 		}
-	      else if ( operatorID == SELGRID && byname == TRUE )
+	      else if ( operatorID == SELGRID && !args_are_numeric )
 		{
-		  if ( memcmp(argnames[isel], gridname, strlen(argnames[isel])) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = memcmp(argnames[isel], gridname, strlen(argnames[isel])) == 0;
 		}
-	      else if ( operatorID == SELZAXIS && byname == FALSE )
+	      else if ( operatorID == SELZAXIS && args_are_numeric )
 		{
-		  if ( intarr[isel] == (zaxisidx+1) )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == (zaxisidx+1);
 		}
-	      else if ( operatorID == SELZAXIS && byname == TRUE )
+	      else if ( operatorID == SELZAXIS && !args_are_numeric )
 		{
-		  if ( memcmp(argnames[isel], zaxisname, strlen(argnames[isel])) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = memcmp(argnames[isel], zaxistypename, strlen(argnames[isel])) == 0;
+		}
+	      else if ( operatorID == SELZAXISNAME )
+		{
+		  found = wildcardmatch(argnames[isel], zaxisname) == 0;
 		}
 	      else if ( operatorID == SELTABNUM )
 		{
-		  if ( intarr[isel] == tabnum )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == tabnum;
 		}
 	      else if ( operatorID == DELCODE )
 		{
-		  if ( intarr[isel] == code )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, FALSE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == code;
 		}
 	      else if ( operatorID == DELNAME )
 		{
-		  if ( strcmp(argnames[isel], varname) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, FALSE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = wildcardmatch(argnames[isel], varname) == 0;
 		}
 	      else if ( operatorID == DELPARAM )
 		{
-		  if ( strcmp(argnames[isel], paramstr) == 0 )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, FALSE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = strcmp(argnames[isel], paramstr) == 0;
 		}
 	      else if ( operatorID == SELLTYPE )
 		{
-		  ltype = zaxis2ltype(zaxisID);
-
-		  if ( intarr[isel] == ltype )
-		    {
-		      vlistDefFlag(vlistID1, varID, levID, TRUE);
-		      selfound[isel] = TRUE;
-		    }
+		  found = intarr[isel] == zaxis2ltype(zaxisID);
 		}
+
+	      if ( found )
+	        {
+		  vlistDefFlag(vlistID1, varID, levID, !INVERTS_SELECTION(operatorID));
+		  selfound[isel] = TRUE;
+	        }
+
 	    }
 	}
     }
 
-  npar = 0;
+  int npar = 0;
   for ( varID = 0; varID < nvars; varID++ )
     {
       zaxisID = vlistInqVarZaxis(vlistID1, varID);
@@ -356,19 +288,23 @@ void *Selvar(void *argument)
 	    {
 	      cdoWarning("Level index %d not found!", intarr[isel]);
 	    }
-	  else if ( operatorID == SELGRID && byname == FALSE )
+	  else if ( operatorID == SELGRID && args_are_numeric )
 	    {
 	      cdoWarning("Grid %d not found!", intarr[isel]);
 	    }
-	  else if ( operatorID == SELGRID && byname == TRUE )
+	  else if ( operatorID == SELGRID && !args_are_numeric )
 	    {
 	      cdoWarning("Grid name %s not found!", argnames[isel]);
 	    }
-	  else if ( operatorID == SELZAXIS && byname == FALSE )
+	  else if ( operatorID == SELZAXIS && args_are_numeric )
 	    {
 	      cdoWarning("Zaxis %d not found!", intarr[isel]);
 	    }
-	  else if ( operatorID == SELZAXIS && byname == TRUE )
+	  else if ( operatorID == SELZAXIS && !args_are_numeric )
+	    {
+	      cdoWarning("Zaxis type %s not found!", argnames[isel]);
+	    }
+	  else if ( operatorID == SELZAXISNAME )
 	    {
 	      cdoWarning("Zaxis name %s not found!", argnames[isel]);
 	    }
@@ -385,7 +321,7 @@ void *Selvar(void *argument)
 
   if ( npar == 0 ) cdoAbort("No variables selected!");
 
-  vlistID2 = vlistCreate();
+  int vlistID2 = vlistCreate();
   vlistCopyFlag(vlistID2, vlistID1);
 
   nvars = vlistNvars(vlistID2);
@@ -393,13 +329,13 @@ void *Selvar(void *argument)
     if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
   if ( varID == nvars ) vlistDefNtsteps(vlistID2, 0);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  nrecs = vlistNrecs(vlistID2);
+  int nrecs = vlistNrecs(vlistID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
@@ -410,7 +346,7 @@ void *Selvar(void *argument)
       array = (double*) malloc(gridsize*sizeof(double));
     }
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Set.c b/src/Set.c
index 1b4c310..7d9099c 100644
--- a/src/Set.c
+++ b/src/Set.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -80,7 +80,7 @@ void *Set(void *argument)
   operatorInputArg(cdoOperatorEnter(operatorID));
   if ( operatorID == SETCODE || operatorID == SETLTYPE )
     {
-      newval = atoi(operatorArgv()[0]);
+      newval = parameter2int(operatorArgv()[0]);
     }
   else if ( operatorID == SETPARAM )
     {
@@ -96,11 +96,11 @@ void *Set(void *argument)
     }
   else if ( operatorID == SETTABNUM )
     {
-      tabnum = atoi(operatorArgv()[0]);
+      tabnum = parameter2int(operatorArgv()[0]);
     }
   else if ( operatorID == SETLEVEL )
     {
-      newlevel = atof(operatorArgv()[0]);
+      newlevel = parameter2double(operatorArgv()[0]);
     }
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Setbox.c b/src/Setbox.c
index 08eba38..631fac0 100644
--- a/src/Setbox.c
+++ b/src/Setbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -83,7 +83,7 @@ void *Setbox(void *argument)
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
-  constant = atof(operatorArgv()[0]);
+  constant = parameter2double(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Setgatt.c b/src/Setgatt.c
index f1fabe1..b2f16b4 100644
--- a/src/Setgatt.c
+++ b/src/Setgatt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Setgrid.c b/src/Setgrid.c
index 969f04e..62568db 100644
--- a/src/Setgrid.c
+++ b/src/Setgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -170,8 +170,8 @@ void *Setgrid(void *argument)
     {
       if ( operatorArgc() >= 1 && operatorArgc() <= 2 )
 	{
-	  number = atoi(operatorArgv()[0]);
-	  if ( operatorArgc() == 2 ) position = atoi(operatorArgv()[1]);
+	  number = parameter2int(operatorArgv()[0]);
+	  if ( operatorArgc() == 2 ) position = parameter2int(operatorArgv()[1]);
 	}
       else
 	{
@@ -283,7 +283,17 @@ void *Setgrid(void *argument)
 	      else if ( gridtype == GRID_LONLAT && gridInqType(gridID1) == GRID_CURVILINEAR )
 		{
 		  gridID2 = gridCurvilinearToRegular(gridID1);
-		  if ( gridID2 == -1 ) cdoAbort("No regular grid found!");
+		  if ( gridID2 == -1 ) cdoWarning("Conversion of curvilinear grid to regular grid failed!");
+ 		}
+	      else if ( gridtype == GRID_LONLAT && gridInqType(gridID1) == GRID_UNSTRUCTURED )
+		{
+		  gridID2 = -1;
+		  if ( gridID2 == -1 ) cdoWarning("Conversion of unstructured grid to regular grid failed!");
+ 		}
+	      else if ( gridtype == GRID_LONLAT && gridInqType(gridID1) == GRID_GENERIC )
+		{
+		  gridID2 = -1;
+		  if ( gridID2 == -1 ) cdoWarning("Conversion of generic grid to regular grid failed!");
  		}
 	      else if ( gridtype == GRID_LONLAT && gridInqType(gridID1) == GRID_LONLAT )
 		{
diff --git a/src/Sethalo.c b/src/Sethalo.c
index 12faa20..3c2d06c 100644
--- a/src/Sethalo.c
+++ b/src/Sethalo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -379,8 +379,8 @@ int genindexgrid(int gridID1, int *lhalo, int *rhalo)
 
   operatorCheckArgc(2);
 
-  *lhalo = atoi(operatorArgv()[0]);
-  *rhalo = atoi(operatorArgv()[1]);
+  *lhalo = parameter2int(operatorArgv()[0]);
+  *rhalo = parameter2int(operatorArgv()[1]);
 
   nlon1 = gridInqXsize(gridID1);
 
diff --git a/src/Setmiss.c b/src/Setmiss.c
index 40a72aa..e135584 100644
--- a/src/Setmiss.c
+++ b/src/Setmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -42,37 +42,27 @@ int isnan(const double x);
 
 void *Setmiss(void *argument)
 {
-  int SETMISSVAL, SETCTOMISS, SETMISSTOC, SETRTOMISS, SETVRANGE;
-  int operatorID;
-  int streamID1, streamID2;
-  int gridsize;
   int nrecs, recID;
-  int nvars;
-  int tsID;
   int varID, levelID;
-  int vlistID1, vlistID2;
   int nmiss;
   int i;
-  int calendar;
   double missval, missval2 = 0;
   double rconst = 0, rmin = 0, rmax = 0;
-  double *array;
-  int taxisID1, taxisID2;
 
   cdoInitialize(argument);
 
-  SETMISSVAL   = cdoOperatorAdd("setmissval",    0, 0, "missing value");
-  SETCTOMISS   = cdoOperatorAdd("setctomiss",    0, 0, "constant");
-  SETMISSTOC   = cdoOperatorAdd("setmisstoc",    0, 0, "constant");
-  SETRTOMISS   = cdoOperatorAdd("setrtomiss",    0, 0, "range (min, max)");
-  SETVRANGE    = cdoOperatorAdd("setvrange",     0, 0, "range (min, max)");
+  int SETMISSVAL = cdoOperatorAdd("setmissval", 0, 0, "missing value");
+  int SETCTOMISS = cdoOperatorAdd("setctomiss", 0, 0, "constant");
+  int SETMISSTOC = cdoOperatorAdd("setmisstoc", 0, 0, "constant");
+  int SETRTOMISS = cdoOperatorAdd("setrtomiss", 0, 0, "range (min, max)");
+  int SETVRANGE  = cdoOperatorAdd("setvrange",  0, 0, "range (min, max)");
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   if ( operatorID == SETMISSVAL )
     {
       operatorCheckArgc(1);
-      missval2 = atof(operatorArgv()[0]);
+      missval2 = parameter2double(operatorArgv()[0]);
     }
   else if ( operatorID == SETCTOMISS || operatorID == SETMISSTOC )
     {
@@ -87,32 +77,43 @@ void *Setmiss(void *argument)
 	}
       else
       */
-	rconst = atof(operatorArgv()[0]);
+      rconst = parameter2double(operatorArgv()[0]);
     }
   else
     {
       operatorCheckArgc(2);
-      rmin = atof(operatorArgv()[0]);
-      rmax = atof(operatorArgv()[1]);
+      rmin = parameter2double(operatorArgv()[0]);
+      rmax = parameter2double(operatorArgv()[1]);
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  calendar = taxisInqCalendar(taxisID1);  
-
   if ( operatorID == SETMISSVAL )
     {
-      nvars = vlistNvars(vlistID2);
+      int nvars = vlistNvars(vlistID2);
       for ( varID = 0; varID < nvars; varID++ )
 	vlistDefVarMissval(vlistID2, varID, missval2);
     }
+  else if ( operatorID == SETMISSTOC )
+    {
+      int nvars = vlistNvars(vlistID2);
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  missval = vlistInqVarMissval(vlistID2, varID);
+	  if ( DBL_IS_EQUAL(rconst, missval) )
+	    {
+	      cdoWarning("Missing value and constant have the same value!");
+	      break;
+	    }
+	}
+    }
 
   /*
   if ( operatorID == SETVRANGE )
@@ -126,15 +127,15 @@ void *Setmiss(void *argument)
 	vlistDefAttFlt(vlistID2, varID, "valid_range", DATATYPE_FLT64, 2, range);
     }
   */
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double*) malloc(gridsize*sizeof(double));
+  double *array = (double*) malloc(gridsize*sizeof(double));
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Setpartab.c b/src/Setpartab.c
index bcbcbd4..a801219 100644
--- a/src/Setpartab.c
+++ b/src/Setpartab.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -174,6 +174,7 @@ void *get_converter(char *src_unit_str, char *tgt_unit_str, int *rstatus)
 
 typedef struct
 {
+  int convert;
   int remove;
   // missing value
   int changemissval;
@@ -201,7 +202,6 @@ typedef struct
   void *ut_converter;
 } var_t;
 
-int lwarn_udunits = TRUE;
 
 static
 void defineVarAttText(int vlistID2, int varID, const char *attname, const char *atttext)
@@ -211,7 +211,58 @@ void defineVarAttText(int vlistID2, int varID, const char *attname, const char *
 }
 
 static
-void defineVarUnits(var_t *vars, int vlistID2, int varID, char *units, char *name)
+void convertVarUnits(var_t *vars, int varID, char *name)
+{
+  if ( vars[varID].convert == FALSE ) vars[varID].changeunits = FALSE;
+
+  if ( vars[varID].changeunits == TRUE )
+    {
+      char *units = vars[varID].units;
+      char *units_old = vars[varID].units_old;
+#if defined(HAVE_UDUNITS2)
+      int status;
+      UDUNITS_INIT();
+      UDUNITS_LOCK();
+      vars[varID].ut_converter = get_converter(units_old, units, &status);
+      UDUNITS_UNLOCK();
+      if ( vars[varID].ut_converter == NULL )
+	{
+	  if ( status == -2 )
+	    {
+	      if ( cdoVerbose )
+		cdoPrint("%s - not converted from  [%s] to [%s], units are equal!", name, units_old, units);
+	    }
+	  else if ( status == -3 )
+	    {
+	      cdoWarning("%s - converting units from [%s] to [%s] failed, not convertible!", name, units_old, units);
+	    }
+	  else
+	    cdoWarning("%s - converting units from [%s] to [%s] failed!", name, units_old, units);
+	  vars[varID].changeunits = FALSE;
+	}
+      else
+	{
+	  // if ( cdoVerbose )
+	    {
+	      char buf[64];
+	      cv_get_expression(vars[varID].ut_converter, buf, 64, name);
+	      cdoPrint("%s - convert units from [%s] to [%s] (expression: %s).", name, units_old, units, buf);
+	    }
+	}
+#else
+      static int lwarn_udunits = TRUE;
+      if ( lwarn_udunits )
+	{
+	  cdoWarning("%s - converting units from [%s] to [%s] failed, UDUNITS2 support not compiled in!", name,units_old, units);
+	  vars[varID].changeunits = FALSE;
+	  lwarn_udunits = FALSE;
+	}
+#endif
+    }
+}
+
+static
+void defineVarUnits(var_t *vars, int vlistID2, int varID, char *units)
 {
   char units_old[CDI_MAX_NAME];
   size_t len1, len2;
@@ -227,45 +278,6 @@ void defineVarUnits(var_t *vars, int vlistID2, int varID, char *units, char *nam
 	  vars[varID].changeunits = TRUE;
 	  strcpy(vars[varID].units_old, units_old);
 	  strcpy(vars[varID].units, units);
-#if defined(HAVE_UDUNITS2)
-	  int status;
-	  UDUNITS_INIT();
-	  UDUNITS_LOCK();
-	  vars[varID].ut_converter = get_converter(units_old, units, &status);
-	  UDUNITS_UNLOCK();
-	  if ( vars[varID].ut_converter == NULL )
-	    {
-	      if ( status == -2 )
-		{
-		  if ( cdoVerbose )
-		    cdoPrint("%s - not converted from  [%s] to [%s], units are equal!", name, units_old, units);
-		}
-	      else if ( status == -3 )
-		{
-		  cdoWarning("%s - converting units from [%s] to [%s] failed, not convertible!", name, units_old, units);
-		}
-	      else
-		cdoWarning("%s - converting units from [%s] to [%s] failed!", name, units_old, units);
-	      vars[varID].changeunits = FALSE;
-	    }
-	  else
-	    {
-	      if ( cdoVerbose )
-		{
-		  char buf[64];
-		  cv_get_expression(vars[varID].ut_converter, buf, 64, name);
-		  cdoPrint("%s - convert units from [%s] to [%s] (expression: %s).", name, units_old, units, buf);
-		}
-	    }
-#else
-	  UNUSED(name);
-	  if ( lwarn_udunits )
-	    {
-	      cdoWarning("Can't convert units, UDUNITS2 support not compiled in!");
-	      vars[varID].changeunits = FALSE;
-	      lwarn_udunits = FALSE;
-	    }
-#endif
 	}
 
       vlistDefVarUnits(vlistID2, varID, units);
@@ -279,11 +291,11 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
   FILE *fp;
   namelist_t *nml;
   int nml_code, nml_out_code, nml_table, nml_param, nml_out_param, nml_chunktype, nml_datatype, nml_type, nml_name, nml_out_name, nml_stdname;
-  int nml_longname, nml_units, nml_comment, nml_ltype, nml_delete, nml_missval, nml_factor;
+  int nml_longname, nml_units, nml_comment, nml_ltype, nml_delete, nml_convert, nml_missval, nml_factor;
   int nml_cell_methods, nml_cell_measures;
   int nml_valid_min, nml_valid_max, nml_ok_min_mean_abs, nml_ok_max_mean_abs;
   int locc, i;
-  int code, out_code, table, ltype, remove;
+  int code, out_code, table, ltype, remove, convert;
   int nml_index = 0;
   int codenum, tabnum, levtype, param;
   int varID, tableID;
@@ -301,7 +313,8 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
   char varname[CDI_MAX_NAME];
   char comment[1024] = "";
 
-  num_pt_files = operatorArgc();
+  //num_pt_files = operatorArgc();
+  num_pt_files = 1;
 
   for ( int fileID = 0; fileID < num_pt_files; ++fileID )
     {
@@ -318,6 +331,7 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
       nml_table           = namelistAdd(nml, "table",           NML_INT,  0, &table, 1);
       nml_ltype           = namelistAdd(nml, "ltype",           NML_INT,  0, &ltype, 1);
       nml_delete          = namelistAdd(nml, "delete",          NML_INT,  0, &remove, 1);
+      nml_convert         = namelistAdd(nml, "convert",         NML_INT,  0, &convert, 1);
       nml_missval         = namelistAdd(nml, "missing_value",   NML_FLT,  0, &missval, 1);
       nml_factor          = namelistAdd(nml, "factor",          NML_FLT,  0, &factor, 1);
       nml_valid_min       = namelistAdd(nml, "valid_min",       NML_FLT,  0, &valid_min, 1);
@@ -419,19 +433,20 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
 
 	      if ( varID < nvars )
 		{
-		  if ( nml->entry[nml_code]->occ     ) vlistDefVarCode(vlistID2, varID, code);
-		  if ( nml->entry[nml_out_code]->occ ) vlistDefVarCode(vlistID2, varID, out_code);
-		  if ( nml->entry[nml_name]->occ     ) strcpy(vars[varID].name, name);
-		  if ( nml->entry[nml_name]->occ     ) vlistDefVarName(vlistID2, varID, name);
-		  if ( nml->entry[nml_out_name]->occ ) vlistDefVarName(vlistID2, varID, out_name);
-		  if ( nml->entry[nml_out_name]->occ ) defineVarAttText(vlistID2, varID, "original_name", vars[varID].name);
-		  if ( nml->entry[nml_stdname]->occ  ) vlistDefVarStdname(vlistID2, varID, stdname);
-		  if ( nml->entry[nml_longname]->occ ) vlistDefVarLongname(vlistID2, varID, longname);
-		  if ( nml->entry[nml_units]->occ    ) defineVarUnits(vars, vlistID2, varID, units, name);
-		  if ( nml->entry[nml_comment]->occ  ) defineVarAttText(vlistID2, varID, "comment", comment);
+		  if ( nml->entry[nml_code]->occ     )  vlistDefVarCode(vlistID2, varID, code);
+		  if ( nml->entry[nml_out_code]->occ )  vlistDefVarCode(vlistID2, varID, out_code);
+		  if ( nml->entry[nml_name]->occ     )  strcpy(vars[varID].name, name);
+		  if ( nml->entry[nml_name]->occ     )  vlistDefVarName(vlistID2, varID, name);
+		  if ( nml->entry[nml_out_name]->occ )  vlistDefVarName(vlistID2, varID, out_name);
+		  if ( nml->entry[nml_out_name]->occ )  defineVarAttText(vlistID2, varID, "original_name", vars[varID].name);
+		  if ( nml->entry[nml_stdname]->occ  )  vlistDefVarStdname(vlistID2, varID, stdname);
+		  if ( nml->entry[nml_longname]->occ )  vlistDefVarLongname(vlistID2, varID, longname);
+		  if ( nml->entry[nml_units]->occ    )  defineVarUnits(vars, vlistID2, varID, units);
+		  if ( nml->entry[nml_comment]->occ  )  defineVarAttText(vlistID2, varID, "comment", comment);
 		  if ( nml->entry[nml_cell_methods]->occ  ) defineVarAttText(vlistID2, varID, "cell_methods", cell_methods);
 		  if ( nml->entry[nml_cell_measures]->occ ) defineVarAttText(vlistID2, varID, "cell_measures", cell_measures);
 		  if ( nml->entry[nml_delete]->occ && remove == 1 ) vars[varID].remove = TRUE;
+		  if ( nml->entry[nml_convert]->occ )   vars[varID].convert = convert==0 ? FALSE : TRUE;
 		  if ( nml->entry[nml_param]->occ )     vlistDefVarParam(vlistID2, varID, stringToParam(paramstr));
 		  if ( nml->entry[nml_out_param]->occ ) vlistDefVarParam(vlistID2, varID, stringToParam(out_paramstr));
 		  if ( nml->entry[nml_datatype]->occ )
@@ -581,39 +596,38 @@ void check_data(int vlistID2, int varID2, int varID, var_t *vars, long gridsize,
 
 void *Setpartab(void *argument)
 {
-  int SETPARTAB, SETPARTABN, SETPARTABC, SETPARTABP;
-  int operatorID;
-  int streamID1, streamID2 = CDI_UNDEFID;
-  int nrecs, nvars;
-  int tsID1, recID, varID, levelID;
+  int nrecs;
+  int recID, varID, levelID;
   int varID2, levelID2;
-  int vlistID1, vlistID2;
-  int taxisID1, taxisID2;
   int nmiss;
   int delvars = FALSE;
-  long gridsize;
   int tableID = -1;
   int tableformat = 0;
-  char *partab = NULL;
   double missval;
-  double *array = NULL;
-  var_t *vars = NULL;
-  pt_mode_t ptmode = CODE_NUMBER;
-
 
   cdoInitialize(argument);
 
-  SETPARTAB  = cdoOperatorAdd("setpartab",  0, 0, "parameter table name");
-  SETPARTABC = cdoOperatorAdd("setpartabc", 0, 0, "parameter table name");
-  SETPARTABP = cdoOperatorAdd("setpartabp", 0, 0, "parameter table name");
-  SETPARTABN = cdoOperatorAdd("setpartabn", 0, 0, "parameter table name");
+  int SETPARTAB  = cdoOperatorAdd("setpartab",  0, 0, "parameter table name");
+  int SETPARTABC = cdoOperatorAdd("setpartabc", 0, 0, "parameter table name");
+  int SETPARTABP = cdoOperatorAdd("setpartabp", 0, 0, "parameter table name");
+  int SETPARTABN = cdoOperatorAdd("setpartabn", 0, 0, "parameter table name");
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
   if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
 
+  int convert_data = FALSE;
+  if ( operatorArgc() == 2 )
+    {
+      if ( strcmp("convert", operatorArgv()[1]) == 0 ) convert_data = TRUE;
+      else cdoAbort("Unknown parameter: >%s<", operatorArgv()[1]); 
+    }
+
+  if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
+
+  pt_mode_t ptmode = CODE_NUMBER;
   if      ( operatorID == SETPARTAB  ) ptmode = CODE_NUMBER;
   else if ( operatorID == SETPARTABC ) ptmode = CODE_NUMBER;
   else if ( operatorID == SETPARTABP ) ptmode = PARAMETER_ID;
@@ -621,17 +635,13 @@ void *Setpartab(void *argument)
 
   if ( ptmode == CODE_NUMBER )
     {
-      FILE *fp;
-      size_t fsize;
-      char *parbuf = NULL;
-
-      partab = operatorArgv()[0];
-      fp = fopen(partab, "r");
+      char *partab = operatorArgv()[0];
+      FILE *fp = fopen(partab, "r");
       if ( fp != NULL )
 	{
 	  fseek(fp, 0L, SEEK_END);
-	  fsize = (size_t) ftell(fp);
-	  parbuf = (char*) malloc(fsize+1);
+	  size_t fsize = (size_t) ftell(fp);
+	  char *parbuf = (char *) malloc(fsize+1);
 	  fseek(fp, 0L, SEEK_SET);
 	  fread(parbuf, fsize, 1, fp);
 	  parbuf[fsize] = 0;
@@ -654,16 +664,19 @@ void *Setpartab(void *argument)
       tableformat = 1;
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
   /* vlistPrint(vlistID2);*/
 
-  nvars = vlistNvars(vlistID2);
-  vars = (var_t*) malloc(nvars*sizeof(var_t));
+  int nvars = vlistNvars(vlistID2);
+  var_t *vars = (var_t *) malloc(nvars*sizeof(var_t));
   memset(vars, 0, nvars*sizeof(var_t));
 
+  if ( convert_data )
+    for ( varID = 0; varID < nvars; ++varID ) vars[varID].convert = TRUE;
+
   if ( tableformat == 0 )
     {
       for ( varID = 0; varID < nvars; varID++ )
@@ -682,6 +695,7 @@ void *Setpartab(void *argument)
 	{
 	  int levID, nlevs, zaxisID;
 	  int vlistIDx;
+
 	  vlistClearFlag(vlistID1);
 	  vlistClearFlag(vlistID2);
 
@@ -708,22 +722,25 @@ void *Setpartab(void *argument)
 
 	  vlistID2 = vlistIDx;
 	}
+
+      for ( varID = 0; varID < nvars; ++varID )
+	convertVarUnits(vars, varID, vars[varID].name);
     }
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   /* vlistPrint(vlistID2);*/
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  long gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double*) malloc(gridsize*sizeof(double));
+  double *array = (double *) malloc(gridsize*sizeof(double));
 
-  tsID1 = 0;
+  int tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Setrcaname.c b/src/Setrcaname.c
index e84afcf..3e7a692 100644
--- a/src/Setrcaname.c
+++ b/src/Setrcaname.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Settime.c b/src/Settime.c
index ba0153a..1f3fadf 100644
--- a/src/Settime.c
+++ b/src/Settime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -104,17 +104,12 @@ void shifttime(int calendar, int tunit, int ijulinc, int *pdate, int *ptime)
 
 void *Settime(void *argument)
 {
-  int SETYEAR, SETMON, SETDAY, SETDATE, SETTIME, SETTUNITS;
-  int SETTAXIS, SETREFTIME, SETCALENDAR, SHIFTTIME;
-  int operatorID;
-  int streamID1, streamID2 = CDI_UNDEFID;
-  int nrecs, newval = 0, ntsteps, nvars;
+  int nrecs, newval = 0;
   int tsID1, recID, varID, levelID;
-  int vlistID1, vlistID2;
   int vdate, vtime;
   int vdateb[2], vtimeb[2];
   int sdate = 0, stime = 0;
-  int taxisID1, taxisID2 = CDI_UNDEFID;
+  int taxisID2 = CDI_UNDEFID;
   int nmiss;
   int gridsize;
   int tunit = TUNIT_DAY;
@@ -122,28 +117,26 @@ void *Settime(void *argument)
   int year = 1, month = 1, day = 1, hour = 0, minute = 0, second = 0;
   int day0;
   int taxis_has_bounds, copy_timestep = FALSE;
-  int calendar;
   int newcalendar = CALENDAR_STANDARD;
   // int nargs;
   const char *datestr, *timestr;
-  char *rstr;
   juldate_t juldate;
   double *array = NULL;
 
   cdoInitialize(argument);
 
-  SETYEAR     = cdoOperatorAdd("setyear",     0,  1, "year");
-  SETMON      = cdoOperatorAdd("setmon",      0,  1, "month");
-  SETDAY      = cdoOperatorAdd("setday",      0,  1, "day");
-  SETDATE     = cdoOperatorAdd("setdate",     0,  1, "date (format: YYYY-MM-DD)");
-  SETTIME     = cdoOperatorAdd("settime",     0,  1, "time (format: hh:mm:ss)");
-  SETTUNITS   = cdoOperatorAdd("settunits",   0,  1, "time units (seconds, minutes, hours, days, months, years)");
-  SETTAXIS    = cdoOperatorAdd("settaxis",    0, -2, "date,time<,increment> (format YYYY-MM-DD,hh:mm:ss)");
-  SETREFTIME  = cdoOperatorAdd("setreftime",  0, -2, "date,time<,units> (format YYYY-MM-DD,hh:mm:ss)");
-  SETCALENDAR = cdoOperatorAdd("setcalendar", 0,  1, "calendar (standard, proleptic_gregorian, 360_day, 365_day, 366_day)");
-  SHIFTTIME   = cdoOperatorAdd("shifttime",   0,  1, "shift value");
-
-  operatorID = cdoOperatorID();
+  int SETYEAR     = cdoOperatorAdd("setyear",      0,  1, "year");
+  int SETMON      = cdoOperatorAdd("setmon",       0,  1, "month");
+  int SETDAY      = cdoOperatorAdd("setday",       0,  1, "day");
+  int SETDATE     = cdoOperatorAdd("setdate",      0,  1, "date (format: YYYY-MM-DD)");
+  int SETTIME     = cdoOperatorAdd("settime",      0,  1, "time (format: hh:mm:ss)");
+  int SETTUNITS   = cdoOperatorAdd("settunits",    0,  1, "time units (seconds, minutes, hours, days, months, years)");
+  int SETTAXIS    = cdoOperatorAdd("settaxis",     0, -2, "date,time<,increment> (format YYYY-MM-DD,hh:mm:ss)");
+  int SETREFTIME  = cdoOperatorAdd("setreftime",   0, -2, "date,time<,units> (format YYYY-MM-DD,hh:mm:ss)");
+  int SETCALENDAR = cdoOperatorAdd("setcalendar",  0,  1, "calendar (standard, proleptic_gregorian, 360_day, 365_day, 366_day)");
+  int SHIFTTIME   = cdoOperatorAdd("shifttime",    0,  1, "shift value");
+
+  int operatorID = cdoOperatorID();
   // nargs = cdoOperatorF2(operatorID);
 
   operatorInputArg(cdoOperatorEnter(operatorID));
@@ -153,6 +146,7 @@ void *Settime(void *argument)
   if ( operatorID == SETTAXIS || operatorID == SETREFTIME )
     {
       if ( operatorArgc() < 2 ) cdoAbort("Too few arguments!");
+      if ( operatorArgc() > 3 ) cdoAbort("Too many arguments!");
 
       datestr = operatorArgv()[0];
       timestr = operatorArgv()[1];
@@ -164,8 +158,7 @@ void *Settime(void *argument)
 	}
       else
 	{
-	  sdate = (int)strtol(datestr, &rstr, 10);
-	  if ( *rstr != 0 ) cdoAbort("Parameter string contains invalid characters: %s", datestr);
+	  sdate = parameter2int(datestr);
 	}
 
       if ( strchr(timestr, ':') )
@@ -175,8 +168,7 @@ void *Settime(void *argument)
 	}
       else
 	{
-	  stime = (int)strtol(timestr, &rstr, 10);
-	  if ( *rstr != 0 ) cdoAbort("Parameter string contains invalid characters: %s", timestr);
+	  stime = parameter2int(timestr);
 	}
 
       if ( operatorArgc() == 3 )
@@ -193,7 +185,7 @@ void *Settime(void *argument)
     }
   else if ( operatorID == SETDATE )
     {
-      if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
+      operatorCheckArgc(1);
       datestr = operatorArgv()[0];
       if ( strchr(datestr, '-') )
 	{
@@ -202,13 +194,12 @@ void *Settime(void *argument)
 	}
       else
 	{
-	  newval = (int)strtol(datestr, &rstr, 10);
-	  if ( *rstr != 0 ) cdoAbort("Parameter string contains invalid characters: %s", datestr);
+	  newval = parameter2int(datestr);
 	}
     }
   else if ( operatorID == SETTIME )
     {
-      if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
+      operatorCheckArgc(1);
       timestr = operatorArgv()[0];
 
       if ( strchr(timestr, ':') )
@@ -218,12 +209,12 @@ void *Settime(void *argument)
 	}
       else
 	{
-	  newval = (int)strtol(timestr, &rstr, 10);
-	  if ( *rstr != 0 ) cdoAbort("Parameter string contains invalid characters: %s", timestr);
+	  newval = parameter2int(timestr);
 	}
     }
   else if ( operatorID == SHIFTTIME )
     {
+      operatorCheckArgc(1);
       const char *timeunits = operatorArgv()[0];
       incperiod = (int)strtol(timeunits, NULL, 10);
       if ( timeunits[0] == '-' || timeunits[0] == '+' ) timeunits++;
@@ -236,6 +227,7 @@ void *Settime(void *argument)
     }
   else if ( operatorID == SETTUNITS )
     {
+      operatorCheckArgc(1);
       int idum;
       const char *timeunits = operatorArgv()[0];
       incperiod = 0;
@@ -243,6 +235,7 @@ void *Settime(void *argument)
     }
   else if ( operatorID == SETCALENDAR )
     {
+      operatorCheckArgc(1);
       char *cname = operatorArgv()[0];
       strtolower(cname);
       size_t len = strlen(cname);
@@ -261,19 +254,19 @@ void *Settime(void *argument)
     }
   else
     {
-      newval = (int)strtol(operatorArgv()[0], &rstr, 10);
-      if ( *rstr != 0 ) cdoAbort("Parameter string contains invalid characters: %s", operatorArgv()[0]);
+      operatorCheckArgc(1);
+      newval = parameter2int(operatorArgv()[0]);
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
   taxis_has_bounds = taxisHasBounds(taxisID1);
-  ntsteps  = vlistNtsteps(vlistID1);
-  nvars    = vlistNvars(vlistID1);
+  int ntsteps  = vlistNtsteps(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
 
   if ( ntsteps == 1 )
     {
@@ -289,7 +282,7 @@ void *Settime(void *argument)
 	vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
     }
 
-  calendar = taxisInqCalendar(taxisID1);
+  int calendar = taxisInqCalendar(taxisID1);
 
   if ( cdoVerbose ) cdoPrint("calendar = %d", calendar);
 
@@ -370,7 +363,7 @@ void *Settime(void *argument)
 
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
diff --git a/src/Setzaxis.c b/src/Setzaxis.c
index f1de10f..4d21bc4 100644
--- a/src/Setzaxis.c
+++ b/src/Setzaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -26,46 +26,80 @@
 #include "cdo_int.h"
 #include "pstream.h"
 
+void genLayerBounds(int nlev, double *levels, double *lbounds, double *ubounds);
+
+int getkeyval_dp(const char *keyval, const char *key, double *val)
+{
+  int status = 0;
+  size_t keylen = strlen(key);
+
+  if ( strncmp(keyval, key, keylen) == 0 )
+    {
+      const char *pkv = keyval+keylen;
+      if ( pkv[0] == '=' && pkv[1] != 0 )
+        {
+          *val = parameter2double(&pkv[1]);
+          status = 1;
+        }
+      else
+        {
+          cdoAbort("Syntax error for parameter %s!", keyval);
+        }
+    }
+
+  return status;
+}
+
 
 void *Setzaxis(void *argument)
 {
-  int SETZAXIS;
-  int operatorID;
-  int streamID1, streamID2 = CDI_UNDEFID;
   int nrecs;
-  int tsID, recID, varID, levelID;
-  int vlistID1, vlistID2;
-  int taxisID1, taxisID2;
+  int recID, varID, levelID;
   int zaxisID1, zaxisID2 = -1;
   int nzaxis, index;
-  int gridsize;
   int nmiss;
   int found;
-  double *array = NULL;
+  int lztop = FALSE, lzbot = FALSE;
+  double ztop = 0, zbot = 0;
 
   cdoInitialize(argument);
 
-  SETZAXIS = cdoOperatorAdd("setzaxis",     0, 0, "zaxis description file");
+  int SETZAXIS       = cdoOperatorAdd("setzaxis",        0, 0, "zaxis description file");
+  int GENLEVELBOUNDS = cdoOperatorAdd("genlevelbounds",  0, 0, NULL);
 
-  operatorID = cdoOperatorID();
-
-  operatorInputArg(cdoOperatorEnter(operatorID));  
+  int operatorID = cdoOperatorID();
 
   if ( operatorID == SETZAXIS )
     {
+      operatorInputArg(cdoOperatorEnter(operatorID));  
+      operatorCheckArgc(1);
       zaxisID2 = cdoDefineZaxis(operatorArgv()[0]);
     }
+  else if ( operatorID == GENLEVELBOUNDS )
+    { 
+      unsigned npar = operatorArgc();
+      char **parnames = operatorArgv();
+
+      for ( unsigned i = 0; i < npar; i++ )
+        {
+          if ( cdoVerbose ) cdoPrint("keyval[%d]: %s", i+1, parnames[i]);
+          
+          if      ( !lzbot && getkeyval_dp(parnames[i], "zbot", &zbot) ) lzbot = TRUE;
+          else if ( !lztop && getkeyval_dp(parnames[i], "ztop", &ztop) ) lztop = TRUE;
+          else cdoAbort("Parameter >%s< unsupported! Supported parameter are: zbot, ztop", parnames[i]);
+        }
+    }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   if ( operatorID == SETZAXIS )
     {
@@ -83,14 +117,44 @@ void *Setzaxis(void *argument)
 	}
       if ( ! found ) cdoWarning("No zaxis with %d levels found!", zaxisInqSize(zaxisID2));
     }
+  else if ( operatorID == GENLEVELBOUNDS )
+    {
+      nzaxis = vlistNzaxis(vlistID1);
+      for ( index = 0; index < nzaxis; index++ )
+	{
+	  zaxisID1 = vlistZaxis(vlistID1, index);
+          int nlev = zaxisInqSize(zaxisID1);
+          double *levels  = (double *) malloc(nlev*sizeof(double));
+          double *lbounds = (double *) malloc(nlev*sizeof(double));
+          double *ubounds = (double *) malloc(nlev*sizeof(double));
+
+          if ( nlev > 1 )
+            {
+              zaxisInqLevels(zaxisID1, levels);
+              zaxisID2 = zaxisDuplicate(zaxisID1);
+
+              genLayerBounds(nlev, levels, lbounds, ubounds);
+
+              if ( lzbot ) lbounds[0] = zbot;
+              if ( lztop ) ubounds[nlev-1] = ztop;
+              zaxisDefLbounds(zaxisID2, lbounds);
+              zaxisDefUbounds(zaxisID2, ubounds);
+	      vlistChangeZaxisIndex(vlistID2, index, zaxisID2);
+            }
+
+          free(levels);
+          free(lbounds);
+          free(ubounds);
+	}
+    }
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double*) malloc(gridsize*sizeof(double));
+  double *array = (double*) malloc(gridsize*sizeof(double));
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Showinfo.c b/src/Showinfo.c
index 55c2af6..2a3025a 100644
--- a/src/Showinfo.c
+++ b/src/Showinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -59,7 +59,7 @@ void *Showinfo(void *argument)
   char varname[CDI_MAX_NAME];
   char stdname[CDI_MAX_NAME];
   char varunits[CDI_MAX_NAME];
-  char vdatestr[32], vtimestr[32];
+  char vdatetimestr[64], vdatestr[32], vtimestr[32];
 
   cdoInitialize(argument);
 
@@ -185,9 +185,8 @@ void *Showinfo(void *argument)
 	    vdate = taxisInqVdate(taxisID);
 	    vtime = taxisInqVtime(taxisID);
 
-	    date2str(vdate, vdatestr, sizeof(vdatestr));
-	    time2str(vtime, vtimestr, sizeof(vtimestr));
-	    fprintf(stdout, " %sT%s", vdatestr, vtimestr);
+	    datetime2str(vdate, vtime, vdatetimestr, sizeof(vdatetimestr));
+	    fprintf(stdout, " %s", vdatetimestr);
 
 	    tsID++;
 	    nout++;
diff --git a/src/Sinfo.c b/src/Sinfo.c
index 340c18d..e4df17c 100644
--- a/src/Sinfo.c
+++ b/src/Sinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -57,14 +57,15 @@ const char* calendar2str(int calendar)
 }
 
 static
-void limit_string_length(char* string)
+void limit_string_length(char* string, size_t maxlen)
 {
+  string[maxlen-1] = 0;
   size_t len = strlen(string);
 
   if ( len > 10 )
     {
       for ( size_t i = 3; i < len; ++i )
-	if ( string[i] == ' ' )
+	if ( string[i] == ' ' || string[i] == ',' || (i>10 && string[i] == '.') )
 	  {
 	    string[i] = 0;
 	    break;
@@ -159,15 +160,15 @@ void *Sinfo(void *argument)
 	  /* institute info */
 	  instptr = institutInqNamePtr(vlistInqVarInstitut(vlistID, varID));
 	  strcpy(tmpname, "unknown");
-	  if ( instptr ) strcpy(tmpname, instptr);
-	  limit_string_length(tmpname);
+	  if ( instptr ) strncpy(tmpname, instptr, CDI_MAX_NAME);
+	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
 	  /* source info */
 	  modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
 	  strcpy(tmpname, "unknown");
-	  if ( modelptr ) strcpy(tmpname, modelptr);
-	  limit_string_length(tmpname);
+	  if ( modelptr ) strncpy(tmpname, modelptr, CDI_MAX_NAME);
+	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
 	  /* tsteptype */
diff --git a/src/Smooth9.c b/src/Smooth9.c
index e134af5..e1afea6 100644
--- a/src/Smooth9.c
+++ b/src/Smooth9.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -30,7 +30,6 @@
 void *Smooth9(void *argument)
 {
   int operatorID;
-  int operfunc;
   int streamID1, streamID2;
   int gridsize;
   int gridID;
@@ -55,7 +54,7 @@ void *Smooth9(void *argument)
   cdoOperatorAdd("smooth9",   0,   0, NULL);
  
   operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  UNUSED(operatorID);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Sort.c b/src/Sort.c
index b5fcaa3..a2c9b31 100644
--- a/src/Sort.c
+++ b/src/Sort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -146,7 +146,7 @@ void *Sort(void *argument)
 
   if ( operatorID == SORTLEVEL && operatorArgc() == 1 )
     {
-      int iarg = atoi(operatorArgv()[0]);
+      int iarg = parameter2int(operatorArgv()[0]);
       if ( iarg < 0 ) cmpvarlev = cmpvarlevelrev;
     }
 
diff --git a/src/Sorttimestamp.c b/src/Sorttimestamp.c
index e90f17e..607eca6 100644
--- a/src/Sorttimestamp.c
+++ b/src/Sorttimestamp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Specinfo.c b/src/Specinfo.c
index 726eeb7..2c69924 100644
--- a/src/Specinfo.c
+++ b/src/Specinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -263,7 +263,7 @@ void *Specinfo(void *argument)
 
   len = strlen(operatorArgv()[0]);
 
-  if ( (len+1) >= 128 ) cdoAbort("Parameter string to large!");
+  if ( (len+1) >= 128 ) cdoAbort("Parameter string too large!");
 
   for ( i = 0; i < len; i++ ) arg[i] = toupper(operatorArgv()[0][i]);
   arg[len] = 0;
diff --git a/src/Spectral.c b/src/Spectral.c
index bc3e4ec..b83cfaf 100644
--- a/src/Spectral.c
+++ b/src/Spectral.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -188,7 +188,7 @@ void *Spectral(void *argument)
       if ( gridID1 != -1 )
 	{
 	  if ( !isdigit(operatorArgv()[0][0]) ) cdoAbort("parameter truncation must comprise only digits [0-9]!");
-	  int ntr = atoi(operatorArgv()[0]);
+	  int ntr = parameter2int(operatorArgv()[0]);
 	  int nsp = (ntr+1)*(ntr+2);
 	  gridIDsp = gridCreate(GRID_SPECTRAL, nsp);
 	  gridDefTrunc(gridIDsp, ntr);
diff --git a/src/Spectrum.c b/src/Spectrum.c
index 710e417..4cdb7cc 100644
--- a/src/Spectrum.c
+++ b/src/Spectrum.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -247,10 +247,10 @@ void *Spectrum(void *argument)
 
   operatorCheckArgc(4);
 
-  detrend = atoi(operatorArgv()[0]);
-  seg_l = atoi(operatorArgv()[1]);
-  seg_n = atoi(operatorArgv()[2]);
-  which_window = atoi(operatorArgv()[3]);
+  detrend = parameter2int(operatorArgv()[0]);
+  seg_l = parameter2int(operatorArgv()[1]);
+  seg_n = parameter2int(operatorArgv()[2]);
+  which_window = parameter2int(operatorArgv()[3]);
 
   if ( detrend < 0 || detrend > 3 )
     cdoAbort("Illegal value for detrend (=%d)!",detrend);
diff --git a/src/Split.c b/src/Split.c
index 28a91f1..ea1b802 100644
--- a/src/Split.c
+++ b/src/Split.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -33,6 +33,19 @@
 #include "cdo_int.h"
 #include "pstream.h"
 
+void create_uuid(unsigned char uuid[CDI_UUID_SIZE]);
+void uuid2str(const unsigned char *uuid, char *uuidstr);
+
+
+#define UUIDSTR_SIZE (CDI_UUID_SIZE*2 + 4)
+
+static
+void get_uuid(char uuidstr[UUIDSTR_SIZE])
+{
+  unsigned char uuid[CDI_UUID_SIZE];
+  create_uuid(uuid);
+  uuid2str(uuid, uuidstr);
+}
 
 static
 void gen_filename(char *filename, int swap_obase, const char *obase, const char *suffix)
@@ -44,16 +57,13 @@ void gen_filename(char *filename, int swap_obase, const char *obase, const char
 
 void *Split(void *argument)
 {
-  int SPLITCODE, SPLITPARAM, SPLITNAME, SPLITLEVEL, SPLITGRID, SPLITZAXIS, SPLITTABNUM;
-  int operatorID;
   int nchars = 0;
-  int streamID1;
   int varID;
   int code, tabnum, param;
-  int nrecs, nvars, nzaxis, nlevs;
-  int tsID, recID, levelID, zaxisID, levID;
+  int nlevs;
+  int recID, levelID, zaxisID, levID;
   int varID2, levelID2;
-  int vlistID1, vlistID2;
+  int vlistID2;
   int *vlistIDs = NULL, *streamIDs = NULL;
   int  itmp[999];
   double ftmp[999];
@@ -67,36 +77,40 @@ void *Split(void *argument)
   int gridsize;
   int nmiss;
   int swap_obase = FALSE;
-  double *array = NULL;
+  const char *uuid_attribute = NULL;
 
   cdoInitialize(argument);
 
   if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
-  SPLITCODE   = cdoOperatorAdd("splitcode",   0, 0, NULL);
-  SPLITPARAM  = cdoOperatorAdd("splitparam",  0, 0, NULL);
-  SPLITNAME   = cdoOperatorAdd("splitname",   0, 0, NULL);
-  SPLITLEVEL  = cdoOperatorAdd("splitlevel",  0, 0, NULL);
-  SPLITGRID   = cdoOperatorAdd("splitgrid",   0, 0, NULL);
-  SPLITZAXIS  = cdoOperatorAdd("splitzaxis",  0, 0, NULL);
-  SPLITTABNUM = cdoOperatorAdd("splittabnum", 0, 0, NULL);
-
-  operatorID = cdoOperatorID();
+  int SPLITCODE   = cdoOperatorAdd("splitcode",   0, 0, NULL);
+  int SPLITPARAM  = cdoOperatorAdd("splitparam",  0, 0, NULL);
+  int SPLITNAME   = cdoOperatorAdd("splitname",   0, 0, NULL);
+  int SPLITLEVEL  = cdoOperatorAdd("splitlevel",  0, 0, NULL);
+  int SPLITGRID   = cdoOperatorAdd("splitgrid",   0, 0, NULL);
+  int SPLITZAXIS  = cdoOperatorAdd("splitzaxis",  0, 0, NULL);
+  int SPLITTABNUM = cdoOperatorAdd("splittabnum", 0, 0, NULL);
 
-  if ( operatorArgc() == 1 )
-    if ( memcmp("swap", operatorArgv()[0], 4) == 0 ) swap_obase = TRUE;
+  int operatorID = cdoOperatorID();
 
-  if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
+  for( i = 0; i < operatorArgc(); ++i )
+    {
+      if ( strcmp("swap", operatorArgv()[i]) == 0 )
+          swap_obase = TRUE;
+      else if ( strncmp("uuid=", operatorArgv()[i], 5 ) == 0 )
+          uuid_attribute = operatorArgv()[i] + 5;
+      else cdoAbort("Unknown parameter: >%s<", operatorArgv()[0]); 
+    }
 
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
-  nvars  = vlistNvars(vlistID1);
-  nrecs  = vlistNrecs(vlistID1);
-  nzaxis = vlistNzaxis(vlistID1);
+  int nvars  = vlistNvars(vlistID1);
+  int nrecs  = vlistNrecs(vlistID1);
+  int nzaxis = vlistNzaxis(vlistID1);
 
   if ( swap_obase == 0 )
     {
@@ -171,8 +185,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
       if ( codes ) free(codes);
     }
@@ -230,8 +242,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
       if ( params ) free(params);
     }
@@ -284,8 +294,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
       if ( tabnums ) free(tabnums);
     }
@@ -321,8 +329,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistID2);
 	}
     }
   else if ( operatorID == SPLITLEVEL )
@@ -376,8 +382,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistID2);
 	}
       if ( levels ) free(levels);
     }
@@ -421,8 +425,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistID2);
 	}
       if ( gridIDs ) free(gridIDs);
     }
@@ -465,8 +467,6 @@ void *Split(void *argument)
 	  argument_t *fileargument = file_argument_new(filename);
 	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
 	  file_argument_free(fileargument);
-
-	  streamDefVlist(streamIDs[index], vlistID2);
 	}
       if ( zaxisIDs ) free(zaxisIDs);
     }
@@ -475,14 +475,28 @@ void *Split(void *argument)
       cdoAbort("not implemented!");
     }
 
+  for ( index = 0; index < nsplit; index++ )
+    {
+      if ( uuid_attribute )
+        {
+          char uuidstr[UUIDSTR_SIZE];
+          get_uuid(uuidstr);
+          vlistDefAttTxt(vlistIDs[index], CDI_GLOBAL, uuid_attribute, 
+                         UUIDSTR_SIZE, uuidstr);
+        }
+
+      streamDefVlist(streamIDs[index], vlistIDs[index]);
+    }
+
+  double *array = NULL;
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double*) malloc(gridsize*sizeof(double));
+      array = (double *) malloc(gridsize*sizeof(double));
     }
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       for ( index = 0; index < nsplit; index++ )
diff --git a/src/Splitrec.c b/src/Splitrec.c
index 96d8097..38b476a 100644
--- a/src/Splitrec.c
+++ b/src/Splitrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Splitsel.c b/src/Splitsel.c
index 141e14e..0ecb5d3 100644
--- a/src/Splitsel.c
+++ b/src/Splitsel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -71,14 +71,14 @@ void *Splitsel(void *argument)
   if ( nargc < 1 )
     cdoAbort("Too few arguments! Need %d found %d.", 1, nargc);
 
-/*   ndates = atoi(operatorArgv()[0]); */
-/*   if ( nargc > 1 ) noffset = atoi(operatorArgv()[1]); */
-/*   if ( nargc > 2 ) nskip   = atoi(operatorArgv()[2]); */
+/*   ndates = parameter2int(operatorArgv()[0]); */
+/*   if ( nargc > 1 ) noffset = parameter2int(operatorArgv()[1]); */
+/*   if ( nargc > 2 ) nskip   = parameter2int(operatorArgv()[2]); */
 /*   printf("%s %s %s\n", operatorArgv()[0],operatorArgv()[1],operatorArgv()[2]); */
   ndates = noffset = nskip = 0.0;
-  ndates = atof(operatorArgv()[0]);
-  if ( nargc > 1 ) noffset = atof(operatorArgv()[1]);
-  if ( nargc > 2 ) nskip   = atof(operatorArgv()[2]);
+  ndates = parameter2double(operatorArgv()[0]);
+  if ( nargc > 1 ) noffset = parameter2double(operatorArgv()[1]);
+  if ( nargc > 2 ) nskip   = parameter2double(operatorArgv()[2]);
 
   if ( cdoVerbose ) cdoPrint("nsets = %f, noffset = %f, nskip = %f", ndates, noffset, nskip);
 
diff --git a/src/Splittime.c b/src/Splittime.c
index b6c4ce6..640ea12 100644
--- a/src/Splittime.c
+++ b/src/Splittime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -55,50 +55,40 @@ struct tm datetime_to_tm(int date, int time)
 
 void *Splittime(void *argument)
 {
-  int SPLITHOUR, SPLITDAY, SPLITMON, SPLITSEAS;
-  int operatorID;
-  int operfunc, operintval;
-  int nchars;
-  int streamID1, streamID2;
+  int streamID2;
   int varID;
   int nrecs;
   int tsID, recID, levelID;
-  int vlistID1, vlistID2;
   int  streamIDs[MAX_STREAMS], tsIDs[MAX_STREAMS];
   char filesuffix[32];
   char filename[8192];
-  const char *refname;
   int index = 0;
   int i;
-  int taxisID1, taxisID2;
   int vdate, vtime;
   int lcopy = FALSE;
   int gridsize;
   int nmiss;
   int gridID;
-  int nvars, nlevel;
-  int nconst;
+  int nlevel;
   double *array = NULL;
   field_t **vars = NULL;
-  int season_start;
-  const char *seas_name[4];
   const char *format = NULL;
 
   cdoInitialize(argument);
 
   if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
-  SPLITHOUR = cdoOperatorAdd("splithour", func_time, 10000, NULL);
-  SPLITDAY  = cdoOperatorAdd("splitday",  func_date,     1, NULL);
-  SPLITMON  = cdoOperatorAdd("splitmon",  func_date,   100, NULL);
-  SPLITSEAS = cdoOperatorAdd("splitseas", func_date,   100, NULL);
+  int SPLITHOUR = cdoOperatorAdd("splithour", func_time, 10000, NULL);
+  int SPLITDAY  = cdoOperatorAdd("splitday",  func_date,     1, NULL);
+  int SPLITMON  = cdoOperatorAdd("splitmon",  func_date,   100, NULL);
+  int SPLITSEAS = cdoOperatorAdd("splitseas", func_date,   100, NULL);
 
   UNUSED(SPLITDAY);
   UNUSED(SPLITHOUR);
 
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
-  operintval = cdoOperatorF2(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
+  int operintval = cdoOperatorF2(operatorID);
 
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
@@ -107,25 +97,26 @@ void *Splittime(void *argument)
       if ( operatorArgc() == 1 ) format = operatorArgv()[0];
     }
 
-  season_start = get_season_start();
+  int season_start = get_season_start();
+  const char *seas_name[4];
   get_season_name(seas_name);
 
   for ( i = 0; i < MAX_STREAMS; i++ ) streamIDs[i] = -1;
   for ( i = 0; i < MAX_STREAMS; i++ ) tsIDs[i] = 0;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
   strcpy(filename, cdoStreamName(1)->args);
-  nchars = strlen(filename);
+  int nchars = strlen(filename);
 
-  refname = cdoStreamName(0)->argv[cdoStreamName(0)->argc-1];
+  const char *refname = cdoStreamName(0)->argv[cdoStreamName(0)->argc-1];
   filesuffix[0] = 0;
   cdoGenFileSuffix(filesuffix, sizeof(filesuffix), streamInqFiletype(streamID1), vlistID1, refname);
 
@@ -136,8 +127,8 @@ void *Splittime(void *argument)
       array = (double*) malloc(gridsize*sizeof(double));
     }
 
-  nvars = vlistNvars(vlistID1);
-  nconst = 0;
+  int nvars = vlistNvars(vlistID1);
+  int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
     if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
 
diff --git a/src/Splityear.c b/src/Splityear.c
index cc4b129..f20ef3a 100644
--- a/src/Splityear.c
+++ b/src/Splityear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,8 @@
 /*
    This module contains the following operators:
 
-     Splittime  splityear       Split years
+     Splityear  splityear       Split in years
+     Splityear  splityearmon    Split in years and month
 */
 
 #include <cdi.h>
@@ -31,20 +32,16 @@
 
 void *Splityear(void *argument)
 {
-  int nchars;
-  int streamID1, streamID2 = -1;
+  int streamID2 = -1;
   int varID;
   int nrecs;
   int tsID, tsID2, recID, levelID;
-  int vlistID1, vlistID2;
   char filesuffix[32];
   char filename[8192];
-  const char *refname;
   int vdate;
   int day;
   int year1, year2;
   int mon1, mon2;
-  int taxisID1, taxisID2;
   int lcopy = FALSE;
   int gridsize;
   int ic = 0;
@@ -58,17 +55,24 @@ void *Splityear(void *argument)
 
   if ( UNCHANGED_RECORD ) lcopy = TRUE;
 
+  int SPLITYEAR    = cdoOperatorAdd("splityear",     func_date, 10000, NULL);
+  int SPLITYEARMON = cdoOperatorAdd("splityearmon",  func_date,   100, NULL);
+  
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
+  int operintval = cdoOperatorF2(operatorID);
+
   memset(cyear, 0, MAX_YEARS*sizeof(int));
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
   strcpy(filename, cdoStreamName(1)->args);
-  nchars = strlen(filename);
+  int nchars = strlen(filename);
 
-  refname = cdoStreamName(0)->argv[cdoStreamName(0)->argc-1];
+  const char *refname = cdoStreamName(0)->argv[cdoStreamName(0)->argc-1];
   filesuffix[0] = 0;
   cdoGenFileSuffix(filesuffix, sizeof(filesuffix), streamInqFiletype(streamID1), vlistID1, refname);
 
@@ -79,10 +83,12 @@ void *Splityear(void *argument)
       array = (double*) malloc(gridsize*sizeof(double));
     }
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
+  int index1 = - 1<<31;
+  int index2;
   year1 = -1;
   mon1  = -1;
   tsID  = 0;
@@ -92,38 +98,67 @@ void *Splityear(void *argument)
       vdate = taxisInqVdate(taxisID1);
       cdiDecodeDate(vdate, &year2, &mon2, &day);
 
-      if ( tsID == 0 || year1 != year2 || (year1 == year2 && mon1 > mon2) )
+      if ( operatorID == SPLITYEAR )
 	{
-	  tsID2 = 0;
+	  if ( tsID == 0 || year1 != year2 || (year1 == year2 && mon1 > mon2) )
+	    {
+	      tsID2 = 0;
 
-	  if ( year1 != year2 ) ic = 0;
-	  else                  ic++;
+	      if ( year1 != year2 ) ic = 0;
+	      else                  ic++;
 
-	  if ( year2 >= 0 && year2 < MAX_YEARS )
-	    {
-	      ic = cyear[year2];
-	      cyear[year2]++;
-	    }
+	      if ( year2 >= 0 && year2 < MAX_YEARS )
+		{
+		  ic = cyear[year2];
+		  cyear[year2]++;
+		}
 
-	  year1 = year2;
+	      year1 = year2;
 
-	  if ( streamID2 >= 0 ) streamClose(streamID2);
+	      if ( streamID2 >= 0 ) streamClose(streamID2);
 
-	  sprintf(filename+nchars, "%04d", year1);
-	  if ( ic > 0 ) sprintf(filename+strlen(filename), "_%d", ic+1);
-	  if ( filesuffix[0] )
-	    sprintf(filename+strlen(filename), "%s", filesuffix);
+	      sprintf(filename+nchars, "%04d", year1);
+	      if ( ic > 0 ) sprintf(filename+strlen(filename), "_%d", ic+1);
+	      if ( filesuffix[0] )
+		sprintf(filename+strlen(filename), "%s", filesuffix);
 	  
-	  if ( cdoVerbose ) cdoPrint("create file %s", filename);
+	      if ( cdoVerbose ) cdoPrint("create file %s", filename);
 
-	  argument_t *fileargument = file_argument_new(filename);
-	  streamID2 = streamOpenWrite(fileargument, cdoFiletype());
-	  file_argument_free(fileargument);
+	      argument_t *fileargument = file_argument_new(filename);
+	      streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+	      file_argument_free(fileargument);
 
-	  streamDefVlist(streamID2, vlistID2);
+	      streamDefVlist(streamID2, vlistID2);
+	    }
+	  mon1 = mon2;
 	}
-      mon1 = mon2;
+      else if ( operatorID == SPLITYEARMON )
+	{
+	  index2 = (vdate/operintval);
+	  
+	  if ( tsID == 0 || index1 != index2 )
+	    {
+	      tsID2 = 0;
 
+	      index1 = index2;
+
+	      if ( streamID2 >= 0 ) streamClose(streamID2);
+
+	      sprintf(filename+nchars, "%04d", index1);
+	      //if ( ic > 0 ) sprintf(filename+strlen(filename), "_%d", ic+1);
+	      if ( filesuffix[0] )
+		sprintf(filename+strlen(filename), "%s", filesuffix);
+	  
+	      if ( cdoVerbose ) cdoPrint("create file %s", filename);
+
+	      argument_t *fileargument = file_argument_new(filename);
+	      streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+	      file_argument_free(fileargument);
+
+	      streamDefVlist(streamID2, vlistID2);
+	    }
+	}
+      
       taxisCopyTimestep(taxisID2, taxisID1);
 
       streamDefTimestep(streamID2, tsID2++);
diff --git a/src/Subtrend.c b/src/Subtrend.c
index 5a85b8a..3f5671c 100644
--- a/src/Subtrend.c
+++ b/src/Subtrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tee.c b/src/Tee.c
index 7dbf48a..fc56326 100644
--- a/src/Tee.c
+++ b/src/Tee.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Templates.c b/src/Templates.c
index b159d35..7ff8385 100644
--- a/src/Templates.c
+++ b/src/Templates.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Test.c b/src/Test.c
index 5205160..eb3efca 100644
--- a/src/Test.c
+++ b/src/Test.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tests.c b/src/Tests.c
index 231c223..f0efedf 100644
--- a/src/Tests.c
+++ b/src/Tests.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -54,7 +54,7 @@ void *Tests(void *argument)
 
       operatorCheckArgc(1);
 
-      degree_of_freedom = atof(operatorArgv()[0]);
+      degree_of_freedom = parameter2double(operatorArgv()[0]);
 
       if ( degree_of_freedom <= 0 )
 	cdoAbort("degree of freedom must be positive!");
@@ -65,8 +65,8 @@ void *Tests(void *argument)
 
       operatorCheckArgc(2);
 
-      p = atof(operatorArgv()[0]);
-      q = atof(operatorArgv()[1]);
+      p = parameter2double(operatorArgv()[0]);
+      q = parameter2double(operatorArgv()[1]);
 
       if ( p <= 0 || q <= 0 )
 	cdoAbort("p and q must be positive!");
@@ -77,8 +77,8 @@ void *Tests(void *argument)
 
       operatorCheckArgc(2);
 
-      n = atof(operatorArgv()[0]);
-      d = atof(operatorArgv()[1]);
+      n = parameter2double(operatorArgv()[0]);
+      d = parameter2double(operatorArgv()[1]);
 
       if ( n <= 0 || d <= 0 )
 	cdoAbort("both degrees must be positive!");
diff --git a/src/Timpctl.c b/src/Timpctl.c
index 2d7d4ef..ebfe8e3 100644
--- a/src/Timpctl.c
+++ b/src/Timpctl.c
@@ -36,69 +36,67 @@
 static
 void timpctl(int operatorID)
 {
-  int cmplen;
+  int timestat_date = TIMESTAT_MEAN;
   char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
-  int gridsize;
   int vdate1 = 0, vtime1 = 0;
   int vdate2 = 0, vtime2 = 0;
   int vdate3 = 0, vtime3 = 0;
-  int vdate4 = 0, vtime4 = 0;
-  int nrecs, nrecords;
+  int nrecs;
   int gridID, varID, levelID, recID;
   int tsID;
   int otsID;
   long nsets;
-  int streamID1, streamID2, streamID3, streamID4;
-  int vlistID1, vlistID2, vlistID3, vlistID4, taxisID1, taxisID2, taxisID3, taxisID4;
   int nmiss;
-  int nvars, nlevels;
-  int *recVarID, *recLevelID;
+  int nlevels;
   field_t **vars1 = NULL;
   field_t field;
-  double pn;
   HISTOGRAM_SET *hset = NULL;
   
   operatorInputArg("percentile number");
-  pn = atof(operatorArgv()[0]);
+  double pn = parameter2double(operatorArgv()[0]);
       
   if ( !(pn >= 0 && pn <= 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
 
-  cmplen = DATE_LEN - cdoOperatorF2(operatorID);
+  int cmplen = DATE_LEN - cdoOperatorF2(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
-  streamID3 = streamOpenRead(cdoStreamName(2));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID3 = streamOpenRead(cdoStreamName(2));
   
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = streamInqVlist(streamID3);
-  vlistID4 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = streamInqVlist(streamID3);
+  int vlistID4 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
   vlistCompare(vlistID1, vlistID3, CMP_ALL);
   
   if ( cdoOperatorF2(operatorID) == 16 ) vlistDefNtsteps(vlistID4, 1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = vlistInqTaxis(vlistID3);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = vlistInqTaxis(vlistID3);
   /* TODO - check that time axes 2 and 3 are equal */
 
-  taxisID4 = taxisDuplicate(taxisID1);
+  int taxisID4 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID4, taxisID4);
 
-  streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
+  int streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
 
   streamDefVlist(streamID4, vlistID4);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords * sizeof(int));
-  recLevelID = (int*) malloc(nrecords * sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords * sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords * sizeof(int));
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
+
+  int gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
   field.ptr = (double*) malloc(gridsize * sizeof(double));
@@ -117,9 +115,7 @@ void timpctl(int operatorID)
   tsID    = 0;
   otsID   = 0;
   while ( TRUE )
-    {
-      nsets = 0;
-      
+    {      
       nrecs = streamInqTimestep(streamID2, otsID);
       if ( nrecs != streamInqTimestep(streamID3, otsID) )
         cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
@@ -137,6 +133,7 @@ void timpctl(int operatorID)
 	  streamReadRecord(streamID2, vars1[varID][levelID].ptr, &nmiss);
           vars1[varID][levelID].nmiss = nmiss;
         }
+
       for ( recID = 0; recID < nrecs; recID++ )
         {
           streamInqRecord(streamID3, &varID, &levelID);
@@ -148,11 +145,12 @@ void timpctl(int operatorID)
 	  hsetDefVarLevelBounds(hset, varID, levelID, &vars1[varID][levelID], &field);
         }
           
+      nsets = 0;
       while ( nrecs && (nrecs = streamInqTimestep(streamID1, tsID)) )
 	{
-	  vdate1 = taxisInqVdate(taxisID1);
-	  vtime1 = taxisInqVtime(taxisID1);
-
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
+	  vdate1 = dtlist_get_vdate(dtlist, nsets);
+	  vtime1 = dtlist_get_vtime(dtlist, nsets);
 
 	  if ( nsets == 0 ) SET_DATE(indate2, vdate1, vtime1);
 	  SET_DATE(indate1, vdate1, vtime1);
@@ -173,20 +171,11 @@ void timpctl(int operatorID)
 	      hsetAddVarLevelValues(hset, varID, levelID, &vars1[varID][levelID]);
 	    }
 
-	  vdate4 = vdate1;
-	  vtime4 = vtime1;
 	  nsets++;
 	  tsID++;
 	}
 
       if ( nrecs == 0 && nsets == 0 ) break;
-
-      if ( vdate2 != vdate4 )
-        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-      if ( vtime2 != vtime4 )
-        cdoAbort("Verification times at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
       
       for ( varID = 0; varID < nvars; varID++ )
 	{
@@ -197,8 +186,7 @@ void timpctl(int operatorID)
             hsetGetVarLevelPercentiles(&vars1[varID][levelID], hset, varID, levelID, pn);
 	}
 
-      taxisDefVdate(taxisID4, vdate4);
-      taxisDefVtime(taxisID4, vtime4);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID4, nsets);
       streamDefTimestep(streamID4, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -218,6 +206,8 @@ void timpctl(int operatorID)
 
   field_free(vars1, vlistID1);
   hsetDestroy(hset);
+
+  dtlist_delete(dtlist);
   
   if ( field.ptr ) free(field.ptr);
 
diff --git a/src/Timselpctl.c b/src/Timselpctl.c
index 2299afa..933c077 100644
--- a/src/Timselpctl.c
+++ b/src/Timselpctl.c
@@ -31,26 +31,18 @@
 
 void *Timselpctl(void *argument)
 {
-  int gridsize;
-  int vdate1 = 0, vtime1 = 0;
+  int timestat_date = TIMESTAT_MEAN;
   int vdate2 = 0, vtime2 = 0;
   int vdate3 = 0, vtime3 = 0;
-  int vdate4 = 0, vtime4 = 0;
-  int nrecs = 0, nrecords;
+  int nrecs = 0;
   int gridID, varID, levelID, recID;
   int tsID;
-  int otsID;
   int nsets = 0;
   int i;
-  int streamID1, streamID2, streamID3, streamID4;
-  int vlistID1, vlistID2, vlistID3, vlistID4, taxisID1, taxisID2, taxisID3, taxisID4;
   int nmiss;
-  int nvars, nlevels;
-  int ndates = 0, noffset = 0, nskip = 0, nargc;
-  int *recVarID, *recLevelID;
+  int nlevels;
   field_t **vars1 = NULL;
   field_t field;
-  double pn;
   HISTOGRAM_SET *hset = NULL;
 
   cdoInitialize(argument);
@@ -59,51 +51,55 @@ void *Timselpctl(void *argument)
 
   operatorInputArg("percentile number, nsets <,noffset <,nskip>>");
 
-  nargc = operatorArgc();
-  if ( nargc < 2 )
-    cdoAbort("Too few arguments! Need %d found %d.", 2, nargc);
+  int nargc = operatorArgc();
+  if ( nargc < 2 ) cdoAbort("Too few arguments! Need %d found %d.", 2, nargc);
 
-  pn     = atof(operatorArgv()[0]);
-  ndates = atoi(operatorArgv()[1]);
-  if ( nargc > 2 ) noffset = atoi(operatorArgv()[2]);
-  if ( nargc > 3 ) nskip   = atoi(operatorArgv()[3]);
+  double pn  = parameter2double(operatorArgv()[0]);
+  int ndates = parameter2int(operatorArgv()[1]);
+  int noffset = 0, nskip = 0;
+  if ( nargc > 2 ) noffset = parameter2int(operatorArgv()[2]);
+  if ( nargc > 3 ) nskip   = parameter2int(operatorArgv()[3]);
 
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
 
   if ( cdoVerbose ) cdoPrint("nsets = %d, noffset = %d, nskip = %d", ndates, noffset, nskip);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
-  streamID3 = streamOpenRead(cdoStreamName(2));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID3 = streamOpenRead(cdoStreamName(2));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = streamInqVlist(streamID3);
-  vlistID4 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = streamInqVlist(streamID3);
+  int vlistID4 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
   vlistCompare(vlistID1, vlistID3, CMP_ALL);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = vlistInqTaxis(vlistID3);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = vlistInqTaxis(vlistID3);
   /* TODO - check that time axes 2 and 3 are equal */
 
-  taxisID4 = taxisDuplicate(taxisID1);
+  int taxisID4 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID4, taxisID4);
 
-  streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
+  int streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
 
   streamDefVlist(streamID4, vlistID4);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
+
+  int gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
   field.ptr = (double*) malloc(gridsize * sizeof(double));
@@ -142,7 +138,7 @@ void *Timselpctl(void *argument)
       goto LABEL_END;
     }
 
-  otsID = 0;
+  int otsID = 0;
   while ( TRUE )
     {
       nrecs = streamInqTimestep(streamID2, otsID);
@@ -162,6 +158,7 @@ void *Timselpctl(void *argument)
           streamReadRecord(streamID2, vars1[varID][levelID].ptr, &nmiss);
           vars1[varID][levelID].nmiss = nmiss;
         }
+
       for ( recID = 0; recID < nrecs; recID++ )
         {
           streamInqRecord(streamID3, &varID, &levelID);
@@ -172,46 +169,37 @@ void *Timselpctl(void *argument)
           
           hsetDefVarLevelBounds(hset, varID, levelID, &vars1[varID][levelID], &field);
         }
-      
+
+      nsets = 0;
       if ( nrecs )
-      for ( nsets = 0; nsets < ndates; nsets++ )
-	{
-	  nrecs = streamInqTimestep(streamID1, tsID);
-	  if ( nrecs == 0 ) break;
+	for ( nsets = 0; nsets < ndates; nsets++ )
+	  {
+	    nrecs = streamInqTimestep(streamID1, tsID);
+	    if ( nrecs == 0 ) break;
 
-	  vdate1 = taxisInqVdate(taxisID1);
-	  vtime1 = taxisInqVtime(taxisID1);
+	    dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
 
-	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      streamInqRecord(streamID1, &varID, &levelID);
+	    for ( recID = 0; recID < nrecs; recID++ )
+	      {
+		streamInqRecord(streamID1, &varID, &levelID);
 
-	      if ( tsID == 0 )
-		{
-		  recVarID[recID]   = varID;
-		  recLevelID[recID] = levelID;
-		}
+		if ( tsID == 0 )
+		  {
+		    recVarID[recID]   = varID;
+		    recLevelID[recID] = levelID;
+		  }
 
-	      streamReadRecord(streamID1, vars1[varID][levelID].ptr, &nmiss);
-	      vars1[varID][levelID].nmiss = nmiss;
+		streamReadRecord(streamID1, vars1[varID][levelID].ptr, &nmiss);
+		vars1[varID][levelID].nmiss = nmiss;
                   
-              hsetAddVarLevelValues(hset, varID, levelID, &vars1[varID][levelID]);
-	    }
+		hsetAddVarLevelValues(hset, varID, levelID, &vars1[varID][levelID]);
+	      }
 
-	  vdate4 = vdate1;
-	  vtime4 = vtime1;
-	  tsID++;
-	}
+	    tsID++;
+	  }
 
       if ( nrecs == 0 && nsets == 0 ) break;
 
-      if ( vdate2 != vdate4 )
-        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-      if ( vtime2 != vtime4 )
-        cdoAbort("Verification times at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-
       for ( varID = 0; varID < nvars; varID++ )
         {
           if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -221,8 +209,7 @@ void *Timselpctl(void *argument)
             hsetGetVarLevelPercentiles(&vars1[varID][levelID], hset, varID, levelID, pn);
         }
 
-      taxisDefVdate(taxisID4, vdate4);
-      taxisDefVtime(taxisID4, vtime4);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID4, nsets);
       streamDefTimestep(streamID4, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -254,6 +241,8 @@ void *Timselpctl(void *argument)
   field_free(vars1, vlistID1);
   hsetDestroy(hset);
 
+  dtlist_delete(dtlist);
+
   if ( field.ptr ) free(field.ptr);
 
   if ( recVarID   ) free(recVarID);
diff --git a/src/Timselstat.c b/src/Timselstat.c
index e3c3e81..890551e 100644
--- a/src/Timselstat.c
+++ b/src/Timselstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -38,28 +38,15 @@
 
 void *Timselstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
+  int timestat_date = TIMESTAT_MEAN;
   int gridsize;
-  int vdate = 0, vtime = 0;
-  int vdate0 = 0, vtime0 = 0;
-  int vdate_lb = 0, vdate_ub = 0, date_lb = 0, date_ub = 0;
-  int vtime_lb = 0, vtime_ub = 0, time_lb = 0, time_ub = 0;
-  int nrecs = 0, nrecords;
+  int nrecs = 0;
   int varID, levelID, recID;
   int tsID;
-  int otsID;
   int nsets;
   int i;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2, taxisID1, taxisID2;
-  int taxis_has_bounds = FALSE;
   int nmiss;
-  int nvars, nlevel;
-  int ndates = 0, noffset = 0, nskip = 0, nargc;
-  int *recVarID, *recLevelID;
-  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
-  double divisor;
+  int nlevel;
   field_t **vars1 = NULL, **vars2 = NULL, **samp1 = NULL;
   field_t field;
 
@@ -75,43 +62,46 @@ void *Timselstat(void *argument)
   cdoOperatorAdd("timselstd",  func_std,  0, NULL);
   cdoOperatorAdd("timselstd1", func_std1, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg("nsets <noffset <nskip>>");
 
-  nargc = operatorArgc();
-
-  ndates = atoi(operatorArgv()[0]);
-  if ( nargc > 1 ) noffset = atoi(operatorArgv()[1]);
-  if ( nargc > 2 ) nskip   = atoi(operatorArgv()[2]);
+  int nargc  = operatorArgc();
+  int ndates = parameter2int(operatorArgv()[0]);
+  int noffset = 0, nskip = 0;
+  if ( nargc > 1 ) noffset = parameter2int(operatorArgv()[1]);
+  if ( nargc > 2 ) nskip   = parameter2int(operatorArgv()[2]);
 
   if ( cdoVerbose ) cdoPrint("nsets = %d, noffset = %d, nskip = %d", ndates, noffset, nskip);
 
-  lmean   = operfunc == func_mean || operfunc == func_avg;
-  lstd    = operfunc == func_std || operfunc == func_std1;
-  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
-  divisor = operfunc == func_std1 || operfunc == func_var1;
+  int lmean   = operfunc == func_mean || operfunc == func_avg;
+  int lstd    = operfunc == func_std || operfunc == func_std1;
+  int lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  double divisor = operfunc == func_std1 || operfunc == func_var1;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxis_has_bounds = taxisHasBounds(taxisID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
+
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
@@ -146,7 +136,7 @@ void *Timselstat(void *argument)
       goto LABEL_END;
     }
 
-  otsID   = 0;
+  int otsID   = 0;
   while ( TRUE )
     {
       for ( nsets = 0; nsets < ndates; nsets++ )
@@ -154,21 +144,7 @@ void *Timselstat(void *argument)
 	  nrecs = streamInqTimestep(streamID1, tsID);
 	  if ( nrecs == 0 ) break;
 
-	  vdate = taxisInqVdate(taxisID1);
-	  vtime = taxisInqVtime(taxisID1);
-
-	  if ( taxis_has_bounds )
-	    {
-	      taxisInqVdateBounds(taxisID1, &date_lb, &date_ub);
-	      taxisInqVtimeBounds(taxisID1, &time_lb, &time_ub);
-	      if ( nsets == 0 )
-		{
-		  vdate_lb = date_lb;
-		  vtime_lb = time_lb;
-		}
-	      vdate_ub = date_ub;
-	      vtime_ub = time_ub;
-	    }
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
 
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
@@ -241,8 +217,6 @@ void *Timselstat(void *argument)
 		  farmoq(&vars2[varID][levelID], vars1[varID][levelID]);
 	      }
 
-	  vdate0 = vdate;
-	  vtime0 = vtime;
 	  tsID++;
 	}
 
@@ -285,13 +259,7 @@ void *Timselstat(void *argument)
 	      }
 	  }
 
-      taxisDefVdate(taxisID2, vdate0);
-      taxisDefVtime(taxisID2, vtime0);
-      if ( taxis_has_bounds )
-	{
-	  taxisDefVdateBounds(taxisID2, vdate_lb, vdate_ub);
-	  taxisDefVtimeBounds(taxisID2, vtime_lb, vtime_ub);
-	}
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, nsets);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -325,6 +293,8 @@ void *Timselstat(void *argument)
   field_free(samp1, vlistID1);
   if ( lvarstd ) field_free(vars2, vlistID1);
 
+  dtlist_delete(dtlist);
+
   if ( field.ptr ) free(field.ptr);
 
   if ( recVarID   ) free(recVarID);
diff --git a/src/Timsort.c b/src/Timsort.c
index b93ed2d..bd72bd2 100644
--- a/src/Timsort.c
+++ b/src/Timsort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Timstat.c b/src/Timstat.c
index 5743e4c..d28f34c 100644
--- a/src/Timstat.c
+++ b/src/Timstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,48 +74,35 @@
 
 void *Timstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int cmplen;
-  char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
+  int timestat_date = TIMESTAT_MEAN;
   int gridsize;
   int vdate = 0, vtime = 0;
   int vdate0 = 0, vtime0 = 0;
-  int vdate_lb = 0, vdate_ub = 0, date_lb = 0, date_ub = 0;
-  int vtime_lb = 0, vtime_ub = 0, time_lb = 0, time_ub = 0;
-  int nrecs, nrecords;
+  int nrecs;
   int varID, levelID, recID;
-  int tsID;
-  int otsID;
   long nsets;
   int i;
-  int streamID1, streamID2, streamID3 = -1;
-  int vlistID1, vlistID2, vlistID3, taxisID1, taxisID2, taxisID3 = -1;
+  int streamID3 = -1;
+  int vlistID3, taxisID3 = -1;
   int nmiss;
-  int nvars, nlevel;
-  int *recVarID, *recLevelID;
-  int taxis_has_bounds = FALSE;
+  int nlevel;
   int lvfrac = FALSE;
-  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
   int nwpv; // number of words per value; real:1  complex:2
-  char vdatestr[32], vtimestr[32];
+  char indate1[DATE_LEN+1], indate2[DATE_LEN+1];
   double vfrac = 1;
-  double divisor;
   double missval;
-  field_t **vars1 = NULL, **vars2 = NULL, **samp1 = NULL;
-  field_t field;
 
   cdoInitialize(argument);
 
-  cdoOperatorAdd("timmin",    func_min,  31, NULL);
-  cdoOperatorAdd("timmax",    func_max,  31, NULL);
-  cdoOperatorAdd("timsum",    func_sum,  31, NULL);
-  cdoOperatorAdd("timmean",   func_mean, 31, NULL);
-  cdoOperatorAdd("timavg",    func_avg,  31, NULL);
-  cdoOperatorAdd("timvar",    func_var,  31, NULL);
-  cdoOperatorAdd("timvar1",   func_var1, 31, NULL);
-  cdoOperatorAdd("timstd",    func_std,  31, NULL);
-  cdoOperatorAdd("timstd1",   func_std1, 31, NULL);
+  cdoOperatorAdd("timmin",    func_min,  DATE_LEN, NULL);
+  cdoOperatorAdd("timmax",    func_max,  DATE_LEN, NULL);
+  cdoOperatorAdd("timsum",    func_sum,  DATE_LEN, NULL);
+  cdoOperatorAdd("timmean",   func_mean, DATE_LEN, NULL);
+  cdoOperatorAdd("timavg",    func_avg,  DATE_LEN, NULL);
+  cdoOperatorAdd("timvar",    func_var,  DATE_LEN, NULL);
+  cdoOperatorAdd("timvar1",   func_var1, DATE_LEN, NULL);
+  cdoOperatorAdd("timstd",    func_std,  DATE_LEN, NULL);
+  cdoOperatorAdd("timstd1",   func_std1, DATE_LEN, NULL);
   cdoOperatorAdd("yearmin",   func_min,  10, NULL);
   cdoOperatorAdd("yearmax",   func_max,  10, NULL);
   cdoOperatorAdd("yearsum",   func_sum,  10, NULL);
@@ -153,13 +140,14 @@ void *Timstat(void *argument)
   cdoOperatorAdd("hourstd",   func_std,   4, NULL);
   cdoOperatorAdd("hourstd1",  func_std1,  4, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
+  int comparelen = cdoOperatorF2(operatorID);
 
-  lmean   = operfunc == func_mean || operfunc == func_avg;
-  lstd    = operfunc == func_std || operfunc == func_std1;
-  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
-  divisor = operfunc == func_std1 || operfunc == func_var1;
+  int lmean   = operfunc == func_mean || operfunc == func_avg;
+  int lstd    = operfunc == func_std || operfunc == func_std1;
+  int lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  double divisor = operfunc == func_std1 || operfunc == func_var1;
 
   if ( operfunc == func_mean )
     {
@@ -177,27 +165,30 @@ void *Timstat(void *argument)
 	cdoAbort("Too many arguments!");
     }
 
-  cmplen = DATE_LEN - cdoOperatorF2(operatorID);
+  int cmplen = DATE_LEN - comparelen;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  if ( cdoOperatorF2(operatorID) == 31 ) vlistDefNtsteps(vlistID2, 1);
+  if ( cmplen == 0 ) vlistDefNtsteps(vlistID2, 1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   if ( taxisInqType(taxisID2) == TAXIS_FORECAST ) taxisDefType(taxisID2, TAXIS_RELATIVE);
-  taxis_has_bounds = taxisHasBounds(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  streamDefVlist(streamID2, vlistID2);
+  if ( cmplen == 0 && CDO_Reduce_Dim )
+    for ( varID = 0; varID < nvars; ++varID )
+      vlistDefVarTsteptype(vlistID2, varID, TSTEP_CONSTANT);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
 
   if ( cdoDiag )
     {
@@ -226,53 +217,41 @@ void *Timstat(void *argument)
       streamDefVlist(streamID3, vlistID3);
     }
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
+
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, taxisInqCalendar(taxisID1));
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
 
+  field_t field;
   field_init(&field);
   field.ptr = (double*) malloc(gridsize*sizeof(double));
 
-  vars1 = field_malloc(vlistID1, FIELD_PTR);
-  samp1 = field_malloc(vlistID1, FIELD_NONE);
-  if ( lvarstd )
-    vars2 = field_malloc(vlistID1, FIELD_PTR);
+  field_t **vars1 = field_malloc(vlistID1, FIELD_PTR);
+  field_t **samp1 = field_malloc(vlistID1, FIELD_NONE);
+  field_t **vars2 = NULL;
+  if ( lvarstd ) vars2 = field_malloc(vlistID1, FIELD_PTR);
 
-  tsID    = 0;
-  otsID   = 0;
+  int tsID  = 0;
+  int otsID = 0;
   while ( TRUE )
     {
       nsets = 0;
       while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
 	{
-	  vdate = taxisInqVdate(taxisID1);
-	  vtime = taxisInqVtime(taxisID1);
-
-	  if ( taxis_has_bounds )
-	    {
-	      taxisInqVdateBounds(taxisID1, &date_lb, &date_ub);
-	      taxisInqVtimeBounds(taxisID1, &time_lb, &time_ub);
-	      if ( nsets == 0 )
-		{ vdate_lb = date_lb; vtime_lb = time_lb; }
-	    }
-	  else
-	    {
-	      if ( nsets == 0 )
-		{ vdate_lb = vdate; vtime_lb = vtime; }
-	    }
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
+	  vdate = dtlist_get_vdate(dtlist, nsets);
+	  vtime = dtlist_get_vtime(dtlist, nsets);
 
 	  if ( nsets == 0 ) SET_DATE(indate2, vdate, vtime);
 	  SET_DATE(indate1, vdate, vtime);
 
 	  if ( DATE_IS_NEQ(indate1, indate2, cmplen) ) break;
 
-	  if ( taxis_has_bounds )
-	    { vdate_ub = date_ub; vtime_ub = time_ub; }
-	  else
-	    { vdate_ub = vdate; vtime_ub = vtime; }
-
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
 	      streamInqRecord(streamID1, &varID, &levelID);
@@ -391,6 +370,7 @@ void *Timstat(void *argument)
 
       if ( cdoVerbose )
 	{
+	  char vdatestr[32], vtimestr[32];
 	  date2str(vdate0, vdatestr, sizeof(vdatestr));
 	  time2str(vtime0, vtimestr, sizeof(vtimestr));
 	  cdoPrint("%s %s  vfrac = %g, nsets = %d", vdatestr, vtimestr, vfrac, nsets);
@@ -429,18 +409,12 @@ void *Timstat(void *argument)
 	      }
 	  }
 
-      taxisDefVdate(taxisID2, vdate0);
-      taxisDefVtime(taxisID2, vtime0);
-      taxisDefVdateBounds(taxisID2, vdate_lb, vdate_ub);
-      taxisDefVtimeBounds(taxisID2, vtime_lb, vtime_ub);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, nsets);
       streamDefTimestep(streamID2, otsID);
 
       if ( cdoDiag )
 	{
-	  taxisDefVdate(taxisID3, vdate0);
-	  taxisDefVtime(taxisID3, vtime0);
-	  taxisDefVdateBounds(taxisID3, vdate_lb, vdate_ub);
-	  taxisDefVtimeBounds(taxisID3, vtime_lb, vtime_ub);
+	  dtlist_stat_taxisDefTimestep(dtlist, taxisID3, nsets);
 	  streamDefTimestep(streamID3, otsID);
 	}
 
@@ -472,6 +446,8 @@ void *Timstat(void *argument)
   field_free(samp1, vlistID1);
   if ( lvarstd ) field_free(vars2, vlistID1);
 
+  dtlist_delete(dtlist);
+
   if ( cdoDiag ) streamClose(streamID3);
   streamClose(streamID2);
   streamClose(streamID1);
diff --git a/src/Timstat2.c b/src/Timstat2.c
index 415988d..94e3fd1 100644
--- a/src/Timstat2.c
+++ b/src/Timstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -107,66 +107,56 @@ int covariance_t(long gridsize, double missval1, double missval2, int *nofvals,
 
 void *Timstat2(void *argument)
 {
-  int operatorID;
-  int operfunc;
   int nwork = 0;
-  int streamID1, streamID2, streamID3;
   int vdate = 0, vtime = 0;
-  int nrecs, nrecs2, nrecs3, nvars, nlevs;
+  int nrecs2, nlevs;
   long i, gridsize;
-  int tsID;
   int varID, recID, levelID, gridID;
   int nmiss;
-  int *recVarID, *recLevelID;
-  int vlistID1, vlistID2, vlistID3;
-  int taxisID1, taxisID2, taxisID3;
   double missval1, missval2;
-  double ****work = NULL;
-  int ***nofvals = NULL;
-  double *array1 = NULL, *array2 = NULL;
 
   cdoInitialize(argument);
 
   cdoOperatorAdd("timcor",   func_cor,   0, NULL);
   cdoOperatorAdd("timcovar", func_covar, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
 
   if      ( operfunc == func_cor   ) nwork = 5;
   else if ( operfunc == func_covar ) nwork = 3;
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
  
-  nvars  = vlistNvars(vlistID1);
-  nrecs  = vlistNrecs(vlistID1);
-  nrecs3 = nrecs;
-  recVarID   = (int*) malloc(nrecs*sizeof(int));
-  recLevelID = (int*) malloc(nrecs*sizeof(int));
-
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = taxisDuplicate(taxisID1);
+  int nvars  = vlistNvars(vlistID1);
+  int nrecs  = vlistNrecs(vlistID1);
+  int nrecs3 = nrecs;
+  int *recVarID   = (int*) malloc(nrecs*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecs*sizeof(int));
+
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  //int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = taxisDuplicate(taxisID1);
  
   vlistDefTaxis(vlistID3, taxisID3);
-  streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+  int streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
 
   streamDefVlist(streamID3, vlistID3);
  
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1  = (double*) malloc(gridsize*sizeof(double));
-  array2  = (double*) malloc(gridsize*sizeof(double));
+  double *array1  = (double*) malloc(gridsize*sizeof(double));
+  double *array2  = (double*) malloc(gridsize*sizeof(double));
   				 
-  work    = (double ****) malloc(nvars*sizeof(double ***));
-  nofvals = (int ***) malloc(nvars*sizeof(int **));
+  double ****work = (double ****) malloc(nvars*sizeof(double ***));
+  int ***nofvals  = (int ***) malloc(nvars*sizeof(int **));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -191,7 +181,7 @@ void *Timstat2(void *argument)
 	}
     }
  
-  tsID=0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       vdate = taxisInqVdate(taxisID1);
diff --git a/src/Timstat3.c b/src/Timstat3.c
index feadd27..fee2eaf 100644
--- a/src/Timstat3.c
+++ b/src/Timstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -37,18 +37,14 @@
 void *Timstat3(void *argument)
 {
   int VARQUOT2TEST, MEANDIFF2TEST;
-  int operatorID;
-  int streamID[NIN], streamID3;
-  int vlistID[NIN], vlistID2 = -1, vlistID3 = -1;
+  int streamID[NIN];
+  int vlistID[NIN], vlistID2 = -1;
   int gridsize;
   int vdate = 0, vtime = 0;
-  int nrecs, nrecs3, nvars, nlevs ;
+  int nlevs;
   int i, iw, is;
-  int tsID;
   int varID, recID, levelID, gridID;
   int nmiss3;
-  int *recVarID, *recLevelID;
-  int taxisID1, taxisID3;
   double rconst, risk;
   double fnvals0, fnvals1;
   double missval, missval1, missval2;
@@ -66,12 +62,12 @@ void *Timstat3(void *argument)
   VARQUOT2TEST  = cdoOperatorAdd("varquot2test",  0, 0, NULL);
   MEANDIFF2TEST = cdoOperatorAdd("meandiff2test", 0, 0, NULL);
 
-  operatorID = cdoOperatorID();
+  int operatorID = cdoOperatorID();
 
   operatorInputArg("constant and risk (e.g. 0.05)");
   operatorCheckArgc(2);
-  rconst = atof(operatorArgv()[0]);
-  risk   = atof(operatorArgv()[1]);
+  rconst = parameter2double(operatorArgv()[0]);
+  risk   = parameter2double(operatorArgv()[1]);
 
   if ( operatorID == VARQUOT2TEST )
     {
@@ -94,20 +90,20 @@ void *Timstat3(void *argument)
 	}
     }
 
-  vlistID3 = vlistDuplicate(vlistID[0]);
+  int vlistID3 = vlistDuplicate(vlistID[0]);
 
   gridsize = vlistGridsizeMax(vlistID[0]);
-  nvars = vlistNvars(vlistID[0]);
-  nrecs = vlistNrecs(vlistID[0]);
-  nrecs3 = nrecs;
-  recVarID   = (int*) malloc(nrecs*sizeof(int));
-  recLevelID = (int*) malloc(nrecs*sizeof(int));
-
-  taxisID1 = vlistInqTaxis(vlistID[0]);
-  taxisID3 = taxisDuplicate(taxisID1);
+  int nvars = vlistNvars(vlistID[0]);
+  int nrecs = vlistNrecs(vlistID[0]);
+  int nrecs3 = nrecs;
+  int *recVarID   = (int*) malloc(nrecs*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecs*sizeof(int));
+
+  int taxisID1 = vlistInqTaxis(vlistID[0]);
+  int taxisID3 = taxisDuplicate(taxisID1);
  
   vlistDefTaxis(vlistID3, taxisID3);
-  streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+  int streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
 
   streamDefVlist(streamID3, vlistID3);
 
@@ -163,7 +159,7 @@ void *Timstat3(void *argument)
 	}
     }
  
-  tsID=0;
+  int tsID = 0;
   while ( TRUE )
     {
       for ( is = 0; is < NIN; ++is )
@@ -219,10 +215,10 @@ void *Timstat3(void *argument)
       tsID++;
     }
 
-  tsID = 0;
+
   taxisDefVdate(taxisID3, vdate);
   taxisDefVtime(taxisID3, vtime);
-  streamDefTimestep(streamID3, tsID);
+  streamDefTimestep(streamID3, 0);
 
   for ( recID = 0; recID < nrecs3; recID++ )
     {
diff --git a/src/Tinfo.c b/src/Tinfo.c
index 03fbe98..ef60e5e 100644
--- a/src/Tinfo.c
+++ b/src/Tinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2007-2012 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tocomplex.c b/src/Tocomplex.c
index 05fe39a..d106448 100644
--- a/src/Tocomplex.c
+++ b/src/Tocomplex.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Transpose.c b/src/Transpose.c
index d2477b0..9b2af4c 100644
--- a/src/Transpose.c
+++ b/src/Transpose.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Trend.c b/src/Trend.c
index c517564..75ea5aa 100644
--- a/src/Trend.c
+++ b/src/Trend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Trms.c b/src/Trms.c
index b7c5aee..63c2e35 100644
--- a/src/Trms.c
+++ b/src/Trms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tstepcount.c b/src/Tstepcount.c
index 99aac1c..a7cf9c6 100644
--- a/src/Tstepcount.c
+++ b/src/Tstepcount.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -77,7 +77,7 @@ void *Tstepcount(void *argument)
 
   cdoInitialize(argument);
 
-  if ( operatorArgc() == 1 ) refval = atof(operatorArgv()[0]);
+  if ( operatorArgc() == 1 ) refval = parameter2double(operatorArgv()[0]);
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/Vardup.c b/src/Vardup.c
index b13774b..d48d366 100644
--- a/src/Vardup.c
+++ b/src/Vardup.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -62,7 +62,7 @@ void *Vardup(void *argument)
   else if ( operatorID == PARMUL )
     {
       operatorInputArg("number of multiply");
-      nmul = atoi(operatorArgv()[0]);
+      nmul = parameter2int(operatorArgv()[0]);
     }
   else
     cdoAbort("operator not implemented!");
diff --git a/src/Vargen.c b/src/Vargen.c
index a7bc13d..9f5c503 100644
--- a/src/Vargen.c
+++ b/src/Vargen.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,7 @@
 #include "pstream.h"
 #include "list.h"
 #include "grid.h"
+#include "constants.h"
 #include "stdnametable.h"
 
 
@@ -63,9 +64,8 @@
 #define T_DELTA          (75.0)
 #define SCALEHEIGHT   (10000.0)   /* [m] */
 #define P_ZERO         (1013.25)  /* surface pressure [hPa] */
-#define C_EARTH_GRAV      (9.80665)
-#define C_R             (287.05)  /*  specific gas constant for air */
-static double TMP4PRESSURE = (C_EARTH_GRAV*SCALEHEIGHT)/(C_R*T_ZERO);
+#define CC_R             (287.05)  /* specific gas constant for air */
+static double TMP4PRESSURE = (C_EARTH_GRAV*SCALEHEIGHT)/(CC_R*T_ZERO);
 
 static double
 std_atm_temperatur(double height)
@@ -127,8 +127,7 @@ void *Vargen(void *argument)
       gridID   = cdoDefineGrid(gridfile);
       if ( operatorArgc() == 2 )
         {
-          long idum;
-          idum = atol(operatorArgv()[1]);
+          int idum = parameter2int(operatorArgv()[1]);
           if ( idum >= 0 && idum < 0x7FFFFFFF )
             seed = idum;
         }
@@ -145,7 +144,7 @@ void *Vargen(void *argument)
     {
       operatorInputArg(cdoOperatorEnter(operatorID));
       operatorCheckArgc(2);
-      rconst   = atof(operatorArgv()[0]);
+      rconst   = parameter2double(operatorArgv()[0]);
       gridfile = operatorArgv()[1];
       gridID   = cdoDefineGrid(gridfile);
     }
@@ -172,10 +171,10 @@ void *Vargen(void *argument)
       if ( operatorArgc() < 2 ) cdoAbort("Too few arguments!");
       if ( operatorArgc() > 3 ) cdoAbort("Too many arguments!");
 
-      rstart = atof(operatorArgv()[0]);
-      rstop  = atof(operatorArgv()[1]);
+      rstart = parameter2double(operatorArgv()[0]);
+      rstop  = parameter2double(operatorArgv()[1]);
       if ( operatorArgc() == 3 )
-        rinc = atof(operatorArgv()[2]);
+        rinc = parameter2double(operatorArgv()[2]);
       else
         rinc = 1;
 
diff --git a/src/Varrms.c b/src/Varrms.c
index cafc24a..c5e11d8 100644
--- a/src/Varrms.c
+++ b/src/Varrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Vertintap.c b/src/Vertintap.c
new file mode 100644
index 0000000..e8d7aea
--- /dev/null
+++ b/src/Vertintap.c
@@ -0,0 +1,464 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  See COPYING file for copying and redistribution conditions.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+*/
+
+/*
+   This module contains the following operators:
+
+      Vertint    ap2pl           Model air pressure level to pressure level interpolation
+*/
+
+
+#include <ctype.h>
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+#include "after_vertint.h"
+#include "list.h"
+#include "stdnametable.h"
+
+
+void *Vertintap(void *argument)
+{
+  enum {ECHAM_MODE, WMO_MODE};
+  enum {func_pl, func_hl};
+  enum {type_lin, type_log};
+  int recID, nrecs;
+  int i, k, offset;
+  int varID, levelID;
+  int zaxisIDp, zaxisIDh = -1, nzaxis;
+  int gridID, zaxisID;
+  int nplev, nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel;
+  int *vert_index = NULL;
+  int nvct;
+  int apressID = -1, dpressID = -1;
+  int tempID = -1;
+  int param;
+  //int sortlevels = TRUE;
+  int *pnmiss = NULL;
+  char paramstr[32];
+  char stdname[CDI_MAX_NAME];
+  double minval, maxval;
+  double missval;
+  double *plev = NULL, *vct = NULL;
+  double *single1, *single2;
+  double *ps_prog = NULL, *full_press = NULL, *dpress = NULL;
+  double *hyb_press = NULL;
+  int Extrapolate = 0;
+  int lhavevct;
+  int mono_level;
+  LIST *flist = listNew(FLT_LIST);
+
+  cdoInitialize(argument);
+
+  int AP2PL     = cdoOperatorAdd("ap2pl",     func_pl, type_lin, "pressure levels in pascal");
+  int AP2PLX    = cdoOperatorAdd("ap2plx",    func_pl, type_lin, "pressure levels in pascal");
+  int AP2PL_LP  = cdoOperatorAdd("ap2pl_lp",  func_pl, type_log, "pressure levels in pascal");
+  int AP2PLX_LP = cdoOperatorAdd("ap2plx_lp", func_pl, type_log, "pressure levels in pascal");
+
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
+  int opertype   = cdoOperatorF2(operatorID);
+
+  if ( operatorID == AP2PL || operatorID == AP2PL_LP )
+    {
+      char *envstr;
+      envstr = getenv("EXTRAPOLATE");
+
+      if ( envstr )
+	{
+	  if ( isdigit((int) envstr[0]) )
+	    {
+	      Extrapolate = atoi(envstr);
+	      if ( Extrapolate == 1 )
+		cdoPrint("Extrapolation of missing values enabled!");
+	    }
+	}
+    }
+  else if ( operatorID == AP2PLX || operatorID == AP2PLX_LP )
+    {
+      Extrapolate = 1;
+    }
+
+  operatorInputArg(cdoOperatorEnter(operatorID));
+
+  nplev = args2fltlist(operatorArgc(), operatorArgv(), flist);
+  plev  = (double *) listArrayPtr(flist);
+
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
+
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  int gridsize = vlist_check_gridsize(vlistID1);
+
+  if ( operfunc == func_hl )
+    zaxisIDp = zaxisCreate(ZAXIS_HEIGHT, nplev);
+  else
+    zaxisIDp = zaxisCreate(ZAXIS_PRESSURE, nplev);
+
+  zaxisDefLevels(zaxisIDp, plev);
+  nzaxis  = vlistNzaxis(vlistID1);
+  lhavevct = FALSE;
+  for ( i = 0; i < nzaxis; i++ )
+    {
+      /* mono_level = FALSE; */
+      mono_level = TRUE;
+      zaxisID = vlistZaxis(vlistID1, i);
+      nlevel  = zaxisInqSize(zaxisID);
+
+      if ( (zaxisInqType(zaxisID) == ZAXIS_HYBRID || zaxisInqType(zaxisID) == ZAXIS_HYBRID_HALF) &&
+	   nlevel > 1 )
+	{
+	  double *level;
+	  int l;
+	  level = (double*) malloc(nlevel*sizeof(double));
+	  zaxisInqLevels(zaxisID, level);
+	  for ( l = 0; l < nlevel; l++ )
+	    {
+	      if ( (l+1) != (int) (level[l]+0.5) ) break;
+	    }
+	  if ( l == nlevel ) mono_level = TRUE; 
+	  free(level);
+	}
+
+      if ( (zaxisInqType(zaxisID) == ZAXIS_HYBRID || zaxisInqType(zaxisID) == ZAXIS_HYBRID_HALF) &&
+	   nlevel > 1 && mono_level )
+	{
+	  nvct = zaxisInqVctSize(zaxisID);
+	  if ( nlevel == (nvct/2 - 1) )
+	    {
+	      if ( lhavevct == FALSE )
+		{
+		  lhavevct = TRUE;
+		  zaxisIDh = zaxisID;
+		  nhlev    = nlevel;
+		  nhlevf   = nhlev;
+		  nhlevh   = nhlevf + 1;
+	      
+		  vct = (double*) malloc(nvct*sizeof(double));
+		  zaxisInqVct(zaxisID, vct);
+
+		  vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
+		}
+	      else
+		{
+		  if ( memcmp(vct, zaxisInqVctPtr(zaxisID), nvct*sizeof(double)) == 0 )
+		    vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
+		}
+	    }
+	  else if ( nlevel == (nvct/2) )
+	    {
+	      if ( lhavevct == FALSE )
+		{
+		  lhavevct = TRUE;
+		  zaxisIDh = zaxisID;
+		  nhlev    = nlevel;
+		  nhlevf   = nhlev - 1;
+		  nhlevh   = nhlev;
+	      
+		  vct = (double*) malloc(nvct*sizeof(double));
+		  zaxisInqVct(zaxisID, vct);
+
+		  vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
+		}
+	      else
+		{
+		  if ( memcmp(vct, zaxisInqVctPtr(zaxisID), nvct*sizeof(double)) == 0 )
+		    vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
+		}
+	    }
+	}
+    }
+
+  int nvars = vlistNvars(vlistID1);
+
+  int vars[nvars];
+  double *vardata1[nvars];
+  double *vardata2[nvars];
+  int *varnmiss[nvars];
+  int varinterp[nvars];
+
+  int maxlev   = nhlevh > nplev ? nhlevh : nplev;
+
+  if ( Extrapolate == 0 )
+    pnmiss = (int*) malloc(nplev*sizeof(int));
+
+  // check levels
+  if ( zaxisIDh != -1 )
+    {
+      int nlev = zaxisInqSize(zaxisIDh);
+      if ( nlev != nhlev ) cdoAbort("Internal error, wrong numner of hybrid level!");
+      double levels[nlev];
+      zaxisInqLevels(zaxisIDh, levels);
+
+      for ( int ilev = 0; ilev < nlev; ++ilev )
+	{
+	  if ( (ilev+1) != (int)levels[ilev] )
+	    {
+	      //sortlevels = FALSE;
+	      break;
+	    }
+	}
+    }
+
+  if ( zaxisIDh != -1 && gridsize > 0 )
+    {
+      vert_index = (int*) malloc(gridsize*nplev*sizeof(int));
+      ps_prog    = (double*) malloc(gridsize*sizeof(double));
+      full_press = (double*) malloc(gridsize*nhlevf*sizeof(double));
+      dpress     = (double*) malloc(gridsize*nhlevf*sizeof(double));
+    }
+  else
+    cdoWarning("No 3D variable with hybrid sigma pressure coordinate found!");
+
+  if ( operfunc == func_hl )
+    {
+      double phlev[nplev];
+      height2pressure(phlev, plev, nplev);
+
+      if ( cdoVerbose )
+	for ( i = 0; i < nplev; ++i )
+	  cdoPrint("level = %d   height = %g   pressure = %g", i+1, plev[i], phlev[i]);
+
+      memcpy(plev, phlev, nplev*sizeof(double));
+    }
+
+  if ( opertype == type_log )
+    for ( k = 0; k < nplev; k++ ) plev[k] = log(plev[k]);
+
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      gridID   = vlistInqVarGrid(vlistID1, varID);
+      zaxisID  = vlistInqVarZaxis(vlistID1, varID);
+      nlevel   = zaxisInqSize(zaxisID);
+
+      param    = vlistInqVarParam(vlistID1, varID);
+
+      vlistInqVarStdname(vlistID1, varID, stdname);
+      strtolower(stdname);
+
+      if      ( strcmp(stdname, var_stdname(air_pressure))       == 0 ) apressID = varID; 
+      else if ( strcmp(stdname, var_stdname(pressure_thickness)) == 0 ) dpressID = varID; 
+      else if ( strcmp(stdname, var_stdname(air_temperature))    == 0 ) tempID = varID; 
+
+
+      if ( gridInqType(gridID) == GRID_SPECTRAL && zaxisInqType(zaxisID) == ZAXIS_HYBRID )
+	cdoAbort("Spectral data on model level unsupported!");
+
+      if ( gridInqType(gridID) == GRID_SPECTRAL )
+	cdoAbort("Spectral data unsupported!");
+
+      vardata1[varID] = (double*) malloc(gridsize*nlevel*sizeof(double));
+
+      if ( zaxisID == zaxisIDh ||
+	   (zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && (nlevel == nhlevh || nlevel == nhlevf)) )
+	{
+	  varinterp[varID] = TRUE;
+	  vardata2[varID]  = (double*) malloc(gridsize*nplev*sizeof(double));
+	  varnmiss[varID]  = (int*) malloc(maxlev*sizeof(int));
+	  memset(varnmiss[varID], 0, maxlev*sizeof(int));
+	}
+      else
+	{
+	  if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && nlevel > 1 )
+	    cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)",
+		       varID+1, paramstr, nlevel);
+	  varinterp[varID] = FALSE;
+	  vardata2[varID]  = vardata1[varID];
+	  varnmiss[varID]  = (int*) malloc(nlevel*sizeof(int));
+	}
+    }
+
+  if ( cdoVerbose )
+    {
+      cdoPrint("Found:");
+      if ( apressID  != -1 ) cdoPrint("  %s", var_stdname(air_pressure));
+      if ( dpressID  != -1 ) cdoPrint("  %s", var_stdname(pressure_thickness));
+      if ( tempID    != -1 ) cdoPrint("  %s", var_stdname(air_temperature));
+    }
+
+  if ( apressID == -1 )  cdoAbort("%s not found!", var_stdname(air_pressure));
+
+  for ( varID = 0; varID < nvars; ++varID )
+    {
+      if ( varinterp[varID] == TRUE && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+    }
+
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
+
+  int tsID = 0;
+  while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
+    {
+      for ( varID = 0; varID < nvars; ++varID ) vars[varID] = FALSE;
+      for ( varID = 0; varID < nvars; ++varID )
+	{
+	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+	  for ( levelID = 0; levelID < nlevel; levelID++ )
+	    varnmiss[varID][levelID] = 0;
+	}
+
+      taxisCopyTimestep(taxisID2, taxisID1);
+
+      streamDefTimestep(streamID2, tsID);
+
+      for ( recID = 0; recID < nrecs; recID++ )
+	{
+	  streamInqRecord(streamID1, &varID, &levelID);
+	  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
+	  nlevel   = zaxisInqSize(zaxisID);
+	  /*
+	  if ( sortlevels && zaxisIDh != -1 && zaxisID == zaxisIDh && nlevel == nhlev )
+	    {
+	      levelID = (int) (zaxisInqLevel(zaxisIDh, levelID)-1);
+	      printf("levelID %d\n", levelID);
+	    }
+	  */
+	  offset   = gridsize*levelID;
+	  single1  = vardata1[varID] + offset;
+
+	  streamReadRecord(streamID1, single1, &varnmiss[varID][levelID]);
+
+	  vars[varID] = TRUE;
+	}
+
+      for ( varID = 0; varID < nvars; varID++ )
+	if ( varinterp[varID] == TRUE ) vars[varID] = TRUE;
+
+      if ( zaxisIDh != -1 )
+	{
+	  if ( dpressID != -1 )
+	    {
+	      memcpy(dpress, vardata1[dpressID], gridsize*nhlevf*sizeof(double)); 
+	      for ( i = 0; i < gridsize; i++ )  ps_prog[i] = 0;
+	      for ( k = 0; k < nhlevf; ++k )
+		for ( i = 0; i < gridsize; i++ )
+		  ps_prog[i] += dpress[k*gridsize+i];
+	    }
+	  else
+	    {
+	      for ( i = 0; i < gridsize; i++ )  ps_prog[i] = 110000;
+	    }
+
+	  /* check range of ps_prog */
+	  minmaxval(gridsize, ps_prog, NULL, &minval, &maxval);
+	  if ( minval < MIN_PS || maxval > MAX_PS )
+	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
+
+	  memcpy(full_press, vardata1[apressID], gridsize*nhlevf*sizeof(double)); 
+
+	  if ( opertype == type_log )
+	    {
+	      for ( i = 0; i < gridsize; i++ ) ps_prog[i] = log(ps_prog[i]);
+
+	      for ( k = 0; k < nhlevf; k++ )
+		for ( i = 0; i < gridsize; i++ )
+		  full_press[k*gridsize+i] = log(full_press[k*gridsize+i]);
+	    }
+
+	  genind(vert_index, plev, full_press, gridsize, nplev, nhlevf);
+
+	  if ( Extrapolate == 0 )
+	    genindmiss(vert_index, plev, gridsize, nplev, ps_prog, pnmiss);
+	}
+
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  if ( vars[varID] )
+	    {
+	      gridID   = vlistInqVarGrid(vlistID1, varID);
+	      zaxisID  = vlistInqVarZaxis(vlistID1, varID);
+	      missval  = vlistInqVarMissval(vlistID1, varID);
+	      nlevel   = zaxisInqSize(zaxisID);
+	      if ( varinterp[varID] )
+		{
+		  if ( nlevel == nhlevf )
+		    {
+		      hyb_press = full_press;
+		    }
+		  else
+		    {
+		      param = vlistInqVarParam(vlistID1, varID);
+		      cdiParamToString(param, paramstr, sizeof(paramstr));
+		      cdoAbort("Number of hybrid level differ from full/half level (param=%s)!", paramstr);
+		    }
+
+		  for ( levelID = 0; levelID < nlevel; levelID++ )
+		    {
+		      if ( varnmiss[varID][levelID] )
+			cdoAbort("Missing values unsupported for this operator!");
+		    }
+
+		  interp_X(vardata1[varID], vardata2[varID], hyb_press,
+			   vert_index, plev, nplev, gridsize, nlevel, missval);
+		  
+		  if ( Extrapolate == 0 )
+		    memcpy(varnmiss[varID], pnmiss, nplev*sizeof(int));
+		}
+	    }
+	}
+
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  if ( vars[varID] )
+	    {
+	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
+	      for ( levelID = 0; levelID < nlevel; levelID++ )
+		{
+		  offset   = gridsize*levelID;
+		  single2  = vardata2[varID] + offset;
+		  streamDefRecord(streamID2, varID, levelID);
+		  streamWriteRecord(streamID2, single2, varnmiss[varID][levelID]);
+		}
+	    }
+	}
+
+      tsID++;
+    }
+
+  streamClose(streamID2);
+  streamClose(streamID1);
+
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      free(varnmiss[varID]);
+      free(vardata1[varID]);
+      if ( varinterp[varID] ) free(vardata2[varID]);
+    }
+
+  if ( pnmiss     ) free(pnmiss);
+
+  if ( ps_prog    ) free(ps_prog);
+  if ( vert_index ) free(vert_index);
+  if ( full_press ) free(full_press);
+  if ( dpress )     free(dpress);
+  if ( vct        ) free(vct);
+
+  listDelete(flist);
+
+  cdoFinish();
+
+  return (0);
+}
diff --git a/src/Vertint.c b/src/Vertintml.c
similarity index 79%
rename from src/Vertint.c
rename to src/Vertintml.c
index e0fd401..a107364 100644
--- a/src/Vertint.c
+++ b/src/Vertintml.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,31 +29,25 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 #include "list.h"
 #include "stdnametable.h"
+#include "constants.h"
 
-#define  C_EARTH_GRAV    (9.80665)
 
-void *Vertint(void *argument)
+void *Vertintml(void *argument)
 {
-  int ML2PL, ML2HL, ML2PLX, ML2HLX;
-  int ML2PL_LP, ML2HL_LP, ML2PLX_LP, ML2HLX_LP;
-  int operatorID;
   int mode;
   enum {ECHAM_MODE, WMO_MODE};
   enum {func_pl, func_hl};
   enum {type_lin, type_log};
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
-  int gridsize, ngp = 0;
+  int gridsize;
   int recID, nrecs;
   int i, k, offset;
   int tsID, varID, levelID;
-  int nvars;
   int zaxisIDp, zaxisIDh = -1, nzaxis;
-  int ngrids, gridID, zaxisID;
-  int nplev, nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel, maxlev;
+  int gridID, zaxisID;
+  int nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel;
   int *vert_index = NULL;
   int nvct;
   int sgeopot_needed = FALSE;
@@ -61,43 +55,38 @@ void *Vertint(void *argument)
   int code, param;
   int pnum, pcat, pdis;
   //int sortlevels = TRUE;
-  int **varnmiss = NULL, *pnmiss = NULL;
-  int *varinterp = NULL;
+  int *pnmiss = NULL;
   char paramstr[32];
   char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
-  int *vars = NULL;
   double minval, maxval;
   double missval;
-  double *plev = NULL, *phlev = NULL, *vct = NULL;
+  double *vct = NULL;
   double *rvct = NULL; /* reduced VCT for LM */
   double *single1, *single2;
-  double **vardata1 = NULL, **vardata2 = NULL;
   double *sgeopot = NULL, *ps_prog = NULL, *full_press = NULL, *half_press = NULL;
   double *hyb_press = NULL;
   int Extrapolate = 0;
-  int taxisID1, taxisID2;
   int lhavevct;
   int mono_level;
   int instNum, tableNum;
   int useTable;
-  int operfunc, opertype;
   gribcode_t gribcodes = {0};
   LIST *flist = listNew(FLT_LIST);
 
   cdoInitialize(argument);
 
-  ML2PL  = cdoOperatorAdd("ml2pl",  func_pl, type_lin, "pressure levels in pascal");
-  ML2PLX = cdoOperatorAdd("ml2plx", func_pl, type_lin, "pressure levels in pascal");
-  ML2HL  = cdoOperatorAdd("ml2hl",  func_hl, type_lin, "height levels in meter");
-  ML2HLX = cdoOperatorAdd("ml2hlx", func_hl, type_lin, "height levels in meter");
-  ML2PL_LP  = cdoOperatorAdd("ml2pl_lp",  func_pl, type_log, "pressure levels in pascal");
-  ML2PLX_LP = cdoOperatorAdd("ml2plx_lp", func_pl, type_log, "pressure levels in pascal");
-  ML2HL_LP  = cdoOperatorAdd("ml2hl_lp",  func_hl, type_log, "height levels in meter");
-  ML2HLX_LP = cdoOperatorAdd("ml2hlx_lp", func_hl, type_log, "height levels in meter");
+  int ML2PL     = cdoOperatorAdd("ml2pl",     func_pl, type_lin, "pressure levels in pascal");
+  int ML2PLX    = cdoOperatorAdd("ml2plx",    func_pl, type_lin, "pressure levels in pascal");
+  int ML2HL     = cdoOperatorAdd("ml2hl",     func_hl, type_lin, "height levels in meter");
+  int ML2HLX    = cdoOperatorAdd("ml2hlx",    func_hl, type_lin, "height levels in meter");
+  int ML2PL_LP  = cdoOperatorAdd("ml2pl_lp",  func_pl, type_log, "pressure levels in pascal");
+  int ML2PLX_LP = cdoOperatorAdd("ml2plx_lp", func_pl, type_log, "pressure levels in pascal");
+  int ML2HL_LP  = cdoOperatorAdd("ml2hl_lp",  func_hl, type_log, "height levels in meter");
+  int ML2HLX_LP = cdoOperatorAdd("ml2hlx_lp", func_hl, type_log, "height levels in meter");
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
-  opertype = cdoOperatorF2(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc   = cdoOperatorF1(operatorID);
+  int opertype   = cdoOperatorF2(operatorID);
 
   if ( operatorID == ML2PL || operatorID == ML2HL || operatorID == ML2PL_LP || operatorID == ML2HL_LP )
     {
@@ -121,39 +110,32 @@ void *Vertint(void *argument)
 
   operatorInputArg(cdoOperatorEnter(operatorID));
 
-  nplev = args2fltlist(operatorArgc(), operatorArgv(), flist);
-  plev  = (double *) listArrayPtr(flist);
-
-  streamID1 = streamOpenRead(cdoStreamName(0));
-
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
-
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
-  vlistDefTaxis(vlistID2, taxisID2);
-
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
+  int nplev = 0;
+  double *plev = NULL;
+  if ( operatorArgc() == 1 && strcmp(operatorArgv()[0], "default") == 0 )
     {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
+      double stdlev[] = {100000, 92500, 85000, 77500, 70000, 60000, 50000, 40000, 30000, 25000, 20000,
+                         15000, 10000, 7000, 5000, 3000, 2000, 1000, 700, 500, 300, 200, 100, 50, 20, 10};
+      nplev = sizeof(stdlev)/sizeof(*stdlev);
+      plev  = (double *) malloc(nplev*sizeof(double));
+      for ( i = 0; i < nplev; ++i ) plev[i] = stdlev[i];
     }
-
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
+  else
     {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
+      nplev = args2fltlist(operatorArgc(), operatorArgv(), flist);
+      plev  = (double *) listArrayPtr(flist);
     }
+  
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
+
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  gridsize = vlist_check_gridsize(vlistID1);
 
   if ( operfunc == func_hl )
     zaxisIDp = zaxisCreate(ZAXIS_HEIGHT, nplev);
@@ -286,15 +268,15 @@ void *Vertint(void *argument)
 	}
     }
 
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
 
-  vars      = (int*) malloc(nvars*sizeof(int));
-  vardata1  = (double**) malloc(nvars*sizeof(double*));
-  vardata2  = (double**) malloc(nvars*sizeof(double*));
-  varnmiss  = (int**) malloc(nvars*sizeof(int*));
-  varinterp = (int*) malloc(nvars*sizeof(int));
+  int vars[nvars];
+  double *vardata1[nvars];
+  double *vardata2[nvars];
+  int *varnmiss[nvars];
+  int varinterp[nvars];
 
-  maxlev   = nhlevh > nplev ? nhlevh : nplev;
+  int maxlev   = nhlevh > nplev ? nhlevh : nplev;
 
   if ( Extrapolate == 0 )
     pnmiss = (int*) malloc(nplev*sizeof(int));
@@ -317,27 +299,26 @@ void *Vertint(void *argument)
 	}
     }
 
-  if ( zaxisIDh != -1 && ngp > 0 )
+  if ( zaxisIDh != -1 && gridsize > 0 )
     {
-      vert_index = (int*) malloc(ngp*nplev*sizeof(int));
-      ps_prog    = (double*) malloc(ngp*sizeof(double));
-      full_press = (double*) malloc(ngp*nhlevf*sizeof(double));
-      half_press = (double*) malloc(ngp*nhlevh*sizeof(double));
+      vert_index = (int*) malloc(gridsize*nplev*sizeof(int));
+      ps_prog    = (double*) malloc(gridsize*sizeof(double));
+      full_press = (double*) malloc(gridsize*nhlevf*sizeof(double));
+      half_press = (double*) malloc(gridsize*nhlevh*sizeof(double));
     }
   else
     cdoWarning("No 3D variable with hybrid sigma pressure coordinate found!");
 
   if ( operfunc == func_hl )
     {
-      phlev = (double*) malloc(nplev*sizeof(double));
-      h2p(phlev, plev, nplev);
+      double phlev[nplev];
+      height2pressure(phlev, plev, nplev);
 
       if ( cdoVerbose )
 	for ( i = 0; i < nplev; ++i )
 	  cdoPrint("level = %d   height = %g   pressure = %g", i+1, plev[i], phlev[i]);
 
       memcpy(plev, phlev, nplev*sizeof(double));
-      free(phlev);
     }
 
   if ( opertype == type_log )
@@ -360,7 +341,7 @@ void *Vertint(void *argument)
     {
       gridID   = vlistInqVarGrid(vlistID1, varID);
       zaxisID  = vlistInqVarZaxis(vlistID1, varID);
-      gridsize = gridInqSize(gridID);
+      // gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
       instNum  = institutInqCenter(vlistInqVarInstitut(vlistID1, varID));
       tableNum = tableInqNum(vlistInqVarTable(vlistID1, varID));
@@ -481,7 +462,7 @@ void *Vertint(void *argument)
 
   if ( zaxisIDh != -1 && sgeopot_needed )
     {
-      sgeopot = (double*) malloc(ngp*sizeof(double));
+      sgeopot = (double*) malloc(gridsize*sizeof(double));
       if ( sgeopotID == -1 )
 	{
 	  if ( geopotID == -1 )
@@ -489,7 +470,7 @@ void *Vertint(void *argument)
 	  else
 	    cdoPrint("%s not found - using bottom layer of %s!", var_stdname(surface_geopotential), var_stdname(geopotential));
 
-	  memset(sgeopot, 0, ngp*sizeof(double));
+	  memset(sgeopot, 0, gridsize*sizeof(double));
 	}
     }
 
@@ -513,7 +494,7 @@ void *Vertint(void *argument)
 	cdoPrint("using %s", var_stdname(surface_air_pressure));
     }
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
@@ -529,7 +510,7 @@ void *Vertint(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+	  //gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  zaxisID  = vlistInqVarZaxis(vlistID1, varID);
 	  nlevel   = zaxisInqSize(zaxisID);
 	  /*
@@ -551,51 +532,51 @@ void *Vertint(void *argument)
 	  if ( sgeopot_needed )
 	    {
 	      if ( sgeopotID != -1 )
-		memcpy(sgeopot, vardata1[sgeopotID], ngp*sizeof(double));
+		memcpy(sgeopot, vardata1[sgeopotID], gridsize*sizeof(double));
 	      else if ( geopotID != -1 )
-		memcpy(sgeopot, vardata1[geopotID]+ngp*(nhlevf-1), ngp*sizeof(double));
+		memcpy(sgeopot, vardata1[geopotID]+gridsize*(nhlevf-1), gridsize*sizeof(double));
 
 	      /* check range of surface geopot */
 	      if ( sgeopotID != -1 || geopotID != -1 )
 		{
-		  minmaxval(ngp, sgeopot, NULL, &minval, &maxval);
+		  minmaxval(gridsize, sgeopot, NULL, &minval, &maxval);
 		  if ( minval < MIN_FIS || maxval > MAX_FIS )
 		    cdoWarning("Surface geopotential out of range (min=%g max=%g)!", minval, maxval);
-		  if ( ngp > 1 && minval >= 0 && maxval <= 9000 )
+		  if ( gridsize > 1 && minval >= 0 && maxval <= 9000 )
 		    cdoWarning("Surface geopotential has an unexpected range (min=%g max=%g)!", minval, maxval);
 		}
 	    }
 
 	  if ( lnpsID != -1 )
-	    for ( i = 0; i < ngp; i++ ) ps_prog[i] = exp(vardata1[lnpsID][i]);
+	    for ( i = 0; i < gridsize; i++ ) ps_prog[i] = exp(vardata1[lnpsID][i]);
 	  else if ( psID != -1 )
-	    memcpy(ps_prog, vardata1[psID], ngp*sizeof(double));
+	    memcpy(ps_prog, vardata1[psID], gridsize*sizeof(double));
 
 	  /* check range of ps_prog */
-	  minmaxval(ngp, ps_prog, NULL, &minval, &maxval);
+	  minmaxval(gridsize, ps_prog, NULL, &minval, &maxval);
 	  if ( minval < MIN_PS || maxval > MAX_PS )
 	    cdoWarning("Surface pressure out of range (min=%g max=%g)!", minval, maxval);
 
 
-	  presh(full_press, half_press, vct, ps_prog, nhlevf, ngp);
+	  presh(full_press, half_press, vct, ps_prog, nhlevf, gridsize);
 
 	  if ( opertype == type_log )
 	    {
-	      for ( i = 0; i < ngp; i++ ) ps_prog[i] = log(ps_prog[i]);
+	      for ( i = 0; i < gridsize; i++ ) ps_prog[i] = log(ps_prog[i]);
 
 	      for ( k = 0; k < nhlevh; k++ )
-		for ( i = 0; i < ngp; i++ )
-		  half_press[k*ngp+i] = log(half_press[k*ngp+i]);
+		for ( i = 0; i < gridsize; i++ )
+		  half_press[k*gridsize+i] = log(half_press[k*gridsize+i]);
 
 	      for ( k = 0; k < nhlevf; k++ )
-		for ( i = 0; i < ngp; i++ )
-		  full_press[k*ngp+i] = log(full_press[k*ngp+i]);
+		for ( i = 0; i < gridsize; i++ )
+		  full_press[k*gridsize+i] = log(full_press[k*gridsize+i]);
 	    }
 
-	  genind(vert_index, plev, full_press, ngp, nplev, nhlevf);
+	  genind(vert_index, plev, full_press, gridsize, nplev, nhlevf);
 
 	  if ( Extrapolate == 0 )
-	    genindmiss(vert_index, plev, ngp, nplev, ps_prog, pnmiss);
+	    genindmiss(vert_index, plev, gridsize, nplev, ps_prog, pnmiss);
 	}
 
       for ( varID = 0; varID < nvars; varID++ )
@@ -605,7 +586,7 @@ void *Vertint(void *argument)
 	      gridID   = vlistInqVarGrid(vlistID1, varID);
 	      zaxisID  = vlistInqVarZaxis(vlistID1, varID);
 	      missval  = vlistInqVarMissval(vlistID1, varID);
-	      gridsize = gridInqSize(gridID);
+	      //gridsize = gridInqSize(gridID);
 	      nlevel   = zaxisInqSize(zaxisID);
 	      if ( varinterp[varID] )
 		{
@@ -657,21 +638,21 @@ void *Vertint(void *argument)
 
 		      interp_T(sgeopot, vardata1[varID], vardata2[varID],
 			       full_press, half_press, vert_index,
-			       plev, nplev, ngp, nlevel, missval);
+			       plev, nplev, gridsize, nlevel, missval);
 		    }
 		  else if ( varID == gheightID )
 		    {
-		      for ( i = 0; i < ngp; ++i )
-			vardata1[varID][ngp*nlevel+i] = sgeopot[i]/C_EARTH_GRAV;
+		      for ( i = 0; i < gridsize; ++i )
+			vardata1[varID][gridsize*nlevel+i] = sgeopot[i]/PlanetGrav;
 
 		      interp_Z(sgeopot, vardata1[varID], vardata2[varID],
 			       full_press, half_press, vert_index, vardata1[tempID],
-			       plev, nplev, ngp, nlevel, missval);
+			       plev, nplev, gridsize, nlevel, missval);
 		    }
 		  else
 		    {
 		      interp_X(vardata1[varID], vardata2[varID], hyb_press,
-			       vert_index, plev, nplev, ngp, nlevel, missval);
+			       vert_index, plev, nplev, gridsize, nlevel, missval);
 		    }
 		  
 		  if ( Extrapolate == 0 )
@@ -687,7 +668,7 @@ void *Vertint(void *argument)
 	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
 		{
-		  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
+		  //gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 		  offset   = gridsize*levelID;
 		  single2  = vardata2[varID] + offset;
 		  streamDefRecord(streamID2, varID, levelID);
@@ -709,12 +690,6 @@ void *Vertint(void *argument)
       if ( varinterp[varID] ) free(vardata2[varID]);
     }
 
-  free(varinterp);
-  free(varnmiss);
-  free(vardata2);
-  free(vardata1);
-  free(vars);
-
   if ( pnmiss     ) free(pnmiss);
 
   if ( sgeopot    ) free(sgeopot);
diff --git a/src/Vertstat.c b/src/Vertstat.c
index e041f93..859e200 100644
--- a/src/Vertstat.c
+++ b/src/Vertstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
       Vertstat   vertmin         Vertical minimum
       Vertstat   vertmax         Vertical maximum
       Vertstat   vertsum         Vertical sum
+      Vertstat   vertint         Vertical integral
       Vertstat   vertmean        Vertical mean
       Vertstat   vertavg         Vertical average
       Vertstat   vertvar         Vertical variance
@@ -34,70 +35,223 @@
 #include "pstream.h"
 
 
+#define IS_SURFACE_LEVEL(zaxisID)  (zaxisInqType(zaxisID) == ZAXIS_SURFACE && zaxisInqSize(zaxisID) == 1)
+
+static
+int getSurfaceID(int vlistID)
+{
+  int surfID = -1;
+  int zaxisID;
+  int nzaxis = vlistNzaxis(vlistID);
+
+  for ( int index = 0; index < nzaxis; ++index )
+    {
+      zaxisID = vlistZaxis(vlistID, index);
+      if ( IS_SURFACE_LEVEL(zaxisID) )
+	{
+	  surfID = vlistZaxis(vlistID, index);
+	  break;
+	}
+    }
+
+  if ( surfID == -1 ) surfID = zaxisCreate(ZAXIS_SURFACE, 1);
+
+  return surfID;
+}
+
+static
+void setSurfaceID(int vlistID, int surfID)
+{
+  int zaxisID;
+  int nzaxis = vlistNzaxis(vlistID);
+
+  for ( int index = 0; index < nzaxis; ++index )
+    {
+      zaxisID = vlistZaxis(vlistID, index);
+      if ( zaxisID != surfID || !IS_SURFACE_LEVEL(zaxisID) )
+	vlistChangeZaxisIndex(vlistID, index, surfID);
+    }
+}
+
+
+void genLayerBounds(int nlev, double *levels, double *lbounds, double *ubounds)
+{
+  if ( nlev == 1 )
+    {
+      lbounds[0] = 0.;
+      ubounds[0] = 1.;
+    }
+  else
+    {
+      lbounds[0]      = levels[0];
+      ubounds[nlev-1] = levels[nlev-1];
+      for ( int i = 0; i < nlev-1; ++i )
+        {
+          double bound = 0.5*(levels[i] + levels[i+1]);
+          lbounds[i+1] = bound;
+          ubounds[i]   = bound;
+        }
+    }
+}
+
+static
+int getLayerThickness(int genbounds, int index, int zaxisID, int nlev, double *thickness, double *weights)
+{
+  int status = 0;
+  int i;
+  double *levels  = (double *) malloc(nlev*sizeof(double));
+  double *lbounds = (double *) malloc(nlev*sizeof(double));
+  double *ubounds = (double *) malloc(nlev*sizeof(double));
+
+  zaxisInqLevels(zaxisID, levels);
+  if ( genbounds )
+    {
+      status = 2;
+      genLayerBounds(nlev, levels, lbounds, ubounds);
+    }
+  else if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      status = 1;
+      zaxisInqLbounds(zaxisID, lbounds);
+      zaxisInqUbounds(zaxisID, ubounds);
+    }
+  else
+    {
+      for ( i = 0; i < nlev; ++i )
+	{
+	  lbounds[i] = 0.;
+	  ubounds[i] = 1.;
+	}
+    }
+  
+  for ( i = 0; i < nlev; ++i ) thickness[i] = fabs(ubounds[i]-lbounds[i]);
+
+  double lsum = 0;
+  for ( i = 0; i < nlev; ++i ) lsum += thickness[i];
+
+  for ( i = 0; i < nlev; ++i ) weights[i] = thickness[i];
+  
+  for ( i = 0; i < nlev; ++i ) weights[i] /= (lsum/nlev);
+
+  double wsum = 0;
+  for ( i = 0; i < nlev; ++i ) wsum += weights[i];
+
+  if ( cdoVerbose )
+    {
+      cdoPrint("zaxisID=%d  nlev=%d  layersum=%g  weightsum=%g", index, nlev, lsum, wsum);
+      printf("         level     bounds   thickness  weight\n");
+      for ( i = 0; i < nlev; ++i )
+	printf("   %3d  %6g  %6g/%-6g  %6g  %6g\n", i+1, levels[i], lbounds[i], ubounds[i], thickness[i], weights[i]);
+    }
+
+  free(levels);
+  free(lbounds);
+  free(ubounds);
+
+  return status;
+}
+
+
 void *Vertstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
-  int gridsize;
   int recID, nrecs;
   int gridID;
   int i;
-  int tsID, varID, levelID;
-  int nmiss, nvars;
-  int zaxisID, nzaxis;
+  int varID, levelID;
+  int nmiss;
   double missval;
-  field_t *vars1 = NULL, *vars2 = NULL, *samp1 = NULL;
-  field_t field;
-  int taxisID1, taxisID2;
+  typedef struct {
+    int zaxisID;
+    int status;
+    int numlevel;
+    double *thickness;
+    double *weights;
+  }
+  vert_t;
 
   cdoInitialize(argument);
 
-  cdoOperatorAdd("vertmin",  func_min,  0, NULL);
-  cdoOperatorAdd("vertmax",  func_max,  0, NULL);
-  cdoOperatorAdd("vertsum",  func_sum,  0, NULL);
-  cdoOperatorAdd("vertmean", func_mean, 0, NULL);
-  cdoOperatorAdd("vertavg",  func_avg,  0, NULL);
-  cdoOperatorAdd("vertvar",  func_var,  0, NULL);
-  cdoOperatorAdd("vertstd",  func_std,  0, NULL);
+                 cdoOperatorAdd("vertmin",  func_min,  0, NULL);
+                 cdoOperatorAdd("vertmax",  func_max,  0, NULL);
+                 cdoOperatorAdd("vertsum",  func_sum,  0, NULL);
+  int VERTINT  = cdoOperatorAdd("vertint",  func_sum,  1, NULL);
+  int VERTMEAN = cdoOperatorAdd("vertmean", func_mean, 1, NULL);
+  int VERTAVG  = cdoOperatorAdd("vertavg",  func_avg,  1, NULL);
+                 cdoOperatorAdd("vertvar",  func_var,  0, NULL);
+                 cdoOperatorAdd("vertstd",  func_std,  0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
+  int operatorID  = cdoOperatorID();
+  int operfunc    = cdoOperatorF1(operatorID);
+  int needWeights = cdoOperatorF2(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
   vlistClearFlag(vlistID1);
-  nvars = vlistNvars(vlistID1);
+  int nvars = vlistNvars(vlistID1);
   for ( varID = 0; varID < nvars; varID++ )
     vlistDefFlag(vlistID1, varID, 0, TRUE);
 
-  vlistID2 = vlistCreate();
+  int vlistID2 = vlistCreate();
   vlistCopyFlag(vlistID2, vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  zaxisID = zaxisCreate(ZAXIS_SURFACE, 1);
-  nzaxis  = vlistNzaxis(vlistID1);
-  for ( i = 0; i < nzaxis; i++ )
-    if ( zaxisInqSize(vlistZaxis(vlistID1, i)) > 1 )
-      vlistChangeZaxisIndex(vlistID2, i, zaxisID);
+  int surfID = getSurfaceID(vlistID1);
+  setSurfaceID(vlistID2, surfID);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int nzaxis = vlistNzaxis(vlistID1);
+  int nlev, zaxisID;
+  vert_t vert[nzaxis];
+  if ( needWeights )
+    {
+      int genbounds = FALSE;
+      unsigned npar = operatorArgc();
+      if ( npar > 0 )
+	{
+	  char **parnames = operatorArgv();
+
+	  if ( cdoVerbose )
+	    for ( unsigned i = 0; i < npar; i++ )
+	      cdoPrint("key %d = %s", i+1, parnames[i]);
+
+	  if ( strcmp(parnames[0], "genbounds") == 0 ) genbounds = TRUE;
+	  else cdoAbort("Parameter >%s< unsupported! Supported parameter are: genbounds", parnames[0]);
+	}
+      
+      for ( int index = 0; index < nzaxis; ++index )
+	{
+	  zaxisID = vlistZaxis(vlistID1, index);
+	  nlev = zaxisInqSize(zaxisID);
+	  vert[index].numlevel = 0;
+	  vert[index].status   = 0;
+	  vert[index].zaxisID  = zaxisID;
+	  // if ( nlev > 1 )
+	    {
+	      vert[index].numlevel = nlev;
+	      vert[index].thickness = (double *) malloc(nlev*sizeof(double));
+	      vert[index].weights = (double *) malloc(nlev*sizeof(double));
+	      vert[index].status = getLayerThickness(genbounds, index, zaxisID, nlev, vert[index].thickness, vert[index].weights); 
+	    }
+	}
+    }
+
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
+  field_t field;
   field_init(&field);
   field.ptr = (double*) malloc(gridsize*sizeof(double));
 
-  vars1 = (field_t*) malloc(nvars*sizeof(field_t));
-  samp1 = (field_t*) malloc(nvars*sizeof(field_t));
+  field_t *vars1 = (field_t*) malloc(nvars*sizeof(field_t));
+  field_t *samp1 = (field_t*) malloc(nvars*sizeof(field_t));
+  field_t *vars2 = NULL;
   if ( operfunc == func_std || operfunc == func_var )
     vars2 = (field_t*) malloc(nvars*sizeof(field_t));
 
@@ -105,11 +259,13 @@ void *Vertstat(void *argument)
     {
       gridID   = vlistInqVarGrid(vlistID1, varID);
       gridsize = gridInqSize(gridID);
+      zaxisID  = vlistInqVarZaxis(vlistID1, varID);
       missval  = vlistInqVarMissval(vlistID1, varID);
 
       field_init(&vars1[varID]);
       field_init(&samp1[varID]);
       vars1[varID].grid    = gridID;
+      vars1[varID].zaxis   = zaxisID;
       vars1[varID].nsamp   = 0;
       vars1[varID].nmiss   = 0;
       vars1[varID].missval = missval;
@@ -128,7 +284,7 @@ void *Vertstat(void *argument)
 	}
     }
 
-  tsID = 0;
+  int tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
       taxisCopyTimestep(taxisID2, taxisID1);
@@ -138,26 +294,57 @@ void *Vertstat(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
+
           vars1[varID].nsamp++;
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+	  gridsize = gridInqSize(vars1[varID].grid);
+	  zaxisID  = vars1[varID].zaxis;
+	  nlev = zaxisInqSize(zaxisID);
+
+	  double layer_weight = 1.0;
+	  double layer_thickness = 1.0;
+	  if ( needWeights )
+	    {
+	      for ( int index = 0; index < nzaxis; ++index )
+		if ( vert[index].zaxisID == zaxisID )
+		  {		    
+		    if ( vert[index].status == 0 && tsID == 0 && levelID == 0 && nlev > 1 )
+		      {
+			char varname[CDI_MAX_NAME];
+			vlistInqVarName(vlistID1, varID, varname);
+			cdoWarning("Layer bounds not available, using constant vertical weights for variable %s!", varname);
+		      }
+		    else
+		      {
+			layer_weight    = vert[index].weights[levelID];
+			layer_thickness = vert[index].thickness[levelID];
+		      }
+
+		    break;
+		  }
+	    }
+
 	  if ( levelID == 0 )
 	    {
 	      streamReadRecord(streamID1, vars1[varID].ptr, &nmiss);
 	      vars1[varID].nmiss = nmiss;
 
+	      if ( operatorID == VERTINT && IS_NOT_EQUAL(layer_thickness, 1.0) ) farcmul(&vars1[varID], layer_thickness);
+	      if ( (operatorID == VERTMEAN || operatorID == VERTAVG) && IS_NOT_EQUAL(layer_weight, 1.0) )
+		farcmul(&vars1[varID], layer_weight);
+
 	      if ( operfunc == func_std || operfunc == func_var )
 		farmoq(&vars2[varID], vars1[varID]);
 
-	      if ( nmiss > 0 || samp1[varID].ptr )
+	      if ( nmiss > 0 || samp1[varID].ptr || needWeights )
 		{
 		  if ( samp1[varID].ptr == NULL )
-		    samp1[varID].ptr = (double*) malloc(gridsize*sizeof(double));
+		    samp1[varID].ptr = (double *) malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[varID].ptr[i], vars1[varID].missval) )
-		      samp1[varID].ptr[i] = 0;
+		      samp1[varID].ptr[i] = 0.;
 		    else
-		      samp1[varID].ptr[i] = 1;
+		      samp1[varID].ptr[i] = layer_weight;
 		}
 	    }
 	  else
@@ -166,6 +353,10 @@ void *Vertstat(void *argument)
 	      field.grid    = vars1[varID].grid;
 	      field.missval = vars1[varID].missval;
 
+	      if ( operatorID == VERTINT && IS_NOT_EQUAL(layer_thickness, 1.0) ) farcmul(&field, layer_thickness);
+	      if ( (operatorID == VERTMEAN || operatorID == VERTAVG) && IS_NOT_EQUAL(layer_weight, 1.0) )
+		 farcmul(&field, layer_weight);
+
 	      if ( field.nmiss > 0 || samp1[varID].ptr )
 		{
 		  if ( samp1[varID].ptr == NULL )
@@ -177,7 +368,7 @@ void *Vertstat(void *argument)
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( !DBL_IS_EQUAL(field.ptr[i], vars1[varID].missval) )
-		      samp1[varID].ptr[i]++;
+		      samp1[varID].ptr[i] += layer_weight;
 		}
 
 	      if ( operfunc == func_std || operfunc == func_var )
@@ -244,6 +435,10 @@ void *Vertstat(void *argument)
 
   if ( field.ptr ) free(field.ptr);
 
+  if ( needWeights )
+    for ( int index = 0; index < nzaxis; ++index )
+      if ( vert[index].numlevel > 1 )  free(vert[index].weights);
+
   streamClose(streamID2);
   streamClose(streamID1);
 
diff --git a/src/Vertwind.c b/src/Vertwind.c
index 43c54da..692dd38 100644
--- a/src/Vertwind.c
+++ b/src/Vertwind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -27,7 +27,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "vinterp.h"
+#include "after_vertint.h"
 
 
 #define R  287.07  /* spezielle Gaskonstante fuer Luft */
@@ -35,8 +35,8 @@
 
 void *Vertwind(void *argument)
 {
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
+  int streamID2;
+  int vlistID2;
   int taxisID1, taxisID2;
   int gridID, zaxisID, tsID;
   int nlevel, nrecs, recID, code;
@@ -45,7 +45,6 @@ void *Vertwind(void *argument)
   int gridsize, i;
   int offset;
   int nmiss, nmiss_out;
-  int ngp = 0, ngrids;
   int temp_code, sq_code, ps_code, omega_code, lsp_code;
   int tempID = -1, sqID = -1, psID = -1, omegaID = -1, lnpsID = -1;
   char varname[CDI_MAX_NAME];
@@ -58,31 +57,11 @@ void *Vertwind(void *argument)
 
   cdoInitialize(argument);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
+  int vlistID1 = streamInqVlist(streamID1);
 
-  ngrids  = vlistNgrids(vlistID1);
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  ngp = gridInqSize(gridID);
-	  break;
-	}
-    }
-
-  /* check gridsize */
-  for ( i = 0; i < ngrids; i++ )
-    {
-      gridID = vlistGrid(vlistID1, i);
-      if ( gridInqType(gridID) != GRID_SPECTRAL )
-	{
-	  if ( ngp != gridInqSize(gridID) )
-	    cdoAbort("Grids have different size!");
-	}
-    }
+  int ngp = vlist_check_gridsize(vlistID1);
 
   temp_code  = 130;
   sq_code    = 133;
diff --git a/src/Wct.c b/src/Wct.c
old mode 100644
new mode 100755
diff --git a/src/Wind.c b/src/Wind.c
index 058d86b..17a95c5 100644
--- a/src/Wind.c
+++ b/src/Wind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Writegrid.c b/src/Writegrid.c
index 74d28c7..bd404f6 100644
--- a/src/Writegrid.c
+++ b/src/Writegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Writerandom.c b/src/Writerandom.c
index 2006175..9e1c5d2 100644
--- a/src/Writerandom.c
+++ b/src/Writerandom.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/YAR.c b/src/YAR.c
index eb9d798..ff8e09a 100644
--- a/src/YAR.c
+++ b/src/YAR.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -84,8 +84,8 @@ void yar_store_link_cnsrv(remapvars_t *rv, long add1, long add2, double weight)
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
+  rv->src_cell_add[nlink] = add1;
+  rv->tgt_cell_add[nlink] = add2;
 
   rv->wts[nlink] = weight;
 }
@@ -139,6 +139,39 @@ void set_source_data(double * source_data, double init_value,
 }
 
 
+/*
+  This routine stores the address and weight for four links associated with one destination
+  point in the appropriate address and weight arrays and resizes those arrays if necessary.
+*/
+static
+void store_link_bilin(remapvars_t *rv, int dst_add, int src_add[4], double weights[4])
+{
+  /*
+    Input variables:
+    int dst_add       ! address on destination grid
+    int src_add[4]    ! addresses on source grid
+    double weights[4] ! array of remapping weights for these links
+  */
+  /* link index */
+  long nlink = rv->num_links;
+  /*
+     Increment number of links and check to see if remap arrays need
+     to be increased to accomodate the new link. Then store the link.
+  */
+  rv->num_links += 4;
+
+  if ( rv->num_links >= rv->max_links ) 
+    resize_remap_vars(rv, rv->resize_increment);
+
+  for ( long n = 0; n < 4; ++n )
+    {
+      rv->src_cell_add[nlink+n] = src_add[n];
+      rv->tgt_cell_add[nlink+n] = dst_add;
+      rv->wts         [nlink+n] = weights[n];
+    }
+
+} /* store_link_bilin */
+
 void yar_remap_bil(field_t *field1, field_t *field2)
 {
   int nlonIn, nlatIn;
@@ -371,7 +404,7 @@ void yar_remap_bil(field_t *field1, field_t *field2)
 
   if ( cdoTimer ) timer_start(timer_yar_remap);
   yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
-	    remap.vars.num_wts, remap.vars.tgt_grid_add, remap.vars.src_grid_add, array1);
+	    remap.vars.num_wts, remap.vars.tgt_cell_add, remap.vars.src_cell_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
   nmiss = 0;
@@ -675,7 +708,7 @@ void yar_remap_con(field_t *field1, field_t *field2)
 
   if ( cdoTimer ) timer_start(timer_yar_remap);
   yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
-	    remap.vars.num_wts, remap.vars.tgt_grid_add, remap.vars.src_grid_add, array1);
+	    remap.vars.num_wts, remap.vars.tgt_cell_add, remap.vars.src_cell_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
   nmiss = 0;
diff --git a/src/Ydayarith.c b/src/Ydayarith.c
index ffeb64b..4b0ab8f 100644
--- a/src/Ydayarith.c
+++ b/src/Ydayarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ydaypctl.c b/src/Ydaypctl.c
index 595382f..78a7bf9 100644
--- a/src/Ydaypctl.c
+++ b/src/Ydaypctl.c
@@ -60,7 +60,7 @@ void *Ydaypctl(void *argument)
   cdoOperatorAdd("ydaypctl", func_pctl, 0, NULL);
 
   operatorInputArg("percentile number");
-  pn = atof(operatorArgv()[0]);
+  pn = parameter2double(operatorArgv()[0]);
       
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
diff --git a/src/Ydaystat.c b/src/Ydaystat.c
index 8319f6e..ff9465f 100644
--- a/src/Ydaystat.c
+++ b/src/Ydaystat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ydrunpctl.c b/src/Ydrunpctl.c
index 0bba504..3d7e75e 100644
--- a/src/Ydrunpctl.c
+++ b/src/Ydrunpctl.c
@@ -30,6 +30,14 @@
 
 #define NDAY 373
 
+static
+int getmonthday(int date)
+{
+  int year, month, day;
+  cdiDecodeDate(date, &year, &month, &day);
+  return month*100+day;
+}
+
 
 void *Ydrunpctl(void *argument)
 {
@@ -37,27 +45,21 @@ void *Ydrunpctl(void *argument)
   int varID;
   int recID;
   int gridID;
-  int nrecs, nrecords;
+  int nrecs;
   int levelID;
   int tsID;
   int otsID;
-  int inp, its, ndates = 0;
-  int streamID1, streamID2, streamID3, streamID4;
-  int vlistID1, vlistID2, vlistID3, vlistID4;
+  int inp, its;
   int nmiss;
-  int nvars, nlevels;
-  int *recVarID, *recLevelID;
+  int nlevels;
   field_t ***vars1 = NULL, **vars2[NDAY];
   datetime_t *datetime;
-  int taxisID1, taxisID2, taxisID3, taxisID4;
-  int calendar, dpy;
   int vdate, vtime;
   int vdates1[NDAY], vtimes1[NDAY];
-  int vdates2[NDAY], vtimes2[NDAY];
+  int vdates2[NDAY] /*, vtimes2[NDAY]*/;
   int nsets[NDAY];
   int year, month, day, dayoy;
   field_t field;
-  double pn;
   HISTOGRAM_SET *hsets[NDAY];
     
   cdoInitialize(argument);
@@ -65,8 +67,8 @@ void *Ydrunpctl(void *argument)
 
   operatorInputArg("percentile number, number of timesteps");
   operatorCheckArgc(2);
-  pn     = atof(operatorArgv()[0]);
-  ndates = atoi(operatorArgv()[1]);
+  double pn  = parameter2double(operatorArgv()[0]);
+  int ndates = parameter2int(operatorArgv()[1]);
 
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
@@ -78,39 +80,39 @@ void *Ydrunpctl(void *argument)
       nsets[dayoy] = 0;
     }
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
-  streamID3 = streamOpenRead(cdoStreamName(2));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID3 = streamOpenRead(cdoStreamName(2));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = streamInqVlist(streamID3);
-  vlistID4 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = streamInqVlist(streamID3);
+  int vlistID4 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
   vlistCompare(vlistID1, vlistID3, CMP_ALL);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = vlistInqTaxis(vlistID3);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = vlistInqTaxis(vlistID3);
   /* TODO - check that time axes 2 and 3 are equal */
 
-  taxisID4 = taxisDuplicate(taxisID1);
+  int taxisID4 = taxisDuplicate(taxisID1);
   if ( taxisHasBounds(taxisID4) ) taxisDeleteBounds(taxisID4);
   vlistDefTaxis(vlistID4, taxisID4);
 
-  calendar = taxisInqCalendar(taxisID1);
-  dpy      = calendar_dpy(calendar);
+  int calendar = taxisInqCalendar(taxisID1);
+  int dpy      = calendar_dpy(calendar);
 
-  streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
+  int streamID4 = streamOpenWrite(cdoStreamName(3), cdoFiletype());
 
   streamDefVlist(streamID4, vlistID4);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
@@ -150,7 +152,7 @@ void *Ydrunpctl(void *argument)
 	cdoAbort("Day %d out of range!", dayoy);
 
       vdates2[dayoy] = vdate;
-      vtimes2[dayoy] = vtime;
+      //vtimes2[dayoy] = vtime;
 
       if ( vars2[dayoy] == NULL )
 	{
@@ -269,16 +271,34 @@ void *Ydrunpctl(void *argument)
       nsets[dayoy] += ndates;
       tsID++;
     }
+  /*
+  int outyear = 1e9;
+  for ( dayoy = 0; dayoy < NDAY; dayoy++ )
+    if ( nsets[dayoy] )
+      {
+	int year, month, day;
+	cdiDecodeDate(vdates1[dayoy], &year, &month, &day);
+	if ( year < outyear ) outyear = year;
+      }
 
+  for ( dayoy = 0; dayoy < NDAY; dayoy++ )
+    if ( nsets[dayoy] )
+      {
+	int year, month, day;
+	cdiDecodeDate(vdates1[dayoy], &year, &month, &day);
+	vdates1[dayoy] = cdiEncodeDate(outyear, month, day);
+      }
+  */
   otsID = 0;
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
     if ( nsets[dayoy] )
       {
-        if ( vdates1[dayoy] != vdates2[dayoy] )
+        if ( getmonthday(vdates1[dayoy]) != getmonthday(vdates2[dayoy]) )
           cdoAbort("Verification dates for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
+        /*
         if ( vtimes1[dayoy] != vtimes2[dayoy] )
           cdoAbort("Verification times for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
-
+        */
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
diff --git a/src/Ydrunstat.c b/src/Ydrunstat.c
index 1accdd5..5870bd9 100644
--- a/src/Ydrunstat.c
+++ b/src/Ydrunstat.c
@@ -58,27 +58,16 @@ static void ydstatFinalize(YDAY_STATS *stats, int operfunc);
 
 void *Ydrunstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
   int varID;
   int recID;
-  int nrecs, nrecords;
+  int nrecs;
   int levelID;
   int tsID;
   int otsID;
-  int inp, its, ndates = 0;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2;
+  int inp, its;
   int nmiss;
-  int *recVarID, *recLevelID;
-  int lvarstd = FALSE;
-  field_t ***vars1 = NULL, ***vars2 = NULL;
-  datetime_t *datetime;
-  int taxisID1, taxisID2;
-  int calendar, dpy;
   int vdate, vtime;
   int dayoy;
-  YDAY_STATS *stats;
     
   cdoInitialize(argument);
 
@@ -92,40 +81,41 @@ void *Ydrunstat(void *argument)
   cdoOperatorAdd("ydrunstd",  func_std,  0, NULL);
   cdoOperatorAdd("ydrunstd1", func_std1, 0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg("number of timesteps");
-  ndates = atoi(operatorArgv()[0]);
+  int ndates = parameter2int(operatorArgv()[0]);
 
-  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  int lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
   
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   if ( taxisHasBounds(taxisID2) ) taxisDeleteBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  calendar = taxisInqCalendar(taxisID1);
-  dpy      = calendar_dpy(calendar);
+  int calendar = taxisInqCalendar(taxisID1);
+  int dpy      = calendar_dpy(calendar);
 
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nrecords = vlistNrecs(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
-  datetime = (datetime_t*) malloc((ndates+1)*sizeof(datetime_t));
+  datetime_t *datetime = (datetime_t*) malloc((ndates+1)*sizeof(datetime_t));
   
-  stats = ydstatCreate(vlistID1);
-  vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+  YDAY_STATS *stats = ydstatCreate(vlistID1);
+  field_t ***vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+  field_t ***vars2 = NULL;
   if ( lvarstd )
     vars2 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   
@@ -254,6 +244,7 @@ void *Ydrunstat(void *argument)
       }
 
   ydstatFinalize(stats, operfunc);
+
   otsID = 0;
 
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
@@ -265,8 +256,8 @@ void *Ydrunstat(void *argument)
 
 	for ( recID = 0; recID < nrecords; recID++ )
 	  {
-	    varID    = recVarID[recID];
-	    levelID  = recLevelID[recID];
+	    varID   = recVarID[recID];
+	    levelID = recLevelID[recID];
 
 	    if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
 
diff --git a/src/Yearmonstat.c b/src/Yearmonstat.c
index da49d9f..3e66ce9 100644
--- a/src/Yearmonstat.c
+++ b/src/Yearmonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -31,63 +31,57 @@
 
 void *Yearmonstat(void *argument)
 {
-  int operatorID;
-  int operfunc;
+  int timestat_date = TIMESTAT_MEAN;
   int gridsize;
   int vdate = 0, vtime = 0;
   int vdate0 = 0, vtime0 = 0;
-  int nrecs, nrecords;
+  int nrecs;
   int varID, levelID, recID;
   int tsID;
   int otsID;
-  long nsets;
-  double dsets;
   int i;
   int dpm;
   int year0 = 0, month0 = 0;
   int year, month, day;
-  int calendar;
-  int streamID1, streamID2;
-  int vlistID1, vlistID2, taxisID1, taxisID2;
   int nmiss;
-  int nvars, nlevel;
-  int *recVarID, *recLevelID;
+  int nlevel;
+  long nsets;
+  double dsets;
   char vdatestr[32], vtimestr[32];
   field_t **vars1 = NULL, **samp1 = NULL;
   field_t field;
-  int timestat_date = DATE_MIDDLE;
-  dtinfo_t dtinfo[13];
 
   cdoInitialize(argument);
 
-  get_timestat_date(&timestat_date);
-
   cdoOperatorAdd("yearmonmean",  func_mean, 0, NULL);
   cdoOperatorAdd("yearmonavg",   func_avg,  0, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  calendar = taxisInqCalendar(taxisID1);
-
-  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+  int streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 
-  nvars    = vlistNvars(vlistID1);
-  nrecords = vlistNrecs(vlistID1);
+  int nvars    = vlistNvars(vlistID1);
+  int nrecords = vlistNrecs(vlistID1);
+
+  int *recVarID   = (int*) malloc(nrecords*sizeof(int));
+  int *recLevelID = (int*) malloc(nrecords*sizeof(int));
 
-  recVarID   = (int*) malloc(nrecords*sizeof(int));
-  recLevelID = (int*) malloc(nrecords*sizeof(int));
+  int calendar = taxisInqCalendar(taxisID1);
+  dtlist_type *dtlist = dtlist_new();
+  dtlist_set_stat(dtlist, timestat_date);
+  dtlist_set_calendar(dtlist, calendar);
 
   gridsize = vlistGridsizeMax(vlistID1);
 
@@ -105,9 +99,9 @@ void *Yearmonstat(void *argument)
       dsets = 0;
       while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
 	{
-	  taxisInqDTinfo(taxisID1, &dtinfo[nsets]);
-	  vdate = dtinfo[nsets].v.date;
-	  vtime = dtinfo[nsets].v.time;
+	  dtlist_taxisInqTimestep(dtlist, taxisID1, nsets);
+	  vdate = dtlist_get_vdate(dtlist, nsets);
+	  vtime = dtlist_get_vtime(dtlist, nsets);
 	  cdiDecodeDate(vdate, &year, &month, &day);
 
 	  if ( nsets == 0 ) year0 = year;
@@ -214,17 +208,7 @@ void *Yearmonstat(void *argument)
 	  cdoPrint("%s %s  nsets = %d", vdatestr, vtimestr, nsets);
 	}
 
-      if      ( timestat_date == DATE_MIDDLE ) datetime_avg_dtinfo(calendar, nsets, dtinfo);
-      else if ( timestat_date == DATE_FIRST  ) dtinfo[nsets].v = dtinfo[0].v;
-      else if ( timestat_date == DATE_LAST   ) dtinfo[nsets].v = dtinfo[nsets-1].v;
-
-      if ( taxisHasBounds(taxisID2) )
-	{
-	  dtinfo[nsets].b[0] = dtinfo[0].b[0];
-	  dtinfo[nsets].b[1] = dtinfo[nsets-1].b[1];
-	}
-
-      taxisDefDTinfo(taxisID2, dtinfo[nsets]);
+      dtlist_stat_taxisDefTimestep(dtlist, taxisID2, nsets);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -246,14 +230,16 @@ void *Yearmonstat(void *argument)
   field_free(vars1, vlistID1);
   field_free(samp1, vlistID1);
 
-  streamClose(streamID2);
-  streamClose(streamID1);
-
   if ( field.ptr ) free(field.ptr);
 
   if ( recVarID   ) free(recVarID);
   if ( recLevelID ) free(recLevelID);
 
+  dtlist_delete(dtlist);
+
+  streamClose(streamID2);
+  streamClose(streamID1);
+
   cdoFinish();
 
   return (0);
diff --git a/src/Yhourarith.c b/src/Yhourarith.c
index fbdecde..19173e6 100644
--- a/src/Yhourarith.c
+++ b/src/Yhourarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Yhourstat.c b/src/Yhourstat.c
index 13ca224..1eba3d6 100644
--- a/src/Yhourstat.c
+++ b/src/Yhourstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ymonarith.c b/src/Ymonarith.c
index 9a997d2..8ba824e 100644
--- a/src/Ymonarith.c
+++ b/src/Ymonarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,10 @@
       Ymonarith  ymonsub         Subtract multi-year monthly time series
       Ymonarith  ymonmul         Multiply multi-year monthly time series
       Ymonarith  ymondiv         Divide multi-year monthly time series
+      Ymonarith  yseasadd        Add multi-year seasonal time series
+      Ymonarith  yseassub        Subtract multi-year seasonal time series
+      Ymonarith  yseasmul        Multiply multi-year seasonal time series
+      Ymonarith  yseasdiv        Divide multi-year seasonal time series
 */
 
 #include <cdi.h>
@@ -30,62 +34,94 @@
 #include "pstream.h"
 
 
-#define  MAX_MON    20
+#define  MAX_MON    12
+
+static
+int month_to_season(int mon)
+{
+  int seas = -1;
+
+  switch ( mon )
+    {
+    case 12:
+    case  1:
+    case  2:
+      seas = 0; break;
+    case  3:
+    case  4:
+    case  5:
+      seas = 1; break;
+    case  6:
+    case  7:
+    case  8:
+      seas = 2; break;
+    case  9:
+    case 10:
+    case 11:
+      seas = 3; break;
+    }
+
+  return seas;
+}
+
 
 void *Ymonarith(void *argument)
 {
-  int operatorID;
-  int operfunc;
-  int streamID1, streamID2, streamID3;
-  int gridsize;
+  enum {MONTHLY, SEASONAL};
   int nrecs, nvars, nlev, recID;
   int tsID;
   int varID, levelID;
   int offset;
-  int vlistID1, vlistID2, vlistID3;
-  int taxisID1, taxisID2, taxisID3;
   int vdate, year, mon, day;
   field_t field1, field2;
   int **varnmiss2[MAX_MON];
   double **vardata2[MAX_MON];
+  const char *seas_name[4];
 
   cdoInitialize(argument);
 
-  cdoOperatorAdd("ymonadd", func_add, 0, NULL);
-  cdoOperatorAdd("ymonsub", func_sub, 0, NULL);
-  cdoOperatorAdd("ymonmul", func_mul, 0, NULL);
-  cdoOperatorAdd("ymondiv", func_div, 0, NULL);
+  cdoOperatorAdd("ymonadd",  func_add, MONTHLY, NULL);
+  cdoOperatorAdd("ymonsub",  func_sub, MONTHLY, NULL);
+  cdoOperatorAdd("ymonmul",  func_mul, MONTHLY, NULL);
+  cdoOperatorAdd("ymondiv",  func_div, MONTHLY, NULL);
+  cdoOperatorAdd("yseasadd", func_add, SEASONAL, NULL);
+  cdoOperatorAdd("yseassub", func_sub, SEASONAL, NULL);
+  cdoOperatorAdd("yseasmul", func_mul, SEASONAL, NULL);
+  cdoOperatorAdd("yseasdiv", func_div, SEASONAL, NULL);
 
-  operatorID = cdoOperatorID();
-  operfunc = cdoOperatorF1(operatorID);
+  int operatorID = cdoOperatorID();
+  int operfunc = cdoOperatorF1(operatorID);
+  int opertype = cdoOperatorF2(operatorID);
 
-  streamID1 = streamOpenRead(cdoStreamName(0));
-  streamID2 = streamOpenRead(cdoStreamName(1));
+  int streamID1 = streamOpenRead(cdoStreamName(0));
+  int streamID2 = streamOpenRead(cdoStreamName(1));
 
-  vlistID1 = streamInqVlist(streamID1);
-  vlistID2 = streamInqVlist(streamID2);
-  vlistID3 = vlistDuplicate(vlistID1);
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = streamInqVlist(streamID2);
+  int vlistID3 = vlistDuplicate(vlistID1);
 
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
 
-  gridsize = vlistGridsizeMax(vlistID1);
+  int gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field1);
   field_init(&field2);
   field1.ptr = (double*) malloc(gridsize*sizeof(double));
   field2.ptr = (double*) malloc(gridsize*sizeof(double));
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
-  taxisID3 = taxisDuplicate(taxisID1);
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = vlistInqTaxis(vlistID2);
+  int taxisID3 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID3, taxisID3);
 
-  streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
+  int streamID3 = streamOpenWrite(cdoStreamName(2), cdoFiletype());
 
   streamDefVlist(streamID3, vlistID3);
 
   nvars  = vlistNvars(vlistID2);
 
+  if ( opertype == SEASONAL ) get_season_name(seas_name);
+
   for ( mon = 0; mon < MAX_MON ; mon++ ) vardata2[mon] = NULL;
 
   tsID = 0;
@@ -94,9 +130,18 @@ void *Ymonarith(void *argument)
       vdate = taxisInqVdate(taxisID2);
 
       cdiDecodeDate(vdate, &year, &mon, &day);
-      if ( mon < 0 || mon >= MAX_MON ) cdoAbort("Month %d out of range!", mon);
+      if ( mon < 1 || mon > MAX_MON ) cdoAbort("Month %d out of range!", mon);
+      mon--;
 
-      if ( vardata2[mon] != NULL ) cdoAbort("Month %d already allocatd!", mon);
+      if ( opertype == SEASONAL ) mon = month_to_season(mon+1);
+
+      if ( vardata2[mon] != NULL )
+	{
+	  if ( opertype == SEASONAL )
+	    cdoAbort("Season %s already allocatd!", seas_name[mon]);
+	  else
+	    cdoAbort("Month %d already allocatd!", mon);
+	}
 
       vardata2[mon]  = (double **) malloc(nvars*sizeof(double *));
       varnmiss2[mon] = (int **) malloc(nvars*sizeof(int *));
@@ -130,7 +175,18 @@ void *Ymonarith(void *argument)
       vdate = taxisInqVdate(taxisID1);
 
       cdiDecodeDate(vdate, &year, &mon, &day);
-      if ( mon < 0 || mon >= MAX_MON ) cdoAbort("Month %d out of range!", mon);
+      if ( mon < 1 || mon > MAX_MON ) cdoAbort("Month %d out of range!", mon);
+      mon--;
+
+      if ( opertype == SEASONAL ) mon = month_to_season(mon+1);
+
+      if ( vardata2[mon] == NULL )
+	{
+	  if ( opertype == SEASONAL )
+	    cdoAbort("Season %s not found!", seas_name[mon]);
+	  else
+	    cdoAbort("Month %d not found!", mon);
+	}
 
       taxisCopyTimestep(taxisID3, taxisID1);
 
@@ -143,7 +199,7 @@ void *Ymonarith(void *argument)
 
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	  offset   = gridsize*levelID;
-	  if ( vardata2[mon] == NULL ) cdoAbort("Month %d not found!", mon);
+
 	  memcpy(field2.ptr, vardata2[mon][varID]+offset, gridsize*sizeof(double));
 	  field2.nmiss = varnmiss2[mon][varID][levelID];
 
diff --git a/src/Ymonpctl.c b/src/Ymonpctl.c
index af5b304..262ec57 100644
--- a/src/Ymonpctl.c
+++ b/src/Ymonpctl.c
@@ -58,7 +58,7 @@ void *Ymonpctl(void *argument)
   cdoOperatorAdd("ymonpctl", func_pctl, 0, NULL);
 
   operatorInputArg("percentile number");
-  pn = atof(operatorArgv()[0]);
+  pn = parameter2double(operatorArgv()[0]);
       
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
diff --git a/src/Ymonstat.c b/src/Ymonstat.c
index 4731598..a39da45 100644
--- a/src/Ymonstat.c
+++ b/src/Ymonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Yseaspctl.c b/src/Yseaspctl.c
index 2aa2c8f..1c629f5 100644
--- a/src/Yseaspctl.c
+++ b/src/Yseaspctl.c
@@ -60,7 +60,7 @@ void *Yseaspctl(void *argument)
   cdoOperatorAdd("yseaspctl", func_pctl, 0, NULL);
 
   operatorInputArg("percentile number");
-  pn = atof(operatorArgv()[0]);
+  pn = parameter2double(operatorArgv()[0]);
       
   if ( !(pn > 0 && pn < 100) )
     cdoAbort("Illegal argument: percentile number %g is not in the range 0..100!", pn);
diff --git a/src/Yseasstat.c b/src/Yseasstat.c
index 64b16d5..0327ae9 100644
--- a/src/Yseasstat.c
+++ b/src/Yseasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Zonstat.c b/src/Zonstat.c
index e91e707..689eee3 100644
--- a/src/Zonstat.c
+++ b/src/Zonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.1
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -67,23 +67,19 @@ void *Zonstat(void *argument)
   cdoOperatorAdd("zonavg",   func_avg,   0, NULL);
   cdoOperatorAdd("zonvar",   func_var,   0, NULL);
   cdoOperatorAdd("zonstd",   func_std,   0, NULL);
-  /* RQ */
   cdoOperatorAdd("zonpctl",  func_pctl,  0, NULL);
-  /* QR */
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
-  /* RQ */
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
-      pn = atoi(operatorArgv()[0]);
+      pn = parameter2int(operatorArgv()[0]);
       
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
     }
-  /* QR */
 
   streamID1 = streamOpenRead(cdoStreamName(0));
 
diff --git a/src/after_dvtrans.c b/src/after_dvtrans.c
new file mode 100644
index 0000000..ed3faad
--- /dev/null
+++ b/src/after_dvtrans.c
@@ -0,0 +1,256 @@
+#include <math.h>
+
+#include "constants.h"
+
+
+#define  SQUARE_RADIUS   (-PlanetRadius * PlanetRadius)
+
+void dv2ps(const double * restrict div, double * restrict pot, long nlev, long ntr)
+{
+  long l, m, n;
+  double fact;
+
+  for ( l = 0; l <  nlev; l++ )
+    {
+      /* m == 0 */
+      *pot++ = 0.0;
+      *pot++ = 0.0;
+      div += 2;
+
+      for ( n = 1; n <= ntr; n++ )
+	{
+	  fact = SQUARE_RADIUS / (n*n + n);
+	  *pot++ = *div++ * fact;
+	  *pot++ = *div++ * fact;
+	}
+
+      /* m >= 0 */
+      for ( m = 1; m <= ntr; m++ )
+	for ( n = m; n <= ntr; n++ )
+	  {
+	    fact = SQUARE_RADIUS / (n*n + n);
+	    *pot++ = *div++ * fact;
+	    *pot++ = *div++ * fact;
+	  }
+      }
+}
+
+
+void dv2uv(double *d, double *o, double *u, double *v, double *f, double *g,
+	   int nt, int nsp, int nlev)
+{
+  /* d(nsp,nlev), o(nsp,nlev)     ! divergence, vorticity        */
+  /* u(nsp,nlev), v(nsp,nlev)     ! zonal wind, meridional wind  */
+  /* f(nsp/2)   , g(nsp/2)        ! factor tables                */
+
+  int l, m, n;
+  int i;
+
+  for ( l = 0; l < nlev; l++ )
+    {
+      i = 0;
+
+      for ( m = 0; m < nt-1; m++ )
+	{
+	  /*********/
+	  /* n = m */
+	  /*********/
+
+	  if ( m == 0 )
+	    {
+	      *u++ = -g[i+1] * o[2*(i+1)  ];
+	      *u++ = -g[i+1] * o[2*(i+1)+1];
+	      *v++ =  g[i+1] * d[2*(i+1)  ];
+	      *v++ =  g[i+1] * d[2*(i+1)+1];
+	    }
+	  else
+	    {
+	      *u++ = -f[i] * d[2*i+1] - g[i+1] * o[2*(i+1)  ];
+	      *u++ =  f[i] * d[2*i  ] - g[i+1] * o[2*(i+1)+1];
+	      *v++ = -f[i] * o[2*i+1] + g[i+1] * d[2*(i+1)  ];
+	      *v++ =  f[i] * o[2*i  ] + g[i+1] * d[2*(i+1)+1];
+	    }
+	  ++i;
+
+	  /****************/
+	  /* m < n < nt-1 */
+	  /****************/
+
+	  for ( n = m+1; n < nt-1; n++ )
+	    {
+	      *u++ =  g[i] * o[2*(i-1)  ] - f[i] * d[2*i+1] - g[i+1] * o[2*(i+1)  ];
+	      *u++ =  g[i] * o[2*(i-1)+1] + f[i] * d[2*i  ] - g[i+1] * o[2*(i+1)+1];
+	      *v++ = -g[i] * d[2*(i-1)  ] - f[i] * o[2*i+1] + g[i+1] * d[2*(i+1)  ];
+	      *v++ = -g[i] * d[2*(i-1)+1] + f[i] * o[2*i  ] + g[i+1] * d[2*(i+1)+1];
+	      ++i;
+	    }
+
+	  /************/
+	  /* n = nt-1 */
+	  /************/
+
+	  *u++ =  g[i] * o[2*(i-1)  ] - f[i] * d[2*i+1];
+	  *u++ =  g[i] * o[2*(i-1)+1] + f[i] * d[2*i  ];
+	  *v++ = -g[i] * d[2*(i-1)  ] - f[i] * o[2*i+1];
+	  *v++ = -g[i] * d[2*(i-1)+1] + f[i] * o[2*i  ];
+	  ++i;
+
+	  /**********/
+	  /* n = nt */
+	  /**********/
+
+	  *u++ =  g[i] * o[2*(i-1)  ];
+	  *u++ =  g[i] * o[2*(i-1)+1];
+	  *v++ = -g[i] * d[2*(i-1)  ];
+	  *v++ = -g[i] * d[2*(i-1)+1];
+	  ++i;
+	}
+
+      /***************************/
+      /* m = nt-1  and  n = nt-1 */
+      /***************************/
+
+      *u++ = -f[i] * d[2*i+1];
+      *u++ =  f[i] * d[2*i  ];
+      *v++ = -f[i] * o[2*i+1];
+      *v++ =  f[i] * o[2*i  ];
+      ++i;
+
+      /*************************/
+      /* m = nt-1  and  n = nt */
+      /*************************/
+
+      *u++ =  g[i] * o[2*(i-1)  ];
+      *u++ =  g[i] * o[2*(i-1)+1];
+      *v++ = -g[i] * d[2*(i-1)  ];
+      *v++ = -g[i] * d[2*(i-1)+1];
+      ++i;
+
+      /***********************/
+      /* m = nt  and  n = nt */
+      /***********************/
+
+      *u++ = 0.0;
+      *u++ = 0.0;
+      *v++ = 0.0;
+      *v++ = 0.0;
+
+      d += nsp;
+      o += nsp;
+    }
+}
+
+/*
+void scaluv(double *fu, double rclat[], int nlat, int lot)
+{
+  int l, lat;
+  double *ful;
+
+#if defined (_OPENMP)
+#pragma tomp parallel for default(shared) private(lat, ful)
+#endif
+  for ( l = 0; l < lot; l++ )
+    {
+      ful = fu + l*nlat;
+      for ( lat = 0; lat < nlat; lat++ )
+	{
+	  ful[lat] = rclat[lat];
+	}
+    }
+}
+*/
+
+
+void scaluv(double *fu, double *rclat, int nlat, int lot)
+{
+  int l,lat;
+
+  for (l = 0; l < lot; l++)
+    for (lat = 0; lat < nlat; lat++)
+      {
+        *fu *= rclat[lat];
+        fu++;
+      }
+}
+
+
+void uv2dv(double *fu, double *fv, double *sd, double *sv,
+           double *pol2, double *pol3, int klev, int nlat, int nt)
+{
+  int lev, jmm, jfc, lat, nfc, nsp2;
+  double dir, dii, vor, voi;
+  double *ufr, *ufi, *vfr, *vfi;
+  double *ful, *fvl, *sdl, *svl;
+  double *po2, *po3;
+
+  nsp2 = (nt+1)*(nt+2);
+  nfc  = (nt+1)*2;
+
+#if defined (_OPENMP)
+#pragma omp parallel for default(shared) private(jmm, jfc, lat, po2, po3, ful, fvl, sdl, svl, ufr, ufi, vfr, vfi, dir, dii, vor, voi)
+#endif
+  for ( lev = 0; lev < klev; lev++ )
+    {
+      po2 = pol2;
+      po3 = pol3;
+      ful = fu + lev*nfc*nlat;
+      fvl = fv + lev*nfc*nlat;
+      sdl = sd + lev*nsp2;
+      svl = sv + lev*nsp2;
+      for ( jmm = 0; jmm <= nt; jmm++ )
+	{
+	  for  ( jfc = jmm; jfc <= nt; jfc++ )
+	    {
+	      ufr = ful;
+	      ufi = ful + nlat;
+	      vfr = fvl;
+	      vfi = fvl + nlat;
+	      dir = 0.0;
+	      dii = 0.0;
+	      vor = 0.0;
+	      voi = 0.0;
+	      for ( lat = 0; lat < nlat; lat++ )
+		{
+		  dir += vfr[lat] * po2[lat] - ufi[lat] * po3[lat];
+		  dii += vfi[lat] * po2[lat] + ufr[lat] * po3[lat];
+		  vor -= ufr[lat] * po2[lat] + vfi[lat] * po3[lat];
+		  voi -= ufi[lat] * po2[lat] - vfr[lat] * po3[lat];
+		}
+	      *sdl++ = dir;
+	      *sdl++ = dii;
+	      *svl++ = vor;
+	      *svl++ = voi;
+	      po2 += nlat;
+	      po3 += nlat;
+	    }
+	  ful += 2 * nlat;
+	  fvl += 2 * nlat;
+	}
+    }
+}
+
+
+void geninx(long ntr, double *f, double *g)
+{
+  long m2,n2;
+  long m, n ;
+
+  for ( m = 0; m <= ntr; m++ )
+    {
+      m2 = m * m;
+      for ( n = m; n <= ntr; n++ )
+	{
+	  n2 = n * n;
+	  if ( n )
+	    {
+	      *g++ = -PlanetRadius / n * sqrt((double)(n2-m2)/(double)(4*n2-1));
+	      *f++ = -PlanetRadius * m / (double)(n2+n);
+	    }
+	  else
+	    {
+	      *g++ = 0.0;
+	      *f++ = 0.0;
+	    }
+	}
+    }
+}
diff --git a/src/fouriertrans.c b/src/after_fctrans.c
similarity index 93%
rename from src/fouriertrans.c
rename to src/after_fctrans.c
index 07efff1..7587ffe 100644
--- a/src/fouriertrans.c
+++ b/src/after_fctrans.c
@@ -6,6 +6,12 @@
 #  include "dmemory.h"
 #endif
 
+#define  OPENMP4  201307
+#if defined(_OPENMP) && defined(OPENMP4) && _OPENMP >= OPENMP4
+#define  HAVE_OPENMP4  1
+#endif
+
+
 #if defined(SX)
 #  define  NFFT  1024
 #else
@@ -160,6 +166,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = a[i0 + i] + a[i1 + i];
@@ -192,6 +201,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a0m1 = a[i0 + i] - a[i1 + i];
@@ -222,6 +234,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = a[i0 + i];
@@ -242,6 +257,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = 2.0 * (a[i0 + i] + a[i1 + i]);
@@ -276,6 +294,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    afa1 = a[i0 + i] - 0.5 * a[i1 + i];
@@ -315,6 +336,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a1p2 = a[i0 + i] - 0.5 * (a[i1 + i] + a[i2 + i]);
@@ -355,6 +379,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0mp = 0.5 * a[i0 + i];
@@ -379,6 +406,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0mp = 2.0 * a[i0 + i] - a[i1 + i];
@@ -418,6 +448,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p2 = a[i0 + i] + a[i2 + i];
@@ -462,6 +495,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a0p2 = a[i0 + i] + a[i2 + i];
@@ -511,6 +547,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0m1 = a[i0 + i] - a[i1 + i];
@@ -537,6 +576,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p2 = a[i0 + i] + a[i2 + i];
@@ -577,6 +619,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a1p2 = QUA * (a[i1 + i] + a[i2 + i]);
@@ -634,6 +679,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a10 = (a[i0 + i] - 0.25 * ((a[i1 + i] + a[i4 + i]) +
@@ -698,6 +746,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = a[i0 + i] + a[i1 + i] + a[i2 + i];
@@ -733,6 +784,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = 2.0 * (a[i0 + i] + a[i1 + i] + a[i2 + i]);
@@ -782,6 +836,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[ja + j] = (a[ia + i] + a[id + i]) + (a[ib + i] + a[ic + i]);
@@ -841,6 +898,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a11 = a[ie + i] + a[ib + i] + a[ic + i] + a[iF + i];
@@ -901,6 +961,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[ja + j] =  a[ib + i] + (a[ia + i] + a[ic + i]);
@@ -929,6 +992,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[ja + j] = (2.0 * (a[ia + i] + a[id + i])) +
@@ -988,6 +1054,9 @@ int rpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 	    for (ijk = 0; ijk < lot; ++ijk)
 	      {
 		a0p7 = a[i0 + i] + a[i7 + i];
@@ -1091,6 +1160,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = a[i0 + i] + a[i1 + i];
@@ -1122,6 +1194,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    c[j0 + j] = a[i0 + i] + c1 * a[i1 + i] + s1 * b[i1 + i];
@@ -1149,6 +1224,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = a[i0 + i];
@@ -1170,6 +1248,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] = z * (a[i0 + i] + a[i1 + i]);
@@ -1203,6 +1284,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[ja + j] = a[ia + i] + a[ib + i] + a[ic + i];
@@ -1239,6 +1323,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a1 = c1 * a[ib + i] + s1 * b[ib + i] +
@@ -1280,6 +1367,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    /* soweit */
@@ -1304,6 +1394,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[ja + j] = z * (a[ia + i] + a[ib + i] + a[ic + i]);
@@ -1341,6 +1434,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p2 = a[i0 + i] + a[i2 + i];
@@ -1386,6 +1482,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a0 = a[i0 + i] + c2 * a[i2 + i] + s2 * b[i2 + i];
@@ -1433,6 +1532,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    c[j0 + j] =  a[i0 + i] + SQ2 * (a[i1 + i] - a[i3 + i]);
@@ -1456,6 +1558,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p2 = a[i0 + i] + a[i2 + i];
@@ -1500,6 +1605,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a1p4 = a[i1 + i] + a[i4 + i];
@@ -1554,6 +1662,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    a1p4 = c1 * a[i1 + i] + s1 * b[i1 + i] + 
@@ -1622,6 +1733,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a1p4 = a[i1 + i] + a[i4 + i];
@@ -1659,6 +1773,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a1p4 = a[i1 + i] + a[i4 + i];
@@ -1717,6 +1834,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p3 = a[i0 + i] + a[i3 + i];
@@ -1777,6 +1897,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 			for (ijk = 0; ijk < lot; ++ijk)
 			  {
 			    ab1a = c1 * a[i1 + i] + s1 * b[i1 + i];
@@ -1847,6 +1970,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a1p5 = a[i1 + i] + a[i5 + i];
@@ -1878,6 +2004,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 		for (ijk = 0; ijk < lot; ++ijk)
 		  {
 		    a0p3 = a[i0 + i] + a[i3 + i];
@@ -1938,6 +2067,9 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 	    for (ijk = 0; ijk < lot; ++ijk)
 	      {
 		a0p4 = a[i0 + i] + a[i4 + i];
@@ -1970,21 +2102,18 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
   return 0;
 }
 
-
-
 /* ====================== */
 /* Fast Fourier Transform */
 /* ====================== */
-void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlon, long nlev, long nfc)
+void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, double *restrict gp, long nlat, long nlon, long nlev, long nfc)
 {
-  long lot, fou, ia, ifac, jump, k, la;
-  long lat, lev, lon, nfax, rix, wix;
-  double *wfc, *wgp, *wpt;
+  long fou, ia, ifac, k, la;
+  long lat, lev, lon, rix, wix;
+  double *wpt;
   long nx, nblox, nvex, nvex0, nb;
   long istart, i, j, ibase, jbase, jj, ii, ix;
   long *istartv;
 
-
   /* fc2gp performs fourier to gridpoint transforms using           */
   /* multiple fast fourier transform of length nlon                 */
   /*                                                                */
@@ -2000,14 +2129,14 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
 
   if ( ifax[9] != nlon ) fprintf(stderr, "fc2gp: wrong initialization!\n");
 
-  nfax = ifax[0];
+  long nfax = ifax[0];
 
-  jump = (nlon + 2);
-  lot  = nlev * nlat;
+  long jump = (nlon + 2);
+  long lot  = nlev * nlat;
 
-  wfc = (double*) malloc(lot*jump*sizeof(double));
+  double *restrict wfc = (double*) malloc(lot*jump*sizeof(double));
 #if ! defined(_OPENMP)
-  wgp = (double*) malloc(lot*jump*sizeof(double));
+  double *restrict wgp = (double*) malloc(lot*jump*sizeof(double));
 #endif
 
   for ( lev = 0; lev < nlev; ++lev )
@@ -2017,12 +2146,10 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
 #endif
       for ( lat = 0; lat < nlat; ++lat )
 	{
-	  wix = jump * (lat + lev * nlat);
-	  rix = lat + lev * nlat * nfc;
-	  for ( fou = 0; fou < nfc; ++fou )
-	    wfc[wix + fou] = fc[rix + fou * nlat];
-	  for ( fou = nfc; fou < jump; ++fou )
-	    wfc[wix + fou] = 0.0;
+	  wix = jump * (lat + lev*nlat);
+	  rix = lat + lev*nlat*nfc;
+	  for ( fou = 0;   fou < nfc;  ++fou ) wfc[wix + fou] = fc[rix + fou*nlat];
+	  for ( fou = nfc; fou < jump; ++fou ) wfc[wix + fou] = 0.0;
 	  /*	  wfc[wix + 1] = 0.5 * wfc[wix]; */
 	}
     }
@@ -2044,12 +2171,12 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
     }
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(istart, nvex, ix, ii, jj, i, j, k, ia, la, ifac, ibase, jbase, wgp)
+#pragma omp parallel for default(shared) private(istart, nvex, ix, ii, jj, i, j, k, ia, la, ifac, ibase, jbase)
 #endif
   for ( nb = 0; nb < nblox; nb++ )
     {
 #if defined(_OPENMP)
-      wgp = (double*) malloc(lot*jump*sizeof(double));
+      double *restrict wgp = (double*) malloc(lot*jump*sizeof(double));
 #endif
       istart = istartv[nb];
       if ( nb == 0 ) nvex = nvex0;
@@ -2145,15 +2272,13 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
 }
 
 
-void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlon, long nlev, long nfc)
+void gp2fc(double *trig, long *ifax, const double *restrict gp, double *restrict fc, long nlat, long nlon, long nlev, long nfc)
 {
   long lot, fou, ia, ifac, jump, k, la;
   long lat, lev, lon, nfax, rix, wix;
-  double *wfc, *wgp, *wpt;
   long nx, nblox, nvex, nb;
   long istart, i, j, ibase, jbase, jj, ii, ix, iz;
 
-
   /* gp2fc performs gridpoint to fourier transforms using           */
   /* multiple fast fourier transform of length nlon                 */
   /*                                                                */
@@ -2174,14 +2299,14 @@ void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlo
   jump = (nlon + 2);
   lot  = nlev * nlat;
 
-  wfc = (double*) malloc(lot * jump * sizeof(double));
-  wgp = (double*) malloc(lot * jump * sizeof(double));
+  double *restrict wfc = (double*) malloc(lot * jump * sizeof(double));
+  double *restrict wgp = (double*) malloc(lot * jump * sizeof(double));
 
   rix = 0;
   wix = 0;
   for ( j = 0; j < lot; ++j )
     {
-      for (lon = 0; lon < nlon; ++lon)
+      for ( lon = 0; lon < nlon; ++lon )
 	wgp[wix + lon] = gp[rix + lon];
       wgp[wix + nlon] = 0.0;
       wgp[wix + nlon + 1] = 0.0;
@@ -2259,7 +2384,8 @@ void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlo
       nvex = NFFT;
     }
 
-  wpt = wgp;
+  const double *restrict wpt;
+  double *restrict fct;
 
   for ( lev = 0; lev < nlev; ++lev )
     {
@@ -2267,10 +2393,12 @@ void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlo
 	{
 	  rix = jump * (lat + lev * nlat);
 	  wix = lat + lev * nlat * nfc;
-	  fc[wix] = wpt[rix];
-	  fc[wix + nlat] = 0.0;
+          wpt = wgp + rix;
+          fct = fc + wix;
+	  fct[0] = wpt[0];
+	  fct[nlat] = 0.0;
 	  for ( fou = 2; fou < nfc; ++fou )
-	    fc[wix + fou * nlat] = wpt[rix + fou];
+	    fct[fou*nlat] = wpt[fou];
 	}
     }
 
diff --git a/src/after_namelist.c b/src/after_namelist.c
new file mode 100644
index 0000000..fb592a8
--- /dev/null
+++ b/src/after_namelist.c
@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "afterburner.h"
+
+
+static
+char *amatch(char *msr, char *sub)
+{
+  int i,nm,ns;
+
+  nm = strlen(msr);
+  ns = strlen(sub);
+
+  for (i = 0; i < nm-ns; i++)
+    if (strncmp (msr+i,sub,ns) == 0) return (msr+i+ns);
+
+  return NULL;
+}
+
+
+int scan_par_obsolate(char *namelist, char *name, int def)
+{
+  char *cp;
+  int value;
+
+  cp = amatch(namelist, name);
+
+  if ( cp == NULL ) value = def;
+  else              value = atoi (cp);
+  /*
+  fprintf(stdout, " %16.16s = %6d ", name, value);
+  if ( value == def ) fprintf(stdout, " (default)\n");
+  else                fprintf(stdout, "          \n");
+  */
+  return (value);
+}
+
+
+int scan_par(int verbose, char *namelist, char *name, int def)
+{
+  char *cp;
+  int value;
+
+  cp = amatch(namelist, name);
+
+  if ( cp == NULL ) value = def;
+  else              value = atoi (cp);
+
+  if ( verbose )
+    {
+      fprintf(stdout, " %16.16s = %6d ", name, value);
+      if ( value == def ) fprintf(stdout, " (default)\n");
+      else                fprintf(stdout, "          \n");
+    }
+  
+  return (value);
+}
+
+
+int scan_time(int verbose, char *namelist, int *hours, int max_hours)
+{
+  char *cp, *icp;
+  int time;
+  int nrqh = 0;
+
+  cp = amatch (namelist, "timesel");
+  if ( cp == NULL )
+    {
+      hours[nrqh++] = -1;
+      if ( verbose ) fprintf(stdout, " %16.16s = all\n","timesel");
+      return (nrqh);
+    }
+
+  time = (int) strtol (cp, &icp, 10);
+
+  while ((char *)icp != (char *)cp && nrqh < max_hours)
+    {
+      hours[nrqh++] = time;
+      cp = icp;
+      time = (int) strtol (cp, &icp, 10);
+    }
+
+  if ( verbose )
+    {
+      fprintf(stdout, " %16.16s = ", "timesel");
+      for ( time = 0; time < nrqh; ++time ) fprintf(stdout, " %02d", hours[time]);
+      fprintf(stdout, "\n");
+    }
+  
+  return (nrqh);
+}
+
+
+void scan_code(char *namelist, struct Variable *vars, int maxCodes, int *numCodes)
+{
+  char *cp, *icp;
+  int code, ncodes = 0;
+
+  cp = amatch(namelist, "code");
+  if ( cp != NULL )
+    {
+      code = (int) strtol(cp,&icp,10);
+      while ( code > 0 && code < maxCodes )
+	{
+	  ncodes++;
+	  vars[code].selected = 1;
+	  cp = icp;
+	  code = (int) strtol(cp,&icp,10);
+	}
+    }
+
+  *numCodes = ncodes;
+}
+
+
+void scan_darray(char *namelist, char *name, double *values, int maxValues, int *numValues)
+{
+  char *cp,*icp;
+  double val;
+  int nval = 0;
+
+  cp = amatch(namelist, name);
+
+  if ( cp != NULL )
+    {
+      val= strtod(cp, &icp);
+      values[nval++] = val;
+      cp = icp;
+      val = strtod(cp, &icp);
+      while ( val > 0 && nval < maxValues )
+	{
+	  values[nval++] = val;
+	  cp = icp;
+	  val = strtod(cp, &icp);
+	}
+    }
+
+  *numValues = nval;
+}
diff --git a/src/legendre.c b/src/after_sptrans.c
similarity index 62%
rename from src/legendre.c
rename to src/after_sptrans.c
index 7d7434f..d78d757 100644
--- a/src/legendre.c
+++ b/src/after_sptrans.c
@@ -1,9 +1,18 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
-#include <stdlib.h> /* malloc zhlp3 */
 
+#include "constants.h"
 
+#define  OPENMP4  201307
+#if defined(_OPENMP) && defined(OPENMP4) && _OPENMP >= OPENMP4
+#define  HAVE_OPENMP4  1
+#endif
+
+void gaussaw(double *pa, double *pw, int nlat);
+
+static
 void jspleg1(double *pleg, double plat, int ktrunc, double *work)
 {
   /*
@@ -140,7 +149,7 @@ void jspleg1(double *pleg, double plat, int ktrunc, double *work)
 /* phcs - Compute values of Legendre polynomials */
 /*        and their meridional derivatives       */
 /* ============================================= */
-
+static
 void phcs(double *pnm, double *hnm, int waves, double pmu,
 	  double *ztemp1, double *ztemp2)
 {
@@ -259,22 +268,157 @@ void phcs(double *pnm, double *hnm, int waves, double pmu,
 }
 
 
+void after_legini_full(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict pdev,
+		       double *restrict pol2, double *restrict pol3, double *restrict coslat)
+{
+  int jgl, jm, jn;
+  int jsp;
+  double gmusq;
+
+  int waves =  ntr + 1;
+  int dimsp = (ntr + 1) * (ntr + 2);
+
+  double *gmu = (double*) malloc(nlat * sizeof(double));
+  double *gwt = (double*) malloc(nlat * sizeof(double));
+
+  gaussaw(gmu, gwt, nlat);
+
+#if ! defined(_OPENMP)
+  double *pnm    = (double*) malloc(dimsp * sizeof(double));
+  double *hnm    = (double*) malloc(dimsp * sizeof(double));
+  double *ztemp1 = (double*) malloc((waves<<1) * sizeof(double));
+  double *ztemp2 = (double*) malloc((waves<<1) * sizeof(double));
+#endif
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(jm, jn, jsp, gmusq)
+#endif
+  for ( jgl = 0; jgl < nlat; jgl++ )
+    {
+#if defined(_OPENMP)
+      double *pnm    = (double*) malloc(dimsp * sizeof(double));
+      double *hnm    = (double*) malloc(dimsp * sizeof(double));
+      double *ztemp1 = (double*) malloc((waves<<1) * sizeof(double));
+      double *ztemp2 = (double*) malloc((waves<<1) * sizeof(double));
+#endif
+      gmusq = 1.0 - gmu[jgl]*gmu[jgl];
+      coslat[jgl] = sqrt(gmusq);
+
+      phcs(pnm, hnm, waves, gmu[jgl], ztemp1, ztemp2);
+
+      double zgwt = gwt[jgl];
+      double zrafgmusqr = 1./(PlanetRadius * gmusq);
+      double zradsqrtgmusqr = 1./(-PlanetRadius * sqrt(gmusq));
+
+      const int lpold = pold != NULL;
+      const int lpdev = pdev != NULL;
+      const int lpol2 = pol2 != NULL;
+      const int lpol3 = pol3 != NULL;
+
+      jsp = jgl;
+      for ( jm = 0; jm < waves; jm++ )
+	for ( jn = 0; jn < waves - jm; jn++ )
+	  {
+	               poli[jsp] = pnm[jm*waves+jn] * 2.0;
+	    if (lpold) pold[jsp] = pnm[jm*waves+jn] * zgwt;
+	    if (lpdev) pdev[jsp] = hnm[jm*waves+jn] * 2.0 * zradsqrtgmusqr;
+	    if (lpol2) pol2[jsp] = hnm[jm*waves+jn] * zgwt * zrafgmusqr;
+	    if (lpol3) pol3[jsp] = pnm[jm*waves+jn] * zgwt * jm * zrafgmusqr;
+	    jsp += nlat;
+	  }
+      
+#if defined(_OPENMP)
+      free(ztemp2);
+      free(ztemp1);
+      free(pnm);
+      free(hnm);
+#endif
+    }
+
+#if ! defined(_OPENMP)
+  free(ztemp2);
+  free(ztemp1);
+  free(pnm);
+  free(hnm);
+#endif
+  free(gwt);
+  free(gmu);
+}
+
+
+void after_legini(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict coslat)
+{
+  int jgl, jm, jn, is;
+  int isp, latn, lats;
+
+  int waves  =  ntr + 1;
+  int dimpnm = (ntr + 1)*(ntr + 4)/2;
+
+  double *gmu  = (double*) malloc(nlat * sizeof(double));
+  double *gwt  = (double*) malloc(nlat * sizeof(double));
+  double *pnm  = (double*) malloc(dimpnm * sizeof(double));
+  double *work = (double*) malloc(3*waves * sizeof(double));
+
+  gaussaw(gmu, gwt, nlat);
+  for ( jgl = 0; jgl < nlat; ++jgl ) gwt[jgl] *= 0.5;
+
+  for ( jgl = 0; jgl < nlat; ++jgl )
+    coslat[jgl] = sqrt(1.0 - gmu[jgl]*gmu[jgl]);
+
+  for ( jgl = 0; jgl < nlat/2; jgl++ )
+    {
+      double zgwt = gwt[jgl];
+
+      jspleg1(pnm, gmu[jgl], ntr, work);
+
+      latn = jgl;
+      isp = 0;
+      for ( jm = 0; jm < waves; jm++ )
+	{
+#if defined(SX)
+#pragma vdir nodep
+#endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+	  for ( jn = 0; jn < waves - jm; jn++ )
+	    {
+	      is = (jn+1)%2 * 2 - 1;
+	      lats = latn - jgl + nlat - jgl - 1;
+	      poli[latn] = pnm[isp];
+	      pold[latn] = pnm[isp] * zgwt;
+	      poli[lats] = pnm[isp] * is;
+	      pold[lats] = pnm[isp] * zgwt * is;
+	      latn += nlat;
+	      isp++;
+	    }
+	  isp++;
+	}
+    }
+
+  free(work);
+  free(pnm);
+  free(gwt);
+  free(gmu);
+}
+
+
 /* to slow for nec, 2.0 instead of 2.3 GFlops ( vector length too small ) */
-void sp2fctest(double *sa, double *fa, double *poli, int nlev, int nlat, int nfc, int nt)
+void sp2fctest(const double *sa, double *fa, const double *poli, int nlev, int nlat, int nfc, int nt)
 {
-  int lev, jm, jn, latn, lats, nsp2, is;
+  int lev, jm, jn, latn, lats, is;
   double sar, sai;
-  double *far, *fai, *pol;
-  double *sal, *fal;
+  double saris, saiis;
   double pval;
+  double *restrict far, *restrict fai;
 
-  nsp2 = (nt+1)*(nt+2);
+  long nsp2 = (nt+1)*(nt+2);
 
   for ( lev = 0; lev < nlev; lev++ )
     {
-      pol = poli;
-      fal = fa + lev*nfc*nlat;
-      sal = sa + lev*nsp2;
+      const double *restrict pol = poli;
+      const double *restrict sal = sa + lev*nsp2;
+      double *fal = fa + lev*nfc*nlat;
       memset(fal, 0, nfc*nlat*sizeof(double));
 
       for ( jm = 0; jm <= nt; jm++ )
@@ -284,19 +428,24 @@ void sp2fctest(double *sa, double *fa, double *poli, int nlev, int nlat, int nfc
 	      is = (jn+1)%2 * 2 - 1;
 	      sar = *sal++;
 	      sai = *sal++;
+              saris = sar*is;
+              saiis = sai*is;
 	      far = fal;
 	      fai = fal + nlat;
 #if defined(SX)
 #pragma vdir nodep
 #endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
 	      for ( latn = 0; latn < nlat/2; latn++ )
 		{
 		  lats = nlat - latn - 1;
 		  pval = pol[latn];
 		  far[latn] += pval * sar;
 		  fai[latn] += pval * sai;
-		  far[lats] += pval * sar * is;
-		  fai[lats] += pval * sai * is;
+		  far[lats] += pval * saris;
+		  fai[lats] += pval * saiis;
 		}
 	      pol += nlat;
 	    }
@@ -308,25 +457,22 @@ void sp2fctest(double *sa, double *fa, double *poli, int nlev, int nlat, int nfc
 
 void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nlat, long nfc, long nt)
 {
-  long lev, jmm, jfc, lat, nsp2;
-  double sar, sai;
-  double *fal;
-  double * restrict far, * restrict fai;
-  const double * restrict pol;
-  const double * restrict sal;
-
-  nsp2 = (nt+1)*(nt+2);
+  long nsp2 = (nt+1)*(nt+2);
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(jmm, jfc, lat, pol, sar, sai, sal, far, fai, fal)
+#pragma omp parallel for default(shared)
 #endif
-  for ( lev = 0; lev < nlev; lev++ )
+  for ( long lev = 0; lev < nlev; lev++ )
     {
-      pol = poli;
-      fal = fa + lev*nfc*nlat;
-      sal = sa + lev*nsp2;
+      const double *restrict pol = poli;
+      const double *restrict sal = sa + lev*nsp2;
+      double *fal = fa + lev*nfc*nlat;
       memset(fal, 0, nfc*nlat*sizeof(double));
 
+      double *restrict far, *restrict fai;
+      double sar, sai;
+      long jmm, jfc, lat;
+
       for ( jmm = 0; jmm <= nt; jmm++ )
 	{
 	  for ( jfc = jmm; jfc <= nt; jfc++ )
@@ -335,6 +481,11 @@ void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nla
 	      sai = *sal++;
 	      far = fal;
 	      fai = fal + nlat;
+              /* unaligned loop start
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+              */
 	      for ( lat = 0; lat < nlat; lat++ )
 		{
 		  far[lat] += pol[lat] * sar;
@@ -350,24 +501,22 @@ void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nla
 
 void fc2sp(double *fa, double *sa, double *poli, int nlev, int nlat, int nfc, int nt)
 {
-  int lev, jmm, jfc, lat, nsp2;
-  double sar, sai;
-  const double * restrict far;
-  const double * restrict fai;
-  const double * restrict pol;
-  double *sal;
-  double *fal;
-
-  nsp2 = (nt+1)*(nt+2);
+  int nsp2 = (nt+1)*(nt+2);
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(jmm, jfc, lat, pol, sar, sai, sal, far, fai, fal)
+#pragma omp parallel for default(shared)
 #endif
-  for ( lev = 0; lev < nlev; lev++ )
+  for ( int lev = 0; lev < nlev; lev++ )
     {
-      pol = poli;
-      fal = fa + lev*nfc*nlat;
-      sal = sa + lev*nsp2;
+      const double *restrict pol = poli;
+      double *fal = fa + lev*nfc*nlat;
+      double *sal = sa + lev*nsp2;
+
+      const double *restrict far;
+      const double *restrict fai;
+      double sar, sai;
+      int jmm, jfc, lat;
+
       for ( jmm = 0; jmm <= nt; jmm++ )
 	{
 	  for ( jfc = jmm; jfc <= nt; jfc++ )
@@ -376,6 +525,9 @@ void fc2sp(double *fa, double *sa, double *poli, int nlev, int nlat, int nfc, in
 	      fai = fal + nlat;
 	      sar = 0.0;
 	      sai = 0.0;
+#if defined(HAVE_OPENMP4)
+#pragma omp simd reduction(+:sar) reduction(+:sai)
+#endif
 	      for ( lat = 0; lat < nlat; lat++ )
 		{
 		  sar += pol[lat] * far[lat];
diff --git a/src/after_vertint.c b/src/after_vertint.c
new file mode 100644
index 0000000..8b894d0
--- /dev/null
+++ b/src/after_vertint.c
@@ -0,0 +1,665 @@
+#include <stdio.h>
+#include <stdlib.h> /* exit */
+#include <string.h>
+#include <math.h>
+
+#include "compare.h"
+#include "constants.h"
+#include "after_vertint.h"
+
+#define  SCALEHEIGHT     (-7000.)
+#define  SCALESLP        (101325.0)
+
+int Mars = 0;
+
+
+void height2pressure(double * restrict phlev, const double * restrict hlev, long nphlev)
+{
+  long k;
+  double exp_arg;
+  double height;
+
+  for ( k = 0; k < nphlev; k++ )
+    {
+      height  = hlev[k];
+      /*
+	unitsel == 1 : hlev[k] is given in meters
+	unitsel == 2 : hlev[k] is given in kilometers
+	height2pressure needs meters (MKSC-standard)
+      */
+
+      exp_arg = height / SCALEHEIGHT;
+
+      phlev[k] = SCALESLP * exp(exp_arg);
+    }
+}
+
+
+void pressure2height(double * restrict hlev, const double * restrict plev, long nphlev)
+{
+  long  k;
+
+  for ( k = 0; k < nphlev; k++ )
+    {
+      hlev[k] = log(plev[k]/SCALESLP)*SCALEHEIGHT;
+    }
+}
+
+
+void presh(double * restrict fullp, double * halfp, const double *restrict vct,
+	   const double *restrict ps, long nhlev, long ngp)
+{
+  long i, lh;
+  double zp, ze;
+  double *halfpres = halfp;
+
+  if ( ps == NULL )
+    {
+      fprintf(stderr, "ps undefined!\n");
+      exit(EXIT_FAILURE);
+    }
+
+  for ( lh = 0; lh < nhlev; lh++ )
+    {
+      zp = vct[lh];
+      ze = vct[lh+nhlev+1];
+
+      for ( i = 0; i < ngp; i++ ) halfpres[i] = zp + ze * ps[i];
+
+      halfpres += ngp;
+    }
+  memcpy(halfpres, ps, ngp*sizeof(double));
+
+  if ( fullp )
+    {
+      halfpres = halfp;
+      for ( i = 0; i < ngp*nhlev; i++ )
+	fullp[i] = 0.5 * (halfpres[i] + halfpres[i+ngp]);
+    }
+
+} /* presh */
+
+
+void genind(int *nx, const double * restrict plev, const double * restrict fullp, long ngp, long nplev, long nhlev)
+{
+  long  i, lp, lh;
+  int *nxl;
+  double pres;
+
+  memset(nx, 0, ngp*nplev*sizeof(int));
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(i, lh, pres, nxl)
+#endif
+  for ( lp = 0; lp < nplev; lp++ )
+    {
+      pres = plev[lp];
+      nxl  = nx + lp*ngp;
+      for ( lh = 0; lh < nhlev; lh++ )
+	for ( i = 0; i < ngp ; i++ )
+	   {
+	     if ( pres > fullp[lh*ngp+i] ) nxl[i] = lh;
+	   }
+    }
+
+}  /* genind */
+
+
+void genindmiss(int *nx, const double * restrict plev, int ngp, int nplev, const double * restrict ps_prog, int * restrict pnmiss)
+{
+  long i, lp;
+  int *nxl;
+  double pres;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(i, pres, nxl)
+#endif
+  for ( lp = 0; lp < nplev; lp++ )
+    {
+      pnmiss[lp] = 0;
+      pres = plev[lp];
+      nxl  = nx + lp*ngp;
+      for ( i = 0; i < ngp; i++ )
+	{
+	  if ( pres > ps_prog[i] )
+	    {
+	      nxl[i] = -1;
+	      pnmiss[lp]++;
+	    }
+	}
+    }
+
+}  /* genindmiss */
+
+
+void extra_P(double * restrict slp, const double * restrict halfp, const double * restrict fullp,
+	     const double * restrict geop, const double * restrict temp, long ngp)
+{
+  double alpha, tstar, tmsl, zprt, zprtal;
+  double zrg;
+  double zlapse = 0.0065;
+  long j;
+
+  zrg = 1.0 / PlanetGrav;
+
+  for ( j = 0; j < ngp; ++j )
+    {
+      if ( geop[j] < 0.0001 && geop[j] > -0.0001 ) slp[j] = halfp[j];
+      else
+	{
+	  alpha = PlanetRD * zlapse * zrg;
+	  tstar = (1.0 + alpha * (halfp[j]/fullp[j] - 1.0)) * temp[j];
+
+	  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
+
+	  tmsl = tstar + zlapse * zrg * geop[j];
+	  if ( tmsl > 290.5 && tstar > 290.5 )
+	    {
+	      tstar = 0.5 * (290.5 + tstar);
+	      tmsl  = tstar;
+	    }
+
+	  if ( tmsl-tstar < 0.000001 && tstar-tmsl < 0.000001 )
+	    alpha = 0.0;
+	  else if ( geop[j] > 0.0001 || geop[j] < -0.0001 )
+	    alpha = PlanetRD * (tmsl-tstar) / geop[j];
+
+	  zprt   = geop[j] / (PlanetRD * tstar);
+	  zprtal = zprt * alpha;
+	  slp[j] = halfp[j] * exp(zprt*(1.0-zprtal*(0.5-zprtal/3.0)));
+	}
+    }
+
+}  /* extrap */
+
+
+static 
+double extra_T(double pres, double halfp, double fullp, double geop, double temp)
+{
+  double tstar, ztsz, z1, ztmsl, zalph, peval, zhts, zalp;
+  double zrg;
+  double zlapse = 0.0065;
+
+  zrg   = 1.0 / PlanetGrav;
+  tstar = (1.0 + zlapse * PlanetRD * zrg * (halfp/fullp - 1.0)) * temp;
+  ztsz  = tstar;
+  z1    = tstar + zlapse * zrg * geop;
+
+  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
+
+  ztmsl = tstar + zlapse * zrg * geop;
+
+  if ( ztmsl > 290.5 && tstar > 290.5 )
+    {
+      tstar = 0.5 * (290.5 + tstar);
+      ztmsl = tstar;
+    }
+
+  if ( ztmsl > 290.5 && tstar <= 290.5 ) ztmsl=290.5;
+
+  zalph = PlanetRD*zlapse*zrg;
+
+  if ( ztmsl-tstar < 0.000001 && tstar-ztmsl < 0.000001 ) zalph=0.0;
+
+  if ( (ztmsl-tstar > 0.000001 || tstar-ztmsl > 0.000001 ) &&
+       (geop > 0.0001 || geop < -0.0001) )
+    zalph = PlanetRD*(ztmsl-tstar)/geop;
+
+  if ( pres <= halfp )
+    peval = ((halfp-pres)*temp+ (pres-fullp)*tstar)/ (halfp-fullp);
+  else
+    {
+      ztmsl = z1;
+      tstar = ztsz;
+      zhts  = geop * zrg;
+
+      if ( zhts > 2000. && z1 > 298. )
+	{
+	  ztmsl = 298.;
+	  if ( zhts < 2500. ) ztmsl = 0.002*((2500.-zhts)*z1+(zhts-2000.)*ztmsl);
+	}
+
+      if ( (ztmsl-tstar) < 0.000001 )
+	zalph = 0.;
+      else if (geop > 0.0001 || geop < -0.0001)
+	zalph = PlanetRD*(ztmsl-tstar)/geop;
+      else
+	zalph = PlanetRD*zlapse*zrg;
+
+      zalp  = zalph*log(pres/halfp);
+      peval = tstar*(1.0+zalp*(1.0+zalp*(0.5+0.16666666667*zalp)));
+    }
+
+  return peval;
+
+}  /* extra_T */
+
+
+static 
+double extra_Z(double pres, double halfp, double fullp, double geop, double temp)
+{
+  double alpha, tstar, tmsl, zalp, zalpal;
+  double zrg;
+  double zlapse = 0.0065;
+  double ztlim = 290.5;
+
+  zrg   = 1.0 / PlanetGrav;
+  alpha = PlanetRD * zlapse * zrg;
+  tstar = (1.0 + alpha * (halfp/fullp - 1.0)) * temp;
+
+  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
+
+  tmsl = tstar + zlapse * zrg * geop;
+
+  if ( tmsl > ztlim && tstar > ztlim )
+    {
+      tstar = 0.5 * (ztlim + tstar);
+      tmsl  = tstar;
+    }
+
+  if ( tmsl > ztlim && tstar <= ztlim ) tmsl = ztlim;
+
+  if ( tmsl-tstar < 0.000001 && tstar-tmsl < 0.000001 )
+    alpha = 0.0;
+  else if ( geop > 0.0001 || geop < -0.0001 )
+    alpha = PlanetRD * (tmsl-tstar) / geop;
+
+  zalp   = log(pres/halfp);
+  zalpal = zalp * alpha;
+
+  return ((geop - PlanetRD*tstar*zalp*(1.0 + zalpal*(0.5 + zalpal/6.0)))*zrg);
+}  /* extra_Z */
+
+
+void interp_X(const double * restrict gt, double *pt, const double * restrict hyb_press, const int *nx,
+	      const double * restrict plev, long nplev, long ngp, long nhlev, double missval)
+{
+  long lp, i;
+  long nl, nh;
+  const int *nxl;
+  double *ptl;
+  double pres;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, ptl)
+#endif
+  for ( lp = 0; lp < nplev; lp++ )
+    {
+      pres = plev[lp];
+      nxl  = nx + lp*ngp;
+      ptl  = pt + lp*ngp;
+      for ( i = 0; i < ngp; i++ )
+	{
+	  if ( nxl[i] == -1 )
+	    ptl[i] = missval;
+	  else
+	    {
+	      nl = nxl[i] * ngp + i;
+	      nh = nl + ngp;
+	      if ( nh >= ngp*nhlev )
+		ptl[i] = gt[nl];
+	      else
+		ptl[i] =  gt[nl] + (pres-hyb_press[nl])
+		       * (gt[nh] - gt[nl]) / (hyb_press[nh] - hyb_press[nl]);
+	    }
+	}
+    }
+}  /* interp_X */
+
+
+void interp_T(const double * restrict geop, const double * restrict gt, double *pt, const double * restrict fullp,
+	      const double * restrict halfp, const int *nx, const double * restrict plev, long nplev, long ngp,
+	      long nhlev, double missval)
+{
+  long lp, i;
+  long nl, nh;
+  const int *nxl;
+  double *ptl;
+  double pres;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, ptl)
+#endif
+  for ( lp = 0; lp < nplev; lp++ )
+    {
+      pres = plev[lp];
+      nxl  = nx + lp*ngp;
+      ptl  = pt + lp*ngp;
+#if defined(CRAY)
+#pragma _CRI inline extra_T
+#endif
+      for ( i = 0; i < ngp; i++ )
+	{
+	  nl = nxl[i];
+	  if ( nl < 0 )
+	    ptl[i] = missval;
+	  else
+	    {
+	      if ( nl > nhlev-2 )
+		{
+		  if ( Mars )
+		    ptl[i] = gt[(nhlev-1)*ngp+i];
+		  else
+#if defined(SX)
+#pragma cdir inline
+#endif
+		    ptl[i] = extra_T(pres, halfp[nhlev*ngp+i],
+				     fullp[(nhlev-1)*ngp+i], geop[i],
+				     gt[(nhlev-1)*ngp+i]);
+		}
+	      else
+		{
+		  nh = nl + 1;
+		  ptl[i] =  gt[nl*ngp+i] + (pres-fullp[nl*ngp+i])
+                         * (gt[nh*ngp+i] - gt[nl*ngp+i])
+                         / (fullp[nh*ngp+i] - fullp[nl*ngp+i]);
+		}
+	    }
+	}
+    }
+}  /* interp_T */
+
+
+void interp_Z(const double * restrict geop, const double * restrict gz, double *pz, const double * restrict fullp,
+	      const double * restrict halfp, const int *nx, const double * restrict gt, const double * restrict plev,
+	      long nplev, long ngp, long nhlev, double missval)
+{
+  long lp, i;
+  long nl, nh;
+  const int *nxl;
+  double *pzl;
+  double pres;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, pzl)
+#endif
+  for ( lp = 0; lp < nplev; lp++ )
+    {
+      pres = plev[lp];
+      nxl  = nx + lp*ngp;
+      pzl  = pz + lp*ngp;
+#if defined(CRAY)
+#pragma _CRI inline extra_Z
+#endif
+      for ( i = 0; i < ngp; i++ )
+	{
+	  nl = nxl[i];
+	  if ( nl < 0 )
+	    pzl[i] = missval;
+	  else
+	    {
+	      if ( pres > halfp[(nl+1)*ngp+i] ) nl++;
+
+	      if ( nl > nhlev-1 )
+		{
+		  if ( Mars )
+		    pzl[i] = gt[(nhlev-1)*ngp+i];
+		  else
+#if defined(SX)
+#pragma cdir inline
+#endif
+		    pzl[i] = extra_Z(pres, halfp[nhlev*ngp+i],
+				     fullp[(nhlev-1)*ngp+i], geop[i],
+				     gt[(nhlev-1)*ngp+i]);
+		}
+	      else
+		{
+		  nh = nl + 1;
+		  pzl[i] =  gz[nl*ngp+i] + (pres-halfp[nl*ngp+i])
+		         * (gz[nh*ngp+i] - gz[nl*ngp+i])
+                         / (halfp[nh*ngp+i] - halfp[nl*ngp+i]);
+		}
+	    }
+	}
+    }
+}  /* interp_Z */
+
+
+/*
+ * 3d vertical interpolation routine (see vert_interp_lev() in src/Intlevel.c)
+ */
+void vert_interp_lev3d(int gridsize, double missval, double *vardata1, double *vardata2,
+		       int nlev2, int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
+{
+  int i, ilev;
+  int idx1, idx2;
+  int offset;
+  double wgt1, wgt2;
+  double w1, w2;
+  double var1L1, var1L2, *var2;
+
+  for ( ilev = 0; ilev < nlev2; ilev++ )
+    {
+      offset = ilev*gridsize;
+      var2 = vardata2 + offset;
+
+      for ( i = 0; i < gridsize; i++ )
+	{
+          idx1 = lev_idx1[offset+i];
+          idx2 = lev_idx2[offset+i];
+          wgt1 = lev_wgt1[offset+i];
+          wgt2 = lev_wgt2[offset+i];
+
+          /* upper/lower values from input field */
+          var1L1 = *(vardata1+idx1);
+          var1L2 = *(vardata1+idx2);
+
+          /* if (cdoVerbose) printf("i:%d level %d: idx1=%d idx2=%d (offset+i:%d) wgt1=%g wgt2=%g var1L1:%g var1L2:%g ",
+           *                         i,       ilev, idx1,   idx2,    offset+i,    wgt1,   wgt2,   var1L1,   var1L2);
+           */
+	  w1 = wgt1;
+	  w2 = wgt2;
+	  if ( DBL_IS_EQUAL(var1L1, missval) ) w1 = 0;
+	  if ( DBL_IS_EQUAL(var1L2, missval) ) w2 = 0;
+
+	  if ( IS_EQUAL(w1, 0) && IS_EQUAL(w2, 0) )
+	    {
+	      var2[i] = missval;
+	    }
+	  else if ( IS_EQUAL(w1, 0) )
+	    {
+	      if ( w2 >= 0.5 )
+		var2[i] = var1L2;
+	      else
+		var2[i] = missval;	      
+	    }
+	  else if ( IS_EQUAL(w2, 0) )
+	    {
+	      if ( w1 >= 0.5 )
+		var2[i] = var1L1;
+	      else
+		var2[i] = missval;	      
+	    }
+	  else
+	    {
+	      var2[i] = var1L1*w1 + var1L2*w2;
+	    }
+	}
+    }
+}
+
+#if defined(CDO)
+#include "util.h"
+/*
+ * Create weights for the 3d vertical coordinate
+ *
+ * The resulting index sets lev_idx1 and lev_idx2 contain absolute numbers,i.e.
+ * wrt. the given gridsize. They can directly be used to read values from 3d
+ * data fields.
+ *
+ * 3d version of vert_gen_weights() (src/Intlevel.c)
+ */
+void vert_gen_weights3d(int expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
+			int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
+{
+  int i,i1, i2;
+  int    idx1 = 0, idx2 = 0;
+  double val1, val2 = 0;
+
+  for ( i = 0; i < gridsize; i++ )
+    {
+      for ( i2 = 0; i2 < nlev2; i2++ )
+        {
+          /* Because 2 levels were added to the source vertical coordinate (one on
+           * top, one at the bottom), its loop starts at 1 */
+          for ( i1 = 1; i1 < nlev1; i1++ )
+            {
+              if ( lev1[(i1-1)*gridsize+i] < lev1[i1*gridsize+i] )
+                {
+                  idx1 = (i1-1)*gridsize+i;
+                  idx2 = i1*gridsize+i;
+                }
+              else
+                {
+                  idx1 = i1*gridsize+i;
+                  idx2 = (i1-1)*gridsize+i;
+                }
+              val1 = lev1[idx1];
+              val2 = lev1[idx2];
+
+              if ( lev2[i2*gridsize+i] > val1 && lev2[i2*gridsize+i] <= val2 ) break;
+            }
+
+          if ( i1 == nlev1 ) 
+            {
+              if ( expol )
+                cdoAbort("Level %g at index %d not found! Use extrapolation", lev2[i2*gridsize],i2);
+              else
+                cdoAbort("Level %g at index %d not found!");
+            }
+
+          if ( i1-1 == 0 ) /* destination levels ios not covert by the first two input z levels */
+            {
+              lev_idx1[i2*gridsize+i] = gridsize+i;
+              lev_idx2[i2*gridsize+i] = gridsize+i;
+              lev_wgt1[i2*gridsize+i] = 0;
+              if ( expol || IS_EQUAL(lev2[i2*gridsize+i], val2) )
+                lev_wgt2[i2*gridsize+i] = 1;
+              else
+                lev_wgt2[i2*gridsize+i] = 0;
+            }
+          else if ( i1 == nlev1-1 ) /* destination level is beyond the last value of the input z field */
+            {
+              lev_idx1[i2*gridsize+i] = (nlev1-2)*gridsize+i;
+              lev_idx2[i2*gridsize+i] = (nlev1-2)*gridsize+i;
+              if ( expol || IS_EQUAL(lev2[i2*gridsize+i], val2) )
+                lev_wgt1[i2*gridsize+i] = 1;
+              else
+                lev_wgt1[i2*gridsize+i] = 0;
+              lev_wgt2[i2*gridsize+i] = 0;
+            }
+          else /* target z values has two bounday values in input z field */
+            {
+              lev_idx1[i2*gridsize+i] = idx1;
+              lev_idx2[i2*gridsize+i] = idx2;
+              lev_wgt1[i2*gridsize+i] = (lev1[idx2]        - lev2[i2*gridsize+i]) / (lev1[idx2] - lev1[idx1]);
+              lev_wgt2[i2*gridsize+i] = (lev2[i2*gridsize+i] - lev1[idx1])        / (lev1[idx2] - lev1[idx1]);
+
+            }
+  /*         if (cdoVerbose)
+   *         {
+   *           printf("i:%d i2:%d\ti2*gridsize+i:%d\tlev2[i2*gridsize+i]:%g\tidx1:%d\tidx2:%d\tlev1[idx1]:%g\tlev1[idx2]:%g\t",
+   *                   i, i2, i2*gridsize+i,         lev2[i2*gridsize+i],    idx1,    idx2,    lev1[idx1],    lev1[idx2]);
+   *           printf("\tlev_wgt1:%g\tlev_wgt2:%g\n", lev_wgt1[i2*gridsize+i], lev_wgt2[i2*gridsize+i]);
+   *         }
+   */
+          /* backshift of the indices because of the two additional levels in input vertical coordinate */
+          lev_idx1[i2*gridsize+i] -= gridsize;
+          lev_idx2[i2*gridsize+i] -= gridsize;
+
+        }
+    }
+}
+
+
+/*
+ * Create weights for the 1d vertical coordinate from a 3d vertical coordinate
+ *
+ * The resulting index sets lev_idx1 and lev_idx2 contain absolute numbers,i.e.
+ * wrt. the given gridsize. They can directly be used to read values from 3d
+ * data fields.
+ *
+ * 3d1d version of vert_gen_weights() (src/Intlevel.c)
+ */
+void vert_gen_weights3d1d(int expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
+			  int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2)
+{
+  int i,i1, i2;
+  int    idx1 = 0, idx2 = 0;
+  double val1, val2 = 0;
+
+  for ( i = 0; i < gridsize; i++ )
+    {
+      for ( i2 = 0; i2 < nlev2; i2++ )
+        {
+          /* Because 2 levels were added to the source vertical coordinate (one on
+           * top, one at the bottom), its loop starts at 1 */
+          for ( i1 = 1; i1 < nlev1; i1++ )
+            {
+              if ( lev1[(i1-1)*gridsize+i] < lev1[i1*gridsize+i] )
+                {
+                  idx1 = (i1-1)*gridsize+i;
+                  idx2 = i1*gridsize+i;
+                }
+              else
+                {
+                  idx1 = i1*gridsize+i;
+                  idx2 = (i1-1)*gridsize+i;
+                }
+              val1 = lev1[idx1];
+              val2 = lev1[idx2];
+
+              if ( lev2[i2] > val1 && lev2[i2] <= val2 ) break;
+            }
+
+          if ( i1 == nlev1 ) 
+            {
+              if ( expol )
+                cdoAbort("Level %g at index %d not found! Use extrapolation", lev2[i2],i2);
+              else
+                cdoAbort("Level %g at index %d not found!");
+            }
+
+          if ( i1-1 == 0 ) /* destination levels ios not covert by the first two input z levels */
+            {
+              lev_idx1[i2*gridsize+i] = gridsize+i;
+              lev_idx2[i2*gridsize+i] = gridsize+i;
+              lev_wgt1[i2*gridsize+i] = 0;
+              if ( expol || IS_EQUAL(lev2[i2], val2) )
+                lev_wgt2[i2*gridsize+i] = 1;
+              else
+                lev_wgt2[i2*gridsize+i] = 0;
+            }
+          else if ( i1 == nlev1-1 ) /* destination level is beyond the last value of the input z field */
+            {
+              lev_idx1[i2*gridsize+i] = (nlev1-2)*gridsize+i;
+              lev_idx2[i2*gridsize+i] = (nlev1-2)*gridsize+i;
+              if ( expol || IS_EQUAL(lev2[i2], val2) )
+                lev_wgt1[i2*gridsize+i] = 1;
+              else
+                lev_wgt1[i2*gridsize+i] = 0;
+              lev_wgt2[i2*gridsize+i] = 0;
+            }
+          else /* target z values has two bounday values in input z field */
+            {
+              lev_idx1[i2*gridsize+i] = idx1;
+              lev_idx2[i2*gridsize+i] = idx2;
+              lev_wgt1[i2*gridsize+i] = (lev1[idx2]  - lev2[i2]) / (lev1[idx2] - lev1[idx1]);
+              lev_wgt2[i2*gridsize+i] = (lev2[i2] - lev1[idx1])  / (lev1[idx2] - lev1[idx1]);
+
+            }
+  /*         if (cdoVerbose)
+   *         {
+   *           printf("i:%d i2:%d\ti2*gridsize+i:%d\tlev2[i2]:%g\tidx1:%d\tidx2:%d\tlev1[idx1]:%g\tlev1[idx2]:%g\t",
+   *                   i, i2, i2*gridsize+i,         lev2[i2],    idx1,    idx2,    lev1[idx1],    lev1[idx2]);
+   *           printf("\tlev_wgt1:%g\tlev_wgt2:%g\n", lev_wgt1[i2*gridsize+i], lev_wgt2[i2*gridsize+i]);
+   *         }
+   */
+          /* backshift of the indices because of the two additional levels in input vertical coordinate */
+          lev_idx1[i2*gridsize+i] -= gridsize;
+          lev_idx2[i2*gridsize+i] -= gridsize;
+
+        }
+    }
+}
+#endif
diff --git a/src/vinterp.h b/src/after_vertint.h
similarity index 70%
rename from src/vinterp.h
rename to src/after_vertint.h
index 9a361be..8c315e7 100644
--- a/src/vinterp.h
+++ b/src/after_vertint.h
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-void h2p(double * restrict phlev, const double * restrict hlev, long nphlev);
+void height2pressure(double * restrict phlev, const double * restrict hlev, long nphlev);
 
 void presh(double * restrict fullp, double * halfp, const double *restrict vct,
 	   const double *restrict ps, long nhlev, long ngp);
@@ -25,6 +25,14 @@ void interp_Z(const double * restrict geop, const double * restrict gz, double *
 void interp_X(const double * restrict gt, double *pt, const double * restrict hyb_press, const int *nx,
 	      const double * restrict plev, long nplev, long ngp, long nhlev, double missval);
 
+
+void vert_interp_lev3d(int gridsize, double missval, double *vardata1, double *vardata2,
+		       int nlev2, int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2);
+void vert_gen_weights3d(int expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
+			int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2);
+void vert_gen_weights3d1d(int expol, int nlev1, int gridsize, double *lev1, int nlev2, double *lev2,
+			  int *lev_idx1, int *lev_idx2, double *lev_wgt1, double *lev_wgt2);
+
 #if defined(__cplusplus)
 }
 #endif
diff --git a/src/afterburner.h b/src/afterburner.h
new file mode 100644
index 0000000..0b801a4
--- /dev/null
+++ b/src/afterburner.h
@@ -0,0 +1,260 @@
+#ifndef _AFTERBURNER_H
+#define _AFTERBURNER_H
+
+/* =============================================== */
+/* These include files should be standard on all   */
+/* UNIX systems.                                   */
+/* =============================================== */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#include <math.h>
+#include <float.h>
+#include <time.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#ifndef _ERROR_H
+#  include "error.h"
+#endif
+#ifndef _DMEMORY_H
+#  include "dmemory.h"
+#endif
+
+#ifndef TRUE
+#define TRUE  1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MaxLevel 1024
+
+#define MaxCodes  277
+
+#define S_ECHAM5  1
+
+struct Date
+{
+   int yr;
+   int mo;
+   int dy;
+   int hr;
+   int mn;
+};
+
+struct Control
+{
+  int    Verbose;
+ 
+  int    Mean;
+  int    MeanCount0;
+  int    MeanCount;
+  int    Multi;
+  int    Nfiles;
+  int    TermCount;
+
+  int    OutputInterval;
+  int    EndOfInterval;
+
+  int    AnalysisData; /* 0 = ECHAM Data, 1 = ECMWF Spectral Analyses */
+  int    DayIn;        /* day increment of infiles if Multi = TRUE    */
+  int    Debug;
+  int    Extrapolate;
+  int    Szip;
+
+  int    istreamID;
+  int    ostreamID;
+  int    ostreamID2;
+  int    ivlistID;
+  int    ovlistID;
+  int    ovlistID2;
+  int    taxisID;
+  int    taxisID2;
+
+  struct Date NextDate;
+  struct Date NewDate;
+  struct Date OldDate;
+  struct Date StartDate;
+
+  int    nvct;
+  double *vct;
+
+  int    *vert_index;
+  int    *pnmiss;
+  double *Orography;
+  double *p_of_height;
+
+  int    Type;
+  int    unitsel;
+  
+  int    Fouriers;
+  int    Latitudes;
+  int    Longitudes;
+  int    HalfLevels;
+  int    Gaussian;
+  int    Spectral;
+
+  int    Truncation;
+  int    Waves;
+
+  int    Dim3FC,    Dim3SP,    Dim3GP;
+  int    DimFC,     DimGP,     DimSP;
+  int    DimSP_half;
+
+  double *poli;
+  double *pold;
+  double *pdev;
+  double *pol2;
+  double *pol3;
+
+  double *dv2uv_f1;
+  double *dv2uv_f2;
+
+  int    NumCodesRequest;
+  
+  int    NumLevel;
+  int    NumLevelFound;
+  int    NumLevelRequest;
+  double LevelRequest[MaxLevel];
+
+  double *rcoslat;
+  double *coslat;
+  double *DerivationFactor;
+  double *Field;
+};
+  
+struct Variable
+{
+  int     needed0;   /* var needed for process  */
+  int     needed;    /* var needed for process  */
+  int     selected;  /* var selected for output */
+  int     detected;  /* var detected in input   */
+  int     comp;      /* compute var if selected and not detected */
+  int     sfit;
+  int     hlev;
+  int     plev;
+  int     ivarID;
+  int     ovarID;    /* 1st variable ID */
+  int     ovarID2;   /* 2nd variable ID used for variance */
+  int     tableID;
+  int     igridID;
+  int     ogridID;
+  int     izaxisID;
+  int     ozaxisID;
+  int     nmiss0;
+  int     nmiss;
+  double  missval;
+  double *spectral;
+  double *spectral0;
+  double *fourier;
+  double *hybrid;
+  double *hybrid0;
+  double *height;
+  double *grid;
+  double *grid0;
+  double *mean;
+  double *variance;
+  int    *samp;
+};
+
+/* FFT */
+void fft_set(double *trigs, long *ifax, long n);
+void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, double *restrict gp, long nlat, long nlon, long nlev, long nfc);
+void gp2fc(double *trig, long *ifax, const double *restrict gp, double *restrict fc, long nlat, long nlon, long nlev, long nfc);
+
+/* Convert Spectral Array to new resolution */
+void sp2sp(double *arrayIn, int truncIn, double *arrayOut, int truncOut);
+void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nlat, long nfc, long nt);
+void fc2sp(double *fa, double *sa, double *poli, int klev, int nlat, int nfc, int nt);
+
+/* Physc */
+void dv2ps(const double * restrict div, double * restrict pot, long nlev, long ntr);
+void dv2uv(double *d, double *o, double *u, double *v, double *f, double *g, int nt, int nsp, int nlev);
+void scaluv(double *fu, double rclat[], int nlat, int lot);
+void uv2dv(double *fu, double *fv, double *sd, double *sv,
+           double *pol2, double *pol3, int klev, int nlat, int nt);
+void geninx(long ntr, double *f, double *g);
+
+#define    LOW_CLOUD   34
+#define    MID_CLOUD   35
+#define    HIH_CLOUD   36
+#define    LOW_WATER   37  /* not used ?   */
+#define    MID_WATER   38  /* not used ?   */
+#define    HIH_WATER   39  /* not used ?   */
+#define    ALL_WATER   40  /* not used ?   */
+
+#define GEOPOTENTIAL  129
+#define  TEMPERATURE  130
+#define       U_WIND  131
+#define       V_WIND  132
+#define     HUMIDITY  133
+#define           PS  134
+#define        OMEGA  135
+#define    VORTICITY  138
+#define           TS  139
+#define       STREAM  148
+#define      VELOPOT  149
+#define          SLP  151
+#define         LNPS  152
+#define   DIVERGENCE  155
+#define GEOPOTHEIGHT  156
+#define    RHUMIDITY  157
+
+#define   SW_BOT_CLF  189  /* not used ?   */
+#define   LW_BOT_CLF  190  /* not used ?   */
+#define   SW_TOP_CLF  191  /* not used ?   */
+#define   LW_TOP_CLF  192  /* not used ?   */
+#define  NET_TOP_CLF  193  /* not computed */
+
+#define    WINDSPEED  259
+#define       PRECIP  260
+#define      NET_TOP  261
+#define      NET_BOT  262
+#define     NET_HEAT  263
+#define    NET_WATER  264
+#define       SW_CLF  265
+#define       LW_CLF  266
+#define      NET_CLF  267
+#define       SW_ATM  268
+#define       LW_ATM  269
+#define      NET_ATM  270
+#define  SURF_RUNOFF  271
+#define        DPSDX  273
+#define        DPSDY  274
+#define  FRESH_WATER  275
+#define      PS_PROG  276  /* PS for prognostic timestep */
+#define   HALF_PRESS  277
+#define   FULL_PRESS  278
+#define       THETAH  279
+#define       THETAF  280
+
+void after_read_vct(const char *vctfile, double **vct, int *nvct);
+
+void after_gp2sp(struct Control *globs, struct Variable *vars, int ccode);
+void after_GP2FC(double *gp, double *fc, long nlat, long nlon, long nlev, long nfc);
+void after_FC2GP(double *fc, double *gp, long nlat, long nlon, long nlev, long nfc);
+void after_FCrh2FCsh(struct Control *globs, struct Variable *vars);
+void after_SPuv2SPdv(struct Control *globs, struct Variable *vars);
+void after_FCsh2FCrh(struct Control *globs, struct Variable *vars);
+
+void after_EchamCompGP(struct Control *globs, struct Variable *vars);
+void after_processPL(struct Control *globs, struct Variable *vars);
+void after_processML(struct Control *globs, struct Variable *vars);
+
+void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss);
+void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss);
+
+void  after_AnalysisDependencies(struct Variable *vars, int ncodes);
+void  after_EchamDependencies(struct Variable *vars, int ncodes, int type, int source);
+
+void after_legini_setup(struct Control *globs, struct Variable *vars);
+
+#endif /*  afterburner.h  */
diff --git a/src/afterburnerlib.c b/src/afterburnerlib.c
new file mode 100644
index 0000000..89c03a9
--- /dev/null
+++ b/src/afterburnerlib.c
@@ -0,0 +1,2946 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cdi.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#if defined(CDO)
+#include "cdo_int.h"
+#include "pstream_write.h"
+#else
+#define  OPENMP4  201307
+#if defined(_OPENMP) && defined(OPENMP4) && _OPENMP >= OPENMP4
+#define  HAVE_OPENMP4  1
+#endif
+#endif
+#endif
+
+#include "error.h"
+#include "afterburner.h"
+#include "constants.h"
+#include "compare.h"
+#include "after_vertint.h"
+
+int afterDebug = 0;
+int labort_after = TRUE;
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+static
+char *FieldName(int code, const char *text)
+{
+  static char name[256];
+
+  sprintf(name, "[%3d].%s", code, text);
+
+  return (name);
+}
+
+/* Free array space */
+static
+void *FreeMemory(void *ptr)
+{
+  free(ptr);
+
+  return (NULL);
+}
+
+static
+void FreeSpectral(struct Variable *vars)
+{
+  int code;
+
+  for ( code = MaxCodes-1; code >= 0; --code )
+    if ( vars[code].spectral )
+      vars[code].spectral = FreeMemory(vars[code].spectral);
+}
+
+static
+void FreeFourier(struct Variable *vars)
+{
+  int code;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].fourier )
+      vars[code].fourier = FreeMemory(vars[code].fourier);
+}
+
+static
+void FreeHybrid(struct Variable *vars)
+{
+  int code;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].hybrid )
+      vars[code].hybrid = FreeMemory(vars[code].hybrid);
+}
+
+static
+void FreeGrid(struct Variable *vars)
+{
+  int code;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].grid )
+      vars[code].grid = FreeMemory(vars[code].grid);
+}
+
+static
+void FreeSamp(struct Variable *vars)
+{
+  int code;
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].samp )
+      vars[code].samp = FreeMemory(vars[code].samp);
+}
+
+/* alloc_dp - Allocate space for double array */
+static
+double *alloc_dp(int words, char *array_name)
+{
+  double *result = NULL;
+
+  if ( words > 0 )
+    {
+      result = (double *) malloc(words * sizeof(double));
+
+      if ( result == NULL ) SysError(array_name, "No Memory!");
+    }
+
+  return(result);
+}
+
+/* after_copy_array - Copy array of type double */
+static
+void after_copy_array(void *destination, void *source, int words)
+{
+   memcpy(destination, source, words*sizeof(double));
+}
+
+/* after_zero_array -  Set array of type double to zero */
+static
+void after_zero_array(double *field, int words)
+{
+   memset((char *)field, 0, words*sizeof(double));
+}
+
+static
+void IniQuaSum(double *dest, const double *restrict src, int len)
+{
+  int i;
+
+  for ( i = 0; i < len; i++ )
+    dest[i] = src[i] * src[i];
+}
+
+static 
+void AddQuaSum(double *dest, const double *restrict src, int len)
+{
+  int i;
+
+  for ( i = 0; i < len; i++ )
+    dest[i] += src[i] * src[i];
+}
+
+static
+void VarQuaSum(double *Variance, const double *restrict Sum, int len, int n)
+{
+  int i;
+  double rn1;
+
+  rn1 = 1.0 / (n-1);
+
+  for ( i = 0; i < len; i++ )
+    Variance[i] = (Variance[i] - Sum[i] * Sum[i] * n) * rn1;
+
+  for ( i = 0; i < len; i++ )
+    if (Variance[i] > 0.0) Variance[i] = sqrt(Variance[i]);
+    else                   Variance[i] = 0.0;
+}
+
+static
+void AddVector(double * restrict dest, const double *restrict src, long len, int *nmiss, double missval)
+{
+  long i;
+
+  if ( *nmiss > 0 )
+    {
+      for ( i = 0; i < len; i++ )
+	if ( IS_NOT_EQUAL(src[i], missval) )
+	  {
+	    if ( IS_NOT_EQUAL(dest[i], missval) )
+	      dest[i] += src[i];
+	    else
+	      dest[i] = src[i];
+	  }
+
+      *nmiss = 0;
+      for ( i = 0; i < len; i++ )
+	if ( IS_EQUAL(dest[i], missval) ) *nmiss = *nmiss + 1;
+
+      if ( *nmiss == 0 ) *nmiss = 1;
+    }
+  else
+    {
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+      for ( i = 0; i < len; i++ ) dest[i] += src[i];
+    }
+}
+
+static
+void Add2Vectors(double *dest, const double *restrict srcA, const double *restrict srcB, int len)
+{
+  int i;
+
+  for ( i = 0; i < len; i++ )
+    dest[i] = srcA[i] + srcB[i];
+}
+
+static
+void Sub2Vectors(double *dest, const double *restrict srcA, const double *restrict srcB, int len)
+{
+  int i;
+
+  for ( i = 0; i < len; i++ )
+    dest[i] = srcA[i] - srcB[i];
+}
+
+static
+void MultVectorScalar(double *dest, const double *restrict src, double factor, int len, int nmiss, double missval)
+{
+  int i;
+
+  if ( nmiss > 0 )
+    {
+      for ( i = 0; i < len; i++ )
+	{
+	  if ( IS_EQUAL(src[i], missval) )
+	    dest[i] = missval;
+	  else
+	    dest[i] = src[i] * factor;
+	}
+    }
+  else
+    {
+      for ( i = 0; i < len; i++ ) dest[i] = src[i] * factor;
+    }
+}
+
+static
+void DivVectorIvector(double *dest, const double *restrict src, const int *samp, int len, int *nmiss, double missval)
+{
+  int i;
+
+  *nmiss = 0;
+
+  for ( i = 0; i < len; i++ )
+    {
+      if ( IS_EQUAL(src[i], missval) || samp[i] == 0 )
+	{
+	  dest[i] = missval;
+	  *nmiss = *nmiss + 1;
+	}
+      else
+	dest[i] = src[i] / samp[i];
+    }
+}
+
+
+void after_read_vct(const char *vctfile, double **vct, int *nvct)
+{
+  int n;
+  char line[1024];
+  double va, vb;
+
+  FILE *fp = fopen(vctfile, "r");
+  if ( fp == NULL ) SysError( "Open failed on %s", vctfile);
+
+  while ( fgets(line, 1023, fp) ) nvct++;
+
+  *nvct *= 2;
+  *vct = (double *) malloc(*nvct*sizeof(double));
+
+  rewind(fp);
+  for ( int i = 0; i < *nvct/2; i++ )
+    {
+      fgets(line, 1023, fp);
+      sscanf(line, "%d %lg %lg", &n, &va, &vb);
+      *vct[i]         = va;
+      *vct[i+*nvct/2] = vb;
+    }
+  fprintf(stdout, "  Reading VCT for %d hybrid levels from file %s\n", *nvct/2-1, vctfile);
+
+  fclose(fp);
+}
+
+
+void after_gp2sp(struct Control *globs, struct Variable *vars, int ccode)
+{
+  struct Variable *var = &vars[ccode];
+  
+  if ( var->spectral == NULL )
+    {
+      if ( var->hybrid == NULL )
+	{
+	  fprintf(stderr,"%d.hybrid not found\n", ccode);
+	  exit(99);
+	}
+      
+      if ( var->fourier == NULL )
+	{
+	  long fieldSize = globs->DimFC * var->hlev;
+	  var->fourier = alloc_dp(fieldSize, "gp2sp.fourier");
+	  after_GP2FC(var->hybrid, var->fourier,
+		      globs->Latitudes, globs->Longitudes, var->hlev, globs->Fouriers);
+	}
+
+      var->spectral = alloc_dp(globs->Dim3SP, "gp2sp.spectral");
+      fc2sp(var->fourier, var->spectral,
+            globs->pold, var->hlev, globs->Latitudes, globs->Fouriers, globs->Truncation);    
+    }
+}
+
+
+void after_GP2FC(double *gp, double *fc, long nlat, long nlon, long nlev, long nfc)
+{
+  static long ifax[10];
+  static double *trig = NULL;
+
+  if ( ifax[9] != nlon )
+    {
+      if ( trig ) free (trig);
+      trig = (double *) malloc(nlon * sizeof(double));
+      fft_set (trig, ifax, nlon);
+    }
+
+  gp2fc(trig, ifax, gp, fc, nlat, nlon, nlev, nfc);
+}
+
+
+void after_FC2GP(double *fc, double *gp, long nlat, long nlon, long nlev, long nfc)
+{
+  static long ifax[10];
+  static double *trig = NULL;
+
+  if ( ifax[9] != nlon )
+    {
+      if ( trig ) free (trig);
+      trig = (double *) malloc(nlon * sizeof(double));
+      fft_set (trig, ifax, nlon);
+    }
+
+  fc2gp(trig, ifax, fc, gp, nlat, nlon, nlev, nfc);
+}
+
+/* HUMTEST */
+
+static
+void sh2rh(int AnalysisData, double *sphum, double *rhum, double *t, int lev,
+	   int dimgpout, double *level, double *fullpresshybrid)
+{
+   int lp,i;
+   int lpi,lfp;
+   double  es, qsatr;
+   double *fullp;
+   double  RALPW, RBETW, RGAMW;
+   // double  RALPS, RBETS, RGAMS;
+   double  RALP , RBET , RGAM ;
+
+   /* ***************************************************** */
+   /* Define constants for calculation in presence of water */
+   /* ***************************************************** */
+   RGAMW = (C_RCW - C_RCPV) / C_RV;
+   RBETW = C_RLVTT / C_RV + RGAMW * C_RTT;
+   RALPW = log(C_RESTT) + RBETW / C_RTT + RGAMW * log(C_RTT);
+
+   /* ***************************************************** */
+   /* Define constants for calculation in presence of  ice  */
+   /* ***************************************************** */
+   /*
+   RGAMS = (C_RCS - C_RCPV) / C_RV;
+   RBETS = C_RLSTT / C_RV + RGAMS * C_RTT;
+   RALPS = log(C_RESTT) + RBETS / C_RTT + RGAMS * log(C_RTT);
+   */
+   if (AnalysisData) fullp = level;
+   else              fullp = fullpresshybrid;
+
+   /***************************************************/
+   /* Diagnostics of saturation water vapour pressure */
+   /* over ice makes no sense, therefore ...          */
+   /* Hint of Michael Ponater                08.10.97 */
+   /***************************************************/
+   RGAM = RGAMW; RBET = RBETW; RALP = RALPW;
+   for (lp = 0; lp < lev; lp++) {
+      for (i = 0; i < dimgpout; i++) {
+         lpi = lp*dimgpout + i;
+         lfp = (1 - AnalysisData)*lpi + AnalysisData*lp;
+	 /*
+	 if (t[lpi] < C_RTT) {
+	   RGAM = RGAMS; RBET = RBETS; RALP = RALPS;
+	 } else {
+	   RGAM = RGAMW; RBET = RBETW; RALP = RALPW;
+	 }
+	 */
+         es = (exp(RALP - RBET / t[lpi] - RGAM * log(t[lpi]))) / fullp[lfp];
+         // qsat = es / (1. + C_RETV * (1. - es));
+	 qsatr = (1. + C_RETV * (1. - es)) / es;
+         rhum[lpi] = sphum[lpi] * 100. * qsatr;
+      }
+   }
+}
+
+static
+void rh2sh(double *sphum, double *rhum, double *t, int lev, int dimgpout, double *level)
+{
+   int lp,i;
+   int lpi;
+   double  es,qsat;
+   double  RALPW, RBETW, RGAMW;
+   // double  RALPS, RBETS, RGAMS;
+   double  RALP , RBET , RGAM ;
+
+/* ***************************************************** */
+/* Define constants for calculation in presence of water */
+/* ***************************************************** */
+   RGAMW = (C_RCW - C_RCPV) / C_RV;
+   RBETW = C_RLVTT / C_RV + RGAMW * C_RTT;
+   RALPW = log(C_RESTT) + RBETW / C_RTT + RGAMW * log(C_RTT);
+
+/* ***************************************************** */
+/* Define constants for calculation in presence of  ice  */
+/* ***************************************************** */
+   // RGAMS = (C_RCS - C_RCPV) / C_RV;
+   // RBETS = C_RLSTT / C_RV + RGAMS * C_RTT;
+   // RALPS = log(C_RESTT) + RBETS / C_RTT + RGAMS * log(C_RTT);
+
+/***************************************************/
+/* Diagnostics of saturation water vapour pressure */
+/* over ice makes no sense, therefore ...          */
+/* Hint of Michael Ponater                08.10.97 */
+/***************************************************/
+
+   RGAM = RGAMW; RBET = RBETW; RALP = RALPW;
+   for (lp = 0; lp < lev; lp++) {
+      for (i = 0; i < dimgpout; i++) {
+         lpi = lp*dimgpout + i;
+/*       if (t[lpi] < C_RTT) { */
+/*          RGAM = RGAMS; RBET = RBETS; RALP = RALPS; */
+/*       }  else { */
+/*          RGAM = RGAMW; RBET = RBETW; RALP = RALPW; */
+/*       } */
+         es = (exp(RALP - RBET / t[lpi] - RGAM * log(t[lpi]))) / level[lp];
+         qsat = es / (1. + C_RETV * (1. - es));
+         sphum[lpi] = rhum[lpi] * qsat /  100.;
+      }
+   }
+}
+
+
+void after_FCrh2FCsh(struct Control *globs, struct Variable *vars)
+{
+   long fieldSize = globs->DimGP * globs->NumLevelRequest;
+
+   if ( vars[RHUMIDITY].grid == NULL )
+     vars[RHUMIDITY].grid = alloc_dp(fieldSize, "vars[RHUMIDITY].grid");
+   if ( vars[TEMPERATURE].grid == NULL )
+     vars[TEMPERATURE].grid = alloc_dp(fieldSize, "vars[TEMPERATURE].grid");
+   if ( vars[HUMIDITY].grid == NULL )
+     vars[HUMIDITY].grid = alloc_dp(fieldSize, "vars[HUMIDITY].grid");
+
+   after_FC2GP(vars[RHUMIDITY].fourier, vars[RHUMIDITY].grid,
+	       globs->Latitudes, globs->Longitudes, vars[RHUMIDITY].plev, globs->Fouriers);
+   after_FC2GP(vars[TEMPERATURE].fourier, vars[TEMPERATURE].grid,
+	       globs->Latitudes, globs->Longitudes, vars[TEMPERATURE].plev, globs->Fouriers);
+
+   rh2sh(vars[HUMIDITY].grid, vars[RHUMIDITY].grid, vars[TEMPERATURE].grid, globs->NumLevelRequest,
+	 globs->DimGP, globs->LevelRequest);
+
+   after_GP2FC(vars[HUMIDITY].grid, vars[HUMIDITY].fourier,
+	       globs->Latitudes, globs->Longitudes, vars[HUMIDITY].plev, globs->Fouriers);
+
+   vars[HUMIDITY].grid    = FreeMemory(vars[HUMIDITY].grid);
+   vars[RHUMIDITY].grid   = FreeMemory(vars[RHUMIDITY].grid);
+   vars[TEMPERATURE].grid = FreeMemory(vars[TEMPERATURE].grid);
+}
+
+
+void after_SPuv2SPdv(struct Control *globs, struct Variable *vars)
+{
+   int i;
+   long fieldSize;
+   double *Div, *DivOut, *Vor, *VorOut;
+
+   Div = DivOut = vars[DIVERGENCE].spectral;
+   Vor = VorOut =  vars[VORTICITY].spectral;
+   fieldSize = globs->DimFC * globs->NumLevelRequest;
+
+   if ( vars[U_WIND].fourier == NULL )
+     vars[U_WIND].fourier = alloc_dp(fieldSize, "vars[U_WIND].fourier");
+   if ( vars[V_WIND].fourier == NULL )
+     vars[V_WIND].fourier = alloc_dp(fieldSize, "vars[V_WIND].fourier");
+
+   sp2fc(vars[U_WIND].spectral, vars[U_WIND].fourier, globs->poli,
+         globs->NumLevelRequest, globs->Latitudes, globs->Fouriers, globs->Truncation);
+   sp2fc(vars[V_WIND].spectral, vars[V_WIND].fourier, globs->poli,
+         globs->NumLevelRequest, globs->Latitudes, globs->Fouriers, globs->Truncation);
+   uv2dv(vars[U_WIND].fourier, vars[V_WIND].fourier, Div, Vor,
+         globs->pol2, globs->pol3, globs->NumLevelRequest, globs->Latitudes, globs->Truncation);
+
+   vars[U_WIND].fourier = FreeMemory(vars[U_WIND].fourier);
+   vars[V_WIND].fourier = FreeMemory(vars[V_WIND].fourier);
+
+   for (i = 0; i < globs->NumLevelRequest; ++i) {
+      sp2sp(Div, globs->Truncation, DivOut, globs->Truncation);
+      sp2sp(Vor, globs->Truncation, VorOut, globs->Truncation);
+      Div    += globs->DimSP;
+      Vor    += globs->DimSP;
+      DivOut += globs->DimSP;
+      VorOut += globs->DimSP;
+   }
+}
+
+
+void after_FCsh2FCrh(struct Control *globs, struct Variable *vars)
+{
+   long fieldSize;
+
+   fieldSize = globs->DimGP * globs->NumLevelRequest;
+
+   if ( vars[RHUMIDITY].grid == NULL )
+     vars[RHUMIDITY].grid = alloc_dp(fieldSize, "vars[RHUMIDITY].grid");
+   if ( vars[TEMPERATURE].grid == NULL )
+     vars[TEMPERATURE].grid = alloc_dp(fieldSize, "vars[TEMPERATURE].grid");
+   if ( vars[HUMIDITY].grid == NULL )
+     vars[HUMIDITY].grid = alloc_dp(fieldSize, "vars[HUMIDITY].grid");
+
+   after_FC2GP(vars[HUMIDITY].fourier, vars[HUMIDITY].grid,
+	       globs->Latitudes, globs->Longitudes, vars[HUMIDITY].plev, globs->Fouriers);
+   after_FC2GP(vars[TEMPERATURE].fourier, vars[TEMPERATURE].grid,
+	       globs->Latitudes, globs->Longitudes, vars[TEMPERATURE].plev, globs->Fouriers);
+
+   sh2rh(globs->AnalysisData, vars[HUMIDITY].grid, vars[RHUMIDITY].grid, vars[TEMPERATURE].grid, globs->NumLevelRequest,
+	 globs->DimGP, globs->LevelRequest, vars[FULL_PRESS].hybrid);
+
+   after_GP2FC(vars[RHUMIDITY].grid, vars[RHUMIDITY].fourier,
+	       globs->Latitudes, globs->Longitudes, vars[RHUMIDITY].plev, globs->Fouriers);
+
+   vars[HUMIDITY].grid    = FreeMemory(vars[HUMIDITY].grid);
+   vars[RHUMIDITY].grid   = FreeMemory(vars[RHUMIDITY].grid);
+   vars[TEMPERATURE].grid = FreeMemory(vars[TEMPERATURE].grid);
+}
+/* ENDE HUMTEST */
+
+static
+void CheckAnalyses(struct Variable *vars)
+{
+  for ( int code = 0; code < 272; code++ )
+    if ( vars[code].needed      && 
+	 code != DIVERGENCE    &&
+	 code != VORTICITY     &&
+	 code != STREAM        &&
+	 code != U_WIND        &&
+	 code != HUMIDITY      &&
+	 code != VELOPOT       &&
+	 code != V_WIND        &&
+	 code != RHUMIDITY     &&
+	 code != GEOPOTHEIGHT  && 
+	 code != PS            &&
+         vars[code].spectral == NULL && vars[code].grid == NULL )
+      {
+	if ( labort_after )
+	  Error("Code  %3d not found", code);
+	else
+	  Warning("Code  %3d not found", code);
+      }
+}
+
+/*  Process Pressure Level data */
+void after_processPL(struct Control *globs, struct Variable *vars)
+{
+  int code, l;
+  long fieldSize;
+  int lindex, nlevel;
+  int offset;
+
+  globs->MeanCount++;
+  globs->TermCount++;
+
+  if ( globs->MeanCount == 1 )
+    {
+      if ( globs->Debug ) fprintf(stderr, "CheckAnalyses: %d %d\n", globs->TermCount, globs->MeanCount);
+      CheckAnalyses(vars);
+      globs->StartDate = globs->OldDate;
+    }
+  if ( globs->TermCount  > 120 ) globs->Debug = 0;
+
+  /* ============================== */
+  /* Computations in spectral space */
+  /* ============================== */
+
+  if ( vars[TEMPERATURE].needed )
+    {
+      vars[TEMPERATURE].hlev = 2;
+      vars[TEMPERATURE].plev = globs->NumLevelRequest;
+      vars[TEMPERATURE].sfit = TRUE;
+    }
+
+  if ( vars[GEOPOTHEIGHT].comp )
+    {
+      vars[GEOPOTHEIGHT].hlev = 2;
+      vars[GEOPOTHEIGHT].plev = globs->NumLevelRequest;
+      vars[GEOPOTHEIGHT].sfit = TRUE;
+    }
+
+  if ( vars[GEOPOTHEIGHT].comp && vars[GEOPOTENTIAL].detected )
+    {
+      if ( vars[GEOPOTHEIGHT].spectral == NULL )
+	vars[GEOPOTHEIGHT].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "GEOPOTHEIGHT.spectral");
+      MultVectorScalar(vars[GEOPOTHEIGHT].spectral, vars[GEOPOTENTIAL].spectral,
+		       C_RG, globs->DimSP*globs->NumLevelRequest, 0, 0);
+      vars[GEOPOTENTIAL].needed = vars[GEOPOTENTIAL].selected;
+    }
+
+  if ( globs->Type == 50 && vars[HUMIDITY].needed && vars[HUMIDITY].spectral == NULL )
+    {
+      vars[HUMIDITY].plev = globs->NumLevelRequest;
+      vars[HUMIDITY].sfit = TRUE;
+      vars[HUMIDITY].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[HUMIDITY].spectral");
+      /*
+	SPrh2SPsh();
+      */
+      vars[RHUMIDITY].needed = vars[RHUMIDITY].selected;
+      vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+    }
+
+  if ( vars[U_WIND].spectral && vars[V_WIND].spectral &&
+       (vars[DIVERGENCE].comp || vars[VORTICITY].comp) )
+    {
+      vars[DIVERGENCE].hlev = vars[VORTICITY].hlev =    2;
+      vars[DIVERGENCE].plev = vars[VORTICITY].plev = globs->NumLevelRequest;
+      vars[DIVERGENCE].sfit = vars[VORTICITY].sfit = TRUE;
+      if ( vars[DIVERGENCE].spectral == NULL )
+	vars[DIVERGENCE].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[DIVERGENCE].spectral");
+      if ( vars[VORTICITY].spectral == NULL )
+	vars[VORTICITY].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[VORTICITY].spectral");
+      after_SPuv2SPdv(globs, vars);
+    }
+
+  if ( vars[U_WIND].comp || vars[V_WIND].comp )
+    {
+      vars[U_WIND].hlev = vars[V_WIND].hlev =    2;
+      vars[U_WIND].plev = vars[V_WIND].plev = globs->NumLevelRequest;
+      vars[U_WIND].sfit = vars[V_WIND].sfit = TRUE;
+      if ( vars[U_WIND].spectral == NULL )
+	vars[U_WIND].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[U_WIND].spectral");
+      if ( vars[V_WIND].spectral == NULL )
+	vars[V_WIND].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[V_WIND].spectral");
+      dv2uv(vars[DIVERGENCE].spectral, vars[VORTICITY].spectral,
+	    vars[U_WIND].spectral, vars[V_WIND].spectral,
+	    globs->dv2uv_f1, globs->dv2uv_f2,
+	    globs->Truncation, globs->DimSP, globs->NumLevelRequest);
+    }
+
+  if ( vars[VELOPOT].comp )
+    {
+      vars[VELOPOT].hlev =    2;
+      vars[VELOPOT].plev = globs->NumLevelRequest;
+      vars[VELOPOT].sfit = TRUE;
+      if ( vars[VELOPOT].spectral == NULL )
+	vars[VELOPOT].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[VELOPOT].spectral");
+      dv2ps(vars[DIVERGENCE].spectral, vars[VELOPOT].spectral, globs->NumLevelRequest, globs->Truncation);
+    }
+
+  if ( vars[STREAM].comp )
+    {
+      vars[STREAM].hlev =    2;
+      vars[STREAM].plev = globs->NumLevelRequest;
+      vars[STREAM].sfit = TRUE;
+      if ( vars[STREAM].spectral == NULL )
+	vars[STREAM].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[STREAM].spectral");
+      dv2ps(vars[VORTICITY].spectral, vars[STREAM].spectral, globs->NumLevelRequest, globs->Truncation);
+    }
+
+  /* --------------------------- */
+  /*  Output of spectral fields  */
+  /* --------------------------- */
+
+  if ( globs->Type == 50 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].spectral ) Error("Code %d not available on spectral space!", code);
+	      
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimSP;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].spectral+offset, 0);
+	      }	      
+	  }
+
+      FreeSpectral(vars);
+      return;
+    }
+
+  /* =============================== */
+  /* Transformation to fourier space */
+  /* Computations in fourier space   */
+  /* =============================== */
+
+  if ( globs->Type >= 60 )
+    {
+      for (code = 0; code < MaxCodes; code++)
+	if (vars[code].needed && vars[code].spectral)
+	  {
+	    if (vars[code].fourier == NULL)
+	      {
+		fieldSize = vars[code].plev * globs->DimFC;
+		vars[code].fourier = alloc_dp(fieldSize, FieldName(code,"fourier"));
+	      }
+	    sp2fc(vars[code].spectral,vars[code].fourier,globs->poli,
+		  vars[code].plev,globs->Latitudes,globs->Fouriers,globs->Truncation);
+	  }
+      if ( vars[U_WIND].needed && vars[U_WIND].fourier )
+	scaluv(vars[U_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+      if ( vars[V_WIND].needed && vars[V_WIND].fourier )
+	scaluv(vars[V_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+
+      /* HUMTEST */
+      if ( globs->Type < 70 && vars[HUMIDITY].needed && vars[HUMIDITY].fourier == NULL )
+	{
+	  vars[HUMIDITY].plev = globs->NumLevelRequest;
+	  vars[HUMIDITY].sfit = TRUE;
+	  vars[HUMIDITY].fourier = alloc_dp(globs->DimFC*globs->NumLevelRequest, "vars[HUMIDITY].fourier");
+
+	  after_FCrh2FCsh(globs, vars);
+
+	  vars[RHUMIDITY].needed = vars[RHUMIDITY].selected;
+	  vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+	}
+
+      if ( globs->Type < 70 && vars[RHUMIDITY].needed && vars[RHUMIDITY].fourier == NULL )
+	{
+	  vars[RHUMIDITY].plev = globs->NumLevelRequest;
+	  vars[RHUMIDITY].sfit = TRUE;
+	  vars[RHUMIDITY].fourier = alloc_dp(globs->DimFC*globs->NumLevelRequest, "vars[RHUMIDITY].fourier");
+
+	  after_FCsh2FCrh(globs, vars);
+
+	  vars[HUMIDITY].needed = vars[HUMIDITY].selected;
+	  vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+	}
+      /* ENDE HUMTEST */
+    }
+
+  FreeSpectral(vars);
+
+  /* -------------------------- */
+  /*  Output of fourier fields  */
+  /* -------------------------- */
+
+  if ( globs->Type == 60 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on fourier space!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, 0);
+	      }	      
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ----------------------- */
+  /*  Output of zonal means  */
+  /* ----------------------- */
+
+  if ( globs->Type == 61 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on zonal mean!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, 0);
+	      }	      
+	  }
+
+      FreeFourier(vars);
+      return;
+   }
+
+  /* ============================ */
+  /* Transformation to gridpoints */
+  /* ============================ */
+
+  if ( vars[PS].comp && vars[LNPS].grid )
+    {
+      if (vars[PS].grid == NULL) vars[PS].grid = alloc_dp(globs->DimGP, "Ps");
+      for (l = 0; l < globs->DimGP; l++) vars[PS].grid[l] = exp(vars[LNPS].grid[l]);
+    }
+
+  if ( globs->Type >= 70 )
+    {
+      for (code = 0; code < MaxCodes; code++)
+	if (vars[code].needed && vars[code].fourier)
+	  {
+	    if (vars[code].grid == NULL)
+	      {
+		fieldSize = vars[code].plev * globs->DimGP;
+		vars[code].grid = alloc_dp(fieldSize,FieldName(code,"grid"));
+	      }
+
+	    after_FC2GP(vars[code].fourier,vars[code].grid,
+			globs->Latitudes,globs->Longitudes,vars[code].plev,globs->Fouriers);
+	  }
+    }
+
+   FreeFourier(vars);
+
+  /* HUMTEST */
+  /* -------------------------------- */
+  /*  Computation in gridpoint space  */
+  /* -------------------------------- */
+
+  if ( vars[RHUMIDITY].needed && vars[RHUMIDITY].grid == NULL )
+    {
+      vars[RHUMIDITY].plev = globs->NumLevelRequest;
+      vars[RHUMIDITY].sfit = TRUE;
+      vars[RHUMIDITY].grid = alloc_dp(globs->DimGP*globs->NumLevelRequest, "vars[RHUMIDITY].grid");
+      sh2rh(globs->AnalysisData, vars[HUMIDITY].grid, vars[RHUMIDITY].grid, vars[TEMPERATURE].grid, globs->NumLevelRequest,
+	    globs->DimGP, globs->LevelRequest, vars[FULL_PRESS].hybrid);
+      vars[HUMIDITY].needed = vars[HUMIDITY].selected;
+      vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+    }
+
+  if ( vars[HUMIDITY].needed && vars[HUMIDITY].grid == NULL )
+    {
+      vars[HUMIDITY].plev = globs->NumLevelRequest;
+      vars[HUMIDITY].sfit = TRUE;
+      vars[HUMIDITY].grid = alloc_dp(globs->DimGP*globs->NumLevelRequest, "vars[HUMIDITY].grid");
+      rh2sh(vars[HUMIDITY].grid, vars[RHUMIDITY].grid, vars[TEMPERATURE].grid, globs->NumLevelRequest,
+	    globs->DimGP, globs->LevelRequest);
+      vars[RHUMIDITY].needed = vars[RHUMIDITY].selected;
+      vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+    }
+  /* HUMTEST ENDE */
+
+  /* -------------------------- */
+  /*  Computation of Means      */
+  /* -------------------------- */
+
+  if ( globs->Mean )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].needed && vars[code].grid )
+	{
+	  fieldSize = globs->DimGP * vars[code].plev;
+	  if (vars[code].mean == NULL)
+	    vars[code].mean = alloc_dp(fieldSize,FieldName(code,"mean"));
+
+	  if (globs->MeanCount == 1)
+	    after_copy_array(vars[code].mean, vars[code].grid, fieldSize);
+	  else
+	    AddVector(vars[code].mean, vars[code].grid, fieldSize,
+		      &vars[code].nmiss, vars[code].missval);
+
+	  if ( globs->EndOfInterval )
+	    {
+	      if ( vars[code].samp == NULL )
+		MultVectorScalar(vars[code].mean, vars[code].mean, 1.0/globs->MeanCount, fieldSize,
+				 vars[code].nmiss, vars[code].missval);
+	      else
+		DivVectorIvector(vars[code].mean, vars[code].mean, vars[code].samp, fieldSize,
+				 &vars[code].nmiss, vars[code].missval);
+	    }
+	}
+
+  /* -------------------------- */
+  /*  Computation of Variances  */
+  /* -------------------------- */
+
+  if ( globs->Mean > 1 )
+    for (code = 0; code < MaxCodes; code++)
+      if (vars[code].needed && vars[code].mean)
+	{
+	  fieldSize = globs->DimGP * vars[code].plev;
+	  if (vars[code].variance == NULL)
+	    vars[code].variance = alloc_dp(fieldSize,FieldName(code,"var"));
+	  if (globs->MeanCount == 1)
+	    IniQuaSum(vars[code].variance,vars[code].grid,fieldSize);
+	  else
+	    AddQuaSum(vars[code].variance,vars[code].grid,fieldSize);
+
+	  if (globs->EndOfInterval) VarQuaSum(vars[code].variance,vars[code].mean,fieldSize, globs->MeanCount);
+	}
+
+  if ( globs->Mean && !globs->EndOfInterval )
+    {
+      FreeGrid(vars);
+      return;
+    }
+
+  /* ---------------------------------------------- */
+  /*  Output of pressure level means and variances  */
+  /* ---------------------------------------------- */
+
+  if ( globs->Type == 70 && globs->Mean && globs->EndOfInterval )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimGP;
+		if ( globs->Mean != 2 )
+		  {
+		    streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		    streamWriteRecord(globs->ostreamID, vars[code].mean+offset, vars[code].nmiss);
+		  }
+		if ( globs->Mean >= 2 )
+		  {
+		    streamDefRecord(globs->ostreamID2, vars[code].ovarID2, lindex);
+		    streamWriteRecord(globs->ostreamID2, vars[code].variance+offset, vars[code].nmiss);
+		  }
+	      }
+	  }
+
+      FreeSamp(vars);
+      FreeGrid(vars);
+      return;
+    }
+
+  /* -------------------------------- */
+  /*  Output of pressure level grids  */
+  /* -------------------------------- */
+
+  if ( globs->Type == 70 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimGP;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].grid+offset, vars[code].nmiss);
+	      }
+	  }
+
+      FreeGrid(vars);
+      return;
+    }
+}
+
+static
+void theta(double *pthetaf, double *pthetah, double *ph, double *ps,
+	   double *tf, double *ts, int levels, int dimgp, int dim3gp)
+{
+   int h,l;
+   double  kappa;
+   double *thetah = pthetah;
+   double *thetaf = pthetaf;
+
+   kappa = PlanetRD / C_RCPD;
+
+   for (h = 0; h < dimgp; h++) thetah[h] = 0.0;
+   thetah += dimgp;
+   for (l = 0; l < levels - 1; l++) {
+      for (h = 0; h < dimgp; h++) {
+         thetah[h] = 0.5 * (tf[h] + tf[h+dimgp]) * pow((ps[h]/ph[h]),kappa);
+      }
+      ph += dimgp;
+      tf += dimgp;
+      thetah += dimgp;
+   }
+   after_copy_array(thetah,ts,dimgp);
+   thetah = pthetah;
+   for (h = 0; h < dim3gp; h++) {
+      thetaf[h] = 0.5 * (thetah[h] + thetah[h+dimgp]);
+   }
+}
+
+static
+void windSpeed(double *uvspeed, double *u, double *v, int dim3gp)
+{
+  int i;
+
+  for (i = 0; i < dim3gp; i++)
+    uvspeed[i] = sqrt(u[i] * u[i] + v[i] * v[i]);
+}
+
+static
+void Omega(double *omega_in, double *divergence, double *u_wind, double *v_wind,
+	   double *halfpress, double *fullpress, double *dpsdx, double *dpsdy,
+	   double *vct, int dimgp, int nlev)
+{
+  int i, j;
+  double DeltaHybrid, Cterm, Pterm;
+  double *diver, *halfp, *fullp, *uwind, *vwind;
+  double *omega = omega_in;
+
+  /* Compute half level part of vertical velocity */
+
+  for ( i = 0; i < dimgp; i++ ) omega[i] = 0.0;
+
+  for ( j = 0; j < nlev; j++ )
+    {
+      omega = omega_in   + j*dimgp;
+      halfp = halfpress  + j*dimgp;
+      diver = divergence + j*dimgp;
+      uwind = u_wind     + j*dimgp;
+      vwind = v_wind     + j*dimgp;
+
+      DeltaHybrid = vct[nlev+j+2] - vct[nlev+j+1];
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined (__uxp__)
+#pragma loop novrec
+#endif
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+      for ( i = 0; i < dimgp; i++ )
+	{
+	  omega[i+dimgp] = omega[i]
+	                 - diver[i] * (halfp[i+dimgp] - halfp[i])
+	                 - DeltaHybrid * (uwind[i]*dpsdx[i] + vwind[i]*dpsdy[i]);
+	}
+    }
+
+  /* interpolate to full levels  */
+
+  for ( j = 0; j < nlev; j++ )
+    {
+      omega = omega_in   + j*dimgp;
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined (__uxp__)
+#pragma loop novrec
+#endif
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+      for ( i = 0; i < dimgp; i++ )
+	omega[i] = 0.5 * (omega[i] + omega[i+dimgp]);
+    }
+
+  /* compute full level part of vertical velocity */
+
+#if defined (_OPENMP)
+#pragma omp parallel for default(shared) private(i, omega, halfp, fullp, uwind, vwind, DeltaHybrid, Cterm, Pterm)
+#endif
+  for ( j = 0; j < nlev; j++ )
+    {
+      omega = omega_in   + j*dimgp;
+      halfp = halfpress  + j*dimgp;
+      fullp = fullpress  + j*dimgp;
+      uwind = u_wind     + j*dimgp;
+      vwind = v_wind     + j*dimgp;
+
+      DeltaHybrid = vct[nlev+j+2] - vct[nlev+j+1];
+      if ( fabs(DeltaHybrid) > 0 )
+	{
+	  Cterm = vct[j+1]*vct[nlev+j+1] - vct[j]*vct[nlev+j+2];
+#if defined (__uxp__)
+#pragma loop novrec
+#endif
+	  for ( i = 0; i < dimgp; i++ )
+	    {
+	      if ( Cterm != 0.0 )
+		Pterm = Cterm / (halfp[i+dimgp]-halfp[i]) * log(halfp[i+dimgp]/halfp[i]);
+	      else
+		Pterm = 0.0;
+
+	      omega[i] += fullp[i] * (uwind[i]*dpsdx[i] + vwind[i]*dpsdy[i])
+	 	        / (halfp[i+dimgp] - halfp[i]) * (DeltaHybrid + Pterm);
+	    }
+	}
+    }
+}
+
+
+void MakeGeopotHeight(double *geop, double *gt, double *gq, double *ph, int nhor, int nlev)
+{
+  int i, j;
+  double vtmp;
+  double zrg;
+  double z2log2;
+  double *restrict geopl, *restrict gtl, *restrict gql, *restrict phl;
+
+  z2log2 = 2.0 * log(2.0);
+  vtmp   = (C_RV / PlanetRD) - 1.0;
+  zrg    = 1.0 / PlanetGrav;
+
+  if ( gq ) /* Humidity is present */
+    {
+      for ( j = nlev ; j > 1 ; j-- )
+	{
+	  geopl = geop + nhor*(j-1);
+	  gtl   = gt   + nhor*(j-1);
+	  gql   = gq   + nhor*(j-1);
+	  phl   = ph   + nhor*(j-1);
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+	  for ( i = 0; i < nhor; i++ )
+	    geopl[i] = geopl[i+nhor] + PlanetRD * gtl[i] * (1.0 + vtmp * gql[i])
+	             * log(phl[i+nhor] / phl[i]);
+	}
+
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+      for ( i = 0; i < nhor; i++ )
+	geop[i] = geop[i+nhor] + PlanetRD * gt[i] * (1.0 + vtmp * gq[i]) * z2log2;
+    }
+  else    /* No humidity */
+    {
+      geopl = geop + nhor;
+      phl   = ph   + nhor;
+      
+      for ( j = nlev ; j > 1 ; j-- )
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+        for ( i = nhor * (j-1) ; i < nhor * j ; i++ )
+          geop[i] = geopl[i] + PlanetRD * gt[i] * log(phl[i] / ph[i]);
+
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+      for ( i = 0; i < nhor; i++ )
+	geop[i] = geopl[i] + PlanetRD * gt[i] * z2log2;
+    }
+
+#if defined (SX)
+#pragma vdir nodep
+#endif
+#if defined (_OPENMP)
+#pragma omp parallel for
+#endif
+  for ( i = 0; i < nhor * (nlev+1); i++ ) geop[i] *= zrg;
+}
+
+#define  SCALESLP        (101325.0)
+
+/* ======================================== */
+/* LayerWater integral liquid water content */
+/* ======================================== */
+
+void LayerWater(double *ww, double *ll, double pmax, double pmin,
+		int DimGP, int HalfLevels, double *vct)
+{
+   int  i,k;
+   int  MaxLev, MinLev;
+   double pph[MaxLevel];
+
+   for (k = 0; k < HalfLevels; k++)
+      pph[k] = vct[k] + vct[k+HalfLevels] * SCALESLP;
+   for (k = 0; k < HalfLevels; k++)
+      if (pph[k] > pmax) break;
+   MaxLev = k - 1;
+   for (k = HalfLevels - 1; k >= 0; k--)
+      if (pph[k] < pmin) break;
+   MinLev = k;
+
+   after_zero_array (ll, DimGP);
+
+   for (k = MaxLev; k <= MinLev; k++) {
+     for (i = 0;     i < DimGP;  i++)
+        ll[i] += ww[i+k*DimGP] * (pph[k+1] - pph[k]);
+   }
+   for (i = 0; i < DimGP; i++) ll[i] /= PlanetGrav;
+}
+
+/* ================================================= */
+/* LayerCloud calculates random overlap cloud cover */
+/* ================================================= */
+
+void LayerCloud(double *cc, double *ll, double pmax, double pmin,
+		int DimGP, int HalfLevels, double *vct)
+{
+   int  i, k;
+   int  MaxLev, MinLev;
+   double pph[MaxLevel];
+   double ZEPSEC = 1.0e-12;
+
+   for (k = 0; k < HalfLevels; k++)
+      pph[k] = vct[k] + vct[k+HalfLevels] * SCALESLP;
+   for (k = 0; k < HalfLevels; k++)
+      if (pph[k] > pmax) break;
+   MaxLev = k - 1;
+   for (k  =  HalfLevels - 1; k >=0; k--)
+      if (pph[k] < pmin) break;
+   MinLev = k;
+
+   for (i = 0; i < DimGP; i++) ll[i] = 1. - cc[i+MaxLev*DimGP];
+
+   for (k = MaxLev + 1; k <= MinLev; k++) {
+     for (i = 0;     i < DimGP;  i++)
+         ll[i] *= (1. - MAX(cc[i+(k-1)*DimGP],cc[i+k*DimGP]))
+                / (1. - MIN(cc[i+(k-1)*DimGP],1.-ZEPSEC));
+   }
+   for (i = 0; i < DimGP; i++) ll[i] = 1. - ll[i];
+}
+
+/* Grid Point Computations */
+void after_EchamCompGP(struct Control *globs, struct Variable *vars)
+{
+  int l;
+
+  if ( vars[GEOPOTHEIGHT].comp || vars[SLP].comp || vars[THETAF].needed ||
+       vars[HALF_PRESS].needed || vars[RHUMIDITY].comp || vars[OMEGA].comp ||
+       globs->Type >= 30 )
+    {
+      if ( vars[FULL_PRESS].hybrid == NULL )
+	vars[FULL_PRESS].hybrid = alloc_dp(globs->Dim3GP, "vars[FULL_PRESS].hybrid");
+
+      vars[HALF_PRESS].hlev = globs->NumLevel+1;
+      vars[HALF_PRESS].plev = globs->NumLevelRequest;
+      vars[HALF_PRESS].sfit = FALSE;
+
+      if ( vars[HALF_PRESS].hybrid == NULL )
+	vars[HALF_PRESS].hybrid = alloc_dp(globs->Dim3GP+globs->DimGP, "vars[HALF_PRESS].hybrid");
+
+      presh(vars[FULL_PRESS].hybrid, vars[HALF_PRESS].hybrid, globs->vct, vars[PS_PROG].hybrid,
+	    globs->NumLevel, globs->DimGP);
+    }
+
+  if ( globs->unitsel > 2 ) vars[FULL_PRESS].hybrid = FreeMemory(vars[FULL_PRESS].hybrid);
+
+  if ( vars[THETAF].needed )
+    {
+      vars[THETAF].hlev = globs->NumLevel;
+      vars[THETAF].plev = globs->NumLevelRequest;
+      vars[THETAF].sfit = TRUE;
+      if ( vars[THETAF].hybrid == NULL )
+	vars[THETAF].hybrid = alloc_dp(globs->Dim3GP, "vars[THETAF].hybrid");
+      if ( vars[THETAH].hybrid == NULL )
+	vars[THETAH].hybrid = alloc_dp(globs->Dim3GP, "vars[THETAH].hybrid");
+      theta(vars[THETAF].hybrid, vars[THETAH].hybrid, vars[HALF_PRESS].hybrid, vars[PS_PROG].hybrid,
+	    vars[TEMPERATURE].hybrid, vars[TS].hybrid, globs->NumLevel, globs->DimGP, globs->Dim3GP);
+    }
+
+  if ( vars[GEOPOTHEIGHT].comp )
+    {
+      vars[GEOPOTHEIGHT].hlev = globs->NumLevel+1;
+      vars[GEOPOTHEIGHT].plev = globs->NumLevelRequest;
+      vars[GEOPOTHEIGHT].sfit = TRUE;
+      vars[GEOPOTHEIGHT].hybrid = alloc_dp(globs->Dim3GP+globs->DimGP, "vars[GEOPOTHEIGHT].hybrid");
+
+      after_copy_array(vars[GEOPOTHEIGHT].hybrid+globs->Dim3GP, globs->Orography, globs->DimGP);
+      MakeGeopotHeight(vars[GEOPOTHEIGHT].hybrid, vars[TEMPERATURE].hybrid,
+		       vars[HUMIDITY].hybrid, vars[HALF_PRESS].hybrid, globs->DimGP, globs->NumLevel);
+
+      vars[HUMIDITY].needed = vars[HUMIDITY].selected;
+    }
+
+  if ( vars[DPSDX].needed || vars[DPSDY].needed )
+    for (l = 0; l < globs->DimGP; l++)
+      {
+	vars[DPSDX].hybrid[l] *= vars[PS_PROG].hybrid[l];
+	vars[DPSDY].hybrid[l] *= vars[PS_PROG].hybrid[l];
+      }
+
+  if ( vars[OMEGA].comp )
+    {
+      vars[OMEGA].hlev = globs->NumLevel+1;
+      vars[OMEGA].plev = globs->NumLevelRequest;
+      vars[OMEGA].sfit = TRUE;
+      vars[OMEGA].hybrid = alloc_dp(globs->Dim3GP+globs->DimGP, "OMEGA.hybrid");
+
+      Omega(vars[OMEGA].hybrid, vars[DIVERGENCE].hybrid, vars[U_WIND].hybrid, vars[V_WIND].hybrid,
+	    vars[HALF_PRESS].hybrid, vars[FULL_PRESS].hybrid, vars[DPSDX].hybrid, vars[DPSDY].hybrid,
+	    globs->vct, globs->DimGP, globs->NumLevel);
+      
+      vars[DPSDX].needed = vars[DPSDX].selected;
+      vars[DPSDY].needed = vars[DPSDY].selected;
+    }
+
+  if ( vars[WINDSPEED].comp )
+    {
+      vars[WINDSPEED].hlev = globs->NumLevel;
+      vars[WINDSPEED].plev = globs->NumLevelRequest;
+      vars[WINDSPEED].sfit = TRUE;
+      vars[WINDSPEED].hybrid = alloc_dp(globs->Dim3GP, "vars[WINDSPEED].hybrid");
+
+      windSpeed(vars[WINDSPEED].hybrid, vars[U_WIND].hybrid, vars[V_WIND].hybrid, globs->Dim3GP);
+    }
+
+  if ( vars[RHUMIDITY].comp )
+    {
+      vars[RHUMIDITY].hlev = globs->NumLevel;
+      vars[RHUMIDITY].plev = globs->NumLevelRequest;
+      vars[RHUMIDITY].sfit = FALSE;
+      vars[RHUMIDITY].hybrid = alloc_dp(globs->Dim3GP, "vars[RHUMIDITY].hybrid");
+
+      sh2rh(globs->AnalysisData, vars[HUMIDITY].hybrid, vars[RHUMIDITY].hybrid, vars[TEMPERATURE].hybrid, globs->NumLevel,
+	    globs->DimGP, globs->LevelRequest, vars[FULL_PRESS].hybrid);
+
+      vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+      vars[HUMIDITY].needed    = vars[HUMIDITY].selected;
+    }
+
+  if ( vars[PS].comp )
+    {
+      vars[PS].hlev = 1;
+      vars[PS].plev = 1;
+      vars[PS].sfit = TRUE; /* ??? */
+      vars[PS].hybrid = alloc_dp(globs->DimGP, "vars[PS].hybrid");
+      for (l = 0; l < globs->DimGP; l++) vars[PS].hybrid[l] = exp(vars[LNPS].hybrid[l]);
+    }
+
+  if ( vars[SLP].comp )
+    {
+      vars[SLP].hlev = 1;
+      vars[SLP].plev = 1;
+      vars[SLP].sfit = TRUE;
+      vars[SLP].hybrid = alloc_dp(globs->DimGP, "vars[SLP].hybrid");
+
+      extra_P(vars[SLP].hybrid, vars[HALF_PRESS].hybrid + globs->Dim3GP,
+	      vars[FULL_PRESS].hybrid + globs->Dim3GP - globs->DimGP , globs->Orography,
+	      vars[TEMPERATURE].hybrid + globs->Dim3GP - globs->DimGP , globs->DimGP);
+      vars[TEMPERATURE].needed = vars[TEMPERATURE].selected || vars[GEOPOTHEIGHT].selected;
+    }
+
+  if ( vars[PRECIP].comp )
+    {
+      vars[PRECIP].hlev = vars[PRECIP].plev = 1;
+      vars[PRECIP].sfit = FALSE;
+      vars[PRECIP].hybrid = alloc_dp(globs->DimGP, "PRECIP.hybrid");
+      Add2Vectors(vars[PRECIP].hybrid, vars[142].hybrid, vars[143].hybrid, globs->DimGP);
+    }
+
+  if ( vars[NET_TOP].comp )
+    {
+      vars[NET_TOP].hlev = vars[NET_TOP].plev = 1;
+      vars[NET_TOP].sfit = FALSE;
+      vars[NET_TOP].hybrid = alloc_dp(globs->DimGP, "NET_TOP.hybrid");
+      Add2Vectors(vars[NET_TOP].hybrid, vars[178].hybrid, vars[179].hybrid, globs->DimGP);
+    }
+
+  if ( vars[NET_BOT].comp )
+    {
+      vars[NET_BOT].hlev = vars[NET_BOT].plev = 1;
+      vars[NET_BOT].sfit = FALSE;
+      vars[NET_BOT].hybrid = alloc_dp(globs->DimGP, "NET_BOT.hybrid");
+      Add2Vectors(vars[NET_BOT].hybrid, vars[176].hybrid, vars[177].hybrid, globs->DimGP);
+    }
+
+  if ( vars[NET_HEAT].comp )
+    {
+      vars[NET_HEAT].hlev = vars[NET_HEAT].plev = 1;
+      vars[NET_HEAT].sfit = FALSE;
+      vars[NET_HEAT].hybrid = alloc_dp(globs->DimGP, "NET_HEAT.hybrid");
+      /*
+      if ( Source == S_ECHAM5 )
+	{
+	  MultVectorScalar(vars[NET_HEAT].hybrid, vars[218].hybrid, (-3.345e5), globs->DimGP,
+	                   vars[218].nmiss, vars[218].missval);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[176].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[177].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[146].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[147].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[206].hybrid, globs->DimGP);
+	  Sub2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[208].hybrid, globs->DimGP);
+	  Sub2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[209].hybrid, globs->DimGP);
+	}
+      else
+      */
+	{
+	  MultVectorScalar(vars[NET_HEAT].hybrid, vars[218].hybrid, C_TIMES_RHOH2O, globs->DimGP,
+			   vars[218].nmiss, vars[218].missval);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[176].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[177].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[146].hybrid, globs->DimGP);
+	  Add2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[147].hybrid, globs->DimGP);
+	  Sub2Vectors(vars[NET_HEAT].hybrid, vars[NET_HEAT].hybrid, vars[220].hybrid, globs->DimGP);
+	}
+    }
+
+  if ( vars[NET_WATER].comp )
+    {
+      vars[NET_WATER].hlev = vars[NET_WATER].plev = 1;
+      vars[NET_WATER].sfit = FALSE;
+      vars[NET_WATER].hybrid = alloc_dp(globs->DimGP, "NET_WATER.hybrid");
+      Sub2Vectors(vars[NET_WATER].hybrid, vars[182].hybrid ,      vars[160].hybrid, globs->DimGP);
+      Add2Vectors(vars[NET_WATER].hybrid, vars[NET_WATER].hybrid, vars[142].hybrid, globs->DimGP);
+      Add2Vectors(vars[NET_WATER].hybrid, vars[NET_WATER].hybrid, vars[143].hybrid, globs->DimGP);
+    }
+
+  if ( vars[LOW_WATER].comp)
+    {
+      vars[LOW_WATER].hlev = vars[LOW_WATER].plev = 1;
+      vars[LOW_WATER].sfit = FALSE;
+      vars[LOW_WATER].hybrid = alloc_dp(globs->DimGP, "vars[LOW_WATER].hybrid");
+      LayerWater(vars[222].hybrid, vars[LOW_WATER].hybrid, 75000.,101300., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[MID_WATER].comp)
+    {
+      vars[MID_WATER].hlev = vars[MID_WATER].plev = 1;
+      vars[MID_WATER].sfit = FALSE;
+      vars[MID_WATER].hybrid = alloc_dp(globs->DimGP, "vars[MID_WATER].hybrid");
+      LayerWater(vars[222].hybrid, vars[MID_WATER].hybrid, 46000., 73000., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[HIH_WATER].comp )
+    {
+      vars[HIH_WATER].hlev = vars[HIH_WATER].plev = 1;
+      vars[HIH_WATER].sfit = FALSE;
+      vars[HIH_WATER].hybrid = alloc_dp(globs->DimGP, "vars[HIH_WATER].hybrid");
+      LayerWater(vars[222].hybrid, vars[HIH_WATER].hybrid,  5000., 44000., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[ALL_WATER].comp )
+    {
+      vars[ALL_WATER].hlev = vars[ALL_WATER].plev = 1;
+      vars[ALL_WATER].sfit = FALSE;
+      vars[ALL_WATER].hybrid = alloc_dp(globs->DimGP, "vars[ALL_WATER].hybrid");
+      LayerWater(vars[222].hybrid, vars[ALL_WATER].hybrid,  5000.,101300., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[LOW_CLOUD].comp )
+    {
+      vars[LOW_CLOUD].hlev = vars[LOW_CLOUD].plev = 1;
+      vars[LOW_CLOUD].sfit = FALSE;
+      vars[LOW_CLOUD].hybrid = alloc_dp(globs->DimGP, "vars[LOW_CLOUD].hybrid");
+      LayerCloud(vars[223].hybrid, vars[LOW_CLOUD].hybrid, 75000.,101300., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[MID_CLOUD].comp )
+    {
+      vars[MID_CLOUD].hlev = vars[MID_CLOUD].plev = 1;
+      vars[MID_CLOUD].sfit = FALSE;
+      vars[MID_CLOUD].hybrid = alloc_dp(globs->DimGP, "vars[MID_CLOUD].hybrid");
+      LayerCloud(vars[223].hybrid, vars[MID_CLOUD].hybrid, 46000., 73000., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[HIH_CLOUD].comp )
+    {
+      vars[HIH_CLOUD].hlev = vars[HIH_CLOUD].plev = 1;
+      vars[HIH_CLOUD].sfit = FALSE;
+      vars[HIH_CLOUD].hybrid = alloc_dp(globs->DimGP, "vars[HIH_CLOUD].hybrid");
+      LayerCloud(vars[223].hybrid, vars[HIH_CLOUD].hybrid,  5000., 44000., globs->DimGP, globs->HalfLevels, globs->vct);
+    }
+
+  if ( vars[SW_CLF].comp )
+    {
+      vars[SW_CLF].hlev = vars[SW_CLF].plev = 1;
+      vars[SW_CLF].sfit = FALSE;
+      vars[SW_CLF].hybrid = alloc_dp(globs->DimGP, "SW_CLF.hybrid");
+      Sub2Vectors(vars[SW_CLF].hybrid, vars[178].hybrid, vars[224].hybrid, globs->DimGP);
+    }
+
+  if ( vars[SW_BOT_CLF].comp )
+    {
+      vars[SW_BOT_CLF].hlev = vars[SW_BOT_CLF].plev = 1;
+      vars[SW_BOT_CLF].sfit = FALSE;
+      vars[SW_BOT_CLF].hybrid = alloc_dp(globs->DimGP, "vars[SW_BOT_CLF].hybrid");
+      Sub2Vectors(vars[SW_BOT_CLF].hybrid, vars[176].hybrid, vars[185].hybrid, globs->DimGP);
+    }
+
+  if ( vars[SW_TOP_CLF].comp )
+    {
+      vars[SW_TOP_CLF].hlev = vars[SW_TOP_CLF].plev = 1;
+      vars[SW_TOP_CLF].sfit = FALSE;
+      vars[SW_TOP_CLF].hybrid = alloc_dp(globs->DimGP, "vars[SW_TOP_CLF].hybrid");
+      Sub2Vectors(vars[SW_TOP_CLF].hybrid, vars[178].hybrid, vars[187].hybrid, globs->DimGP);
+    }
+
+  if ( vars[LW_CLF].comp )
+    {
+      vars[LW_CLF].hlev = vars[LW_CLF].plev = 1;
+      vars[LW_CLF].sfit = FALSE;
+      vars[LW_CLF].hybrid = alloc_dp(globs->DimGP, "LW_CLF.hybrid");
+      Sub2Vectors(vars[LW_CLF].hybrid, vars[179].hybrid, vars[225].hybrid, globs->DimGP);
+    }
+
+  if ( vars[LW_BOT_CLF].comp )
+    {
+      vars[LW_BOT_CLF].hlev = vars[LW_BOT_CLF].plev = 1;
+      vars[LW_BOT_CLF].sfit = FALSE;
+      vars[LW_BOT_CLF].hybrid = alloc_dp(globs->DimGP, "vars[LW_BOT_CLF].hybrid");
+      Sub2Vectors(vars[LW_BOT_CLF].hybrid, vars[177].hybrid, vars[186].hybrid, globs->DimGP);
+    }
+
+  if ( vars[LW_TOP_CLF].comp )
+    {
+      vars[LW_TOP_CLF].hlev = vars[LW_TOP_CLF].plev = 1;
+      vars[LW_TOP_CLF].sfit = FALSE;
+      vars[LW_TOP_CLF].hybrid = alloc_dp(globs->DimGP, "vars[LW_TOP_CLF].hybrid");
+      Sub2Vectors(vars[LW_TOP_CLF].hybrid, vars[179].hybrid, vars[188].hybrid, globs->DimGP);
+    }
+
+  if ( vars[NET_CLF].comp )
+    {
+      vars[NET_CLF].hlev = vars[NET_CLF].plev = 1;
+      vars[NET_CLF].sfit = FALSE;
+      vars[NET_CLF].hybrid = alloc_dp(globs->DimGP, "NET_CLF.hybrid");
+      Add2Vectors(vars[NET_CLF].hybrid, vars[178].hybrid, vars[179].hybrid, globs->DimGP);
+      Sub2Vectors(vars[NET_CLF].hybrid, vars[NET_CLF].hybrid, vars[224].hybrid, globs->DimGP);
+      Sub2Vectors(vars[NET_CLF].hybrid, vars[NET_CLF].hybrid, vars[225].hybrid, globs->DimGP);
+    }
+
+  if ( vars[SW_ATM].comp )
+    {
+      vars[SW_ATM].hlev = vars[SW_ATM].plev = 1;
+      vars[SW_ATM].sfit = FALSE;
+      vars[SW_ATM].hybrid = alloc_dp(globs->DimGP, "vars[SW_ATM].hybrid");
+      Sub2Vectors(vars[SW_ATM].hybrid, vars[178].hybrid, vars[176].hybrid,globs->DimGP);
+    }
+
+  if ( vars[LW_ATM].comp )
+    {
+      vars[LW_ATM].hlev = vars[LW_ATM].plev = 1;
+      vars[LW_ATM].sfit = FALSE;
+      vars[LW_ATM].hybrid = alloc_dp(globs->DimGP, "vars[LW_ATM].hybrid");
+      Sub2Vectors(vars[LW_ATM].hybrid, vars[179].hybrid, vars[177].hybrid,globs->DimGP);
+    }
+
+  if ( vars[NET_ATM].comp )
+    {
+      vars[NET_ATM].hlev = vars[NET_ATM].plev = 1;
+      vars[NET_ATM].sfit = FALSE;
+      vars[NET_ATM].hybrid = alloc_dp(globs->DimGP, "vars[NET_ATM].hybrid");
+      Add2Vectors(vars[NET_ATM].hybrid, vars[178].hybrid, vars[179].hybrid,globs->DimGP);
+      Sub2Vectors(vars[NET_ATM].hybrid, vars[NET_ATM].hybrid, vars[176].hybrid,globs->DimGP);
+      Sub2Vectors(vars[NET_ATM].hybrid, vars[NET_ATM].hybrid, vars[177].hybrid,globs->DimGP);
+    }
+
+  if ( vars[SURF_RUNOFF].comp )
+    {
+      vars[SURF_RUNOFF].hlev = vars[SURF_RUNOFF].plev = 1;
+      vars[SURF_RUNOFF].sfit = FALSE;
+      vars[SURF_RUNOFF].hybrid = alloc_dp(globs->DimGP, "vars[SURF_RUNOFF].hybrid");
+      Sub2Vectors(vars[SURF_RUNOFF].hybrid, vars[182].hybrid, vars[221].hybrid,globs->DimGP);
+      Add2Vectors(vars[SURF_RUNOFF].hybrid, vars[SURF_RUNOFF].hybrid, vars[142].hybrid,globs->DimGP);
+      Add2Vectors(vars[SURF_RUNOFF].hybrid, vars[SURF_RUNOFF].hybrid, vars[143].hybrid,globs->DimGP);
+    }
+
+  if ( vars[FRESH_WATER].comp )
+    {
+      vars[FRESH_WATER].hlev = vars[FRESH_WATER].plev = 1;
+      vars[FRESH_WATER].sfit = FALSE;
+      vars[FRESH_WATER].hybrid = alloc_dp(globs->DimGP, "vars[FRESH_WATER].hybrid");
+      Add2Vectors(vars[FRESH_WATER].hybrid, vars[142].hybrid, vars[143].hybrid, globs->DimGP);
+      Add2Vectors(vars[FRESH_WATER].hybrid, vars[FRESH_WATER].hybrid, vars[182].hybrid, globs->DimGP);
+    }
+}
+
+static
+void CheckContent(struct Variable *vars, int timestep)
+{
+  for ( int code = 0; code < 272; code++ )
+    {
+      /*  if ( code == GEOPOTENTIAL ) continue; */
+      if ( code ==          SLP ) continue;
+      if ( code == GEOPOTHEIGHT ) continue;
+      if ( code ==       STREAM ) continue;
+      if ( code ==      VELOPOT ) continue;
+      if ( code ==       U_WIND ) continue;
+      if ( code ==       V_WIND ) continue;
+      if ( code ==        OMEGA ) continue;
+      if ( code ==    RHUMIDITY ) continue;
+      if ( code ==    LOW_CLOUD ) continue;
+      if ( code ==    MID_CLOUD ) continue;
+      if ( code ==    HIH_CLOUD ) continue;
+      if ( code ==           PS ) continue;
+      if ( code ==     HUMIDITY )
+	{
+	  if ( vars[code].needed && !vars[code].selected &&
+	       vars[code].spectral == NULL &&
+	       vars[code].hybrid   == NULL )
+	    {
+	      Warning( "No humidity in data file, set to zero !");
+	      vars[code].needed = FALSE;
+	    }
+	}
+      else
+	{
+	  if ( vars[code].needed && !vars[code].comp &&
+	       vars[code].spectral == NULL &&
+	       vars[code].hybrid   == NULL )
+	    {
+	      if ( labort_after )
+		Error( "Code  %3d not found at timestep %d!", code, timestep);
+	      else
+		Warning( "Code  %3d not found at timestep %d!", code, timestep);
+	    }
+	}
+    }
+  /*
+  if ( NumLevelRequest > 0 )
+    {
+      vars[HALF_PRESS].needed = 1;
+      vars[FULL_PRESS].needed = 1;
+    }
+
+  code = HALF_PRESS;
+  if ( vars[code].needed && !vars[code].comp &&
+       vars[code].spectral == NULL && vars[code].hybrid == NULL )
+    Error( "Hybrid model level not found!");
+
+  code = FULL_PRESS;
+  if ( vars[code].needed && !vars[code].comp &&
+       vars[code].spectral == NULL && vars[code].hybrid == NULL )
+    Error( "Hybrid model level not found!");
+  */
+}
+
+static
+void Derivate(double field[], double derilam[], int levels,
+	      int Waves, int Latitudes, double DerivationFactor[])
+{
+   int l, n, lev;
+   int i;
+
+   i = 0;
+   for (lev = 0; lev < levels; lev++)
+   for (n = 0; n < Waves    ; n++) {
+     for (l = 0; l < Latitudes; l++) {
+       derilam[i] = -n * field[i+Latitudes] * DerivationFactor[l];
+       i++;
+     }
+     for (l = 0; l < Latitudes; l++) {
+       derilam[i] =  n * field[i-Latitudes] * DerivationFactor[l];
+       i++;
+     }
+   }
+}
+
+/* Process Model Level data */
+void after_processML(struct Control *globs, struct Variable *vars)
+{
+  int code,l,i;
+  long fieldSize = 0;
+  int lindex, nlevel;
+  int offset;
+  int leveltype;
+  int nmiss;
+  double *pressureLevel = NULL;
+
+  globs->MeanCount++;
+  globs->TermCount++;
+
+  CheckContent(vars, globs->TermCount);
+
+  if ( globs->MeanCount == 1 )
+    {
+      if ( globs->Debug ) Message( "TermCount = %d MeanCount = %d", globs->TermCount, globs->MeanCount);
+      globs->StartDate = globs->OldDate;
+    }
+
+  if ( globs->TermCount  > 120 ) globs->Debug = 0;
+
+  /* ============================== */
+  /* Computations in spectral space */
+  /* ============================== */
+
+  if ( vars[U_WIND].comp || vars[V_WIND].comp )
+    {
+      vars[U_WIND].hlev = vars[V_WIND].hlev = vars[DIVERGENCE].hlev;
+      vars[U_WIND].plev = vars[V_WIND].plev = vars[DIVERGENCE].plev;
+      vars[U_WIND].sfit = vars[V_WIND].sfit = TRUE;
+      vars[U_WIND].spectral = alloc_dp(globs->Dim3SP, "vars[U_WIND].spectral");
+      vars[V_WIND].spectral = alloc_dp(globs->Dim3SP, "vars[V_WIND].spectral");
+
+      if ( vars[DIVERGENCE].spectral == NULL ) after_gp2sp(globs, vars, DIVERGENCE);
+      if ( vars[VORTICITY].spectral == NULL )  after_gp2sp(globs, vars, VORTICITY);
+
+      dv2uv(vars[DIVERGENCE].spectral, vars[VORTICITY].spectral,
+	    vars[U_WIND].spectral, vars[V_WIND].spectral,
+	    globs->dv2uv_f1, globs->dv2uv_f2,
+	    globs->Truncation, globs->DimSP, vars[DIVERGENCE].hlev);
+    }
+
+   if ( vars[VELOPOT].comp && globs->Type < 30 )
+     {
+       vars[VELOPOT].hlev = vars[DIVERGENCE].hlev;
+       vars[VELOPOT].plev = vars[DIVERGENCE].plev;
+       vars[VELOPOT].spectral = alloc_dp(globs->Dim3SP, "vars[VELOPOT].spectral");
+
+       if ( vars[DIVERGENCE].spectral == NULL ) after_gp2sp(globs, vars, DIVERGENCE);
+
+       dv2ps(vars[DIVERGENCE].spectral, vars[VELOPOT].spectral, vars[DIVERGENCE].hlev, globs->Truncation);
+     }
+
+   if ( vars[STREAM].comp && globs->Type < 30 )
+     {
+       vars[STREAM].hlev = vars[VORTICITY].hlev;
+       vars[STREAM].plev = vars[VORTICITY].plev;
+       vars[STREAM].spectral = alloc_dp(globs->Dim3SP, "vars[STREAM].spectral");
+
+       if ( vars[VORTICITY].spectral == NULL ) after_gp2sp(globs, vars, VORTICITY);
+
+       dv2ps(vars[VORTICITY].spectral, vars[STREAM].spectral,
+	     vars[VORTICITY].hlev, globs->Truncation);
+     }
+
+   if ( vars[VORTICITY].spectral && !vars[VORTICITY].needed )
+        vars[VORTICITY].spectral = FreeMemory(vars[VORTICITY].spectral);
+
+   if ( vars[DIVERGENCE].spectral && !vars[DIVERGENCE].needed )
+        vars[DIVERGENCE].spectral = FreeMemory(vars[DIVERGENCE].spectral);
+
+  /* --------------------------- */
+  /*  Output of spectral fields  */
+  /* --------------------------- */
+
+  if ( globs->Type == 0 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].spectral ) Error("Code %d not available on spectral space!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimSP;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].spectral+offset, 0);
+	      }
+	  }
+
+      FreeSpectral(vars);
+      return;
+    }
+
+  /* ------------------------------- */
+  /*  Computations in fourier space  */
+  /* ------------------------------- */
+
+  if ( globs->Type >= 10 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].spectral )
+	  {
+	    if ( vars[code].fourier == NULL )
+	      {
+		fieldSize = vars[code].hlev * globs->DimFC;
+		vars[code].fourier = alloc_dp(fieldSize,
+						FieldName(code,"fourier"));
+		sp2fc(vars[code].spectral, vars[code].fourier, globs->poli,
+		      vars[code].hlev, globs->Latitudes, globs->Fouriers, globs->Truncation);
+	      }
+	    if ( code != LNPS )
+	      vars[code].spectral = FreeMemory(vars[code].spectral);
+	  }
+
+      /*    if (globs->Type < 60) globs->poli = FreeMemory(globs->poli); */
+      /*    if (globs->Type < 50) globs->pol2 = FreeMemory(globs->pol2); */
+      /*    if (globs->Type < 50) globs->pol3 = FreeMemory(globs->pol3); */
+
+      if ( vars[U_WIND].needed && vars[U_WIND].fourier )
+	scaluv(vars[U_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevel);
+      if ( vars[V_WIND].needed && vars[V_WIND].fourier )
+	scaluv(vars[V_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevel);
+
+      if ( vars[DPSDX].needed )
+	{
+	  vars[DPSDX].hlev = 1;
+	  vars[DPSDX].plev = 1;
+	  vars[DPSDX].sfit = FALSE;
+	  vars[DPSDX].fourier = alloc_dp(globs->DimFC, "vars[DPSDX].fourier");
+	  if ( vars[LNPS].fourier == NULL )  after_gp2sp(globs, vars, LNPS);
+	  Derivate(vars[LNPS].fourier, vars[DPSDX].fourier, 1, globs->Waves, globs->Latitudes, globs->DerivationFactor);
+	}
+      if ( vars[DPSDY].needed )
+	{
+	  vars[DPSDY].hlev = 1;
+	  vars[DPSDY].plev = 1;
+	  vars[DPSDY].sfit = FALSE;
+	  vars[DPSDY].fourier = alloc_dp(globs->DimFC, "vars[DPSDY].fourier");
+	  if ( vars[LNPS].spectral == NULL )  after_gp2sp(globs, vars, LNPS);
+	  sp2fc(vars[LNPS].spectral, vars[DPSDY].fourier, globs->pdev,
+		vars[DPSDY].hlev, globs->Latitudes, globs->Fouriers, globs->Truncation);
+	}
+    }
+
+  FreeSpectral(vars);
+
+  /* -------------------------- */
+  /*  Output of fourier fields  */
+  /* -------------------------- */
+
+  if ( globs->Type == 10 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on fourier space!", code);
+	    
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, 0);
+	      }
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ----------------------- */
+  /*  Output of zonal means  */
+  /* ----------------------- */
+
+  if ( globs->Type == 11 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on zonal mean!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, 0);
+	      }
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ------------------------------ */
+  /*  Transformation to gridpoints  */
+  /* ------------------------------ */
+
+  if ( globs->Type >= 20 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].fourier )
+	  {
+	    if ( vars[code].hybrid == NULL )
+	      {
+		fieldSize = globs->DimGP * vars[code].hlev;
+		vars[code].hybrid = alloc_dp(fieldSize,
+					       FieldName(code,"hybrid"));
+		after_FC2GP(vars[code].fourier,vars[code].hybrid,
+			    globs->Latitudes,globs->Longitudes,vars[code].hlev,globs->Fouriers);
+	      }
+	    vars[code].fourier = FreeMemory(vars[code].fourier);
+	  }
+
+      if ( vars[PS_PROG].comp && vars[PS_PROG].hybrid == NULL )
+	{
+	  vars[PS_PROG].hybrid = alloc_dp(globs->DimGP, "PS_PROG");
+	  if ( vars[LNPS].hybrid )
+	    {
+	      for (l = 0; l < globs->DimGP; l++) vars[PS_PROG].hybrid[l] = exp(vars[LNPS].hybrid[l]);
+	    }
+	  else if ( vars[PS].hybrid )
+	    {
+	      Warning("log surface pressure (code 152) not found - using surface pressure (code 134)!");
+	      after_copy_array(vars[PS_PROG].hybrid, vars[PS].hybrid, globs->DimGP);
+	    }
+	  else
+	    {
+	      Error("surface pressure not found!");
+	    }
+	}
+      vars[LNPS].needed = vars[LNPS].selected;
+      
+      if ( globs->Orography == NULL )
+	{
+	  globs-> Orography = alloc_dp(globs->DimGP , "Orography");
+	  if ( vars[GEOPOTENTIAL].hybrid )
+	    after_copy_array(globs->Orography, vars[GEOPOTENTIAL].hybrid, globs->DimGP);
+	  else
+	    {
+	      if ( vars[GEOPOTENTIAL].selected || globs->Type >= 30 )
+		{
+		  Warning("Orography not found - using zero orography!");
+		  after_zero_array(globs->Orography, globs->DimGP);
+		}
+	    }
+	}
+      vars[GEOPOTENTIAL].needed = vars[GEOPOTENTIAL].selected;
+
+      after_EchamCompGP(globs, vars);
+    }
+
+  FreeFourier(vars);
+
+  if ( globs->Type == 20 )
+    {
+      /* ----------------------- */
+      /*  Means on hybrid grids  */
+      /* ----------------------- */
+
+      if ( globs->Mean )
+	{
+	  for ( code = 0; code < MaxCodes; code++ )
+	    {
+	      if ( vars[code].selected && vars[code].hybrid )
+		{
+		  fieldSize = globs->DimGP * vars[code].hlev;
+
+		  if ( vars[code].mean == NULL )
+		    vars[code].mean = alloc_dp(fieldSize, FieldName(code, "mean"));
+
+		  if ( globs->Mean > 1 && vars[code].variance == NULL )
+		    vars[code].variance = alloc_dp(fieldSize, FieldName(code, "variance"));
+
+		  if ( globs->MeanCount == 1 )
+		    {
+		      after_copy_array(vars[code].mean, vars[code].hybrid, fieldSize);
+		      if ( globs->Mean > 1 )
+			IniQuaSum(vars[code].variance, vars[code].hybrid, fieldSize);
+		    }
+		  else
+		    {
+		      AddVector(vars[code].mean, vars[code].hybrid, fieldSize,
+				&vars[code].nmiss, vars[code].missval);
+		      if ( globs->Mean > 1 )
+			AddQuaSum(vars[code].variance, vars[code].hybrid, fieldSize);
+		    }
+
+		  if ( globs->EndOfInterval )
+		    {
+		      if ( vars[code].samp == NULL )
+			MultVectorScalar(vars[code].hybrid, vars[code].mean, 1.0/globs->MeanCount, fieldSize,
+					 vars[code].nmiss, vars[code].missval);
+		      else
+			DivVectorIvector(vars[code].hybrid, vars[code].mean, vars[code].samp, fieldSize,
+					 &vars[code].nmiss, vars[code].missval);
+
+		      if ( globs->Mean > 1 )
+			VarQuaSum(vars[code].variance, vars[code].hybrid, fieldSize, globs->MeanCount);
+		    }
+		}
+	    }
+	}
+
+      /* ---------------------------- */
+      /* Output of hybrid level grids */
+      /* ---------------------------- */
+
+      if ( globs->Mean == 0 || globs->EndOfInterval )
+	{
+	  for ( code = 0; code < MaxCodes; code++ )
+	    if ( vars[code].selected )
+	      {
+		if ( vars[code].hybrid == NULL )
+		  Error("Internal problem. Code %d not allocated!", code);
+
+		nlevel = zaxisInqSize(vars[code].ozaxisID);
+		for ( lindex = 0; lindex < nlevel; lindex++ )
+		  {
+		    offset = lindex*globs->DimGP;
+		    if ( globs->Mean != 2 )
+		      {
+			streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+			streamWriteRecord(globs->ostreamID, vars[code].hybrid+offset, vars[code].nmiss);
+		      }
+		    if ( globs->Mean >= 2 )
+		      {
+			streamDefRecord(globs->ostreamID2, vars[code].ovarID2, lindex);
+			streamWriteRecord(globs->ostreamID2, vars[code].variance+offset, vars[code].nmiss);
+		      }
+		  }
+	      }
+
+	  FreeSamp(vars);
+	}
+
+      FreeHybrid(vars);
+      return;
+    }
+
+  /* -------------------------------------- */
+  /* Vertical interpolation / extrapolation */
+  /* -------------------------------------- */
+
+  if ( globs->Type >= 30 )
+    {
+      if ( globs->vert_index == NULL )
+	globs->vert_index = (int *) malloc(globs->NumLevelRequest*globs->DimGP*sizeof(int));
+
+      if ( globs->unitsel )
+	{
+	  if ( globs->p_of_height == NULL ) globs->p_of_height = alloc_dp(globs->NumLevelRequest,"p_of_height");
+	  height2pressure(globs->p_of_height, globs->LevelRequest, globs->NumLevelRequest);
+	  pressureLevel = globs->p_of_height;
+	}
+      else
+	{
+	  pressureLevel = globs->LevelRequest;
+	}
+
+      genind(globs->vert_index, pressureLevel, vars[FULL_PRESS].hybrid, globs->DimGP, globs->NumLevelRequest, globs->NumLevel);
+
+      nmiss = 0;
+      if ( ! globs->Extrapolate )
+	{
+	  if ( globs->pnmiss == NULL ) globs->pnmiss = (int *) malloc(globs->NumLevelRequest*sizeof(int));  
+	  genindmiss(globs->vert_index, pressureLevel, globs->DimGP, globs->NumLevelRequest, vars[PS_PROG].hybrid, globs->pnmiss);
+	  for ( i = 0; i < globs->NumLevelRequest; i++ ) nmiss += globs->pnmiss[i];
+	}
+
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].hybrid )
+	  {
+	    leveltype = zaxisInqType(vars[code].izaxisID);
+	    if ( vars[code].hlev == 1 || leveltype != ZAXIS_HYBRID || (vars[code].hlev < globs->NumLevel) )
+	      {
+		if ( vars[code].grid ) FreeMemory(vars[code].grid);
+		vars[code].grid = vars[code].hybrid;
+		vars[code].hybrid = NULL;
+	      }
+	    else
+	      {
+		if ( vars[code].grid == NULL )
+		  {
+		    fieldSize = globs->DimGP * globs->NumLevelRequest;
+		    vars[code].grid = alloc_dp(fieldSize, FieldName(code, "grid"));
+		  }
+
+		if ( code == TEMPERATURE )
+		  {
+		    interp_T(globs->Orography, vars[TEMPERATURE].hybrid, vars[TEMPERATURE].grid,
+			     vars[FULL_PRESS].hybrid, vars[HALF_PRESS].hybrid, globs->vert_index,
+			     pressureLevel, globs->NumLevelRequest, globs->DimGP, globs->NumLevel, vars[code].missval);
+		  }
+		else if ( code == GEOPOTHEIGHT )
+		  {
+		    if ( vars[TEMPERATURE].hybrid == NULL ) Error("Code  130 not found!");
+		    interp_Z(globs->Orography, vars[GEOPOTHEIGHT].hybrid, vars[GEOPOTHEIGHT].grid,
+			     vars[FULL_PRESS].hybrid, vars[HALF_PRESS].hybrid, globs->vert_index,
+			     vars[TEMPERATURE].hybrid,
+			     pressureLevel, globs->NumLevelRequest, globs->DimGP, globs->NumLevel, vars[code].missval);
+		  }
+		else
+		  {
+		    interp_X(vars[code].hybrid, vars[code].grid, vars[FULL_PRESS].hybrid,
+			     globs->vert_index, pressureLevel, globs->NumLevelRequest, globs->DimGP, globs->NumLevel, vars[code].missval);
+		  }
+
+		if ( ! globs->Extrapolate ) vars[code].nmiss = nmiss;
+
+		if ( code != TEMPERATURE )
+		  vars[code].hybrid = FreeMemory(vars[code].hybrid);
+	      }
+	  }
+    }
+
+  vars[TEMPERATURE].needed = vars[TEMPERATURE].selected;
+  FreeHybrid(vars);
+  if ( vars[HALF_PRESS].hybrid )
+    vars[HALF_PRESS].hybrid = FreeMemory(vars[HALF_PRESS].hybrid);
+
+  /* -------------------------------- */
+  /*  Output of pressure level grids  */
+  /* -------------------------------- */
+
+  if ( globs->Type == 30 && globs->Mean == 0 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected && vars[code].grid )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimGP;
+		if ( globs->Mean != 2 )
+		  {
+		    streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		    streamWriteRecord(globs->ostreamID, vars[code].grid+offset, vars[code].nmiss);
+		  }
+	      }
+	  }
+      
+      FreeGrid(vars);
+      return;
+    }
+
+  /* ---------------------- */
+  /*  Computation of Means  */
+  /* ---------------------- */
+
+  if ( globs->Type >= 30 && globs->Mean )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].needed && vars[code].grid )
+	{
+	  fieldSize = globs->DimGP * vars[code].plev;
+
+	  if ( vars[code].mean == NULL )
+	    vars[code].mean = alloc_dp(fieldSize, FieldName(code, "mean"));
+
+	  if ( globs->MeanCount == 1 )
+	    after_copy_array(vars[code].mean, vars[code].grid, fieldSize);
+	  else
+	    AddVector(vars[code].mean, vars[code].grid, fieldSize,
+		      &vars[code].nmiss, vars[code].missval);
+
+	  if ( globs->EndOfInterval )
+	    {
+	      if ( vars[code].samp == NULL )
+		MultVectorScalar(vars[code].mean, vars[code].mean, 1.0/globs->MeanCount, fieldSize,
+				 vars[code].nmiss, vars[code].missval);
+	      else
+		DivVectorIvector(vars[code].mean, vars[code].mean, vars[code].samp, fieldSize,
+				 &vars[code].nmiss, vars[code].missval);
+	    }
+	}
+
+  /* -------------------------- */
+  /*  Computation of Variances  */
+  /* -------------------------- */
+
+  if ( globs->Type >= 30 && globs->Mean > 1 )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].needed && vars[code].mean )
+	{
+	  fieldSize = globs->DimGP * vars[code].plev;
+
+	  if (vars[code].variance == NULL)
+	    vars[code].variance = alloc_dp(fieldSize, FieldName(code, "var"));
+
+	  if ( globs->MeanCount == 1 )
+	    IniQuaSum(vars[code].variance, vars[code].grid, fieldSize);
+	  else
+	    AddQuaSum(vars[code].variance, vars[code].grid, fieldSize);
+
+	  if ( globs->EndOfInterval )
+	    VarQuaSum(vars[code].variance, vars[code].mean, fieldSize, globs->MeanCount);
+	}
+
+   if ( globs->Mean && !globs->EndOfInterval )
+     {
+       FreeGrid(vars);
+       return;
+     }
+
+  /* --------------------------------------------- */
+  /*  Output of pressure level means and variances */
+  /* --------------------------------------------- */
+
+  if ( globs->Type == 30 && globs->Mean )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected && vars[code].mean )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimGP;
+		if ( globs->Mean != 2 )
+		  {
+		    streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		    streamWriteRecord(globs->ostreamID, vars[code].mean+offset, vars[code].nmiss);
+		  }
+		if ( globs->Mean >= 2 )
+		  {
+		    streamDefRecord(globs->ostreamID2, vars[code].ovarID2, lindex);
+		    streamWriteRecord(globs->ostreamID2, vars[code].variance+offset, vars[code].nmiss);
+		  }
+	      }
+	  }
+
+      FreeSamp(vars);
+      FreeGrid(vars);
+      return;
+    }
+
+
+  /* ------------------ */
+  /*  Free mean fields  */
+  /* ------------------ */
+
+  if ( globs->Type >= 40 && globs->Mean )
+    for ( code = 0; code < MaxCodes; code++ )
+      if ( vars[code].mean )
+	{
+	  if ( vars[code].variance ) vars[code].variance = FreeMemory(vars[code].variance);
+	  if ( vars[code].grid )     vars[code].grid     = FreeMemory(vars[code].grid);
+	  vars[code].grid = vars[code].mean;
+	  vars[code].mean = NULL;
+	}
+
+  /* --------------------------------- */
+  /*  Transformation to fourier space  */
+  /* --------------------------------- */
+
+  if ( globs->Type >= 40 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].grid && (vars[code].sfit || globs->Type < 70) )
+	  {
+	    if ( vars[code].nmiss > 0 )
+	      Error("Missing values for code %d unsupported with TYPE > 30!", code);
+
+	    if ( vars[code].fourier == NULL )
+	      {
+		fieldSize = globs->DimFC * vars[code].plev;
+		vars[code].fourier = alloc_dp(fieldSize,FieldName(code,"fourier"));
+	      }
+
+	    after_GP2FC(vars[code].grid, vars[code].fourier,
+			globs->Latitudes, globs->Longitudes, vars[code].plev, globs->Fouriers);
+
+	    if ( vars[code].grid && (vars[code].sfit || globs->Type < 70) )
+	      vars[code].grid = FreeMemory(vars[code].grid);
+	  }
+    }
+
+  for (code = 0; code < MaxCodes; code++)
+    if (vars[code].grid && (vars[code].sfit || globs->Type < 70))
+      vars[code].grid = FreeMemory(vars[code].grid);
+
+  /* -------------------------- */
+  /*  Output of fourier fields  */
+  /* -------------------------- */
+
+  if ( globs->Type == 40 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on fourier space!", code);
+	    
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, vars[code].nmiss);
+	      }
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* --------------------- */
+  /* Output of zonal means */
+  /* --------------------- */
+
+  if ( globs->Type == 41 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on zonal mean!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, vars[code].nmiss);
+	      }
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ---------------------------------- */
+  /*  Transformation to spectral space  */
+  /* ---------------------------------- */
+
+  if ( globs->Type >= 50 )
+    {
+      if ( vars[U_WIND].needed && vars[U_WIND].fourier )
+	scaluv(vars[U_WIND].fourier, globs->coslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+      if ( vars[V_WIND].needed && vars[V_WIND].fourier )
+	scaluv(vars[V_WIND].fourier, globs->coslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].fourier )
+	  {
+	    if ( vars[code].spectral == NULL )
+	      {
+		fieldSize = vars[code].plev * globs->DimSP;
+		vars[code].spectral = alloc_dp(fieldSize, FieldName(code,"spectral"));
+	      }
+
+	    fc2sp(vars[code].fourier,vars[code].spectral,
+		  globs->pold,vars[code].plev,globs->Latitudes,globs->Fouriers,globs->Truncation);
+	  }
+
+      if ( vars[DIVERGENCE].needed || vars[VORTICITY].needed ||
+	   vars[VELOPOT].needed    || vars[STREAM].needed )
+	{
+	  if ( vars[DIVERGENCE].spectral == NULL )
+	    vars[DIVERGENCE].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest,
+						   "vars[DIVERGENCE].spectral");
+	  if ( vars[VORTICITY].spectral == NULL )
+	    vars[VORTICITY].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest,
+						  "vars[VORTICITY].spectral");
+	  if ( (vars[U_WIND].fourier == 0 || vars[V_WIND].fourier == 0) && globs->NumLevelRequest )
+	    Error("uwind or vwind missing!");
+	  uv2dv(vars[U_WIND].fourier, vars[V_WIND].fourier,
+		vars[DIVERGENCE].spectral, vars[VORTICITY].spectral,
+		globs->pol2, globs->pol3, globs->NumLevelRequest, globs->Latitudes, globs->Truncation);
+	}
+
+      if ( vars[VELOPOT].needed )
+	{
+	  vars[VELOPOT].hlev = vars[DIVERGENCE].hlev;
+	  vars[VELOPOT].plev = vars[DIVERGENCE].plev;
+	  vars[VELOPOT].sfit = TRUE;
+	  if ( vars[VELOPOT].spectral == NULL )
+	    vars[VELOPOT].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[VELOPOT].spectral");
+	  dv2ps(vars[DIVERGENCE].spectral, vars[VELOPOT].spectral, globs->NumLevelRequest, globs->Truncation);
+	}
+
+      if ( vars[STREAM].needed )
+	{
+	  vars[STREAM].hlev = vars[VORTICITY].hlev;
+	  vars[STREAM].plev = vars[VORTICITY].plev;
+	  vars[STREAM].sfit = TRUE;
+	  if ( vars[STREAM].spectral == NULL )
+	    vars[STREAM].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest, "vars[STREAM].spectral");
+	  dv2ps(vars[VORTICITY].spectral, vars[STREAM].spectral, globs->NumLevelRequest, globs->Truncation);
+	}
+    }
+
+  for ( code = 0; code < MaxCodes; code++ )
+    if ( vars[code].fourier && (vars[code].sfit || globs->Type < 61) )
+      vars[code].fourier = FreeMemory(vars[code].fourier);
+
+  /* --------------------------- */
+  /*  Output of spectral fields  */
+  /* --------------------------- */
+
+  if ( globs->Type == 50 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected && vars[code].spectral )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimSP;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].spectral+offset, 0);
+	      }	      
+	  }
+
+      FreeSpectral(vars);
+      return;
+    }
+
+  /* -------------------------------*/
+  /*  Computations in fourier space */
+  /* -------------------------------*/
+
+  if ( globs->Type >= 60 )
+    {
+      for (code = 0; code < MaxCodes; code++)
+      if (vars[code].needed && vars[code].spectral)
+	{
+	  if (vars[code].fourier == NULL)
+	    {
+	      fieldSize = vars[code].plev * globs->DimFC;
+	      vars[code].fourier = alloc_dp(fieldSize, FieldName(code,"fourier"));
+	    }
+	  sp2fc(vars[code].spectral,vars[code].fourier,globs->poli,
+		vars[code].plev,globs->Latitudes,globs->Fouriers,globs->Truncation);
+	}
+      if ( vars[U_WIND].needed && vars[U_WIND].fourier )
+	scaluv(vars[U_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+      if ( vars[V_WIND].needed && vars[V_WIND].fourier )
+	scaluv(vars[V_WIND].fourier, globs->rcoslat, globs->Latitudes, globs->Fouriers*globs->NumLevelRequest);
+    }
+
+  FreeSpectral(vars);
+
+  /* -------------------------- */
+  /*  Output of fourier fields  */
+  /* -------------------------- */
+
+  if ( globs->Type == 60 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on fourier space!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, 0);
+	      }	      
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ----------------------- */
+  /*  Output of zonal means  */
+  /* ----------------------- */
+
+  if ( globs->Type == 61 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    if ( ! vars[code].fourier ) Error("Code %d not available on zonal mean!", code);
+
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimFC;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].fourier+offset, vars[code].nmiss);
+	      }	      
+	  }
+
+      FreeFourier(vars);
+      return;
+    }
+
+  /* ------------------------------ */
+  /*  Transformation to gridpoints  */
+  /* ------------------------------ */
+
+  if ( globs->Type >= 70 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].needed && vars[code].fourier )
+	  {
+	    fieldSize = vars[code].plev * globs->DimGP;
+	    if ( vars[code].grid == NULL )
+	      vars[code].grid = alloc_dp(fieldSize, FieldName(code, "grid"));
+
+	    after_FC2GP(vars[code].fourier, vars[code].grid,
+			globs->Latitudes, globs->Longitudes, vars[code].plev, globs->Fouriers);
+	  }
+    }
+
+  FreeFourier(vars);
+
+  /* -------------------------------- */
+  /*  Output of pressure level grids  */
+  /* -------------------------------- */
+
+  if ( globs->Type == 70 )
+    {
+      for ( code = 0; code < MaxCodes; code++ )
+	if ( vars[code].selected )
+	  {
+	    nlevel = zaxisInqSize(vars[code].ozaxisID);
+	    for ( lindex = 0; lindex < nlevel; lindex++ )
+	      {
+		offset = lindex*globs->DimGP;
+		streamDefRecord(globs->ostreamID, vars[code].ovarID, lindex);
+		streamWriteRecord(globs->ostreamID, vars[code].grid+offset, vars[code].nmiss);
+	      }
+	  }
+
+      FreeSamp(vars);
+      FreeGrid(vars);
+      return;
+    }
+}
+
+void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+{
+  long fieldSize;
+  int truncation;
+  int dataSize;
+  int dataOffset;
+  int nlevel;
+  int gridSize;
+  int gridtype, leveltype;
+
+  gridtype   = gridInqType(gridID);
+  leveltype  = zaxisInqType(zaxisID);
+  nlevel     = zaxisInqSize(zaxisID);
+  gridSize   = gridInqSize(gridID);
+  dataSize   = gridSize*nlevel;
+  dataOffset = gridSize*levelID;
+
+  vars[code].nmiss0 += nmiss;
+
+  if ( gridtype == GRID_SPECTRAL )
+    {
+      vars[code].sfit = TRUE;
+      vars[code].hlev = globs->NumLevelRequest;
+      vars[code].plev = globs->NumLevelRequest;
+      if ( nlevel > 1 && leveltype == ZAXIS_PRESSURE )
+	{
+	  if ( code != U_WIND && code != V_WIND )
+	    {
+	      fieldSize = globs->Dim3SP;
+	      if (vars[code].spectral0 == NULL)
+		vars[code].spectral0 = alloc_dp(fieldSize, FieldName(code,"spectral"));
+	      truncation = gridInqTrunc(gridID);
+	      sp2sp(globs->Field, truncation, vars[code].spectral0+levelID*globs->DimSP, globs->Truncation);
+	    }
+	  else
+	    {
+	      fieldSize = globs->Dim3SP;
+	      if (vars[code].spectral0 == NULL)
+		vars[code].spectral0 = alloc_dp(fieldSize, FieldName(code,"spectral"));
+	      after_copy_array(vars[code].spectral0+levelID*globs->DimSP,globs->Field,globs->DimSP);
+	    }
+	}
+      else
+	Error("Only pressure level data supported for spectral data!");
+    }
+  else
+    {
+      if ( nlevel > 1 && leveltype == ZAXIS_PRESSURE )
+	{
+	  vars[code].sfit = TRUE;
+	  fieldSize = globs->Dim3GP;
+	  vars[code].hlev = globs->NumLevelRequest;
+	  vars[code].plev = globs->NumLevelRequest;
+	  if ( vars[code].grid0 == NULL )
+	    vars[code].grid0 = alloc_dp(fieldSize, FieldName(code,"grid0"));
+	  after_copy_array(vars[code].grid0+levelID*globs->DimGP, globs->Field, globs->DimGP);
+	}
+      else
+	{
+	  vars[code].sfit = FALSE;
+	  fieldSize = globs->DimGP;
+	  vars[code].hlev = 1;
+	  vars[code].plev = 1;
+	  if ( vars[code].grid0 == NULL )
+	    vars[code].grid0 = alloc_dp(fieldSize, FieldName(code,"grid0"));
+	  after_copy_array(vars[code].grid0, globs->Field, globs->DimGP);
+	}
+
+      if ( globs->Mean > 0 && (nmiss > 0 || vars[code].samp) )
+	{
+	  int i;
+	  if ( vars[code].samp == NULL )
+	    {
+	      vars[code].samp = (int *) malloc(dataSize*sizeof(int));
+	      for ( i = 0; i < dataSize; i++ ) vars[code].samp[i] = globs->MeanCount0;
+	    }
+
+	  for ( i = 0; i < gridSize; i++ )
+	    if ( IS_NOT_EQUAL(globs->Field[i], vars[code].missval) ) vars[code].samp[i+dataOffset]++;
+	}
+    }
+}
+
+
+void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+{
+  int dataSize;
+  int dataOffset;
+  int nlevel;
+  int gridSize;
+  int gridtype, leveltype;
+
+  gridtype   = gridInqType(gridID);
+  leveltype  = zaxisInqType(zaxisID);
+  nlevel     = zaxisInqSize(zaxisID);
+  gridSize   = gridInqSize(gridID);
+  dataSize   = gridSize*nlevel;
+  dataOffset = gridSize*levelID;
+
+  vars[code].nmiss0 += nmiss;
+
+  if ( gridtype == GRID_SPECTRAL )
+    {
+      /* ---------------------------------------------------------- */
+      /* Found spectral field ! If needed, allocate memory and copy */
+      /* ---------------------------------------------------------- */
+      vars[code].sfit = TRUE;
+      vars[code].hlev = nlevel;
+      vars[code].plev = 1;
+      if ( nlevel > 1 && leveltype == ZAXIS_HYBRID )
+	vars[code].plev = globs->NumLevelRequest;
+
+      if ( gridInqTrunc(gridID) != globs->Truncation )
+	Error("Resolution error. Required %d - Found %d", globs->Truncation, gridInqTrunc(gridID));
+
+      if ( vars[code].spectral0 == NULL )
+	vars[code].spectral0 = alloc_dp(dataSize, FieldName(code, "spectral0"));
+
+      after_copy_array(vars[code].spectral0+dataOffset, globs->Field, gridSize);
+    }
+  else
+    {
+      vars[code].hlev = nlevel;
+      vars[code].plev = nlevel;
+      vars[code].sfit = FALSE;
+      if ( nlevel > 1 && leveltype == ZAXIS_HYBRID && nlevel == globs->NumLevel )
+	{
+	  vars[code].plev = globs->NumLevelRequest;
+	  vars[code].sfit = TRUE;
+	}
+
+      if ( globs->Mean > 0 && (nmiss > 0 || vars[code].samp) )
+	{
+	  int i;
+	  if ( vars[code].samp == NULL )
+	    {
+	      vars[code].samp = (int *) malloc(dataSize*sizeof(int));
+	      for ( i = 0; i < dataSize; i++ ) vars[code].samp[i] = globs->MeanCount0;
+	    }
+
+	  for ( i = 0; i < gridSize; i++ )
+	    if ( IS_NOT_EQUAL(globs->Field[i], vars[code].missval) ) vars[code].samp[i+dataOffset]++;
+	}
+
+      if ( vars[code].hybrid0 == NULL )
+	vars[code].hybrid0 = alloc_dp(dataSize, FieldName(code, "hybrid0"));
+
+      after_copy_array(vars[code].hybrid0+dataOffset, globs->Field, gridSize);
+    }
+}
+
+static
+void MakeDependencies(struct Variable *vars, int varcode, int depcode)
+{
+  if ( vars[varcode].needed && ! vars[varcode].detected )
+    {
+      vars[depcode].needed = TRUE;
+      vars[varcode].comp   = TRUE;
+
+      if ( afterDebug )
+	fprintf(stderr, "Needed code %d to compute code %d\n", depcode, varcode);
+
+      if ( vars[depcode].ivarID == -1 )
+	{
+	  if ( depcode == U_WIND )
+	    {
+	      MakeDependencies(vars, U_WIND, DIVERGENCE);
+	      MakeDependencies(vars, U_WIND, VORTICITY);
+	    }
+	  if ( depcode == V_WIND )
+	    {
+	      MakeDependencies(vars, V_WIND, DIVERGENCE);
+	      MakeDependencies(vars, V_WIND, VORTICITY);
+	    }
+	}
+
+      if ( vars[varcode].ivarID == -1 )
+	{
+	  if ( vars[depcode].ivarID == -1 )
+	    {
+	      Error("code %d undefined, needed to compute code %d", depcode, varcode);
+	    }
+	  else
+	    {
+	      vars[varcode].ivarID   = vars[depcode].ivarID;
+	      vars[varcode].igridID  = vars[depcode].igridID;
+	      vars[varcode].ogridID  = vars[depcode].ogridID;
+	      vars[varcode].izaxisID = vars[depcode].izaxisID;
+	      vars[varcode].ozaxisID = vars[depcode].ozaxisID;
+	    }
+	}
+    }
+}
+
+static
+void CheckDependencies(struct Variable *vars, int analysisdata)
+{
+  MakeDependencies(vars, VELOPOT, U_WIND);
+  MakeDependencies(vars, VELOPOT, V_WIND);
+  MakeDependencies(vars, VELOPOT, VORTICITY);
+  MakeDependencies(vars, VELOPOT, DIVERGENCE);
+
+  MakeDependencies(vars, STREAM, U_WIND);
+  MakeDependencies(vars, STREAM, V_WIND);
+  MakeDependencies(vars, STREAM, VORTICITY);
+  MakeDependencies(vars, STREAM, DIVERGENCE);
+
+  MakeDependencies(vars, VORTICITY, U_WIND);
+  MakeDependencies(vars, VORTICITY, V_WIND);
+
+  MakeDependencies(vars, DIVERGENCE, U_WIND);
+  MakeDependencies(vars, DIVERGENCE, V_WIND);
+
+  MakeDependencies(vars, U_WIND, VORTICITY);
+  MakeDependencies(vars, U_WIND, DIVERGENCE);
+  MakeDependencies(vars, U_WIND, V_WIND);
+
+  MakeDependencies(vars, V_WIND, VORTICITY);
+  MakeDependencies(vars, V_WIND, DIVERGENCE);
+  MakeDependencies(vars, V_WIND, U_WIND);
+
+  MakeDependencies(vars, WINDSPEED, U_WIND);
+  MakeDependencies(vars, WINDSPEED, V_WIND);
+
+  if ( analysisdata )
+    {
+      MakeDependencies(vars, RHUMIDITY, HUMIDITY);
+      MakeDependencies(vars, RHUMIDITY, TEMPERATURE);
+      MakeDependencies(vars, HUMIDITY, RHUMIDITY);
+      MakeDependencies(vars, HUMIDITY, TEMPERATURE);
+      MakeDependencies(vars, GEOPOTHEIGHT, GEOPOTENTIAL);
+    }
+  else
+    {
+      MakeDependencies(vars, THETAF, TEMPERATURE);
+      MakeDependencies(vars, SLP, TEMPERATURE);
+    }
+
+  MakeDependencies(vars, SW_ATM, 176);
+  MakeDependencies(vars, SW_ATM, 178);
+  MakeDependencies(vars, LW_ATM, 177);
+  MakeDependencies(vars, LW_ATM, 179);
+  MakeDependencies(vars, NET_ATM, 176);
+  MakeDependencies(vars, NET_ATM, 177);
+  MakeDependencies(vars, NET_ATM, 178);
+  MakeDependencies(vars, NET_ATM, 179);
+
+  MakeDependencies(vars, SW_BOT_CLF, 176);
+  MakeDependencies(vars, SW_BOT_CLF, 185);
+  MakeDependencies(vars, LW_BOT_CLF, 177);
+  MakeDependencies(vars, LW_BOT_CLF, 186);
+  MakeDependencies(vars, SW_TOP_CLF, 178);
+  MakeDependencies(vars, SW_TOP_CLF, 187);
+  MakeDependencies(vars, LW_TOP_CLF, 179);
+  MakeDependencies(vars, LW_TOP_CLF, 188);
+  MakeDependencies(vars, NET_TOP_CLF, 178);
+  MakeDependencies(vars, NET_TOP_CLF, 179);
+  MakeDependencies(vars, NET_TOP_CLF, 187);
+  MakeDependencies(vars, NET_TOP_CLF, 188);
+
+  MakeDependencies(vars, ALL_WATER, 222);
+  MakeDependencies(vars, LOW_WATER, 222);
+  MakeDependencies(vars, MID_WATER, 222);
+  MakeDependencies(vars, HIH_WATER, 222);
+
+  MakeDependencies(vars, LOW_CLOUD, 223);
+  MakeDependencies(vars, MID_CLOUD, 223);
+  MakeDependencies(vars, HIH_CLOUD, 223);
+
+  if ( vars[LOW_CLOUD].comp || vars[MID_CLOUD].comp || vars[HIH_CLOUD].comp )
+    {
+      static int zaxisID = -999;
+      if ( zaxisID == -999 ) zaxisID = zaxisCreate(ZAXIS_SURFACE, 1);
+
+      vars[LOW_CLOUD].izaxisID = zaxisID;
+      vars[LOW_CLOUD].ozaxisID = zaxisID;
+      vars[MID_CLOUD].izaxisID = zaxisID;
+      vars[MID_CLOUD].ozaxisID = zaxisID;
+      vars[HIH_CLOUD].izaxisID = zaxisID;
+      vars[HIH_CLOUD].ozaxisID = zaxisID;
+    }
+}
+
+void after_AnalysisDependencies(struct Variable *vars, int ncodes)
+{
+   int code;
+
+   for ( code = 0; code < ncodes; code++ )
+     vars[code].needed = vars[code].selected;
+
+   MakeDependencies(vars, PS, LNPS);
+
+   CheckDependencies(vars, 1);
+}
+
+void after_EchamDependencies(struct Variable *vars, int ncodes, int type, int source)
+{
+  int code;
+
+  for ( code = 0; code < ncodes; code++ )
+    vars[code].needed = vars[code].selected;
+
+  for ( code = 0; code < ncodes; code++ )
+    if ( vars[code].detected == FALSE ) vars[code].ivarID = -1;
+
+  if ( type >= 50 )
+    {
+      vars[U_WIND].needed |= vars[DIVERGENCE].needed;
+      vars[V_WIND].needed |= vars[DIVERGENCE].needed;
+      vars[U_WIND].needed |=  vars[VORTICITY].needed;
+      vars[V_WIND].needed |=  vars[VORTICITY].needed;
+      vars[U_WIND].needed |=    vars[VELOPOT].needed;
+      vars[V_WIND].needed |=    vars[VELOPOT].needed;
+      vars[U_WIND].needed |=     vars[STREAM].needed;
+      vars[V_WIND].needed |=     vars[STREAM].needed;
+    }
+
+  if ( type >= 30 ) vars[LNPS].needed = TRUE;
+
+  if ( type >= 20 )
+    {
+      MakeDependencies(vars, THETAF, LNPS);
+      MakeDependencies(vars, SLP, LNPS);
+      MakeDependencies(vars, SLP, GEOPOTENTIAL);
+      /*
+      MakeDependencies(vars, SLP, HALF_PRESS);
+      MakeDependencies(vars, SLP, FULL_PRESS);
+      */
+      MakeDependencies(vars, RHUMIDITY, TEMPERATURE);
+      MakeDependencies(vars, RHUMIDITY, HUMIDITY);
+      MakeDependencies(vars, RHUMIDITY, LNPS);
+      MakeDependencies(vars, GEOPOTHEIGHT, TEMPERATURE);
+      MakeDependencies(vars, GEOPOTHEIGHT, HUMIDITY);
+      MakeDependencies(vars, GEOPOTHEIGHT, LNPS);
+      MakeDependencies(vars, OMEGA, DIVERGENCE);
+      MakeDependencies(vars, OMEGA, U_WIND);
+      MakeDependencies(vars, OMEGA, V_WIND);
+      MakeDependencies(vars, OMEGA, LNPS);
+      MakeDependencies(vars, OMEGA, DPSDX);
+      MakeDependencies(vars, OMEGA, DPSDY);
+    }
+
+   MakeDependencies(vars, DPSDX, LNPS);
+   MakeDependencies(vars, HALF_PRESS, LNPS);
+   MakeDependencies(vars, PS, LNPS);
+
+   MakeDependencies(vars, SURF_RUNOFF, 142);
+   MakeDependencies(vars, SURF_RUNOFF, 143);
+   MakeDependencies(vars, SURF_RUNOFF, 182);
+   MakeDependencies(vars, SURF_RUNOFF, 221);  /* snow depth change */
+
+   MakeDependencies(vars, THETAF, TS);
+
+   MakeDependencies(vars, FRESH_WATER, 142);
+   MakeDependencies(vars, FRESH_WATER, 143);
+   MakeDependencies(vars, FRESH_WATER, 182);
+
+   MakeDependencies(vars, PRECIP, 142);
+   MakeDependencies(vars, PRECIP, 143);
+
+   if ( source != S_ECHAM5 )
+     {
+       MakeDependencies(vars, NET_WATER, 142);
+       MakeDependencies(vars, NET_WATER, 143);
+       MakeDependencies(vars, NET_WATER, 160);
+       MakeDependencies(vars, NET_WATER, 182);
+
+       MakeDependencies(vars, NET_TOP, 178);
+       MakeDependencies(vars, NET_TOP, 179);
+
+       MakeDependencies(vars, NET_BOT, 176);
+       MakeDependencies(vars, NET_BOT, 177);
+
+       MakeDependencies(vars, NET_HEAT, 146);
+       MakeDependencies(vars, NET_HEAT, 147);
+       MakeDependencies(vars, NET_HEAT, 176);
+       MakeDependencies(vars, NET_HEAT, 177);
+       MakeDependencies(vars, NET_HEAT, 218);
+       /*
+	 if ( source == S_ECHAM5 )
+	 {
+	 MakeDependencies(vars, NET_HEAT, 206);
+	 MakeDependencies(vars, NET_HEAT, 208);
+	 MakeDependencies(vars, NET_HEAT, 209);
+	 }
+	 else
+       */
+       {
+	 MakeDependencies(vars, NET_HEAT, 220);
+       }
+     }
+
+   MakeDependencies(vars, SW_CLF, 178);
+   MakeDependencies(vars, SW_CLF, 224);
+
+   MakeDependencies(vars, LW_CLF, 179);
+   MakeDependencies(vars, LW_CLF, 225);
+
+   MakeDependencies(vars, NET_CLF, 178);
+   MakeDependencies(vars, NET_CLF, 179);
+   MakeDependencies(vars, NET_CLF, 224);
+   MakeDependencies(vars, NET_CLF, 225);
+
+   if ( vars[DPSDX].needed || vars[DPSDY].needed || 
+	vars[GEOPOTHEIGHT].comp || vars[SLP].comp || vars[THETAF].needed ||
+        vars[HALF_PRESS].needed || vars[RHUMIDITY].comp || vars[OMEGA].comp ||
+        type >= 30 )
+     vars[PS_PROG].comp = TRUE;
+
+   CheckDependencies(vars, 0);
+}
+
+void after_legini_full(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict pdev,
+		       double *restrict pol2, double *restrict pol3, double *restrict coslat);
+void after_legini(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict coslat);
+
+void after_legini_setup(struct Control *globs, struct Variable *vars)
+{
+  int ntr   = globs->Truncation;
+  int nlat  = globs->Latitudes;
+  int dimsp = (ntr + 1) * (ntr + 2);
+  int pdim  = dimsp / 2 * nlat;
+
+  globs->poli = (double *) malloc(pdim*sizeof(double));
+  
+  if ( ! globs->AnalysisData )
+    {
+      if ( globs->Type >= 20 )  globs->pold = (double *) malloc(pdim*sizeof(double));
+      if ( vars[DPSDY].needed ) globs->pdev = (double *) malloc(pdim*sizeof(double));
+    }
+  
+  if ( (vars[DIVERGENCE].needed || vars[VORTICITY].needed ||
+	vars[VELOPOT].needed || vars[STREAM].needed ) && globs->Type > 20 )
+    {
+      globs->pol2 = (double *) malloc(pdim*sizeof(double));
+      globs->pol3 = (double *) malloc(pdim*sizeof(double));
+    }
+
+  if ( globs->AnalysisData && (globs->Type == 70) && globs->Gaussian && !globs->Spectral )
+    {
+      if ( globs->poli ) { free(globs->poli); globs->poli = NULL;}
+      if ( globs->pol2 ) { free(globs->pol2); globs->pol2 = NULL;}
+      if ( globs->pol3 ) { free(globs->pol3); globs->pol3 = NULL;}
+      return;
+    }
+
+  int flag = 1;
+  //if ( globs->poli && globs->pold && globs->pdev == NULL && globs->pol2 == NULL && globs->pol3 == NULL ) flag = 0;
+
+  if ( flag )
+    after_legini_full(ntr, nlat, globs->poli, globs->pold, globs->pdev,
+		      globs->pol2, globs->pol3, globs->coslat);
+  else
+    after_legini(ntr, nlat, globs->poli, globs->pold, globs->coslat);
+
+  for ( int jgl = 0; jgl < nlat; ++jgl )
+    globs->rcoslat[jgl] = 1.0 / globs->coslat[jgl];
+  
+  for ( int jgl = 0; jgl < nlat; ++jgl )
+    globs->DerivationFactor[jgl] = globs->rcoslat[jgl] / PlanetRadius;
+}
diff --git a/src/cdo.c b/src/cdo.c
index 6c153d4..e91631a 100644
--- a/src/cdo.c
+++ b/src/cdo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -44,15 +44,11 @@
 #define RLIM_T  rlim_t
 #endif
 
-
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
 
 #include "cdo_getopt.h"
-extern int   CDO_optind;
-extern char *CDO_optarg;
-
 
 #if defined(HAVE_LIBPTHREAD)
 #include "pstream_int.h"
@@ -71,95 +67,38 @@ extern char *CDO_optarg;
 #  define  VERSION  "0.0.1"
 #endif
 
-char CDO_Version[] = "Climate Data Operators version "VERSION" (https://code.zmaw.de/projects/cdo)";
-
-char *Progname;
-
-int ompNumThreads = 1;
-
-int stdin_is_tty  = 0;
-int stdout_is_tty = 0;
-int stderr_is_tty = 0;
-
-char* cdoGridSearchDir   = NULL;
-int cdoDefaultFileType   = CDI_UNDEFID;
-int cdoDefaultDataType   = CDI_UNDEFID;
-int cdoDefaultTimeType   = CDI_UNDEFID;
-int cdoDefaultByteorder  = CDI_UNDEFID;
-int cdoDefaultTableID    = CDI_UNDEFID;
-
-int cdoLockIO            = FALSE;
-int cdoCheckDatarange    = FALSE;
-
-int CDO_Color            = FALSE;
-int CDO_Use_FFTW         = TRUE;
-int cdoDiag              = FALSE;
-int CDO_Append_History   = TRUE;
-int CDO_Reset_History    = FALSE;
-int cdoCompType          = COMPRESS_NONE;  // compression type
-int cdoCompLevel         = 0;              // compression level
-int cdoChunkType         = CDI_UNDEFID;
-int cdoLogOff            = FALSE;
-int cdoSilentMode        = FALSE;
-int cdoOverwriteMode     = FALSE;
-int cdoBenchmark         = FALSE;
-int cdoTimer             = FALSE;
-int cdoVerbose           = FALSE;
-int cdoDebug             = 0;
-int cdoCompress          = FALSE;
-int cdoInteractive       = FALSE;
-int cdoParIO             = FALSE;
-int cdoRegulargrid       = FALSE;
-
-int CDO_netcdf_hdr_pad   = 0;
-
 #define MAX_NUM_VARNAMES 256
-int cdoNumVarnames       = 0;
-char **cdoVarnames       = NULL;
-
-char CDO_File_Suffix[32];
-
 
 static int Debug = 0;
 static int Version = 0;
 static int Help = 0;
 static int DebugLevel = 0;
 static int numThreads = 0;
-
-
-int cdoExpMode           = -1;
-char *cdoExpName         = NULL;
-void exp_run(int argc, char *argv[], char *cdoExpName);
-
-
-int timer_total, timer_read, timer_write;
+static int timer_total;
+static int CDO_netcdf_hdr_pad   = 0;
 
 
 #define PRINT_RLIMIT(resource) \
       { \
-	int status; \
-	struct rlimit rlim; \
-	status = getrlimit(resource, &rlim); \
-	if ( status == 0 ) \
-	  { \
-	    if ( sizeof(RLIM_T) > sizeof(long) ) \
-	      { \
-		fprintf(stderr, "CUR %-15s = %llu\n", #resource, (long long) rlim.rlim_cur); \
-		fprintf(stderr, "MAX %-15s = %llu\n", #resource, (long long) rlim.rlim_max); \
-	      } \
-	    else \
-	      { \
-		fprintf(stderr, "CUR %-15s = %lu\n", #resource, (long) rlim.rlim_cur); \
-		fprintf(stderr, "MAX %-15s = %lu\n", #resource, (long) rlim.rlim_max); \
-	      } \
-	  } \
+        int status; \
+        struct rlimit rlim; \
+        status = getrlimit(resource, &rlim); \
+        if ( status == 0 ) \
+          { \
+            if ( sizeof(RLIM_T) > sizeof(long) ) \
+              { \
+                fprintf(stderr, "CUR %-15s = %llu\n", #resource, (long long) rlim.rlim_cur); \
+                fprintf(stderr, "MAX %-15s = %llu\n", #resource, (long long) rlim.rlim_max); \
+              } \
+            else \
+              { \
+                fprintf(stderr, "CUR %-15s = %lu\n", #resource, (long) rlim.rlim_cur); \
+                fprintf(stderr, "MAX %-15s = %lu\n", #resource, (long) rlim.rlim_max); \
+              } \
+          } \
       }
 
 
-void printFeatures(void);
-void printLibraries(void);
-
-
 static
 void cdo_version(void)
 {
@@ -194,8 +133,7 @@ void cdo_version(void)
 static
 void cdo_usage(void)
 {
-  int id = 0;
-  char *name;
+  const char *name;
 
   /*  fprintf(stderr, "%s\n", CDO_Version);*/
   /*  fprintf(stderr, "\n");*/
@@ -218,7 +156,7 @@ void cdo_usage(void)
   /*
   fprintf(stderr, "    -i <inst>      Institution name/file\n");
   fprintf(stderr, "                   Predefined instituts: ");
-  for ( id = 0; id < institutInqNumber; id++ )
+  for ( int id = 0; id < institutInqNumber; id++ )
     if ( (name = institutInqNamePtr(id)) )
       fprintf(stderr, " %s", name);
   fprintf(stderr, "\n");
@@ -241,7 +179,7 @@ void cdo_usage(void)
   fprintf(stderr, "    -s, --silent   Silent mode\n");
   fprintf(stderr, "    -t <partab>    Set default parameter table name or file\n");
   fprintf(stderr, "                   Predefined tables: ");
-  for ( id = 0; id < tableInqNumber(); id++ )
+  for ( int id = 0; id < tableInqNumber(); id++ )
     if ( (name = tableInqNamePtr(id)) )
       fprintf(stderr, " %s", name);
   fprintf(stderr, "\n");
@@ -261,10 +199,10 @@ void cdo_usage(void)
   reset_text_color(stderr);
 
   fprintf(stderr, "\n");
-  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2014 Uwe Schulzweida\n", VERSION);
-  //  fprintf(stderr, "  Available from <https://code.zmaw.de/projects/cdo>\n");
+  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2015 Uwe Schulzweida\n", VERSION);
+  //  fprintf(stderr, "  Available from <http://mpimet.mpg.de/cdo>\n");
   fprintf(stderr, "  This is free software and comes with ABSOLUTELY NO WARRANTY\n");
-  fprintf(stderr, "  Report bugs to <https://code.zmaw.de/projects/cdo>\n");
+  fprintf(stderr, "  Report bugs to <http://mpimet.mpg.de/cdo>\n");
 }
 
 static
@@ -288,104 +226,45 @@ void cdoPrintHelp(char *phelp[]/*, char *xoperator*/)
     {
       int lprint;
       while ( *phelp )
-	{
-	  lprint = TRUE;
-	  if ( *phelp[0] == '\0' )
-	    if ( *(phelp+1) )
-	      if ( *(phelp+1)[0] == ' ' ) lprint = FALSE;
-	  
-	  if ( lprint )
-	    {
-	      if ( COLOR_STDOUT )
-		{
-		  if ( (strcmp(*phelp, "NAME")        == 0) ||
-		       (strcmp(*phelp, "SYNOPSIS")    == 0) ||
-		       (strcmp(*phelp, "DESCRIPTION") == 0) ||
-		       (strcmp(*phelp, "OPERATORS")   == 0) ||
-		       (strcmp(*phelp, "ENVIRONMENT") == 0) ||
-		       (strcmp(*phelp, "PARAMETER")   == 0) ||
-		       (strcmp(*phelp, "EXAMPLES")    == 0) )
-		    {
-		      set_text_color(stdout, BRIGHT, BLACK);
-		      fprintf(stdout, "%s", *phelp);
-		      reset_text_color(stdout);
-		      fprintf(stdout, "\n");
-		    }
-		  else
-		    fprintf(stdout, "%s\n", *phelp);
-		}
-	      else
-		{
-		  fprintf(stdout, "%s\n", *phelp);
-		}
-	    }
-
-	  phelp++;
-	}
+        {
+          lprint = TRUE;
+          if ( *phelp[0] == '\0' )
+            if ( *(phelp+1) )
+              if ( *(phelp+1)[0] == ' ' ) lprint = FALSE;
+          
+          if ( lprint )
+            {
+              if ( COLOR_STDOUT )
+                {
+                  if ( (strcmp(*phelp, "NAME")        == 0) ||
+                       (strcmp(*phelp, "SYNOPSIS")    == 0) ||
+                       (strcmp(*phelp, "DESCRIPTION") == 0) ||
+                       (strcmp(*phelp, "OPERATORS")   == 0) ||
+                       (strcmp(*phelp, "NAMELIST")    == 0) ||
+                       (strcmp(*phelp, "PARAMETER")   == 0) ||
+                       (strcmp(*phelp, "ENVIRONMENT") == 0) ||
+                       (strcmp(*phelp, "EXAMPLES")    == 0) )
+                    {
+                      set_text_color(stdout, BRIGHT, BLACK);
+                      fprintf(stdout, "%s", *phelp);
+                      reset_text_color(stdout);
+                      fprintf(stdout, "\n");
+                    }
+                  else
+                    fprintf(stdout, "%s\n", *phelp);
+                }
+              else
+                {
+                  fprintf(stdout, "%s\n", *phelp);
+                }
+            }
+
+          phelp++;
+        }
     }
 }
 
 
-void cdoGenFileSuffix(char *filesuffix, size_t maxlen, int filetype, int vlistID, const char *refname)
-{
-  if ( strncmp(CDO_File_Suffix, "NULL", 4) != 0 )
-    {
-      if ( CDO_File_Suffix[0] != 0 )
-	{
-	  strncat(filesuffix, CDO_File_Suffix, maxlen-1);
-	}
-      else
-	{
-	  int lready = FALSE;
-	  int lcompsz = FALSE;
-	  
-	  if ( filetype == cdoDefaultFileType && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
-	    {
-	      size_t len = 0;
-	      if ( refname != NULL && *refname != 0 && *refname != '-' && *refname != '.' ) len = strlen(refname);
-
-	      if ( len > 2 )
-		{
-		  char *result = strrchr(refname, '.');
-		  if ( result != NULL && result[1] != 0 )
-		    {
-		      int firstchar = tolower(result[1]);
-		      switch (firstchar)
-			{
-			case 'g':
-			  if ( cdoDefaultFileType == FILETYPE_GRB || cdoDefaultFileType == FILETYPE_GRB2 ) lready = TRUE;
-			  break;
-			case 'n':
-			  if ( cdoDefaultFileType == FILETYPE_NC || cdoDefaultFileType == FILETYPE_NC2 ||
-			       cdoDefaultFileType == FILETYPE_NC4 || cdoDefaultFileType == FILETYPE_NC4C ) lready = TRUE;
-			  break;
-			case 's':
-			  if ( cdoDefaultFileType == FILETYPE_SRV ) lready = TRUE;
-			  break;
-			case 'e':
-			  if ( cdoDefaultFileType == FILETYPE_EXT ) lready = TRUE;
-			  break;
-			case 'i':
-			  if ( cdoDefaultFileType == FILETYPE_IEG ) lready = TRUE;
-			  break;
-			}
-		    }
-		  if ( lready )  strncat(filesuffix, result, maxlen-1);
-		}
-	    }
-
-	  if ( !lready )
-	    {
-	      strncat(filesuffix, streamFilesuffix(cdoDefaultFileType), maxlen-1);
-	      if ( cdoDefaultFileType == FILETYPE_GRB && vlistIsSzipped(vlistID) ) lcompsz = TRUE;
-	    }
-
-	  if ( cdoDefaultFileType == FILETYPE_GRB && cdoCompType == COMPRESS_SZIP ) lcompsz = TRUE;
-	  if ( lcompsz ) strncat(filesuffix, ".sz", maxlen-1);
-	}
-    }
-}
-
 static
 void cdoSetDebug(int level)
 {
@@ -451,92 +330,92 @@ void setDefaultDataType(char *datatypestr)
     {
       nbits = atoi(datatypestr);
       if ( nbits < 10 )
-	datatypestr += 1;
+        datatypestr += 1;
       else
-	datatypestr += 2;
+        datatypestr += 2;
 
       if ( dtype == -1 )
-	{
-	  if      ( nbits > 0 && nbits < 32 ) cdoDefaultDataType = nbits;
-	  else if ( nbits == 32 )
-	    {
-	      if ( cdoDefaultFileType == FILETYPE_GRB )
-		cdoDefaultDataType = DATATYPE_PACK32;
-	      else
-		cdoDefaultDataType = DATATYPE_FLT32;
-	    }
-	  else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_FLT64;
-	  else
-	    {
-	      fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
-	      fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n");
-	      exit(EXIT_FAILURE);
-	    }
-	}
+        {
+          if      ( nbits > 0 && nbits < 32 ) cdoDefaultDataType = nbits;
+          else if ( nbits == 32 )
+            {
+              if ( cdoDefaultFileType == FILETYPE_GRB )
+                cdoDefaultDataType = DATATYPE_PACK32;
+              else
+                cdoDefaultDataType = DATATYPE_FLT32;
+            }
+          else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_FLT64;
+          else
+            {
+              fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
+              fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n");
+              exit(EXIT_FAILURE);
+            }
+        }
       else
-	{
-	  if ( dtype == D_INT )
-	    {
-	      if      ( nbits ==  8 ) cdoDefaultDataType = DATATYPE_INT8;
-	      else if ( nbits == 16 ) cdoDefaultDataType = DATATYPE_INT16;
-	      else if ( nbits == 32 ) cdoDefaultDataType = DATATYPE_INT32;
-	      else
-		{
-		  fprintf(stderr, "Unsupported number of bits = %d for datatype INT!\n", nbits);
-		  exit(EXIT_FAILURE);
-		}
-	    }
-	  else if ( dtype == D_UINT )
-	    {
-	      if      ( nbits ==  8 ) cdoDefaultDataType = DATATYPE_UINT8;
-	      else if ( nbits == 16 ) cdoDefaultDataType = DATATYPE_UINT16;
-	      else if ( nbits == 32 ) cdoDefaultDataType = DATATYPE_UINT32;
-	      else
-		{
-		  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
-		  exit(EXIT_FAILURE);
-		}
-	    }
-	  else if ( dtype == D_FLT )
-	    {
-	      if      ( nbits == 32 ) cdoDefaultDataType = DATATYPE_FLT32;
-	      else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_FLT64;
-	      else
-		{
-		  fprintf(stderr, "Unsupported number of bits = %d for datatype FLT!\n", nbits);
-		  exit(EXIT_FAILURE);
-		}
-	    }
-	  else if ( dtype == D_CPX )
-	    {
-	      if      ( nbits == 32 ) cdoDefaultDataType = DATATYPE_CPX32;
-	      else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_CPX64;
-	      else
-		{
-		  fprintf(stderr, "Unsupported number of bits = %d for datatype CPX!\n", nbits);
-		  exit(EXIT_FAILURE);
-		}
-	    }
-	}
+        {
+          if ( dtype == D_INT )
+            {
+              if      ( nbits ==  8 ) cdoDefaultDataType = DATATYPE_INT8;
+              else if ( nbits == 16 ) cdoDefaultDataType = DATATYPE_INT16;
+              else if ( nbits == 32 ) cdoDefaultDataType = DATATYPE_INT32;
+              else
+                {
+                  fprintf(stderr, "Unsupported number of bits = %d for datatype INT!\n", nbits);
+                  exit(EXIT_FAILURE);
+                }
+            }
+          else if ( dtype == D_UINT )
+            {
+              if      ( nbits ==  8 ) cdoDefaultDataType = DATATYPE_UINT8;
+              else if ( nbits == 16 ) cdoDefaultDataType = DATATYPE_UINT16;
+              else if ( nbits == 32 ) cdoDefaultDataType = DATATYPE_UINT32;
+              else
+                {
+                  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
+                  exit(EXIT_FAILURE);
+                }
+            }
+          else if ( dtype == D_FLT )
+            {
+              if      ( nbits == 32 ) cdoDefaultDataType = DATATYPE_FLT32;
+              else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_FLT64;
+              else
+                {
+                  fprintf(stderr, "Unsupported number of bits = %d for datatype FLT!\n", nbits);
+                  exit(EXIT_FAILURE);
+                }
+            }
+          else if ( dtype == D_CPX )
+            {
+              if      ( nbits == 32 ) cdoDefaultDataType = DATATYPE_CPX32;
+              else if ( nbits == 64 ) cdoDefaultDataType = DATATYPE_CPX64;
+              else
+                {
+                  fprintf(stderr, "Unsupported number of bits = %d for datatype CPX!\n", nbits);
+                  exit(EXIT_FAILURE);
+                }
+            }
+        }
     }
 
   if ( *datatypestr != 0 )
     {
       if ( *datatypestr == 'l' || *datatypestr == 'L' )
-	{
-	  if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
-	  datatypestr++;
-	}
+        {
+          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
+          datatypestr++;
+        }
       else if ( *datatypestr == 'b' || *datatypestr == 'B' )
-	{
-	  if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
-	  datatypestr++;
-	}
+        {
+          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
+          datatypestr++;
+        }
       else
-	{
-	  fprintf(stderr, "Unsupported character in number of bytes: >%s< !\n", datatypestr);
-	  exit(EXIT_FAILURE);
-	}
+        {
+          fprintf(stderr, "Unsupported character in number of bytes: >%s< !\n", datatypestr);
+          exit(EXIT_FAILURE);
+        }
     }
 }
 
@@ -557,30 +436,30 @@ void setDefaultDataTypeByte(char *datatypestr)
       else if ( datatype == 4 ) cdoDefaultDataType = DATATYPE_FLT32;
       else if ( datatype == 8 ) cdoDefaultDataType = DATATYPE_FLT64;
       else
-	{
-	  fprintf(stderr, "Unsupported datatype %d!\n", datatype);
-	  fprintf(stderr, "Use 4/8 for filetype nc/srv/ext/ieg and 1/2/3 for grb/grb2.\n");
-	  exit(EXIT_FAILURE);
-	}
+        {
+          fprintf(stderr, "Unsupported datatype %d!\n", datatype);
+          fprintf(stderr, "Use 4/8 for filetype nc/srv/ext/ieg and 1/2/3 for grb/grb2.\n");
+          exit(EXIT_FAILURE);
+        }
     }
 
   if ( *datatypestr != 0 )
     {
       if ( *datatypestr == 'l' || *datatypestr == 'L' )
-	{
-	  if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
-	  datatypestr++;
-	}
+        {
+          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
+          datatypestr++;
+        }
       else if ( *datatypestr == 'b' || *datatypestr == 'B' )
-	{
-	  if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
-	  datatypestr++;
-	}
+        {
+          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
+          datatypestr++;
+        }
       else
-	{
-	  fprintf(stderr, "Unsupported character in number of bytes: %s!\n", datatypestr);
-	  exit(EXIT_FAILURE);
-	}
+        {
+          fprintf(stderr, "Unsupported character in number of bytes: %s!\n", datatypestr);
+          exit(EXIT_FAILURE);
+        }
     }
 }
 
@@ -590,48 +469,49 @@ void setDefaultFileType(char *filetypestr, int labort)
   if ( filetypestr )
     {
       char *ftstr = filetypestr;
-
-      if      ( memcmp(filetypestr, "grb2", 4)  == 0 ) { ftstr += 4; cdoDefaultFileType = FILETYPE_GRB2;}
-      else if ( memcmp(filetypestr, "grb1", 4)  == 0 ) { ftstr += 4; cdoDefaultFileType = FILETYPE_GRB; }
-      else if ( memcmp(filetypestr, "grb",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_GRB; }
-      else if ( memcmp(filetypestr, "nc2",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_NC2; }
-      else if ( memcmp(filetypestr, "nc4c", 4)  == 0 ) { ftstr += 4; cdoDefaultFileType = FILETYPE_NC4C;}
-      else if ( memcmp(filetypestr, "nc4",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_NC4; }
-      else if ( memcmp(filetypestr, "nc",   2)  == 0 ) { ftstr += 2; cdoDefaultFileType = FILETYPE_NC;  }
-      else if ( memcmp(filetypestr, "srv",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_SRV; }
-      else if ( memcmp(filetypestr, "ext",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_EXT; }
-      else if ( memcmp(filetypestr, "ieg",  3)  == 0 ) { ftstr += 3; cdoDefaultFileType = FILETYPE_IEG; }
+      size_t len;
+
+      if      ( cmpstrlen(filetypestr, "grb2", len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_GRB2;}
+      else if ( cmpstrlen(filetypestr, "grb1", len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_GRB; }
+      else if ( cmpstrlen(filetypestr, "grb",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_GRB; }
+      else if ( cmpstrlen(filetypestr, "nc2",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_NC2; }
+      else if ( cmpstrlen(filetypestr, "nc4c", len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_NC4C;}
+      else if ( cmpstrlen(filetypestr, "nc4",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_NC4; }
+      else if ( cmpstrlen(filetypestr, "nc",   len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_NC;  }
+      else if ( cmpstrlen(filetypestr, "srv",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_SRV; }
+      else if ( cmpstrlen(filetypestr, "ext",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_EXT; }
+      else if ( cmpstrlen(filetypestr, "ieg",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = FILETYPE_IEG; }
       else
-	{
-	  if ( labort )
-	    {
-	      fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
-	      fprintf(stderr, "Available filetypes: grb/grb2/nc/nc2/nc4/nc4c/srv/ext/ieg\n");
-	      exit(EXIT_FAILURE);
-	    }
-	  else
-	    {
-	      return;
-	    }
-	}
+        {
+          if ( labort )
+            {
+              fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
+              fprintf(stderr, "Available filetypes: grb/grb2/nc/nc2/nc4/nc4c/srv/ext/ieg\n");
+              exit(EXIT_FAILURE);
+            }
+          else
+            {
+              return;
+            }
+        }
 
       if ( cdoDefaultFileType != CDI_UNDEFID && *ftstr != 0 )
-	{
-	  if ( *ftstr == '_' )
-	    {
-	      ftstr++;
-
-	      setDefaultDataType(ftstr);
-	    }
-	  else
-	    {
-	      fprintf(stderr, "Unexpected character >%c< in file type >%s<!\n", *ftstr, filetypestr);
-	      fprintf(stderr, "Use format[_nbits] with:\n");
-	      fprintf(stderr, "    format = grb, grb2, nc, nc2, nc4, nc4c, srv, ext or ieg\n");
-	      fprintf(stderr, "    nbits  = 32/64 for grb2/nc/nc2/nc4/nc4c/srv/ext/ieg; 1 - 24 for grb/grb2\n");
-	      exit(EXIT_FAILURE);
-	    }
-	}
+        {
+          if ( *ftstr == '_' )
+            {
+              ftstr++;
+
+              setDefaultDataType(ftstr);
+            }
+          else
+            {
+              fprintf(stderr, "Unexpected character >%c< in file type >%s<!\n", *ftstr, filetypestr);
+              fprintf(stderr, "Use format[_nbits] with:\n");
+              fprintf(stderr, "    format = grb, grb2, nc, nc2, nc4, nc4c, srv, ext or ieg\n");
+              fprintf(stderr, "    nbits  = 32/64 for grb2/nc/nc2/nc4/nc4c/srv/ext/ieg; 1 - 24 for grb/grb2\n");
+              exit(EXIT_FAILURE);
+            }
+        }
     }
 }
 
@@ -675,45 +555,33 @@ int getMemAlignment(void)
 }
 
 
-int cdoFiletype(void)
-{
-  if ( cdoDefaultFileType == CDI_UNDEFID )
-    {
-      cdoDefaultFileType = FILETYPE_GRB;
-      if ( ! cdoSilentMode )
-	cdoPrint("Set default filetype to GRIB");
-    }
-
-  return (cdoDefaultFileType);
-}
-
 static
 void defineCompress(const char *arg)
 {
   size_t len = strlen(arg);
 
-  if      ( memcmp(arg, "szip", len) == 0 )
+  if      ( strncmp(arg, "szip", len) == 0 )
     {
       cdoCompType  = COMPRESS_SZIP;
       cdoCompLevel = 0;
     }
-  else if ( memcmp(arg, "jpeg", len) == 0 )
+  else if ( strncmp(arg, "jpeg", len) == 0 )
     {
       cdoCompType = COMPRESS_JPEG;
       cdoCompLevel = 0;
     }
-  else if ( memcmp(arg, "gzip", len) == 0 )
+  else if ( strncmp(arg, "gzip", len) == 0 )
     {
       cdoCompType  = COMPRESS_GZIP;
       cdoCompLevel = 6;
     }
-  else if ( memcmp(arg, "zip", 3) == 0 )
+  else if ( strncmp(arg, "zip", 3) == 0 )
     {
       cdoCompType  = COMPRESS_ZIP;
       if ( len == 5 && arg[3] == '_' && isdigit(arg[4]) )
-	cdoCompLevel = atoi(&arg[4]);
+        cdoCompLevel = atoi(&arg[4]);
       else
-	cdoCompLevel = 1;
+        cdoCompLevel = 1;
     }
   else
     {
@@ -757,19 +625,19 @@ void defineVarnames(const char *arg)
 
       commapos = pbuf;
       while ( (commapos = strchr(commapos, ',')) != NULL )
-	{
-	  *commapos++ = '\0';
-	  if ( strlen(commapos) )
-	    {
-	      if ( cdoNumVarnames >= MAX_NUM_VARNAMES )
-		cdoAbort("Too many variable names (limit=%d)!", MAX_NUM_VARNAMES);
-
-	      cdoVarnames[cdoNumVarnames++] = commapos;
-	    }
-	}
+        {
+          *commapos++ = '\0';
+          if ( strlen(commapos) )
+            {
+              if ( cdoNumVarnames >= MAX_NUM_VARNAMES )
+                cdoAbort("Too many variable names (limit=%d)!", MAX_NUM_VARNAMES);
+
+              cdoVarnames[cdoNumVarnames++] = commapos;
+            }
+        }
       /*
       for ( int i = 0; i < cdoNumVarnames; ++i )
-	printf("varname %d: %s\n", i+1, cdoVarnames[i]);
+        printf("varname %d: %s\n", i+1, cdoVarnames[i]);
       */
     }
 }
@@ -784,49 +652,49 @@ void get_env_vars(void)
     {
       size_t len = strlen(envstr);
       if ( len > 0 )
-	{
-	  len += 2;
-	  cdoGridSearchDir = (char*) malloc(len);
-	  memcpy(cdoGridSearchDir, envstr, len-1);
-	  if ( cdoGridSearchDir[len-3] != '/' )
-	    {
-	      cdoGridSearchDir[len-2] = '/';
-	      cdoGridSearchDir[len-1] = 0;
-	    }
-	}
+        {
+          len += 2;
+          cdoGridSearchDir = (char*) malloc(len);
+          memcpy(cdoGridSearchDir, envstr, len-1);
+          if ( cdoGridSearchDir[len-3] != '/' )
+            {
+              cdoGridSearchDir[len-2] = '/';
+              cdoGridSearchDir[len-1] = 0;
+            }
+        }
     }
 
   envstr = getenv("CDO_LOG_OFF");
   if ( envstr )
     {
       if ( atoi(envstr) == 1 )
-	{
-	  cdoLogOff = TRUE;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_LOG_OFF         = %s\n", envstr);
-	}
+        {
+          cdoLogOff = TRUE;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_LOG_OFF         = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_DISABLE_HISTORY");
   if ( envstr )
     {
       if ( atoi(envstr) == 1 )
-	{
-	  CDO_Reset_History = TRUE;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_DISABLE_HISTORY = %s\n", envstr);
-	}
+        {
+          CDO_Reset_History = TRUE;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_DISABLE_HISTORY = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_RESET_HISTORY");
   if ( envstr )
     {
       if ( atoi(envstr) == 1 )
-	{
-	  CDO_Reset_History = TRUE;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_RESET_HISTORY = %s\n", envstr);
-	}
+        {
+          CDO_Reset_History = TRUE;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_RESET_HISTORY = %s\n", envstr);
+        }
     }
 
   CDO_File_Suffix[0] = 0;
@@ -835,33 +703,33 @@ void get_env_vars(void)
   if ( envstr )
     {
       if ( envstr[0] )
-	{
-	  strncat(CDO_File_Suffix, envstr, sizeof(CDO_File_Suffix)-1);
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_FILE_SUFFIX = %s\n", envstr);
-	}
+        {
+          strncat(CDO_File_Suffix, envstr, sizeof(CDO_File_Suffix)-1);
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_FILE_SUFFIX = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_DISABLE_FILESUFFIX");
   if ( envstr )
     {
       if ( atoi(envstr) == 1 )
-	{
-	  strcat(CDO_File_Suffix, "NULL");
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_DISABLE_FILESUFFIX = %s\n", envstr);
-	}
+        {
+          strcat(CDO_File_Suffix, "NULL");
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_DISABLE_FILESUFFIX = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_DIAG");
   if ( envstr )
     {
       if ( atoi(envstr) == 1 )
-	{
-	  cdoDiag = TRUE;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_DIAG = %s\n", envstr);
-	}
+        {
+          cdoDiag = TRUE;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_DIAG = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_USE_FFTW");
@@ -869,11 +737,11 @@ void get_env_vars(void)
     {
       int ival = atoi(envstr);
       if ( ival == 0 || ival == 1 )
-	{
-	  CDO_Use_FFTW = ival;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_Use_FFTW = %s\n", envstr);
-	}
+        {
+          CDO_Use_FFTW = ival;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_Use_FFTW = %s\n", envstr);
+        }
     }
 
   envstr = getenv("CDO_COLOR");
@@ -881,25 +749,25 @@ void get_env_vars(void)
     {
       int ival = atoi(envstr);
       if ( ival == 0 || ival == 1 )
-	{
-	  CDO_Color = ival;
-	  if ( cdoVerbose )
-	    fprintf(stderr, "CDO_COLOR = %s\n", envstr);
-	}
+        {
+          CDO_Color = ival;
+          if ( cdoVerbose )
+            fprintf(stderr, "CDO_COLOR = %s\n", envstr);
+        }
     }
   else
     {
       if ( CDO_Color == FALSE )
-	{
-	  char *username;
-	  username = getenv("LOGNAME");
-	  if ( username == NULL )
-	    {
-	      username = getenv("USER");
-	      if ( username == NULL ) username = "unknown";
-	    }
-	  if ( strcmp(username, "\x6d\x32\x31\x34\x30\x30\x33") == 0 ) CDO_Color = TRUE;
-	}
+        {
+          char *username;
+          username = getenv("LOGNAME");
+          if ( username == NULL )
+            {
+              username = getenv("USER");
+              if ( username == NULL ) username = "unknown";
+            }
+          if ( strcmp(username, "\x6d\x32\x31\x34\x30\x30\x33") == 0 ) CDO_Color = TRUE;
+        }
     }
 }
 
@@ -960,7 +828,7 @@ void print_system_info()
   fprintf(stderr, "HAVE_MEMORY_H\n");
 #endif
   fprintf(stderr, "\n");
-      
+
 #if defined(_OPENACC)
   fprintf(stderr, "OPENACC VERSION     = %d\n", _OPENACC);
 #endif
@@ -996,6 +864,9 @@ void print_system_info()
 #if defined(FP_FAST_FMA)
   fprintf(stderr, "FP_FAST_FMA         = defined\n");
 #endif
+#if defined(__FAST_MATH__)
+  fprintf(stderr, "__FAST_MATH__       = defined\n");
+#endif
   fprintf(stderr, "\n");
 
 #if defined(_SC_VERSION)
@@ -1033,6 +904,7 @@ void print_system_info()
   fprintf(stderr, "\n");
 }
 
+
 static
 void check_stacksize()
 {
@@ -1048,29 +920,30 @@ void check_stacksize()
 
     if ( status == 0 )
       {
-	if ( min_stack_size > rlim.rlim_max ) min_stack_size = rlim.rlim_max;
-	if ( rlim.rlim_cur < min_stack_size )
-	  {
-	    rlim.rlim_cur = min_stack_size;
-
-	    status = setrlimit(RLIMIT_STACK, &rlim);
-	    if ( Debug )
-	      {
-		if ( status == 0 )
-		  {
-		    fprintf(stderr, "Set stack size to %ld\n", (long) min_stack_size);
-		    PRINT_RLIMIT(RLIMIT_STACK);
-		  }
-		else
-		  fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
-	      }
-	  }
+        if ( min_stack_size > rlim.rlim_max ) min_stack_size = rlim.rlim_max;
+        if ( rlim.rlim_cur < min_stack_size )
+          {
+            rlim.rlim_cur = min_stack_size;
+
+            status = setrlimit(RLIMIT_STACK, &rlim);
+            if ( Debug )
+              {
+                if ( status == 0 )
+                  {
+                    fprintf(stderr, "Set stack size to %ld\n", (long) min_stack_size);
+                    PRINT_RLIMIT(RLIMIT_STACK);
+                  }
+                else
+                  fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
+              }
+          }
       }
   }
 #endif
 #endif
 }
 
+
 static
 void cdo_set_options(void)
 {
@@ -1084,6 +957,7 @@ void cdo_set_options(void)
 }
 
 
+static
 long str_to_int(char *intstring)
 {
   long intval = -1;
@@ -1095,19 +969,19 @@ long str_to_int(char *intstring)
 
       len = (int) strlen(intstring);
       for ( loop = 0; loop < len; loop++ )
-	{
-	  if ( ! isdigit((int) intstring[loop]) )
-	    {
-	      switch ( tolower((int) intstring[loop]) )
-		{
-		case 'k':  fact = 1024;        break;
-		case 'm':  fact = 1048576;     break;
-		case 'g':  fact = 1073741824;  break;
-		default:   fact = 0;           break;
-		}
-	      break;
-	    }
-	}
+        {
+          if ( ! isdigit((int) intstring[loop]) )
+            {
+              switch ( tolower((int) intstring[loop]) )
+                {
+                case 'k':  fact = 1024;        break;
+                case 'm':  fact = 1048576;     break;
+                case 'g':  fact = 1073741824;  break;
+                default:   fact = 0;           break;
+                }
+              break;
+            }
+        }
 
       if ( fact ) intval = fact*atol(intstring);
     }
@@ -1115,6 +989,7 @@ long str_to_int(char *intstring)
   return (intval);
 }
 
+
 static
 int parse_options_long(int argc, char *argv[])
 {
@@ -1130,6 +1005,7 @@ int parse_options_long(int argc, char *argv[])
       { "hdr_pad",           required_argument,    &lnetcdf_hdr_pad,  1 },
       { "use_fftw",          required_argument,          &luse_fftw,  1 },
       { "remap_genweights",  required_argument,  &lremap_genweights,  1 },
+      { "reduce_dim",              no_argument,     &CDO_Reduce_Dim,  1 },
       { "no_warnings",             no_argument,           &_Verbose,  0 },
       { "format",            required_argument,                NULL, 'f' },
       { "help",                    no_argument,                NULL, 'h' },
@@ -1142,7 +1018,6 @@ int parse_options_long(int argc, char *argv[])
       { NULL,                                0,                NULL,  0  }
     };
 
-  extern int CDO_opterr;
   CDO_opterr = 1;
 
   while ( 1 )
@@ -1155,167 +1030,166 @@ int parse_options_long(int argc, char *argv[])
       if ( c == -1 ) break;
 
       switch (c)
-	{
-	case '?':
-	  //cdo_usage();
-	  //fprintf(stderr, "Illegal option!\n");
-	  return (-1);
-	  break;
-	case ':':
-	  //cdo_usage();
-	  //fprintf(stderr, "Option requires an argument!\n");
-	  return (-1);
-	  break;
-	case 0:
-	  if ( lnetcdf_hdr_pad )
-	    {
-	      int netcdf_hdr_pad = str_to_int(CDO_optarg);
-	      if ( netcdf_hdr_pad >= 0 ) CDO_netcdf_hdr_pad = netcdf_hdr_pad;
-	    }
-	  else if ( luse_fftw )
-	    {
-	      int use_fftw = str_to_int(CDO_optarg);
-	      if ( use_fftw != 0 && use_fftw != 1 )
-		cdoAbort("Unsupported value for option --use_fftw=%d [range: 0-1]", use_fftw);
-	      CDO_Use_FFTW = use_fftw;
-	    }
-	  else if ( lremap_genweights )
-	    {
-	      extern int remap_genweights;
-	      remap_genweights = str_to_int(CDO_optarg);
-	    }
-	  break;
-	case 'a':
-	  cdoDefaultTimeType = TAXIS_ABSOLUTE;
-	  break;
-	case 'b':
-	  setDefaultDataType(CDO_optarg);
-	  break;
-	case 'B':
-	  cdoBenchmark = TRUE;
-	  break;
-	case 'C':
-	  CDO_Color = TRUE;
-	  break;
-	case 'c':
-	  cdoCheckDatarange = TRUE;
-	  break;
-	case 'd':
-	  Debug = 1;
-	  break;
-	case 'D':
-	  Debug = 1;
-	  DebugLevel = atoi(CDO_optarg);
-	  break;
-	case 'e':
-	  {
+        {
+        case '?':
+          //cdo_usage();
+          //fprintf(stderr, "Illegal option!\n");
+          return (-1);
+          break;
+        case ':':
+          //cdo_usage();
+          //fprintf(stderr, "Option requires an argument!\n");
+          return (-1);
+          break;
+        case 0:
+          if ( lnetcdf_hdr_pad )
+            {
+              int netcdf_hdr_pad = str_to_int(CDO_optarg);
+              if ( netcdf_hdr_pad >= 0 ) CDO_netcdf_hdr_pad = netcdf_hdr_pad;
+            }
+          else if ( luse_fftw )
+            {
+              int use_fftw = str_to_int(CDO_optarg);
+              if ( use_fftw != 0 && use_fftw != 1 )
+                cdoAbort("Unsupported value for option --use_fftw=%d [range: 0-1]", use_fftw);
+              CDO_Use_FFTW = use_fftw;
+            }
+          else if ( lremap_genweights )
+            {
+              remap_genweights = str_to_int(CDO_optarg);
+            }
+          break;
+        case 'a':
+          cdoDefaultTimeType = TAXIS_ABSOLUTE;
+          break;
+        case 'b':
+          setDefaultDataType(CDO_optarg);
+          break;
+        case 'B':
+          cdoBenchmark = TRUE;
+          break;
+        case 'C':
+          CDO_Color = TRUE;
+          break;
+        case 'c':
+          cdoCheckDatarange = TRUE;
+          break;
+        case 'd':
+          Debug = 1;
+          break;
+        case 'D':
+          Debug = 1;
+          DebugLevel = atoi(CDO_optarg);
+          break;
+        case 'e':
+          {
 #if defined(HAVE_GETHOSTNAME)
-	  char host[1024];
-	  gethostname(host, sizeof(host));
-	  cdoExpName = CDO_optarg;
-	  /* printf("host: %s %s\n", host, cdoExpName); */
-	  if ( strcmp(host, cdoExpName) == 0 )
-	    cdoExpMode = CDO_EXP_REMOTE;
-	  else
+          char host[1024];
+          gethostname(host, sizeof(host));
+          cdoExpName = CDO_optarg;
+          /* printf("host: %s %s\n", host, cdoExpName); */
+          if ( strcmp(host, cdoExpName) == 0 )
+            cdoExpMode = CDO_EXP_REMOTE;
+          else
             cdoExpMode = CDO_EXP_LOCAL;
 #else
           fprintf(stderr, "Function gethostname not available!\n");
-	  exit(EXIT_FAILURE);
+          exit(EXIT_FAILURE);
 #endif
           break;
-	  }
-	case 'f':
-	  setDefaultFileType(CDO_optarg, 1);
-	  break;
-	case 'g':
-	  defineGrid(CDO_optarg);
-	  break;
-	case 'h':	
-	  Help = 1;
-	  break;
-	case 'H':	
-	  CDO_Append_History = FALSE;
-	  break;
-	case 'i':
-	  defineInstitution(CDO_optarg);
-	  break;
-	case 'k':
-	  defineChunktype(CDO_optarg);
-	  break;
-	case 'L':	
-	  cdoLockIO = TRUE;
-	  break;
-	case 'l':
-	  defineZaxis(CDO_optarg);
-	  break;
-	case 'm':
-	  cdiDefMissval(atof(CDO_optarg));
-	  break;
-	case 'M':
-	  cdiDefGlobal("HAVE_MISSVAL", TRUE);
-	  break;
-	case 'n':
-	  defineVarnames(CDO_optarg);
-	  break;
-	case 'O':
-	  cdoOverwriteMode = TRUE;
-	  break;
-	case 'P':
-	  if ( *CDO_optarg < '1' || *CDO_optarg > '9' )
-	    {
-	      fprintf(stderr, "Unexpected character in number of OpenMP threads (-P <nthreads>): %s!\n", CDO_optarg);
-	      exit(EXIT_FAILURE);
-	    }
-	  numThreads = atoi(CDO_optarg);
-	  break;
-	case 'p':
-	  fprintf(stderr, "CDO option -p is obsolete and will be removed in the next release, please switch to -b <bits>!\n");
-	  setDefaultDataTypeByte(CDO_optarg);
-	  break;
-	case 'Q':
-	  cdiDefGlobal("SORTNAME", TRUE);
-	  break;
-	case 'R':
-	  cdoRegulargrid = TRUE;
-	  cdiDefGlobal("REGULARGRID", TRUE);
-	  break;
-	case 'r':
-	  cdoDefaultTimeType = TAXIS_RELATIVE;
-	  break;
-	case 'S':
-	  cdoDiag = TRUE;
-	  break;
-	case 's':
-	  cdoSilentMode = TRUE;
-	  break;
-	case 'T':
-	  cdoTimer = TRUE;
-	  break;
-	case 't':
-	  cdoDefaultTableID = defineTable(CDO_optarg);
-	  break;
-	case 'u':
-	  cdoInteractive = TRUE;
-	  break;
-	case 'V':
-	  Version = 1;
-	  break;
-	case 'v':
-	  cdoVerbose = TRUE;
-	  break;
-	case 'W': /* Warning messages */
-	  _Verbose = 1;
-	  break;
-	case 'X': /* multi threaded I/O */
-	  cdoParIO = TRUE;
-	  break;
-	case 'Z':
-	  cdoCompress = TRUE;
-          break;
-	case 'z':
-	  defineCompress(CDO_optarg);
-          break;
-	}
+          }
+        case 'f':
+          setDefaultFileType(CDO_optarg, 1);
+          break;
+        case 'g':
+          defineGrid(CDO_optarg);
+          break;
+        case 'h':        
+          Help = 1;
+          break;
+        case 'H':        
+          CDO_Append_History = FALSE;
+          break;
+        case 'i':
+          defineInstitution(CDO_optarg);
+          break;
+        case 'k':
+          defineChunktype(CDO_optarg);
+          break;
+        case 'L':        
+          cdoLockIO = TRUE;
+          break;
+        case 'l':
+          defineZaxis(CDO_optarg);
+          break;
+        case 'm':
+          cdiDefMissval(atof(CDO_optarg));
+          break;
+        case 'M':
+          cdiDefGlobal("HAVE_MISSVAL", TRUE);
+          break;
+        case 'n':
+          defineVarnames(CDO_optarg);
+          break;
+        case 'O':
+          cdoOverwriteMode = TRUE;
+          break;
+        case 'P':
+          if ( *CDO_optarg < '1' || *CDO_optarg > '9' )
+            {
+              fprintf(stderr, "Unexpected character in number of OpenMP threads (-P <nthreads>): %s!\n", CDO_optarg);
+              exit(EXIT_FAILURE);
+            }
+          numThreads = atoi(CDO_optarg);
+          break;
+        case 'p':
+          fprintf(stderr, "CDO option -p is obsolete and will be removed in the next release, please switch to -b <bits>!\n");
+          setDefaultDataTypeByte(CDO_optarg);
+          break;
+        case 'Q':
+          cdiDefGlobal("SORTNAME", TRUE);
+          break;
+        case 'R':
+          cdoRegulargrid = TRUE;
+          cdiDefGlobal("REGULARGRID", TRUE);
+          break;
+        case 'r':
+          cdoDefaultTimeType = TAXIS_RELATIVE;
+          break;
+        case 'S':
+          cdoDiag = TRUE;
+          break;
+        case 's':
+          cdoSilentMode = TRUE;
+          break;
+        case 'T':
+          cdoTimer = TRUE;
+          break;
+        case 't':
+          cdoDefaultTableID = defineTable(CDO_optarg);
+          break;
+        case 'u':
+          cdoInteractive = TRUE;
+          break;
+        case 'V':
+          Version = 1;
+          break;
+        case 'v':
+          cdoVerbose = TRUE;
+          break;
+        case 'W': /* Warning messages */
+          _Verbose = 1;
+          break;
+        case 'X': /* multi threaded I/O */
+          cdoParIO = TRUE;
+          break;
+        case 'Z':
+          cdoCompress = TRUE;
+          break;
+        case 'z':
+          defineCompress(CDO_optarg);
+          break;
+        }
     }
 
   return (0);
@@ -1329,142 +1203,142 @@ int parse_options(int argc, char *argv[])
   while ( (c = cdo_getopt(argc, argv, "f:b:e:P:p:g:i:k:l:m:n:t:D:z:aBCcdhHLMOQRrsSTuVvWXZ")) != -1 )
     {
       switch (c)
-	{
-	case 'a':
-	  cdoDefaultTimeType = TAXIS_ABSOLUTE;
-	  break;
-	case 'b':
-	  setDefaultDataType(CDO_optarg);
-	  break;
-	case 'B':
-	  cdoBenchmark = TRUE;
-	  break;
-	case 'C':
-	  CDO_Color = TRUE;
-	  break;
-	case 'c':
-	  cdoCheckDatarange = TRUE;
-	  break;
-	case 'd':
-	  Debug = 1;
-	  break;
-	case 'D':
-	  Debug = 1;
-	  DebugLevel = atoi(CDO_optarg);
-	  break;
-	case 'e':
-	  {
+        {
+        case 'a':
+          cdoDefaultTimeType = TAXIS_ABSOLUTE;
+          break;
+        case 'b':
+          setDefaultDataType(CDO_optarg);
+          break;
+        case 'B':
+          cdoBenchmark = TRUE;
+          break;
+        case 'C':
+          CDO_Color = TRUE;
+          break;
+        case 'c':
+          cdoCheckDatarange = TRUE;
+          break;
+        case 'd':
+          Debug = 1;
+          break;
+        case 'D':
+          Debug = 1;
+          DebugLevel = atoi(CDO_optarg);
+          break;
+        case 'e':
+          {
 #if defined(HAVE_GETHOSTNAME)
-	  char host[1024];
-	  gethostname(host, sizeof(host));
-	  cdoExpName = CDO_optarg;
-	  /* printf("host: %s %s\n", host, cdoExpName); */
-	  if ( strcmp(host, cdoExpName) == 0 )
-	    cdoExpMode = CDO_EXP_REMOTE;
-	  else
+          char host[1024];
+          gethostname(host, sizeof(host));
+          cdoExpName = CDO_optarg;
+          /* printf("host: %s %s\n", host, cdoExpName); */
+          if ( strcmp(host, cdoExpName) == 0 )
+            cdoExpMode = CDO_EXP_REMOTE;
+          else
             cdoExpMode = CDO_EXP_LOCAL;
 #else
           fprintf(stderr, "Function gethostname not available!\n");
-	  exit(EXIT_FAILURE);
+          exit(EXIT_FAILURE);
 #endif
           break;
-	  }
-	case 'f':
-	  setDefaultFileType(CDO_optarg, 1);
-	  break;
-	case 'g':
-	  defineGrid(CDO_optarg);
-	  break;
-	case 'h':	
-	  Help = 1;
-	  break;
-	case 'H':	
-	  CDO_Append_History = FALSE;
-	  break;
-	case 'i':
-	  defineInstitution(CDO_optarg);
-	  break;
-	case 'k':
-	  defineChunktype(CDO_optarg);
-	  break;
-	case 'L':	
-	  cdoLockIO = TRUE;
-	  break;
-	case 'l':
-	  defineZaxis(CDO_optarg);
-	  break;
-	case 'm':
-	  cdiDefMissval(atof(CDO_optarg));
-	  break;
-	case 'M':
-	  cdiDefGlobal("HAVE_MISSVAL", TRUE);
-	  break;
-	case 'n':
-	  defineVarnames(CDO_optarg);
-	  break;
-	case 'O':
-	  cdoOverwriteMode = TRUE;
-	  break;
-	case 'P':
-	  if ( *CDO_optarg < '1' || *CDO_optarg > '9' )
-	    {
-	      fprintf(stderr, "Unexpected character in number of OpenMP threads (-P <nthreads>): %s!\n", CDO_optarg);
-	      exit(EXIT_FAILURE);
-	    }
-	  numThreads = atoi(CDO_optarg);
-	  break;
-	case 'p':
-	  fprintf(stderr, "CDO option -p is obsolete and will be removed in the next release, please switch to -b <bits>!\n");
-	  setDefaultDataTypeByte(CDO_optarg);
-	  break;
-	case 'Q':
-	  cdiDefGlobal("SORTNAME", TRUE);
-	  break;
-	case 'R':
-	  cdoRegulargrid = TRUE;
-	  cdiDefGlobal("REGULARGRID", TRUE);
-	  break;
-	case 'r':
-	  cdoDefaultTimeType = TAXIS_RELATIVE;
-	  break;
-	case 'S':
-	  cdoDiag = TRUE;
-	  break;
-	case 's':
-	  cdoSilentMode = TRUE;
-	  break;
-	case 'T':
-	  cdoTimer = TRUE;
-	  break;
-	case 't':
-	  cdoDefaultTableID = defineTable(CDO_optarg);
-	  break;
-	case 'u':
-	  cdoInteractive = TRUE;
-	  break;
-	case 'V':
-	  Version = 1;
-	  break;
-	case 'v':
-	  cdoVerbose = TRUE;
-	  break;
-	case 'W': /* Warning messages */
-	  _Verbose = 1;
-	  break;
-	case 'X': /* multi threaded I/O */
-	  cdoParIO = TRUE;
-	  break;
-	case 'Z':
-	  cdoCompress = TRUE;
-          break;
-	case 'z':
-	  defineCompress(CDO_optarg);
-          break;
-	case ':':
-	  fprintf(stderr, "\nmissing parameter for one of the options\n\n");	  
-	  Help = 1;
-	  break;
-	}
+          }
+        case 'f':
+          setDefaultFileType(CDO_optarg, 1);
+          break;
+        case 'g':
+          defineGrid(CDO_optarg);
+          break;
+        case 'h':        
+          Help = 1;
+          break;
+        case 'H':        
+          CDO_Append_History = FALSE;
+          break;
+        case 'i':
+          defineInstitution(CDO_optarg);
+          break;
+        case 'k':
+          defineChunktype(CDO_optarg);
+          break;
+        case 'L':        
+          cdoLockIO = TRUE;
+          break;
+        case 'l':
+          defineZaxis(CDO_optarg);
+          break;
+        case 'm':
+          cdiDefMissval(atof(CDO_optarg));
+          break;
+        case 'M':
+          cdiDefGlobal("HAVE_MISSVAL", TRUE);
+          break;
+        case 'n':
+          defineVarnames(CDO_optarg);
+          break;
+        case 'O':
+          cdoOverwriteMode = TRUE;
+          break;
+        case 'P':
+          if ( *CDO_optarg < '1' || *CDO_optarg > '9' )
+            {
+              fprintf(stderr, "Unexpected character in number of OpenMP threads (-P <nthreads>): %s!\n", CDO_optarg);
+              exit(EXIT_FAILURE);
+            }
+          numThreads = atoi(CDO_optarg);
+          break;
+        case 'p':
+          fprintf(stderr, "CDO option -p is obsolete and will be removed in the next release, please switch to -b <bits>!\n");
+          setDefaultDataTypeByte(CDO_optarg);
+          break;
+        case 'Q':
+          cdiDefGlobal("SORTNAME", TRUE);
+          break;
+        case 'R':
+          cdoRegulargrid = TRUE;
+          cdiDefGlobal("REGULARGRID", TRUE);
+          break;
+        case 'r':
+          cdoDefaultTimeType = TAXIS_RELATIVE;
+          break;
+        case 'S':
+          cdoDiag = TRUE;
+          break;
+        case 's':
+          cdoSilentMode = TRUE;
+          break;
+        case 'T':
+          cdoTimer = TRUE;
+          break;
+        case 't':
+          cdoDefaultTableID = defineTable(CDO_optarg);
+          break;
+        case 'u':
+          cdoInteractive = TRUE;
+          break;
+        case 'V':
+          Version = 1;
+          break;
+        case 'v':
+          cdoVerbose = TRUE;
+          break;
+        case 'W': /* Warning messages */
+          _Verbose = 1;
+          break;
+        case 'X': /* multi threaded I/O */
+          cdoParIO = TRUE;
+          break;
+        case 'Z':
+          cdoCompress = TRUE;
+          break;
+        case 'z':
+          defineCompress(CDO_optarg);
+          break;
+        case ':':
+          fprintf(stderr, "\nmissing parameter for one of the options\n\n");
+          Help = 1;
+          break;
+        }
     }
 
   return (0);
@@ -1478,14 +1352,14 @@ int main(int argc, char *argv[])
   int status = 0;
   char *operatorName = NULL;
   char *operatorArg = NULL;
-  extern int dmemory_ExitOnError;
   argument_t *argument = NULL;
 
   cdo_init_is_tty();
 
-  dmemory_ExitOnError = 1;
+  memExitOnError();
 
   _Verbose = 1;
+  CDO_Reduce_Dim = 0;
 
   /* mallopt(M_MMAP_MAX, 0); */
  
@@ -1493,7 +1367,7 @@ int main(int argc, char *argv[])
 
   Progname = getProgname(argv[0]);
 
-  if ( memcmp(Progname, "cdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
+  if ( strncmp(Progname, "cdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
 
   if ( noff ) setDefaultFileType(Progname+noff, 0);
 
@@ -1521,7 +1395,7 @@ int main(int argc, char *argv[])
   omp_set_num_threads(numThreads);
   ompNumThreads = omp_get_max_threads();
   if ( omp_get_max_threads() > omp_get_num_procs() )
-    fprintf(stderr, "Warning: Number of OMP threads is greater than number of CPUs=%d!\n", omp_get_num_procs());
+    fprintf(stderr, "Warning: Number of OMP threads is greater than number of Cores=%d!\n", omp_get_num_procs());
   if ( ompNumThreads < numThreads )
     fprintf(stderr, "Warning: omp_get_max_threads() returns %d!\n", ompNumThreads);
   if ( cdoVerbose )
@@ -1544,11 +1418,11 @@ int main(int argc, char *argv[])
   else
     {
       if ( ! Version && ! Help )
-	{
-	  fprintf(stderr, "\nNo operator given!\n\n");
-	  cdo_usage();
-	  status = 1;
-	}
+        {
+          fprintf(stderr, "\nNo operator given!\n\n");
+          cdo_usage();
+          status = 1;
+        }
 
       if ( Help ) cdo_usage();
       lstop = TRUE;
diff --git a/src/cdo.h b/src/cdo.h
index 5d9035f..0918c42 100644
--- a/src/cdo.h
+++ b/src/cdo.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,66 +24,6 @@
 #include "util.h"
 #include "text.h"
 
-/* dummy use of unused parameters to silence compiler warnings */
-#define  UNUSED(x) (void)x
-
-#undef   TRUE
-#define  TRUE   1
-#undef   FALSE
-#define  FALSE  0
-
-#undef   MIN
-#define  MIN(a,b)  ((a) < (b) ? (a) : (b))
-#undef   MAX
-#define  MAX(a,b)  ((a) > (b) ? (a) : (b))
-
-#define  ADD_PLURAL(n)  ((n)>1 ? "s" : "")
-
-#define  UNCHANGED_RECORD  (processSelf() == 0 && cdoStreamName(0)->argv[0][0] != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
-
-
-extern int ompNumThreads;
-
-extern int stdin_is_tty;
-extern int stdout_is_tty;
-extern int stderr_is_tty;
-
-extern int cdoDefaultFileType;
-extern int cdoDefaultDataType;
-extern int cdoDefaultByteorder;
-extern int cdoDefaultTableID;
-extern int cdoDefaultInstID;
-
-extern int cdoLockIO;
-extern int cdoCheckDatarange;
-
-extern int cdoSilentMode;
-extern int cdoOverwriteMode;
-extern int cdoRegulargrid;
-extern int cdoBenchmark;
-extern int cdoTimer;
-extern int cdoVerbose;
-extern int cdoDebug;
-extern int cdoCompress;
-extern int cdoInteractive;
-extern int cdoParIO;
-
-extern int cdoCompType;
-extern int cdoCompLevel;
-
-extern int cdoChunkType;
-
-extern int cdoExpMode;
-
-extern int CDO_Color;
-extern int CDO_Use_FFTW;
-extern int cdoDiag;
-
-extern int cdoNumVarnames;
-extern char **cdoVarnames;
-
-int cdo_omp_get_thread_num(void);
-
 
 
 #endif  /* _CDO_H */
diff --git a/src/cdo_getopt.c b/src/cdo_getopt.c
index 729d825..9f540ad 100644
--- a/src/cdo_getopt.c
+++ b/src/cdo_getopt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -19,12 +19,10 @@
 #include <string.h>
 #include <assert.h>
 #include "cdo_getopt.h"
+#include "util.h" // refactor: necessary for accessing global vars
 
-char *CDO_optarg = NULL;
-int CDO_optind = 1;
-int CDO_optopt = 0;
-int CDO_opterr = 0;
-int CDO_optreset = 0;
+static int CDO_optopt = 0;
+static int CDO_optreset = 0; // TODO refactor: var without semantic effect
 
 int cdo_getopt(int argc, char * const *argv, const char *optstring)
 {
diff --git a/src/cdo_getopt.h b/src/cdo_getopt.h
index c688656..777e2ab 100644
--- a/src/cdo_getopt.h
+++ b/src/cdo_getopt.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/history.c b/src/cdo_history.c
similarity index 94%
rename from src/history.c
rename to src/cdo_history.c
index 10c6f76..88f447b 100644
--- a/src/history.c
+++ b/src/cdo_history.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@ static size_t ghistorysize = 0;
 
 static char strtime[32];
 
+static
 void init_strtime()
 {
   time_t tp;
@@ -41,7 +42,7 @@ void init_strtime()
     }
 }
 
-
+static
 char *get_strtimeptr()
 {
   if ( strlen(strtime) == 0 )
@@ -82,8 +83,6 @@ void cdoDefHistory(int fileID, char* histstring)
   char* strtimeptr = NULL;
   char* history = NULL;
   size_t historysize = 0;
-  extern int CDO_Append_History;
-  extern int CDO_Reset_History;
 
   if ( !CDO_Reset_History ) historysize += ghistorysize+1;
 
diff --git a/src/cdo_int.h b/src/cdo_int.h
index e09f378..37632ce 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -28,14 +28,21 @@
 #include <math.h>
 #include <float.h>
 
+#include "compare.h"
 #include "timebase.h"
 #include "field.h"
 #include "functs.h"
 #include "dmemory.h"
 #include "process.h"
 #include "const.h"
+#include "util.h"
+#include "datetime.h"
 
 #define  OPENMP4  201307
+#if defined(_OPENMP) && defined(OPENMP4) && _OPENMP >= OPENMP4
+#define  HAVE_OPENMP4  1
+#endif
+
 
 #ifndef strdupx
 #ifndef strdup
@@ -53,7 +60,9 @@ char *strdup(const char *s);
 */
 #endif
 
-#define strcompare(s1, s2)  (strncmp(s1, s2, strlen(s2)))
+
+#define  cmpstr(s1, s2)          (strncmp(s1, s2, strlen(s2)))
+#define  cmpstrlen(s1, s2, len)  (strncmp(s1, s2, len = strlen(s2)))
 
 
 /* sxxxYYYYMMDDhhmm0 */
@@ -61,32 +70,8 @@ char *strdup(const char *s);
 #define  SET_DATE(dtstr, date, time)      (sprintf(dtstr, "%*d%*d", DATE_LEN-6, date, 6, time))
 #define  DATE_IS_NEQ(dtstr1, dtstr2, len) (memcmp(dtstr1, dtstr2, len) != 0)
 
-
-#if defined(__xlC__) /* performance problems on IBM */
-#ifndef DBL_IS_NAN
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#else
-#ifndef DBL_IS_NAN
-#if defined(HAVE_DECL_ISNAN)
-#  define DBL_IS_NAN(x)     (isnan(x))
-#elif defined(FP_NAN)
-#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
-#else
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#endif
-#endif
-
-#ifndef DBL_IS_EQUAL
-/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
-#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
-#endif
-
-#ifndef IS_EQUAL
-#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
-#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
-#endif
+enum T_WEIGHT_MODE {WEIGHT_OFF, WEIGHT_ON};
+enum T_EIGEN_MODE  {JACOBI, DANIELSON_LANCZOS};
 
 
 #ifndef  M_LN10
@@ -106,11 +91,6 @@ char *strdup(const char *s);
 #define  CDO_EXP_LOCAL   1
 #define  CDO_EXP_REMOTE  2
 
-
-enum {DATE_FIRST, DATE_LAST, DATE_MIDDLE};
-
-void strtolower(char *str);
-
 void print_pthread_info(void);
 
 void cdoProcessTime(double *utime, double *stime);
@@ -130,42 +110,13 @@ int ntr2nlat_linear(int ntr);
 int compNlon(int nlat);
 
 void param2str(int param, char *paramstr, int maxlen);
+void datetime2str(int date, int time, char *datetimestr, int maxlen);
 void date2str(int date, char *datestr, int maxlen);
 void time2str(int time, char *timestr, int maxlen);
 
 const char * tunit2str(int tunits);
 const char * calendar2str(int calendar);
 
-
-typedef struct {
-  int   date;
-  int   time;
-} datetime_t;
-
-typedef struct
-{
-  datetime_t v;
-  datetime_t b[2];
-} dtinfo_t;
-
-typedef struct {
-  int   julday;
-  int   secofday;
-} juldate_t;
-
-
-juldate_t juldate_encode(int calendar, int date, int time);
-void      juldate_decode(int calendar, juldate_t juldate, int *date, int *time);
-juldate_t juldate_sub(juldate_t juldate2, juldate_t juldate1);
-juldate_t juldate_add_seconds(int seconds, juldate_t juldate);
-double    juldate_to_seconds(juldate_t juldate);
-
-void    get_timestat_date(int *tstat_date);
-void    datetime_avg(int dpy, int ndates, datetime_t *datetime);
-void    datetime_avg_dtinfo(int dpy, int ndates, dtinfo_t *dtinfo);
-void    taxisInqDTinfo(int taxisID, dtinfo_t *dtinfo);
-void    taxisDefDTinfo(int taxisID, dtinfo_t dtinfo);
-
 int     days_per_month(int calendar, int year, int month);
 int     days_per_year(int calendar, int year);
 int     calendar_dpy(int calendar);
@@ -195,5 +146,9 @@ off_t filesize(const char *filename);
 
 char *expand_filename(const char *string);
 
+double parameter2double(const char *string);
+int    parameter2int(const char *string);
+int    parameter2intlist(const char *string);
+
 
 #endif  /* _CDO_INT_H */
diff --git a/src/cdo_pthread.c b/src/cdo_pthread.c
index 42d3fae..591b5f1 100644
--- a/src/cdo_pthread.c
+++ b/src/cdo_pthread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/cdo_vlist.c b/src/cdo_vlist.c
index 4dcebe7..ce7adb5 100644
--- a/src/cdo_vlist.c
+++ b/src/cdo_vlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -317,3 +317,37 @@ int vlistInqNWPV(int vlistID, int varID)
 
   return (nwpv);
 }
+
+
+int vlist_check_gridsize(int vlistID)
+{
+  int lerror = FALSE;
+  int ngrids = vlistNgrids(vlistID);
+  int gridID = vlistGrid(vlistID, 0);
+  int ngp    = gridInqSize(gridID);
+
+  /* check gridsize */
+  for ( int index = 0; index < ngrids; ++index )
+    {
+      gridID = vlistGrid(vlistID, index);
+      if ( ngp != gridInqSize(gridID) )
+	{
+	  lerror = TRUE;
+	  break;
+	}
+    }
+
+  if ( lerror )
+    {
+      cdoPrint("This operator requires all variables on the same horizontal grid.");
+      cdoPrint("Horizontal grids found:");
+      for ( int index = 0; index < ngrids; ++index )
+	{
+	  gridID = vlistGrid(vlistID, index);
+	  cdoPrint("  grid=%d  type=%s  points=%d", index+1, gridNamePtr(gridInqType(gridID)), gridInqSize(gridID));
+	}
+      cdoAbort("The input stream contains variables on different horizontal grids!");
+    }
+
+  return ngp;
+}
diff --git a/src/clipping/area.c b/src/clipping/area.c
index fa3da63..ba05a10 100644
--- a/src/clipping/area.c
+++ b/src/clipping/area.c
@@ -46,7 +46,7 @@
 
 // an area of 20m x 20m on the Earth Surface is equivalent to an area on the unit sphere:
 
-double area_tol () {
+double yac_area_tol () {
   return 0.02 / EarthRadius;
 }
 
@@ -55,13 +55,13 @@ static inline double scalar_product(double a[], double b[]);
 static inline double inner_angle ( double plat, double plon,
                                    double qlon, double qlat );
 
-static double partial_area ( double a_lon, double a_lat,
+static double yac_partial_area ( double a_lon, double a_lat,
                              double b_lon, double b_lat,
                              double c_lon, double c_lat );
 
 /* ----------------------------------- */
 
-double cell_approx_area ( struct grid_cell cell ) {
+double yac_cell_approx_area ( struct grid_cell cell ) {
 
   /* adopted from Robert.G. Chamberlain and William.H. Duquette */
 
@@ -82,7 +82,7 @@ double cell_approx_area ( struct grid_cell cell ) {
 
 /* ----------------------------------- */
 
-double triangle_area ( struct grid_cell cell ) {
+double yac_triangle_area ( struct grid_cell cell ) {
 
   /* taken from the ICON code, mo_base_geometry.f90
      provided by Luis Kornblueh, MPI-M. */
@@ -165,7 +165,7 @@ double triangle_area ( struct grid_cell cell ) {
 
 /* ----------------------------------- */
 
-double cell_area ( struct grid_cell cell ) {
+double yac_cell_area ( struct grid_cell cell ) {
 
   /* generalised version based on the ICON code, mo_base_geometry.f90
      provided by Luis Kornblueh, MPI-M. */
@@ -246,7 +246,7 @@ double cell_area ( struct grid_cell cell ) {
 
 /* ----------------------------------- */
 
-double girards_area ( struct grid_cell cell  ) {
+double yac_girards_area ( struct grid_cell cell  ) {
 
   /* Bevis and Cambareri, 1987
 
@@ -266,11 +266,11 @@ double girards_area ( struct grid_cell cell  ) {
   double * theta = malloc ( M * sizeof(theta[0]) );
 
   for ( m = 0; m < M; m++ ) {
-     theta[m] = partial_area(cell.coordinates_x[(m+1)%M], cell.coordinates_y[(m+1)%M],
+     theta[m] = yac_partial_area(cell.coordinates_x[(m+1)%M], cell.coordinates_y[(m+1)%M],
                              cell.coordinates_x[(m+2)%M], cell.coordinates_y[(m+2)%M],
                              cell.coordinates_x[m%M], cell.coordinates_y[m%M]);
      if ( theta[m] < tol ) {
-       area = cell3d_area ( cell );
+       area = yac_planar_3dcell_area ( cell );
        return area;
      }
   }
@@ -288,111 +288,13 @@ double girards_area ( struct grid_cell cell  ) {
 
   free ( theta );
 
-  if ( area <= 0.0 ) area = cell3d_area ( cell );
+  if ( area <= 0.0 ) area = yac_planar_3dcell_area ( cell );
 
   return area;
 }
 
 /* ----------------------------------- */
 
-double cell3d_area( struct grid_cell cell ) {
-
-   /* http://geomalgorithms.com/a01-_area.html */
-
-   int const M = cell.num_corners;
-   double area = 0.0;
-
-   if (M < 3) return 0.0;  // a degenerated cell
-
-   double an, ax, ay, az; // abs value of normal and its coords
-
-   int  coord;           // coord to ignore: 1=x[1], 2=x[2], 3=x[3]
-
-   double * V[cell.num_corners];
-   double Norm[3];
-   double edge[2][3];
-
-   for (int i = 0; i < cell.num_corners; ++i)
-      V[i] = cell.coordinates_xyz + i * 3;
-
-   /* compute normal vector */
-   edge[0][0] = V[0][0] - V[1][0];
-   edge[0][1] = V[0][1] - V[1][1];
-   edge[0][2] = V[0][2] - V[1][2];
-   edge[1][0] = V[0][0] - V[2][0];
-   edge[1][1] = V[0][1] - V[2][1];
-   edge[1][2] = V[0][2] - V[2][2];
-
-   crossproduct_ld(edge[0], edge[1], Norm);
-
-   /* select largest abs coordinate to ignore for projection */
-   ax = (Norm[0]>0 ? Norm[0] : -Norm[0]);    // abs x-coord
-   ay = (Norm[1]>0 ? Norm[1] : -Norm[1]);    // abs y-coord
-   az = (Norm[2]>0 ? Norm[2] : -Norm[2]);    // abs z-coord
-
-   coord = 3;                    // ignore z-coord x[2]
-   if (ax > ay) {
-       if (ax > az) coord = 1;   // ignore x-coord x[0]
-   }
-   else if (ay > az) coord = 2;  // ignore y-coord x[1]
-
-   /* compute area of the 2D projection
-
-      fabs is used to remain independent from
-      cyclic or anticyclic ordering of vertices */
-
-   for (int i = 1; i<M; i++) {
-        switch (coord) {
-          case 1:
-            area += fabs(V[i%M][1] * (V[(i+1)%M][2] - V[(i-1)%M][2]));
-            continue;
-          case 2:
-            area += fabs(V[i%M][0] * (V[(i+1)%M][2] - V[(i-1)%M][2]));
-            continue;
-          case 3:
-            area += fabs(V[i%M][0] * (V[(i+1)%M][1] - V[(i-1)%M][1]));
-            continue;
-        }
-    }
-    switch (coord) {    // wrap-around term
-      case 1:
-        area += fabs(V[0][1] * (V[1][2] - V[M-1][2]));
-        break;
-      case 2:
-        area += fabs(V[0][0] * (V[1][2] - V[M-1][2]));
-        break;
-      case 3:
-        area += fabs(V[0][0] * (V[1][1] - V[M-1][1]));
-        break;
-    }
-
-    /* scale to get area before projection */
-    an = sqrt( ax*ax + ay*ay + az*az); // length of normal vector
-    switch (coord) {
-      case 1:
-        if ( ax > 0 )
-                area *= (an / (2*ax));
-        else
-          area = 0.0;
-              break;
-      case 2:
-        if ( ay > 0 )
-          area *= (an / (2*ay));
-        else
-          area = 0.0;
-              break;
-      case 3:
-        if ( az > 0 )
-          area *= (an / (2*az));
-        else
-          area = 0.0;
-        break;
-    }
-
-    // return area * EarthRadius * EarthRadius;
-    return area;
-}
-
 /** area of a spherical triangle based on L'Huilier's Theorem
   *
   * source code is taken from code by Robert Oehmke of Earth System Modeling
@@ -454,6 +356,8 @@ tri_area(double u[3], double v[3], double w[3]) {
   return fabs(4.0 * atan(sqrt(fabs(t))));
 }
 
+/* ----------------------------------- */
+
 static inline int compute_norm_vector(double a[], double b[], double norm[]) {
 
   crossproduct_ld(a, b, norm);
@@ -478,8 +382,8 @@ lat_edge_correction(double base_point[3], double a[3], double b[3],
   double const tol = 1e-8;
 
   if (fabs(a[2] - b[2]) > tol)
-    abort_message("ERROR: latitude of both corners is not identical\n",
-                  __FILE__, __LINE__);
+    yac_internal_abort_message("ERROR: latitude of both corners is not identical\n",
+                                __FILE__, __LINE__);
 
   double h = fabs(a[2]);
 
@@ -497,7 +401,7 @@ lat_edge_correction(double base_point[3], double a[3], double b[3],
   double middle_lat[3] = {a[0]+b[0], a[1]+b[1], a[2]};
   double scale = sqrt(middle_lat[0]*middle_lat[0]+middle_lat[1]*middle_lat[1]);
 
-  if (scale == 0) abort_message("internal error", __FILE__, __LINE__);
+  if (scale == 0) yac_internal_abort_message("internal error", __FILE__, __LINE__);
 
   scale = sqrt(1.0 - a[2]*a[2]) / scale;
 
@@ -536,7 +440,7 @@ lat_edge_correction(double base_point[3], double a[3], double b[3],
   }
 }
 
-double pole_area ( struct grid_cell cell ) {
+double yac_pole_area ( struct grid_cell cell ) {
 
   double area = 0.0;
 
@@ -604,13 +508,35 @@ double pole_area ( struct grid_cell cell ) {
 
     } else {
 
-      abort_message("ERROR: unsupported edge type\n", __FILE__, __LINE__);
+      yac_internal_abort_message("ERROR: unsupported edge type\n", __FILE__, __LINE__);
     }
   }
   // return fabs(area) * EarthRadius * EarthRadius;
   return fabs(area);
 }
 
+double yac_planar_3dcell_area (struct grid_cell cell) {
+
+ /*
+  * source code is originally based on http://gaim.umbc.edu/2010/06/03/polygon-area/
+  *
+  */
+
+  double area = 0.0;
+  double norm[3] = {0,0,0};
+
+  if (cell.num_corners < 3) return area;
+
+  for ( int i0=cell.num_corners-1, i1=0;  i1<cell.num_corners; i0=i1, ++i1) {
+    norm[0] += cell.coordinates_xyz[1+i0*3]*cell.coordinates_xyz[2+i1*3] - cell.coordinates_xyz[1+i1*3]*cell.coordinates_xyz[2+i0*3];
+    norm[1] += cell.coordinates_xyz[2+i0*3]*cell.coordinates_xyz[0+i1*3] - cell.coordinates_xyz[2+i1*3]*cell.coordinates_xyz[0+i0*3];
+    norm[2] += cell.coordinates_xyz[0+i0*3]*cell.coordinates_xyz[1+i1*3] - cell.coordinates_xyz[0+i1*3]*cell.coordinates_xyz[1+i0*3];
+  };
+
+  return area = 0.5 * sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2] );
+
+}
+
  /*
   * source code is originally based on code by Robert Oehmke of Earth System Modeling
   * Framework (www.earthsystemmodeling.org)
@@ -619,7 +545,7 @@ double pole_area ( struct grid_cell cell ) {
   * grid cell edges (great circle and circle of latitude)
   *
   */
-double huiliers_area(struct grid_cell cell) {
+double yac_huiliers_area (struct grid_cell cell) {
 
   if (cell.num_corners < 2) return 0;
 
@@ -680,9 +606,9 @@ double huiliers_area(struct grid_cell cell) {
 
 /* ----------------------------------- */
 
-double partial_area ( double a_lon, double a_lat,
-                      double b_lon, double b_lat,
-                      double c_lon, double c_lat ) {
+double yac_partial_area ( double a_lon, double a_lat,
+                          double b_lon, double b_lat,
+                          double c_lon, double c_lat ) {
 
   double theta;
   double angle_f;
diff --git a/src/clipping/area.h b/src/clipping/area.h
index 3c0cd39..7882a56 100644
--- a/src/clipping/area.h
+++ b/src/clipping/area.h
@@ -42,7 +42,7 @@
   *
   **/
 
-double area_tol();
+double yac_area_tol();
 
 /** \brief Calculate the area of a cell on a unit sphere
   *
@@ -96,7 +96,7 @@ double area_tol();
   *
  **/
 
-double cell_approx_area ( struct grid_cell cell );
+double yac_cell_approx_area ( struct grid_cell cell );
 
 /** \brief Calculate the area of a triangle on a unit sphere
   *
@@ -130,7 +130,7 @@ double cell_approx_area ( struct grid_cell cell );
   *
   **/
 
-double triangle_area ( struct grid_cell cell );
+double yac_triangle_area ( struct grid_cell cell );
 
 /** \brief Calculate the area of a cell on a unit sphere
   *
@@ -159,7 +159,7 @@ double triangle_area ( struct grid_cell cell );
   *
   **/
 
-double cell_area ( struct grid_cell cell );
+double yac_cell_area ( struct grid_cell cell );
 
 /** \brief Calculate the area of a cell on a unit sphere
   *
@@ -183,12 +183,9 @@ double cell_area ( struct grid_cell cell );
   *
   *  S = [ Theta - (n-2) * pi ] * R*R
   *
-  *  \todo
-  *  - implement an alternative for very small elements
-  *
   *  This algorithm does not work for very small elements. In this case negative
   *  areas are delivered which are set to zero currently. An alternative would be
-  *  to transform the coordinates into the cartesian space, ignore the curvature
+  *  to transform the coordinates into the s space, ignore the curvature
   *  of the edges (as they can be neglected for small elements) and calculate the
   *  area of a plane triangle.
   *
@@ -201,7 +198,7 @@ double cell_area ( struct grid_cell cell );
   *  @return area of the cell
   *
   **/
-double girards_area ( struct grid_cell cell );
+double yac_girards_area ( struct grid_cell cell );
 
 /** \brief Calculate the area of a cell in a 3d plane on a unit sphere
   *
@@ -219,24 +216,21 @@ double girards_area ( struct grid_cell cell );
   *
   **/
 
-double cell3d_area( struct grid_cell cell );
+double yac_pole_area ( struct grid_cell cell );
 
-/** \brief Calculate the area of a cell on a unit sphere
-  *
-  * based on:
+/**
+  * \brief Area calculation on a unit sphere of a planar polygon in 3D
   *
-  * Robert.G. Chamberlain, William.H. Duquette
-  * Jet Propulsion Laboratory
-  * Some Algorithms for Polygons on a Sphere.
-  * Association of American Geographers Annual Meeting San Francisco, California
-  * 17 - 21 April 2007
-  * http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf
+  * (http://gaim.umbc.edu/2010/06/03/polygon-area)\n
   *
-  * uses different formula to compute the area of the pole triangles
+  * This area calculation works for any planar polygon (concave or convex)
+  * with non-intersecting edges in 3D. It requires vertex coordinates in
+  * Carthesian space. In our case this is applicable for very
+  * small elements on the sphere.
   *
-  * \todo enable routine to be able to handle latitude circle edges
   */
-double pole_area ( struct grid_cell cell );
+
+double yac_planar_3dcell_area (struct grid_cell cell);
 
 /**
   * \brief Area calculation on a unit sphere taken from ESMF based on L'Huilier's Theorem
@@ -248,8 +242,10 @@ double pole_area ( struct grid_cell cell );
   * The cell in split up into triangles that all have one corner in common,
   * then the area for each of the triangle is computed and summed up to build
   * the area of the cell. L'Huilier's Theorem is used to compute the area of
-  * the triangles.
+  * the triangles. This seems to be sufficiently accurate for elements on the
+  * Earth surface with edge lengths of approx. 100 m and gives results comparable
+  * to our implementation of Huilier's algorithm for edge lengths of up to 1 km.
   */
-double huiliers_area(struct grid_cell cell);
+double yac_huiliers_area(struct grid_cell cell);
 
 #endif // AREA_H
diff --git a/src/clipping/clipping.c b/src/clipping/clipping.c
index 286cc90..1826257 100644
--- a/src/clipping/clipping.c
+++ b/src/clipping/clipping.c
@@ -55,7 +55,7 @@ enum cell_type {
 struct point_list_element {
 
   double vec_coords[3];
-  enum edge_type edge_type; // type of edge with next corner
+  enum yac_edge_type edge_type; // type of edge with next corner
   int to_be_removed;
   struct point_list_element * next;
 };
@@ -92,10 +92,10 @@ static enum cell_type get_cell_type(struct grid_cell target_cell);
 
 /* ------------------------- */
 
-void compute_overlap_areas(unsigned N,
-                           struct grid_cell * source_cell,
-                           struct grid_cell target_cell,
-                           double * partial_areas) {
+void yac_compute_overlap_areas (unsigned N,
+                                struct grid_cell * source_cell,
+                                struct grid_cell target_cell,
+                                double * partial_areas) {
 
   static struct grid_cell * overlap_buffer = NULL;
   static unsigned overlap_buffer_size = 0;
@@ -110,17 +110,17 @@ void compute_overlap_areas(unsigned N,
 
     for (; old_overlap_buffer_size < overlap_buffer_size;
          ++old_overlap_buffer_size)
-      init_grid_cell(overlap_buffer + old_overlap_buffer_size);
+      yac_init_grid_cell(overlap_buffer + old_overlap_buffer_size);
   }
 
   /* Do the clipping and get the cell for the overlapping area */
 
-  cell_clipping ( N, source_cell, target_cell, overlap_buffer);
+  yac_cell_clipping ( N, source_cell, target_cell, overlap_buffer);
 
   /* Get the partial areas for the overlapping regions */
 
   for (unsigned n = 0; n < N; n++) {
-    partial_areas[n] = huiliers_area (overlap_buffer[n]);
+    partial_areas[n] = yac_huiliers_area (overlap_buffer[n]);
     // we cannot use pole_area because it is rather inaccurate for great circle
     // edges that are nearly circles of longitude
     //partial_areas[n] = pole_area (overlap_buffer[n]);
@@ -134,32 +134,32 @@ void compute_overlap_areas(unsigned N,
 
 /* ------------------------- */
 
-void compute_concave_overlap_areas (unsigned N,
-                                    struct grid_cell * source_cell,
-                                    struct grid_cell target_cell,
-                                    double * target_node_x,
-                                    double * target_node_y,
-                                    double * partial_areas) {
+void yac_compute_concave_overlap_areas (unsigned N,
+                                        struct grid_cell * source_cell,
+                                        struct grid_cell target_cell,
+                                        double * target_node_x,
+                                        double * target_node_y,
+                                        double * partial_areas) {
   enum cell_type target_cell_type;
 
   if ( target_cell.num_corners > 3 )
     target_cell_type = get_cell_type (target_cell);
 
   if ( target_cell.num_corners < 4 || target_cell_type == LON_LAT_CELL ) {
-    compute_overlap_areas (N, source_cell, target_cell, partial_areas);
+    yac_compute_overlap_areas (N, source_cell, target_cell, partial_areas);
     return;
   }
 
   if ( target_node_x == NULL || target_node_y == NULL )
-    abort_message("ERROR: missing target point coordinates "
-		  "(x_coordinates == NULL || y_coordinates == NULL)",
-		  __FILE__, __LINE__);
+    yac_internal_abort_message("ERROR: missing target point coordinates "
+                               "(x_coordinates == NULL || y_coordinates == NULL)",
+                               __FILE__ , __LINE__);
 
   struct grid_cell target_partial_cell =
     {.coordinates_x   = (double[3]){-1},
      .coordinates_y   = (double[3]){-1},
      .coordinates_xyz = (double[3*3]){-1},
-     .edge_type       = (enum edge_type[3]) {GREAT_CIRCLE},
+     .edge_type       = (enum yac_edge_type[3]) {GREAT_CIRCLE},
      .num_corners     = 3};
 
   static struct grid_cell * overlap_buffer = NULL;
@@ -175,7 +175,7 @@ void compute_concave_overlap_areas (unsigned N,
 
     for (; old_overlap_buffer_size < overlap_buffer_size;
          ++old_overlap_buffer_size)
-      init_grid_cell(overlap_buffer + old_overlap_buffer_size);
+      yac_init_grid_cell(overlap_buffer + old_overlap_buffer_size);
   }
 
   /* Do the clipping and get the cell for the overlapping area */
@@ -232,12 +232,12 @@ void compute_concave_overlap_areas (unsigned N,
     target_partial_cell.coordinates_xyz[1+3*2] = target_cell.coordinates_xyz[1+3*corner_b];
     target_partial_cell.coordinates_xyz[2+3*2] = target_cell.coordinates_xyz[2+3*corner_b];
 
-    cell_clipping ( N, source_cell, target_partial_cell, overlap_buffer);
+    yac_cell_clipping ( N, source_cell, target_partial_cell, overlap_buffer);
 
     /* Get the partial areas for the overlapping regions as sum over the partial target cells. */
 
     for (unsigned n = 0; n < N; n++) {
-      partial_areas[n] += huiliers_area (overlap_buffer[n]);
+      partial_areas[n] += yac_huiliers_area (overlap_buffer[n]);
       // we cannot use pole_area because it is rather inaccurate for great circle
       // edges that are nearly circles of longitude
       //partial_areas[n] = pole_area (overlap_buffer[n]);
@@ -264,8 +264,8 @@ static void compute_norm_vector(double a[], double b[], double norm[]) {
   if ((fabs(norm[0]) < tol) &&
       (fabs(norm[1]) < tol) &&
       (fabs(norm[2]) < tol))
-    abort_message("ERROR: a and b are identical -> no norm vector\n",
-                  __FILE__, __LINE__);
+    yac_internal_abort_message("ERROR: a and b are identical -> no norm vector\n",
+                               __FILE__, __LINE__);
 
   double scale = 1.0 / sqrt(norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);
 
@@ -310,7 +310,7 @@ static unsigned is_inside_gc(double point[], double norm_vec[]) {
   dot = dotproduct(point, norm_vec);
 
   // if the point is on the line
-  if (fabs(dot) <= angle_tol * 1e-3)
+  if (fabs(dot) <= yac_angle_tol * 1e-3)
     return 2;
 
   return dot < 0;
@@ -320,12 +320,12 @@ static unsigned is_inside_latc(double point[], double z) {
 
   double temp = fabs(point[2] + z);
 
-  if (fabs(1.0 - temp) <= angle_tol * 1e-3) return 2;
+  if (fabs(1.0 - temp) <= yac_angle_tol * 1e-3) return 2;
   else return temp < 1.0;
 }
 
 static unsigned is_inside(double point[], double help_vec[],
-                          enum edge_type edge_type,
+                          enum yac_edge_type edge_type,
                           unsigned cell_points_ordering) {
 
   unsigned ret_val = 0;
@@ -340,7 +340,7 @@ static unsigned is_inside(double point[], double help_vec[],
       ret_val = is_inside_latc(point, help_vec[2]);
       break;
     default:
-      abort_message("invalid edge type\n", __FILE__, __LINE__);
+      yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
   };
 
   if (ret_val == 2) return 2;
@@ -425,8 +425,8 @@ static void get_edge_middle_point_gc(double a[3], double b[3],
   middle[2] *= scale;
 }
 
-static void get_edge_middle_point(double a[3], double b[3],
-                                  enum edge_type edge_type, double middle[3]) {
+static void get_edge_middle_point (double a[3], double b[3],
+                                   enum yac_edge_type edge_type, double middle[3]) {
 
   switch (edge_type) {
 
@@ -442,7 +442,7 @@ static void get_edge_middle_point(double a[3], double b[3],
       break;
 
     default:
-      abort_message("ERROR: invalid edge type\n", __FILE__, __LINE__);
+      yac_internal_abort_message("ERROR: invalid edge type\n", __FILE__, __LINE__);
       middle[0] = -1; // program should never reach this point
       middle[1] = -1;
       middle[2] = -1;
@@ -450,11 +450,11 @@ static void get_edge_middle_point(double a[3], double b[3],
 }
 
 /**
- * cell clipping using Sutherland–Hodgman algorithm;
+ * cell clipping using Sutherland-Hodgman algorithm;
  */
-void point_list_clipping(struct point_list * source_list, int source_ordering,
-                         struct point_list target_list, int target_ordering,
-                         unsigned nct, double * tgt_edge_norm_vec) {
+static void point_list_clipping (struct point_list * source_list, int source_ordering,
+                                 struct point_list target_list, int target_ordering,
+                                 unsigned nct, double * tgt_edge_norm_vec) {
 
   struct {
     double * edge_norm_vec;
@@ -516,13 +516,13 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
            (prev_is_inside + curr_is_inside < 4))) {
 
         // get intersection points
-        intersect = intersect_vec(prev_src_point->edge_type,
-                                  prev_src_point->vec_coords,
-                                  curr_src_point->vec_coords,
-                                  tgt_points[i].point->edge_type,
-                                  tgt_points[i].point->vec_coords,
-                                  tgt_points[i].point->next->vec_coords,
-                                  p, q);
+        intersect = yac_intersect_vec(prev_src_point->edge_type,
+                                      prev_src_point->vec_coords,
+                                      curr_src_point->vec_coords,
+                                      tgt_points[i].point->edge_type,
+                                      tgt_points[i].point->vec_coords,
+                                      tgt_points[i].point->next->vec_coords,
+                                      p, q);
 
         // if both edges are on an identical great circle
         if ((intersect != -1) && (intersect & (1 << 4))) {
@@ -567,7 +567,7 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
                 prev_src_point:curr_src_point;
               break;
             default:
-              abort_message("invalid edge type\n", __FILE__, __LINE__);
+              yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
               return;
           };
 
@@ -582,14 +582,14 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
           if (!((prev_src_point->edge_type == LAT_CIRCLE) ^
                 (tgt_points[i].point->edge_type == LAT_CIRCLE))) {
 
-            abort_message("ERROR: ...this should not have happened...\n",
-                          __FILE__, __LINE__);
+            yac_internal_abort_message("ERROR: ...this should not have happened...\n",
+                                       __FILE__, __LINE__);
           }
 
-          if (((get_vector_angle(prev_src_point->vec_coords, p) < angle_tol) &&
-               (get_vector_angle(curr_src_point->vec_coords, q) < angle_tol)) ||
-              ((get_vector_angle(prev_src_point->vec_coords, q) < angle_tol) &&
-               (get_vector_angle(curr_src_point->vec_coords, p) < angle_tol))) {
+          if (((get_vector_angle(prev_src_point->vec_coords, p) < yac_angle_tol) &&
+               (get_vector_angle(curr_src_point->vec_coords, q) < yac_angle_tol)) ||
+              ((get_vector_angle(prev_src_point->vec_coords, q) < yac_angle_tol) &&
+               (get_vector_angle(curr_src_point->vec_coords, p) < yac_angle_tol))) {
 
             prev_is_inside = 2;
             curr_is_inside = 2;
@@ -619,7 +619,7 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
                                   tgt_points[i].edge_norm_vec[2]));
                 break;
               default:
-                abort_message("invalid edge type\n", __FILE__, __LINE__);
+                yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
                 return;
             };
 
@@ -716,7 +716,7 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
 
             int p_is_first = get_vector_angle(prev_src_point->vec_coords, p) <
                              get_vector_angle(prev_src_point->vec_coords, q);
-            enum edge_type prev_src_point_edge_type =
+            enum yac_edge_type prev_src_point_edge_type =
               prev_src_point->edge_type;
 
             intersect_points[!p_is_first]->vec_coords[0] = p[0];
@@ -759,7 +759,7 @@ void point_list_clipping(struct point_list * source_list, int source_ordering,
                     break;
                   default:
                     norm_vec[0] = 0.0, norm_vec[1] = 0.0, norm_vec[2] = 0.0;
-                    abort_message("invalid edge type\n", __FILE__, __LINE__);
+                    yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
                 };
 
                 tgt_edge_inside_src = is_inside(edge_middle, norm_vec,
@@ -882,10 +882,10 @@ static void copy_point_list(struct point_list in, struct point_list * out) {
   out->last = new;
 }
 
-void cell_clipping(unsigned N,
-                   struct grid_cell * source_cell,
-                   struct grid_cell target_cell,
-                   struct grid_cell * overlap_buffer) {
+void yac_cell_clipping (unsigned N,
+                        struct grid_cell * source_cell,
+                        struct grid_cell target_cell,
+                        struct grid_cell * overlap_buffer) {
 
   unsigned ncs;               /* number of vertices of source cell */
   unsigned nct;               /* number of vertices of target cell */
@@ -900,9 +900,9 @@ void cell_clipping(unsigned N,
   enum cell_type tgt_cell_type = get_cell_type(target_cell);
 
   if (tgt_cell_type == MIXED_CELL)
-    abort_message("invalid target cell type (cell contains edges consisting "
-                  "of great circles and circles of latitude)\n", __FILE__,
-                  __LINE__);
+    yac_internal_abort_message("invalid target cell type (cell contains edges consisting "
+                               "of great circles and circles of latitude)\n",
+			       __FILE__, __LINE__);
 
   init_point_list(&temp_list);
 
@@ -946,7 +946,7 @@ void cell_clipping(unsigned N,
                             norm_vec + 3 * i);
         break;
       default:
-        abort_message("invalid edge type\n", __FILE__, __LINE__);
+        yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
     };
     prev_tgt_point = curr_tgt_point;
     curr_tgt_point = curr_tgt_point->next;
@@ -965,9 +965,9 @@ void cell_clipping(unsigned N,
     enum cell_type src_cell_type = get_cell_type(source_cell[n]);
 
     if (src_cell_type == MIXED_CELL)
-      abort_message("invalid source cell type (cell contains edges consisting "
-                    "of great circles and circles of latitude)\n", __FILE__,
-                    __LINE__);
+      yac_internal_abort_message("invalid source cell type (cell contains edges consisting "
+                                 "of great circles and circles of latitude)\n",
+                                 __FILE__, __LINE__);
 
     if (source_cell[n].num_corners < 2)
       continue;
@@ -1021,7 +1021,7 @@ void cell_clipping(unsigned N,
                                        temp_norm_vec + 3 * i);
             break;
           default:
-            abort_message("invalid edge type\n", __FILE__, __LINE__);
+            yac_internal_abort_message("invalid edge type\n", __FILE__, __LINE__);
         };
         src_point = src_point->next;
       }
@@ -1051,7 +1051,7 @@ void cell_clipping(unsigned N,
 
 /* ---------------------------------------------------- */
 
-void correct_weights ( unsigned nSourceCells, double * weight ) {
+void yac_correct_weights ( unsigned nSourceCells, double * weight ) {
 
   static unsigned maxIter = 10; // number of iterations to get better accuracy of the weights
   static double const tol = 1.0e-15;
@@ -1092,7 +1092,7 @@ void correct_weights ( unsigned nSourceCells, double * weight ) {
 static unsigned get_cell_points_ordering(struct point_list * cell) {
 
   if ((cell->first == NULL) || (cell->first == cell->last))
-    abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
+    yac_internal_abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
 
   double norm_vec[3];
   struct point_list_element * curr = cell->first;
@@ -1102,7 +1102,7 @@ static unsigned get_cell_points_ordering(struct point_list * cell) {
   curr = curr->next;
 
   if (curr->next == cell->first)
-    abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
+    yac_internal_abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
 
   do {
     curr = curr->next;
@@ -1114,8 +1114,8 @@ static unsigned get_cell_points_ordering(struct point_list * cell) {
 
   } while (curr != cell->first);
 
-  abort_message("ERROR: could not determine order of points in cell\n",
-                __FILE__, __LINE__);
+  yac_internal_abort_message("ERROR: could not determine order of points in cell\n",
+                             __FILE__, __LINE__);
 
   return -1;
 }
diff --git a/src/clipping/clipping.h b/src/clipping/clipping.h
index 587813b..bec14fd 100644
--- a/src/clipping/clipping.h
+++ b/src/clipping/clipping.h
@@ -61,15 +61,23 @@
   * \remark source and target cells have to be convex
   * \remark cells in overlap_buffer can be concave
   * \remark overlap_buffer must contain valid grid_cells (have to be initialised
-  *         using \ref init_grid_cell; initialisation have to be done only once,
+  *         using \ref yac_init_grid_cell; initialisation have to be done only once,
   *         in consecutive calls, the cells can be reused with have to be
   *         reinitialised)
   *
  **/
-void cell_clipping ( unsigned N,
-                     struct grid_cell * source_cell,
-                     struct grid_cell target_cell,
-                     struct grid_cell * overlap_buffer );
+void yac_cell_clipping (unsigned N,
+                        struct grid_cell * source_cell,
+                        struct grid_cell target_cell,
+                        struct grid_cell * overlap_buffer);
+
+/** \example test_partial_areas.c
+ * This contains examples on how to use \ref yac_compute_overlap_areas.
+ */
+
+/** \example test_compute_overlap_area.c
+ * This contains examples on how to use \ref yac_compute_overlap_areas.
+ */
 
 /**
   * \brief calculates partial areas for all overlapping parts of the source
@@ -99,10 +107,10 @@ void cell_clipping ( unsigned N,
   * \remark source and target cell have to be convex
   *
  **/
-void compute_overlap_areas(unsigned N,
-                           struct grid_cell * source_cell,
-                           struct grid_cell target_cell,
-                           double * partial_areas);
+void yac_compute_overlap_areas (unsigned N,
+                                struct grid_cell * source_cell,
+                                struct grid_cell target_cell,
+                                double * partial_areas);
 
 /**
   * \brief calculates partial areas for all overlapping parts of the source
@@ -132,12 +140,12 @@ void compute_overlap_areas(unsigned N,
   * \remark source and target cell have to be convex
   *
  **/
-void compute_concave_overlap_areas (unsigned N,
-                                    struct grid_cell * source_cell,
-                                    struct grid_cell target_cell,
-                                    double * target_node_x,
-                                    double * target_node_y,
-                                    double * partial_areas);
+void yac_compute_concave_overlap_areas (unsigned N,
+                                        struct grid_cell * source_cell,
+                                        struct grid_cell target_cell,
+                                        double * target_node_x,
+                                        double * target_node_y,
+                                        double * partial_areas);
 /**
   * \brief correct interpolation weights
   *
@@ -147,6 +155,6 @@ void compute_concave_overlap_areas (unsigned N,
   * @param[out] weight            list of N partial weights
   *
  **/
-void correct_weights ( unsigned N, double * weight );
+void yac_correct_weights (unsigned N, double * weight);
 
 #endif // CLIPPING_H
diff --git a/src/clipping/dep_list.h b/src/clipping/dep_list.h
index 0abbe2e..885cca5 100644
--- a/src/clipping/dep_list.h
+++ b/src/clipping/dep_list.h
@@ -48,7 +48,7 @@
  *    - neighbour cell ids (cell 0 -> neighbours 1, 2, 3; cell 1 -> neighbours 0, 2, 3; 2 -> 0, 1, 3; 3 -> 0, 1, 2)
  *
  * The element index (in the example the cell index) goes from 0 to n-1, where n is the total number of elements in the dependency list.\n
- * The dependencies can have any valid unsigned integer number. However, one has to be careful when using \ref invert_dep_list, because if the values of the dependencies are to big the resulting dependency list can be big.
+ * The dependencies can have any valid unsigned integer number. However, one has to be careful when using \ref yac_invert_dep_list, because if the values of the dependencies are to big the resulting dependency list can be big.
  */
 struct dep_list {
    unsigned num_elements;           //!< total number of elements in the dependency list
@@ -69,14 +69,14 @@ struct dep_list {
  * initialises a dependency list, can be used in order to avoid memory access violations
  * @param[in,out] list dependency list that is to be initialised
  */
-void init_dep_list (struct dep_list * list);
+void yac_init_dep_list (struct dep_list * list);
 
 /**
  * initialises an empty dependency list, can be used if the dependencies themselves are not know a priori
  * @param[in,out] list dependency list that is to be initialised
  * @param[in] num_elements number of elements in the dependency list
  */
-void init_empty_dep_list(struct dep_list * list, unsigned num_elements);
+void yac_init_empty_dep_list(struct dep_list * list, unsigned num_elements);
 
 /**
  * initialises dependency list and sets the dependencies (a previous call to init_dep_list is not mandatory)
@@ -85,10 +85,10 @@ void init_empty_dep_list(struct dep_list * list, unsigned num_elements);
  * @param[in] num_deps_per_element array of size num_elements that contains for each element the number of associated dependencies
  * @param[in] dependencies array that contains all dependencies, entries 0 to num_deps_per_element[0]-1 contain dependencies for element 0, entries num_deps_per_element[0] to num_deps_per_element[0]+num_deps_per_element[1]-1 contain the dependencies for element 1, etc.
  *
- * \remark This routine makes no copy of the array passed to it. The array are assumed to be on the heap and will be freed by a call to \ref free_dep_list.
+ * \remark This routine makes no copy of the array passed to it. The array are assumed to be on the heap and will be freed by a call to \ref yac_free_dep_list.
  */
-void set_dependencies (struct dep_list * list, unsigned num_elements,
-                       unsigned * num_deps_per_element, unsigned * dependencies);
+void yac_set_dependencies (struct dep_list * list, unsigned num_elements,
+                           unsigned * num_deps_per_element, unsigned * dependencies);
 /**
  * adds dependencies to an existing dependency list
  * @param[in,out] list dependency list to be edited
@@ -96,8 +96,8 @@ void set_dependencies (struct dep_list * list, unsigned num_elements,
  * @param[in] num_dependencies number of dependencies to be added
  * @param[in] dependencies array containing the dependencies, which are supposed to be added to the list
  */
-void add_dependencies (struct dep_list * list, unsigned element,
-                       unsigned num_dependencies, unsigned * dependencies);
+void yac_add_dependencies (struct dep_list * list, unsigned element,
+                           unsigned num_dependencies, unsigned * dependencies);
 
 /**
  * gets all dependencies for a given element
@@ -107,14 +107,14 @@ void add_dependencies (struct dep_list * list, unsigned element,
  *
  * \remark the number of dependencies for the respective element can be retrieved from list.num_deps_per_element[index]
  */
-unsigned const * get_dependencies_of_element (struct dep_list list, unsigned index);
+unsigned const * yac_get_dependencies_of_element (struct dep_list list, unsigned index);
 
 /**
  * gets the total number of dependencies stored in the given list
  * @param[in] list dependency list
  * @return total number of dependencies in list
  */
-unsigned get_total_num_dependencies(struct dep_list list);
+unsigned yac_get_total_num_dependencies(struct dep_list list);
 
 /**
  * gets the position of a dependency for a given element in the dep_list::dependencies array
@@ -123,7 +123,7 @@ unsigned get_total_num_dependencies(struct dep_list list);
  * @param[in] dependency dependency of provided element
  * @return position of dependency in dep_list::dependencies array \n -1 in case index and/or dependency is invalid
  */
-unsigned get_dependency_index(struct dep_list list, unsigned index, unsigned dependency);
+unsigned yac_get_dependency_index(struct dep_list list, unsigned index, unsigned dependency);
 
 /**
  * gets the position of the first dependency of an element in the dep_list::dependencies array
@@ -131,7 +131,7 @@ unsigned get_dependency_index(struct dep_list list, unsigned index, unsigned dep
  * @param[in] index element index
  * @return position of the first dependency of an element in the dep_list::dependencies array
  */
-unsigned get_dependency_offset(struct dep_list list, unsigned index);
+unsigned yac_get_dependency_offset(struct dep_list list, unsigned index);
 
 /**
  * search for a given dependency in a dependency list
@@ -139,7 +139,7 @@ unsigned get_dependency_offset(struct dep_list list, unsigned index);
  * @param[in] dependency dependency that is to be searched for
  * @return 0 if the list does not contain the respective dependency
  */
-unsigned list_contains_dependency(struct dep_list list, unsigned dependency);
+unsigned yac_list_contains_dependency(struct dep_list list, unsigned dependency);
 
 /**
  * gets the element and dependency associated to a given position in the dep_list::dependencies array
@@ -148,15 +148,15 @@ unsigned list_contains_dependency(struct dep_list list, unsigned dependency);
  * @param[out] index element index associated to dep_index
  * @param[out] dependency dependency associated to dep_index
  */
-void get_dependency(struct dep_list list, unsigned dep_index,
-                    unsigned * index, unsigned * dependency);
+void yac_get_dependency(struct dep_list list, unsigned dep_index,
+                        unsigned * index, unsigned * dependency);
 
 /**
  * generates an inverted dependency list
  * @param[in] dep dependency list that is to be inverted
  * @param[out] inv_dep inverted version of dep (initialising inv_dep is no required)
  */
-void invert_dep_list(struct dep_list dep, struct dep_list * inv_dep);
+void yac_invert_dep_list(struct dep_list dep, struct dep_list * inv_dep);
 
 /**
  * removes all dependencies of the provided elements
@@ -165,8 +165,8 @@ void invert_dep_list(struct dep_list dep, struct dep_list * inv_dep);
  * @param[in] num_elements number of indices in element_indices array
  * \remark element indices == -1 are being ignored
  */
-void remove_dependencies_of_elements(struct dep_list * dep, unsigned * element_indices,
-                                     unsigned num_elements);
+void yac_remove_dependencies_of_elements(struct dep_list * dep, unsigned * element_indices,
+                                         unsigned num_elements);
 
 /**
  * removes all given dependencies
@@ -175,15 +175,15 @@ void remove_dependencies_of_elements(struct dep_list * dep, unsigned * element_i
  * @param[in] num_dependencies number of dependencies in dependencies array
  * \remark dependencies == -1 are being ignored
  */
-void remove_dependencies(struct dep_list * dep, unsigned * dependencies,
-                         unsigned num_dependencies);
+void yac_remove_dependencies(struct dep_list * dep, unsigned * dependencies,
+                             unsigned num_dependencies);
 
 /**
  * makes a copy of a dependency list
  * @param[in] src source dependency list
  * @param[out] tgt target dependency list (initialising tgt is not required)
  */
-void copy_dep_list(struct dep_list src, struct dep_list * tgt);
+void yac_copy_dep_list(struct dep_list src, struct dep_list * tgt);
 
 /**
  * packs a dependency list into a buffer that can be sent to other processes via the MPI library for example
@@ -193,23 +193,23 @@ void copy_dep_list(struct dep_list src, struct dep_list * tgt);
  * @param[out] data_size size of the data the is added to the buffer
  * @param[in,out] buf_size size of the buffer (this is being updated if necessary)
  * \remark *buf == NULL and *buf_size=0 are valid input values
- * @see unpack_dep_list
+ * @see \ref yac_unpack_dep_list
  */
-void pack_dep_list(struct dep_list list, unsigned ** buf, unsigned offset,
-                   unsigned * data_size, unsigned * buf_size);
+void yac_pack_dep_list(struct dep_list list, unsigned ** buf, unsigned offset,
+                       unsigned * data_size, unsigned * buf_size);
 /**
  * unpacks a packed dependency list
  * @param[out] list dependency into which the unpacked data is to be written (initialising is not required)
  * @param[in] buf buffer containing packed dependency list
  * @param[out] data_size size of the data the was occupied by the packed dependency list
- * @see pack_dep_list
+ * @see yac_pack_dep_list
  */
-void unpack_dep_list(struct dep_list * list, unsigned * buf, unsigned * data_size);
+void yac_unpack_dep_list(struct dep_list * list, unsigned * buf, unsigned * data_size);
 
 /**
  * frees a dependency list
  * @param[in,out] list dependency list to be freed
  */
-void free_dep_list(struct dep_list * list);
+void yac_free_dep_list(struct dep_list * list);
 
 #endif // DEP_LIST_H
diff --git a/src/clipping/ensure_array_size.c b/src/clipping/ensure_array_size.c
index ee9123a..d680ca5 100644
--- a/src/clipping/ensure_array_size.c
+++ b/src/clipping/ensure_array_size.c
@@ -33,8 +33,8 @@
 #include "ensure_array_size.h"
 
 void
-realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
-              size_t requested_size)
+yac_realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
+                  size_t requested_size)
 {
   const size_t array_inc_size = (1024 + elem_size - 1)/ elem_size;
   *curr_array_size = array_inc_size
diff --git a/src/clipping/ensure_array_size.h b/src/clipping/ensure_array_size.h
index 306a376..894a81b 100644
--- a/src/clipping/ensure_array_size.h
+++ b/src/clipping/ensure_array_size.h
@@ -36,8 +36,8 @@
 #include <stdlib.h>
 
 void
-realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
-              size_t requested_size);
+yac_realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
+                  size_t requested_size);
 
 #define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)            \
   do {                                                                  \
@@ -45,8 +45,8 @@ realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
     {                                                                   \
       size_t casize = (curr_array_size);                                \
                                                                         \
-      realloc_array((void **)&(arrayp), sizeof(*(arrayp)), &casize,     \
-                    (req_size));                                        \
+      yac_realloc_array((void **)&(arrayp), sizeof(*(arrayp)), &casize, \
+                        (req_size));                                    \
       (curr_array_size) = casize;                                       \
     }                                                                   \
   }                                                                     \
diff --git a/src/clipping/geometry.h b/src/clipping/geometry.h
index f0d51e4..eb5011d 100644
--- a/src/clipping/geometry.h
+++ b/src/clipping/geometry.h
@@ -37,13 +37,17 @@
  * along with YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
  */
 
+/** \example test_geometry.c
+ * This contains some tests for basic routines of \ref geometry.h.
+ */
+
 #ifndef GEOMETRY_H
 #define GEOMETRY_H
 
 #include "grid.h"
 #include "utils.h"
 
-extern const double angle_tol;
+extern const double yac_angle_tol;
 
 struct line {
    struct {
@@ -58,7 +62,7 @@ struct point {
 
 struct edge {
    struct point points[2];
-   enum edge_type edge_type;
+   enum yac_edge_type edge_type;
 };
 
 /**
@@ -85,8 +89,8 @@ struct bounding_circle {
  * @return 0 if both cells do not overlap
  * @see check_overlap_cells
  */
-int check_overlap_cells (struct grid_cell const cell_a, 
-                         struct grid_cell const cell_b);
+int yac_check_overlap_cells (struct grid_cell const cell_a, 
+                             struct grid_cell const cell_b);
 
 /**
  * checks whether two cells overlap \n
@@ -97,10 +101,10 @@ int check_overlap_cells (struct grid_cell const cell_a,
  * @return 0 if both cells do not overlap
  * @see check_overlap_cells
  */
-int check_overlap_cells2 (struct grid_cell const cell_a,
-                          struct bounding_circle circle_a,
-                          struct grid_cell const cell_b,
-                          struct bounding_circle circle_b);
+int yac_check_overlap_cells2 (struct grid_cell const cell_a,
+                              struct bounding_circle circle_a,
+                              struct grid_cell const cell_b,
+                              struct bounding_circle circle_b);
 
 /** \example test_point_in_cell.c
  * This contains examples on how to use point_in_cell.
@@ -113,12 +117,8 @@ int check_overlap_cells2 (struct grid_cell const cell_a,
  * @param[in] cell
  * @return 0 if the point is not in the cell
  */
-int point_in_cell (struct point point, double point_coords[3],
-                   struct grid_cell cell);
-
-/** \example test_point_in_cell.c
- * This contains examples on how to use point_in_cell.
- */
+int yac_point_in_cell (struct point point, double point_coords[3],
+                       struct grid_cell cell);
 
 /**
  * checks whether a given point is within a given cell \n
@@ -128,8 +128,8 @@ int point_in_cell (struct point point, double point_coords[3],
  * @param[in] bnd_circle
  * @return 0 if the point is not in the cell
  */
-int point_in_cell2 (struct point point,  double point_coords[3],
-                    struct grid_cell cell, struct bounding_circle bnd_circle);
+int yac_point_in_cell2 (struct point point,  double point_coords[3],
+                        struct grid_cell cell, struct bounding_circle bnd_circle);
 
 /**
  * computes the angle between two longitude coordinates (in rad) \n
@@ -155,9 +155,9 @@ static inline double get_angle (double a_lon, double b_lon) {
  * @param[in] initial_src_to_tgt_dep dependency list containing for each source cell a list of target cell that might overlap
  * @param[out] src_to_tgt_dep dependency list containing the result of the search
  */
-void find_overlapping_cells (struct grid * src_grid, struct grid * tgt_grid,
-                             struct dep_list initial_src_to_tgt_dep, 
-                             struct dep_list * src_to_tgt_dep);
+void yac_find_overlapping_cells (struct grid * src_grid, struct grid * tgt_grid,
+                                 struct dep_list initial_src_to_tgt_dep,
+                                 struct dep_list * src_to_tgt_dep);
 
 /**
  * searches for all overlapping cells of a given grid that overlap with a
@@ -187,15 +187,15 @@ void find_overlapping_cells (struct grid * src_grid, struct grid * tgt_grid,
  * @remarks the user is responsible to free the memory associated with deps
  *          and stack
  */
-void find_overlapping_cells_s (struct grid_cell src_cell,
-                               struct bounding_circle src_bnd_circle,
-                               struct grid * tgt_grid,
-                               unsigned const * initial_dep,
-                               unsigned num_initial_deps, unsigned ** deps,
-                               unsigned * deps_size, unsigned * num_deps,
-                               unsigned src_index,
-                               unsigned * tgts_already_touched,
-                               unsigned ** stack, unsigned * stack_size);
+void yac_find_overlapping_cells_s (struct grid_cell src_cell,
+                                   struct bounding_circle src_bnd_circle,
+                                   struct grid * tgt_grid,
+                                   unsigned const * initial_dep,
+                                   unsigned num_initial_deps, unsigned ** deps,
+                                   unsigned * deps_size, unsigned * num_deps,
+                                   unsigned src_index,
+                                   unsigned * tgts_already_touched,
+                                   unsigned ** stack, unsigned * stack_size);
 
 /** \example test_gcxgc.c
  * This contains examples on how to use gcxgc and gcxgc_vec
@@ -218,8 +218,8 @@ void find_overlapping_cells_s (struct grid_cell src_cell,
  *
  * \remark the user can provide NULL for p and/or q in that case the intersection points will not be returned
  */
-int gcxgc (struct edge edge_a, struct edge edge_b,
-           struct point * p, struct point * q);
+int yac_gcxgc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q);
 
 /**
  * computes the intersection points of two great circles \n
@@ -240,8 +240,8 @@ int gcxgc (struct edge edge_a, struct edge edge_b,
  *
  * \remark the user can provide NULL for p and/or q in that case the intersection points will not be returned
  */
- int gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
-                double p[3], double q[3]);
+ int yac_gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
+                    double p[3], double q[3]);
 
 /** \example test_loncxlatc.c
  * This contains examples on loncxlatc and loncxlatc_vec
@@ -260,8 +260,8 @@ int gcxgc (struct edge edge_a, struct edge edge_b,
  *      - 3rd bit will be set if p is between c and d
  *      - 4th bit will be set if q is between c and d
  **/
-int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]);
+int yac_loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]);
 
 /** \brief compute the intersection point of a meridian and a parallel
  *
@@ -276,8 +276,8 @@ int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
  *      - 3rd bit will be set if p is between c and d
  *      - 4th bit will be set if q is between c and d
  **/
-int loncxlatc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q);
+int yac_loncxlatc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q);
 
 /** \example test_latcxlatc.c
  * This contains examples on latcxlatc and latcxlatc_vec
@@ -296,8 +296,8 @@ int loncxlatc (struct edge edge_a, struct edge edge_b,
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of latitude
  **/
-int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]);
+int yac_latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]);
 
 /** \brief compute the intersection point two circles of latitude
  *
@@ -312,8 +312,8 @@ int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of latitude
  **/
-int latcxlatc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q);
+int yac_latcxlatc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q);
 
 /** \example test_loncxlonc.c
  * This contains examples on loncxlonc loncxlonc_vec
@@ -332,8 +332,8 @@ int latcxlatc (struct edge edge_a, struct edge edge_b,
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of longitude
  **/
-int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]);
+int yac_loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]);
 
 /** \brief compute the intersection point two circles of longitude
  *
@@ -348,8 +348,8 @@ int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of longitude
  **/
-int loncxlonc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q);
+int yac_loncxlonc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q);
 
 /** \example test_gcxlatc.c
  * This contains examples on gcxlatc and gcxlatc_vec.
@@ -374,8 +374,8 @@ int loncxlonc (struct edge edge_a, struct edge edge_b,
  * \remarks if the two circles only have one intersection point,
  *          p and q will be identically, but only the p bits will be set
  */
-int gcxlatc (struct edge edge_a, struct edge edge_b,
-             struct point * p, struct point * q);
+int yac_gcxlatc (struct edge edge_a, struct edge edge_b,
+                 struct point * p, struct point * q);
 
 /**
  * compute the intersection points of a great circles
@@ -398,8 +398,8 @@ int gcxlatc (struct edge edge_a, struct edge edge_b,
  * \remarks if the two circles only have one intersection point,
  *          p and q will be identically, but only the p bits will be set
  */
-int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
-                double p[3], double q[3]);
+int yac_gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
+                    double p[3], double q[3]);
 
 /**
  * computes the intersection points of two edges
@@ -413,8 +413,8 @@ int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
  *          the intersection point is returned
  * \remarks only one intersection is returned even if the edges intersect twice
  */
-int intersect (struct edge const edge_a, struct edge const edge_b,
-               struct point * intersection);
+int yac_intersect (struct edge const edge_a, struct edge const edge_b,
+                   struct point * intersection);
 
 /**
  * computes the intersection points of two edges
@@ -438,12 +438,12 @@ int intersect (struct edge const edge_a, struct edge const edge_b,
  * \remarks if the two circles only have one intersection point,
  *          p and q will be identically, but only the p bits will be set
  */
-int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
-                   enum edge_type edge_type_b, double c[3], double d[3],
-                   double p[3], double q[3]);
+int yac_intersect_vec (enum yac_edge_type edge_type_a, double a[3], double b[3],
+                       enum yac_edge_type edge_type_b, double c[3], double d[3],
+                       double p[3], double q[3]);
 
 /** \example test_cell_bnd_circle.c
- * These are some examples on how to use \ref get_cell_bounding_circle.
+ * These are some examples on how to use \ref yac_get_cell_bounding_circle.
  */
 
 /**
@@ -451,8 +451,8 @@ int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
  * @param[in] cell grid cell (coordinates have to be in radian)
  * @param[out] bnd_circle bounding circle of the grid cell
  */
-void get_cell_bounding_circle(struct grid_cell cell,
-                              struct bounding_circle * bnd_circle);
+void yac_get_cell_bounding_circle(struct grid_cell cell,
+                                  struct bounding_circle * bnd_circle);
 
 /**
  * computes the circumscribe circle for a triangle on the sphere
@@ -462,7 +462,7 @@ void get_cell_bounding_circle(struct grid_cell cell,
  * @param[out] bnd_circle circumscribe circle
  * @remark it is assumed that all three edges of the triangle are great circles
  */
-void get_cell_circumscribe_circle_unstruct_triangle(
+void yac_get_cell_circumscribe_circle_unstruct_triangle(
    double a[3], double b[3], double c[3], struct bounding_circle * bnd_circle);
 
 /**
@@ -473,7 +473,7 @@ void get_cell_circumscribe_circle_unstruct_triangle(
  * @param[out] bnd_circle bounding circle
  * @remark it is assumed that all three edges of the triangle are great circles
  */
-void get_cell_bounding_circle_unstruct_triangle(
+void yac_get_cell_bounding_circle_unstruct_triangle(
    double a[3], double b[3], double c[3], struct bounding_circle * bnd_circle);
 
 /**
@@ -486,7 +486,7 @@ void get_cell_bounding_circle_unstruct_triangle(
  * @remark it is assumed that all edges of the quad are either circles of
  *         longitude or latitude
  */
-void get_cell_circumscribe_circle_reg_quad(
+void yac_get_cell_circumscribe_circle_reg_quad(
    double a[3], double b[3], double c[3], double d[3],
    struct bounding_circle * bnd_circle);
 
@@ -500,12 +500,12 @@ void get_cell_circumscribe_circle_reg_quad(
  * @remark it is assumed that all edges of the quad are either circles of
  *         longitude or latitude
  */
-void get_cell_bounding_circle_reg_quad(
+void yac_get_cell_bounding_circle_reg_quad(
    double a[3], double b[3], double c[3], double d[3],
    struct bounding_circle * bnd_circle);
 
 /** \example test_grid_bnd_circle.c
- * These are some examples on how to use \ref get_grid_bounding_circle.
+ * These are some examples on how to use \ref yac_get_grid_bounding_circle.
  */
 
 /**
@@ -513,8 +513,8 @@ void get_cell_bounding_circle_reg_quad(
  * @param[in] grid
  * @param[out] bnd_circle bounding circle of the grid
  */
-void get_grid_bounding_circle(struct grid * grid,
-                              struct bounding_circle * bnd_circle);
+void yac_get_grid_bounding_circle(struct grid * grid,
+                                  struct bounding_circle * bnd_circle);
 
 /**
  * gets all cells of a grid that have an overlap with the area defined by the given bounding circle
@@ -531,11 +531,11 @@ void get_grid_bounding_circle(struct grid * grid,
  * \remark *local_ids == NULL and *curr_local_ids_array_size == 0 are valid input values
  * \remark if matching_cells == NULL or local_ids == NULL the respective data is not returned by this routine
  */
-void get_matching_grid_cells(struct grid * grid, struct bounding_circle extent,
-                             struct grid_cell ** matching_cells,
-                             unsigned * curr_matching_cells_array_size,
-                             unsigned ** local_ids, unsigned * curr_local_ids_array_size,
-                             unsigned * num_matching_cells, unsigned offset);
+void yac_get_matching_grid_cells(struct grid * grid, struct bounding_circle extent,
+                                 struct grid_cell ** matching_cells,
+                                 unsigned * curr_matching_cells_array_size,
+                                 unsigned ** local_ids, unsigned * curr_local_ids_array_size,
+                                 unsigned * num_matching_cells, unsigned offset);
 
 /**
  * checks whether two extents overlap
@@ -543,8 +543,8 @@ void get_matching_grid_cells(struct grid * grid, struct bounding_circle extent,
  * @param[in] extent_b bounding circle
  * @return 0 if the bounding circles do not overlap
  */
-unsigned extents_overlap(struct bounding_circle * extent_a,
-                         struct bounding_circle * extent_b);
+unsigned yac_extents_overlap(struct bounding_circle * extent_a,
+                             struct bounding_circle * extent_b);
 
 /**
  * checks whether a point is within a bounding circle
@@ -552,8 +552,8 @@ unsigned extents_overlap(struct bounding_circle * extent_a,
  * @param[in] bnd_circle bounding circle
  * @return 0 if point is not within the bounding circle
  */
-unsigned point_in_bounding_circle(struct point point,
-                                  struct bounding_circle * bnd_circle);
+unsigned yac_point_in_bounding_circle(struct point point,
+                                      struct bounding_circle * bnd_circle);
 
 /**
  * checks whether a point is within a bounding circle
@@ -561,8 +561,8 @@ unsigned point_in_bounding_circle(struct point point,
  * @param[in] bnd_circle bounding circle
  * @return 0 if point is not within the bounding circle
  */
-unsigned point_in_bounding_circle_vec(double point_vector[3],
-                                      struct bounding_circle * bnd_circle);
+unsigned yac_point_in_bounding_circle_vec(double point_vector[3],
+                                          struct bounding_circle * bnd_circle);
 
 /**
  * converts lon-lat coordinates into xyz ones
@@ -703,7 +703,7 @@ static inline int points_are_identically(double * a, double * b) {
       // for very small angles: asin(alpha) = ~alpha   (alpha in rad)
       return sqrt(cross_ab[0]*cross_ab[0] +
                   cross_ab[1]*cross_ab[1] +
-                  cross_ab[2]*cross_ab[2]) < angle_tol;
+                  cross_ab[2]*cross_ab[2]) < yac_angle_tol;
    }
 }
 
@@ -713,7 +713,7 @@ static inline int points_are_identically(double * a, double * b) {
  * @param[in] b point coordinates of point b (in rad)
  * @return great circle distance in rad between both points
  */
-double get_point_angle(struct point * a, struct point * b);
+double yac_get_point_angle(struct point * a, struct point * b);
 
 /**
  * determines whether two edges intersect
@@ -726,7 +726,7 @@ double get_point_angle(struct point * a, struct point * b);
  * @return 0 if edges do not intersect\n
  *         1 if edges intersect
  */
-int do_intersect (struct edge edge_a, double a[3], double b[3],
-                  struct edge edge_b, double c[3], double d[3]);
+int yac_do_intersect (struct edge edge_a, double a[3], double b[3],
+                      struct edge edge_b, double c[3], double d[3]);
 
 #endif // GEOMETRY_H
diff --git a/src/clipping/geometry_tools.c b/src/clipping/geometry_tools.c
deleted file mode 100644
index f60f7a3..0000000
--- a/src/clipping/geometry_tools.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file geometry_tools.c
- * @brief Set of functions to work with coordinates
- *
- * Note: Not all functions are documented by Doxygen. See the source code
- * and \ref geometry.h for further details.
- *
- * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
- *                                 Rene Redler <rene.redler at mpimet.mpg.de>
- *
- * @version 1.0
- * @author Moritz Hanke <hanke at dkrz.de>
- *         Rene Redler <rene.redler at mpimet.mpg.de>
- */
-/*
- * Keywords:
- * Maintainer: Moritz Hanke <hanke at dkrz.de>
- *             Rene Redler <rene.redler at mpimet.mpg.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
- *
- * This file is part of YAC.
- *
- * YAC is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * YAC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
- */
-
-#include <math.h>
-
-#include "geometry.h"
diff --git a/src/clipping/grid.h b/src/clipping/grid.h
index cd0b815..7ca381d 100644
--- a/src/clipping/grid.h
+++ b/src/clipping/grid.h
@@ -91,7 +91,7 @@ struct grid_vtable {
    unsigned (*get_num_cell_edges) (struct grid *, unsigned);
    unsigned const * (*get_corner_edges)(struct grid *, unsigned);
    unsigned const * (*get_cell_edge_indices)(struct grid *, unsigned);
-   enum edge_type (*get_edge_type)(struct grid *, unsigned);
+   enum yac_edge_type (*get_edge_type)(struct grid *, unsigned);
    unsigned const * (*get_cell_corner_indices)(struct grid *, unsigned);
    unsigned const * (*get_corner_cell_indices)(struct grid *, unsigned);
    unsigned const * (*get_cell_x_coord_indices) (struct grid *, unsigned);
@@ -100,7 +100,7 @@ struct grid_vtable {
    double (*get_corner_y_coord) (struct grid *, unsigned);
    unsigned (*get_corner_x_coord_index) (struct grid *, unsigned);
    unsigned (*get_corner_y_coord_index) (struct grid *, unsigned);
-   int (*get_aux_grid_cell)(struct grid *, unsigned, unsigned *, enum edge_type *);
+   int (*get_aux_grid_cell)(struct grid *, unsigned, unsigned *, enum yac_edge_type *);
    struct dep_list (*get_cell_neigh_dep_list)(struct grid *);
    void (*get_boundary_corners) (struct grid *, unsigned *, unsigned *);
    struct grid * (*generate_cell_grid)(struct grid *, double *, double *);
@@ -122,7 +122,7 @@ struct grid {
  * @param[in] grid is a pointer to a declared grid object
  * @param[out] extent is the computed 2d extent
  */
-void get_2d_grid_extent(struct grid * grid, double (* extent)[2]);
+void yac_get_2d_grid_extent(struct grid * grid, double (* extent)[2]);
 
 /**
  * gets a %grid cell from a grid object
@@ -131,8 +131,8 @@ void get_2d_grid_extent(struct grid * grid, double (* extent)[2]);
  * @param[out] cell requested cell (grid_cell object has be initialised once before)
  * @see init_grid_cell
  */
-void get_grid_cell (struct grid * grid, unsigned cell_index, 
-                    struct grid_cell * cell);
+void yac_get_grid_cell (struct grid * grid, unsigned cell_index,
+                        struct grid_cell * cell);
 
 /**
  * gets a %grid cell from a grid object\n
@@ -143,79 +143,79 @@ void get_grid_cell (struct grid * grid, unsigned cell_index,
  * @param[out] bnd_circle bounding circle of input cell
  * @see init_grid_cell
  */
-void get_grid_cell2 (struct grid * grid, unsigned cell_index, 
-                     struct grid_cell * cell,
-                     struct bounding_circle * bnd_circle);
+void yac_get_grid_cell2 (struct grid * grid, unsigned cell_index,
+                         struct grid_cell * cell,
+                         struct bounding_circle * bnd_circle);
 
 /**
  * @param[in] grid
- * @return size of the array returned by \ref get_x_coords
+ * @return size of the array returned by \ref yac_get_x_coords
  */
-unsigned get_size_x_coords(struct grid * grid);
+unsigned yac_get_size_x_coords(struct grid * grid);
 
 /**
  * @param[in] grid
- * @return size of the array returned by \ref get_y_coords
+ * @return size of the array returned by \ref yac_get_y_coords
  */
-unsigned get_size_y_coords(struct grid * grid);
+unsigned yac_get_size_y_coords(struct grid * grid);
 
 /**
  * returns an array that contains the x coordinates of all corners of the grid
  * @param[in] grid
  * @return x coordinates of all corners of the grid
  */
-double const * get_x_coords(struct grid * grid);
+double const * yac_get_x_coords(struct grid * grid);
 
 /**
  * returns an array that contains the y coordinates of all corners of the grid
  * @param[in] grid
  * @return y coordinates of all corners of the grid
  */
-double const * get_y_coords(struct grid * grid);
+double const * yac_get_y_coords(struct grid * grid);
 
 /**
  * sets the array that contains the x coordinates of all corners of the grid
  * @param[in] grid
  * @param[in] x_coords
  */
-void set_x_coords(struct grid * grid, double * x_coords);
+void yac_set_x_coords(struct grid * grid, double * x_coords);
 
 /**
  * set the array that contains the y coordinates of all corners of the grid
  * @param[in] grid
  * @param[in] y_coords
  */
-void set_y_coords(struct grid * grid, double * y_coords);
+void yac_set_y_coords(struct grid * grid, double * y_coords);
 
 /**
- * gets the size of the x coordiante array of a cell %grid generated by \ref generate_cell_grid for the given %grid object
+ * gets the size of the x coordinate array of a cell %grid generated by \ref yac_generate_cell_grid for the given %grid object
  * @param[in] grid
- * @return size of x coordiante for a potential cell grid
+ * @return size of x coordinate for a potential cell grid
  * @see generate_cell_grid
  */
-unsigned get_size_cell_grid_x_coords(struct grid * grid);
+unsigned yac_get_size_cell_grid_x_coords(struct grid * grid);
 
 /**
- * gets the size of the y coordiante array of a cell %grid generated by \ref generate_cell_grid for the given %grid object
+ * gets the size of the y coordinate array of a cell %grid generated by \ref yac_generate_cell_grid for the given %grid object
  * @param[in] grid
- * @return size of y coordiante array for a potential cell grid
+ * @return size of y coordinate array for a potential cell grid
  * @see generate_cell_grid
  */
-unsigned get_size_cell_grid_y_coords(struct grid * grid);
+unsigned yac_get_size_cell_grid_y_coords(struct grid * grid);
 
 /**
  * gets the number of cells in the given %grid
  * @param[in] grid
  * @return number of cells in the %grid
  */
-unsigned get_num_grid_cells (struct grid * grid);
+unsigned yac_get_num_grid_cells (struct grid * grid);
 
 /**
  * gets the number of corners in the given %grid
  * @param[in] grid
  * @return number of corners in the %grid
  */
-unsigned get_num_grid_corners (struct grid * grid); 
+unsigned yac_get_num_grid_corners (struct grid * grid); 
 
 /**
  * gets the number of corners for a cell of a given %grid
@@ -223,7 +223,7 @@ unsigned get_num_grid_corners (struct grid * grid);
  * @param[in] cell_index local id of the respective cell
  * @return number of corners for the specified cell in %grid
  */
-unsigned get_num_cell_corners (struct grid * grid, unsigned cell_index);
+unsigned yac_get_num_cell_corners (struct grid * grid, unsigned cell_index);
 
 /**
  * gets the number of cells associated to a corner of a given %grid
@@ -231,14 +231,14 @@ unsigned get_num_cell_corners (struct grid * grid, unsigned cell_index);
  * @param[in] corner_index local id of the respective corner
  * @return number of cells for the specified corner in %grid
  */
-unsigned get_num_corner_cells (struct grid * grid, unsigned corner_index);
+unsigned yac_get_num_corner_cells (struct grid * grid, unsigned corner_index);
 
 /**
  * gets the number of edges in the given %grid
  * @param[in] grid
  * @return number of edges in %grid
  */
-unsigned get_num_grid_edges (struct grid * grid);
+unsigned yac_get_num_grid_edges (struct grid * grid);
 
 /**
  * gets the number of edges that are associated with a corner of a given %grid
@@ -247,16 +247,16 @@ unsigned get_num_grid_edges (struct grid * grid);
  * @param[in] corner_index local index of the respective corner
  * @return number of edges associated with given corner
  */
-unsigned get_num_corner_edges (struct grid * grid, unsigned corner_index);
+unsigned yac_get_num_corner_edges (struct grid * grid, unsigned corner_index);
 
 /**
- * gets the number of edges for a cell of a given %grid (identical to \ref get_num_cell_corners)
+ * gets the number of edges for a cell of a given %grid (identical to \ref yac_get_num_cell_corners)
  * @param[in] grid
  * @param[in] cell_index local id of the respective cell
  * @return number of edges for the specified cell in %grid
  * @see get_num_cell_corners
  */
-unsigned get_num_cell_edges (struct grid * grid, unsigned cell_index);
+unsigned yac_get_num_cell_edges (struct grid * grid, unsigned cell_index);
 
 /**
  * gets neighbour corners of a corner of a given %grid
@@ -265,7 +265,7 @@ unsigned get_num_cell_edges (struct grid * grid, unsigned cell_index);
  * @return array containing the local ids of all corners directly linked to the given corner
  * @see get_num_corner_edges
  */
-unsigned const * get_corner_edges (struct grid * grid, unsigned corner_index);
+unsigned const * yac_get_corner_edges (struct grid * grid, unsigned corner_index);
 
 /**
  * gets the %edges of a cell for a given %grid
@@ -274,7 +274,7 @@ unsigned const * get_corner_edges (struct grid * grid, unsigned corner_index);
  * @return array that contains the local ids of all edges for the given cell
  * @see get_num_cell_edges
  */
-unsigned const * get_cell_edge_indices (struct grid * grid, unsigned cell_index);
+unsigned const * yac_get_cell_edge_indices (struct grid * grid, unsigned cell_index);
 
 /**
  * gets the type of an %edge for a given %grid
@@ -282,7 +282,7 @@ unsigned const * get_cell_edge_indices (struct grid * grid, unsigned cell_index)
  * @param[in] edge_index local id of the respective edge
  * @return type of the specified %edge
  */
-enum edge_type get_edge_type(struct grid * grid, unsigned edge_index);
+enum yac_edge_type yac_get_edge_type(struct grid * grid, unsigned edge_index);
 
 /**
  * gets the corners of a cell for a given grid
@@ -291,7 +291,7 @@ enum edge_type get_edge_type(struct grid * grid, unsigned edge_index);
  * @return array that contains the local ids of all corners for the given cell
  * @see get_num_cell_corners
  */
-unsigned const * get_cell_corner_indices (struct grid * grid, unsigned cell_index);
+unsigned const * yac_get_cell_corner_indices (struct grid * grid, unsigned cell_index);
 
 /**
  * gets the cells associated with a corner for a given grid
@@ -300,26 +300,26 @@ unsigned const * get_cell_corner_indices (struct grid * grid, unsigned cell_inde
  * @return array that contains the local ids of all cells for the given cell
  * @see get_num_corner_cells
  */
-unsigned const * get_corner_cell_indices (struct grid * grid, unsigned corner_index);
+unsigned const * yac_get_corner_cell_indices (struct grid * grid, unsigned corner_index);
 
 
 /**
- * gets indices to access x coordiante array for all corners of a cell for a given %grid
+ * gets indices to access x coordinate array for all corners of a cell for a given %grid
  * @param[in] grid
  * @param[in] cell_index local id of the respective cell
- * @return array containing an index for each corner for the respective cell; these indices can be used to access x coordiante array (these indices are not the local corner ids)
+ * @return array containing an index for each corner for the respective cell; these indices can be used to access x coordinate array (these indices are not the local corner ids)
  * @see get_num_cell_corners
  */
-unsigned const * get_cell_x_coord_indices (struct grid * grid, unsigned cell_index);
+unsigned const * yac_get_cell_x_coord_indices (struct grid * grid, unsigned cell_index);
 
 /**
- * gets indices to access y coordiante array for all corners of a cell for a given %grid
+ * gets indices to access y coordinate array for all corners of a cell for a given %grid
  * @param[in] grid
  * @param[in] cell_index local id of the respective cell
- * @return array containing an index for each corner for the respective cell; these indices can be used to access y coordiante array (these indices are not the local corner ids)
+ * @return array containing an index for each corner for the respective cell; these indices can be used to access y coordinate array (these indices are not the local corner ids)
  * @see get_num_cell_corners
  */
-unsigned const * get_cell_y_coord_indices (struct grid * grid, unsigned cell_index);
+unsigned const * yac_get_cell_y_coord_indices (struct grid * grid, unsigned cell_index);
 
 /**
  * gets the x coordinate for a corner of a given %grid
@@ -328,7 +328,7 @@ unsigned const * get_cell_y_coord_indices (struct grid * grid, unsigned cell_ind
  * @return x coordinate of the given corner
  * @see get_num_grid_corners
  */
-double get_corner_x_coord (struct grid * grid, unsigned corner_index);
+double yac_get_corner_x_coord (struct grid * grid, unsigned corner_index);
 
 /**
  * gets the y coordinate for a corner of a given %grid
@@ -337,25 +337,25 @@ double get_corner_x_coord (struct grid * grid, unsigned corner_index);
  * @return y coordinate of the given corner
  * @see get_num_grid_corners
  */
-double get_corner_y_coord (struct grid * grid, unsigned corner_index);
+double yac_get_corner_y_coord (struct grid * grid, unsigned corner_index);
 
 /**
- * gets an index that can used to access x coordiante array for a corner of a given %grid
+ * gets an index that can used to access x coordinate array for a corner of a given %grid
  * @param[in] grid
  * @param[in] corner_index local id of a corner in %grid
- * @return index that can be used to get the actual coordinate from x coordiante array (this is not the local corner id)
+ * @return index that can be used to get the actual coordinate from x coordinate array (this is not the local corner id)
  * @see get_num_grid_corners
  */
-unsigned get_corner_x_coord_index (struct grid * grid, unsigned corner_index);
+unsigned yac_get_corner_x_coord_index (struct grid * grid, unsigned corner_index);
 
 /**
- * gets an index that can used to access y coordiante array for a corner of a given %grid
+ * gets an index that can used to access y coordinate array for a corner of a given %grid
  * @param[in] grid
  * @param[in] corner_index local id of a corner in %grid
- * @return index that can be used to get the actual coordinate from y coordiante array (this is not the local corner id)
+ * @return index that can be used to get the actual coordinate from y coordinate array (this is not the local corner id)
  * @see get_num_grid_corners
  */
-unsigned get_corner_y_coord_index (struct grid * grid, unsigned corner_index);
+unsigned yac_get_corner_y_coord_index (struct grid * grid, unsigned corner_index);
 
 /**
  * computes the cell, whose corners are the cells, which have the given corner
@@ -369,22 +369,22 @@ unsigned get_corner_y_coord_index (struct grid * grid, unsigned corner_index);
  * @return return 0 in case there is no auxiliary cell
  * @see get_num_corner_cells
  */
-int get_aux_grid_cell(struct grid * grid, unsigned corner_index,
-                      unsigned * cell_indices, enum edge_type * edge_type);
+int yac_get_aux_grid_cell(struct grid * grid, unsigned corner_index,
+                          unsigned * cell_indices, enum yac_edge_type * edge_type);
 
 /**
  * gets a dependency list containing all cell neighbourhood information for the given %grid
  * @param[in] grid
  * @return dependency list that contains for each local cell id the local ids of all neighbour cells
  */
-struct dep_list get_cell_neigh_dep_list(struct grid * grid);
+struct dep_list yac_get_cell_neigh_dep_list(struct grid * grid);
 
 /**
  * makes a complete copy of a grid
  * @param[in] grid grid to be copied
  * @returns copy of the given grid
  */
-struct grid * copy_grid(struct grid * grid);
+struct grid * yac_copy_grid(struct grid * grid);
 
 /** \example test_polecover.c
  * This contains examples for cell_covers_pole.
@@ -397,8 +397,8 @@ struct grid * copy_grid(struct grid * grid);
  * @param[in] corners_lat latitude coordinates of the given cell
  * @return 0 if the given cell does not cover a pole
  */
-unsigned cell_covers_pole (unsigned num_corners, double * const corners_lon, 
-                                                 double * const corners_lat);
+unsigned yac_cell_covers_pole (unsigned num_corners, double * const corners_lon, 
+                                                     double * const corners_lat);
 
 /**
  * get local ids of all boundary corners of the given grid
@@ -406,18 +406,19 @@ unsigned cell_covers_pole (unsigned num_corners, double * const corners_lon,
  * @param[in,out] bnd_corners array with the boundary corners (user must provide this array, it must be big enough to be able to hole all boundary cells)
  * @param[out] num_bnd_corners number of boundary corners written to bnd_corners
  */
-void get_boundary_corners (struct grid * grid, unsigned * bnd_corners,
-                           unsigned * num_bnd_corners);
+void yac_get_boundary_corners (struct grid * grid, unsigned * bnd_corners,
+                               unsigned * num_bnd_corners);
 
 /**
- * generates a grid that has a corner for each cell of the input %grid (the corners of the new %grid are in the same order as the cells of the input %grid)
+ * generates a grid that has a corner for each cell of the input %grid
+ * (the corners of the new %grid are in the same order as the cells of the input %grid)
  * @param[in] grid input %grid
  * @param[in] coordinates_x longitude data for the corners of the cell %grid (the layout of this array depends on the %grid type)
  * @param[in] coordinates_y latitude data for the corners of the cell %grid (the layout of this array depends on the %grid type)
  * @returns the generated cell grid
  */
-struct grid * generate_cell_grid(struct grid * grid, double * coordinates_x, 
-                                 double * coordinates_y);
+struct grid * yac_generate_cell_grid(struct grid * grid, double * coordinates_x, 
+                                     double * coordinates_y);
 
 /**
  * generates a grid the contains the selected cells from the input grid (it may actually contain more cells)
@@ -429,9 +430,9 @@ struct grid * generate_cell_grid(struct grid * grid, double * coordinates_x,
  * @param[out] local_edge_ids pointer to an array containing the local ids of the input %grid for all edges of subgrid (the user is responsible for freeing the memory of the array)
  * @returns the generate subgrid
  */
-struct grid * generate_subgrid(struct grid * grid, unsigned * selected_local_cell_ids,
-                               unsigned num_local_cells, unsigned ** local_cell_ids,
-                               unsigned ** local_corner_ids, unsigned ** local_edge_ids);
+struct grid * yac_generate_subgrid(struct grid * grid, unsigned * selected_local_cell_ids,
+                                   unsigned num_local_cells, unsigned ** local_cell_ids,
+                                   unsigned ** local_corner_ids, unsigned ** local_edge_ids);
 
 /**
  * packs given grid into a double and unsigned buffer
@@ -444,16 +445,17 @@ struct grid * generate_subgrid(struct grid * grid, unsigned * selected_local_cel
  * @param[in] uint_buf_offset number of elements already in the buffer (this data is not overwritten by this routine)
  * @param[out] uint_buf_data_size number of elements added to the buffer by this routine
  * @param[in,out] uint_buf_size size of uint_buf (this is adjusted in case this routine reallocates uint_buf)
- * @see unpack_grid
+ * @see \ref yac_unpack_grid
  */
-void pack_grid(struct grid * grid, double ** dble_buf,
-               unsigned dble_buf_offset, unsigned * dble_buf_data_size,
-               unsigned * dble_buf_size, unsigned ** uint_buf,
-               unsigned uint_buf_offset, unsigned * uint_buf_data_size,
-               unsigned * uint_buf_size);
+void yac_pack_grid(struct grid * grid, double ** dble_buf,
+                   unsigned dble_buf_offset, unsigned * dble_buf_data_size,
+                   unsigned * dble_buf_size, unsigned ** uint_buf,
+                   unsigned uint_buf_offset, unsigned * uint_buf_data_size,
+                   unsigned * uint_buf_size);
 
 /**
- * unpacks a grid from the provided double and unsigned buffers; the unpacked grid is identical to the one packed into these buffers by \ref pack_grid
+ * unpacks a grid from the provided double and unsigned buffers; the unpacked grid is identical
+ * to the one packed into these buffers by \ref yac_pack_grid
  * @param[in] dble_buf
  * @param[out] dble_buf_data_size number of elements extracted from dble_buf
  * @param[in] uint_buf
@@ -461,23 +463,25 @@ void pack_grid(struct grid * grid, double ** dble_buf,
  * @returns unpacked grid
  * @see pack_grid
  */
-struct grid * unpack_grid(double * dble_buf, unsigned * dble_buf_data_size,
-                          unsigned * uint_buf, unsigned * uint_buf_data_size);
+struct grid * yac_unpack_grid(double * dble_buf, unsigned * dble_buf_data_size,
+                              unsigned * uint_buf, unsigned * uint_buf_data_size);
 
 /**
  * generates a grid search object for the given grid
  * @param[in] grid
  * @return grid_search object for the provided grid
  * @remark the grid_search object returned by this routine is deleted by
- *         \ref delete_grid
+ *         \ref yac_delete_grid
  */
-struct grid_search * get_grid_search(struct grid * grid);
+struct grid_search * yac_get_grid_search(struct grid * grid);
 
 /**
- * frees all memory associated with the given %grid (memory objects provided by the user must be taken care of by him; e.g. coordinates_x and coordinates_y provided to \ref reg2d_grid_new)
+ * frees all memory associated with the given %grid (memory objects provided
+ * by the user must be taken care of by him; e.g. coordinates_x and coordinates_y
+ * provided to \ref yac_reg2d_grid_new)
  * @param[in] grid
  */
-void delete_grid(struct grid * grid);
+void yac_delete_grid(struct grid * grid);
 
 #undef EARTH_RADIUS
 
diff --git a/src/clipping/grid_cell.c b/src/clipping/grid_cell.c
index c12aabf..cb54473 100644
--- a/src/clipping/grid_cell.c
+++ b/src/clipping/grid_cell.c
@@ -42,7 +42,7 @@
 #include "ensure_array_size.h"
 #include "geometry.h"
 
-void init_grid_cell(struct grid_cell * cell) {
+void yac_init_grid_cell(struct grid_cell * cell) {
 
    cell->coordinates_x = NULL;
    cell->coordinates_y = NULL;
@@ -52,7 +52,7 @@ void init_grid_cell(struct grid_cell * cell) {
    cell->array_size = 0;
 }
 
-void copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell) {
+void yac_copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell) {
 
    if (in_cell.num_corners > out_cell->array_size) {
 
@@ -82,117 +82,12 @@ void copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell) {
    out_cell->num_corners = in_cell.num_corners;
 }
 
-void free_grid_cell(struct grid_cell * cell) {
+void yac_free_grid_cell(struct grid_cell * cell) {
 
    if (cell->coordinates_x != NULL) free(cell->coordinates_x);
    if (cell->coordinates_y != NULL) free(cell->coordinates_y);
    if (cell->coordinates_xyz != NULL) free(cell->coordinates_xyz);
    if (cell->edge_type != NULL) free(cell->edge_type);
 
-   init_grid_cell(cell);
-}
-
-void pack_grid_cell(struct grid_cell cell, double ** dble_buf,
-                    unsigned dble_buf_offset, unsigned * dble_buf_data_size,
-                    unsigned * dble_buf_size, unsigned ** uint_buf,
-                    unsigned uint_buf_offset, unsigned * uint_buf_data_size,
-                    unsigned * uint_buf_size) {
-
-   unsigned required_dble_buf_size, required_uint_buf_size;
-
-   required_dble_buf_size = 2 * cell.num_corners;
-   required_uint_buf_size = cell.num_corners + 1;
-
-   ENSURE_ARRAY_SIZE(*dble_buf, *dble_buf_size, dble_buf_offset+required_dble_buf_size);
-   ENSURE_ARRAY_SIZE(*uint_buf, *uint_buf_size, uint_buf_offset+required_uint_buf_size);
-
-   memcpy((*dble_buf)+dble_buf_offset, cell.coordinates_x, cell.num_corners * sizeof(double));
-   memcpy((*dble_buf)+dble_buf_offset+cell.num_corners, cell.coordinates_y,
-          cell.num_corners * sizeof(double));
-
-   *dble_buf_data_size = required_dble_buf_size;
-
-   (*uint_buf)[uint_buf_offset] = cell.num_corners;
-
-   unsigned i;
-   for (i = 1; i <= cell.num_corners; ++i)
-      (*uint_buf)[uint_buf_offset+i] = cell.edge_type[i-1];
-
-   *uint_buf_data_size = required_uint_buf_size;
-}
-
-void unpack_grid_cell(struct grid_cell * cell, double * dble_buf,
-                      unsigned * dble_buf_data_size, unsigned * uint_buf,
-                      unsigned * uint_buf_data_size) {
-
-   unsigned num_corners;
-
-   num_corners = *uint_buf;
-   uint_buf++;
-
-   *dble_buf_data_size = 2 * num_corners;
-   *uint_buf_data_size = num_corners + 1;
-
-   if (num_corners > cell->array_size) {
-      cell->coordinates_x = realloc(cell->coordinates_x,
-                                    num_corners *
-                                    sizeof(cell->coordinates_x[0]));
-      cell->coordinates_y = realloc(cell->coordinates_y,
-                                    num_corners *
-                                    sizeof(cell->coordinates_y[0]));
-      cell->coordinates_xyz = realloc(cell->coordinates_xyz,
-                                      3 * num_corners *
-                                      sizeof(cell->coordinates_xyz[0]));
-      cell->edge_type = realloc(cell->edge_type,
-                                num_corners * sizeof(cell->edge_type[0]));
-      cell->array_size = num_corners;
-   }
-
-   cell->num_corners = num_corners;
-   memcpy(cell->coordinates_x, dble_buf, num_corners * sizeof(double));
-   memcpy(cell->coordinates_y, dble_buf+num_corners, num_corners * sizeof(double));
-
-   for (unsigned i = 0; i < num_corners; ++i) {
-     cell->edge_type[i] = (enum edge_type)uint_buf[i];
-     LLtoXYZ(cell->coordinates_x[i], cell->coordinates_y[i],
-             cell->coordinates_xyz + 3*i);
-   }
-}
-
-void print_grid_cell(FILE * stream, struct grid_cell cell, char * name) {
-
-  char * out = NULL;
-  unsigned out_array_size = 0;
-  unsigned out_size = 0;
-
-  if (name != NULL) {
-
-    out_size = strlen(name) + 1 + 1 + 1;
-    ENSURE_ARRAY_SIZE(out, out_array_size, out_size);
-
-    strcpy(out, name);
-    strcat(out, ":\n");
-  }
-
-  for (unsigned i = 0; i < cell.num_corners; ++i) {
-
-    char buffer[1024];
-
-    sprintf(buffer, "%d x %.16f y %.16f %s\n", i, cell.coordinates_x[i],
-           cell.coordinates_y[i],
-           (cell.edge_type[i] == LAT_CIRCLE)?("LAT_CIRCLE"):
-           ((cell.edge_type[i] == LON_CIRCLE)?("LON_CIRCLE"):
-                                              ("GREAT_CIRCLE")));
-
-    out_size += strlen(buffer);
-
-    ENSURE_ARRAY_SIZE(out, out_array_size, out_size);
-
-    strcat(out, buffer);
-  }
-
-  if (out != NULL)
-    fputs(out, stream);
-
-  free(out);
+   yac_init_grid_cell(cell);
 }
diff --git a/src/clipping/grid_cell.h b/src/clipping/grid_cell.h
index 6e50c23..dc1c5e6 100644
--- a/src/clipping/grid_cell.h
+++ b/src/clipping/grid_cell.h
@@ -36,7 +36,7 @@
 #ifndef GRID_CELL_H
 #define GRID_CELL_H
 
-enum edge_type {
+enum yac_edge_type {
    GREAT_CIRCLE = 0, //!< great circle
    LAT_CIRCLE   = 1, //!< latitude circle
    LON_CIRCLE   = 2, //!< longitude circle
@@ -45,7 +45,7 @@ enum edge_type {
 struct grid_cell {
    double * coordinates_x, * coordinates_y;
    double * coordinates_xyz;
-   enum edge_type * edge_type;
+   enum yac_edge_type * edge_type;
    unsigned num_corners;
    unsigned array_size; //!< size in elements of the arrays: coordinates_x,
                         //!< coordinates_y, edge_type and 1/3 of coordinates_xyz
@@ -58,7 +58,7 @@ struct grid_cell {
  * @see free_grid_cell
  * @see get_grid_cell
  */
-void init_grid_cell(struct grid_cell * cell);
+void yac_init_grid_cell(struct grid_cell * cell);
 
 /**
  * copies a given grid cell
@@ -67,25 +67,13 @@ void init_grid_cell(struct grid_cell * cell);
  * @remarks out_cell needs to be a cell that has previously been
  *          initialised or a cell that already contains valid data
  */
-void copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell);
+void yac_copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell);
 
 /**
  * frees all memory associated with a grid_cell object and reinitialised
  * the cell
  * @param[in,out] cell
  */
-void free_grid_cell(struct grid_cell * cell);
-
-void pack_grid_cell(struct grid_cell cell, double ** dble_buf,
-                    unsigned dble_buf_offset, unsigned * dble_buf_data_size,
-                    unsigned * dble_buf_size, unsigned ** uint_buf,
-                    unsigned uint_buf_offset, unsigned * uint_buf_data_size,
-                    unsigned * uint_buf_size);
-
-void unpack_grid_cell(struct grid_cell * cell, double * dble_buf,
-                      unsigned * dble_buf_data_size, unsigned * uint_buf,
-                      unsigned * uint_buf_data_size);
-
-void print_grid_cell(FILE * stream, struct grid_cell cell, char * name);
+void yac_free_grid_cell(struct grid_cell * cell);
 
 #endif // GRID_CELL_H
diff --git a/src/clipping/intersection.c b/src/clipping/intersection.c
index 83cc0db..65da69e 100644
--- a/src/clipping/intersection.c
+++ b/src/clipping/intersection.c
@@ -34,6 +34,10 @@
  * along with YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <math.h>
 #include <stdio.h>
@@ -41,8 +45,12 @@
 #include "utils.h"
 #include "geometry.h"
 
+#if defined(CDO) && !defined(HAVE_SQRTL)
+#define sqrtl(x) (sqrt((double)x))
+#endif
+
 // angle tolerance
-const double angle_tol = 1e-9;
+const double yac_angle_tol = 1e-9;
 static double const tol = 1.0e-10;
 
 static int vector_is_between (double a[], double b[], double p[],
@@ -65,7 +73,7 @@ static int vector_is_between (double a[], double b[], double p[],
 
    return fabs(get_vector_angle(a, p) +
                get_vector_angle(b, p) -
-               *angle_ab) < angle_tol;
+               *angle_ab) < yac_angle_tol;
 }
 
 static int vector_is_between_lat (double a[], double b[], double p[]) {
@@ -117,8 +125,8 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
   * - http://www.geoclub.de/viewtopic.php?f=54&t=29689
   **/
 
- int gcxgc (struct edge edge_a, struct edge edge_b,
-            struct point * p, struct point * q) {
+ int yac_gcxgc (struct edge edge_a, struct edge edge_b,
+                struct point * p, struct point * q) {
 
    double a[3], b[3], c[3], d[3], p_[3], q_[3];
 
@@ -127,7 +135,7 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
    LLtoXYZ( edge_b.points[0].lon, edge_b.points[0].lat, c);
    LLtoXYZ( edge_b.points[1].lon, edge_b.points[1].lat, d);
 
-   int ret_val =  gcxgc_vec(a, b, c, d, p_, q_);
+   int ret_val =  yac_gcxgc_vec(a, b, c, d, p_, q_);
 
    if (p != NULL) XYZtoLL(p_, &(p->lon), &(p->lat));
    if (q != NULL) XYZtoLL(q_, &(q->lon), &(q->lat));
@@ -151,8 +159,8 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
   * based on
   * - http://www.geoclub.de/viewtopic.php?f=54&t=29689
   **/
- int gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
-                double p[3], double q[3]) {
+ int yac_gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
+                    double p[3], double q[3]) {
 
    double length_cross_ab, length_cross_cd, length_cross_abxcd;
    long double cross_ab[3], cross_cd[3], cross_abxcd[3];
@@ -331,7 +339,7 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
             q[0] = a[0], q[1] = a[1], q[2] = a[2];
             break;
          default:
-            abort_message("internal error", __FILE__, __LINE__);
+            yac_internal_abort_message("internal error", __FILE__, __LINE__);
       }
 
       ret_value |= 1 + 2 + 4 + 8;
@@ -378,6 +386,7 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
     return result;
 }
 
+static
 int gcxgc_vec_ (double a[3], double b[3], double c[3], double d[3]) {
 
    double length_cross_ab, length_cross_cd, length_cross_abxcd;
@@ -527,8 +536,8 @@ int gcxgc_vec_ (double a[3], double b[3], double c[3], double d[3]) {
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of latitude
  **/
-int latcxlatc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q) {
+int yac_latcxlatc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q) {
 
    // two circles of latitude can only intersect if they are on the same latitude
    if (fabs(edge_a.points[0].lat - edge_b.points[0].lat) > tol)
@@ -613,7 +622,7 @@ int latcxlatc (struct edge edge_a, struct edge edge_b,
          if (q != NULL) *q = edge_a.points[0];
          break;
       default:
-         abort_message("internal error", __FILE__, __LINE__);
+         yac_internal_abort_message("internal error", __FILE__, __LINE__);
    }
 
    if (angle_ab < tol || angle_cd < tol)
@@ -637,8 +646,8 @@ int latcxlatc (struct edge edge_a, struct edge edge_b,
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of latitude
  **/
-int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]) {
+int yac_latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]) {
 
    // two circles of latitude can only intersect if they are on the same latitude
    if (fabs(a[2] - c[2]) > tol)
@@ -669,7 +678,7 @@ int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
       if (b_between_cd) q[0] = b[0], q[1] = b[1], q[2] = b[2];
       else if (c_between_ab) q[0] = c[0], q[1] = c[1], q[2] = c[2];
       else if (d_between_ab) q[0] = d[0], q[1] = d[1], q[2] = d[2];
-      else abort_message("internal error", __FILE__, __LINE__);
+      else yac_internal_abort_message("internal error", __FILE__, __LINE__);
 
    } else if (b_between_cd) {
 
@@ -679,7 +688,7 @@ int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
 
       if (c_between_ab) q[0] = c[0], q[1] = c[1], q[2] = c[2];
       else if (d_between_ab) q[0] = d[0], q[1] = d[1], q[2] = d[2];
-      else abort_message("internal error", __FILE__, __LINE__);
+      else yac_internal_abort_message("internal error", __FILE__, __LINE__);
 
    } else if (c_between_ab && d_between_ab) {
 
@@ -741,8 +750,8 @@ static int latcxlatc_(struct edge edge_a, struct edge edge_b) {
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of longitude
  **/
-int loncxlonc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q) {
+int yac_loncxlonc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q) {
 
    double angle_ab = fabs(get_angle(edge_a.points[0].lon, edge_a.points[1].lon));
    double angle_ac = fabs(get_angle(edge_a.points[0].lon, edge_b.points[0].lon));
@@ -834,7 +843,7 @@ int loncxlonc (struct edge edge_a, struct edge edge_b,
             if (q != NULL) *q = edge_a.points[0];
             break;
          default:
-            abort_message("internal error", __FILE__, __LINE__);
+            yac_internal_abort_message("internal error", __FILE__, __LINE__);
       }
       ret_value |= 1 + 2 + 4 + 8;
 
@@ -885,8 +894,8 @@ int loncxlonc (struct edge edge_a, struct edge edge_b,
  *      - 4th bit will be set if q is between c and d
  *      - 5th bit will be set if both edges are on the same circle of longitude
  **/
-int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]) {
+int yac_loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]) {
 
    int ret_value = 0;
 
@@ -1002,7 +1011,7 @@ int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
             q[0] = a[0], q[1] = a[1], q[2] = a[2];
             break;
          default:
-            abort_message("internal error", __FILE__, __LINE__);
+            yac_internal_abort_message("internal error", __FILE__, __LINE__);
       }
 
    } else {
@@ -1029,6 +1038,7 @@ int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
    return ret_value;
 }
 
+static
 int loncxlonc_ (struct edge edge_a, struct edge edge_b) {
 
    // if edge goes across pole
@@ -1114,8 +1124,8 @@ int loncxlonc_ (struct edge edge_a, struct edge edge_b) {
  *      - 3rd bit will be set if p is between c and d
  *      - 4th bit will be set if q is between c and d
  **/
-int loncxlatc (struct edge edge_a, struct edge edge_b,
-               struct point * p, struct point * q) {
+int yac_loncxlatc (struct edge edge_a, struct edge edge_b,
+                   struct point * p, struct point * q) {
 
    double lon_a, lat_a[2];
    double lon_b[2], lat_b;
@@ -1217,8 +1227,8 @@ int loncxlatc (struct edge edge_a, struct edge edge_b,
  *      - 3rd bit will be set if p is between c and d
  *      - 4th bit will be set if q is between c and d
  **/
-int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
-                   double p[3], double q[3]) {
+int yac_loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                       double p[3], double q[3]) {
 
    unsigned ret_value;
 
@@ -1231,7 +1241,7 @@ int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
        (fabs(fabs(a[2]) - 1.0) > tol) &&
        (fabs(fabs(b[2]) - 1.0) > tol)) {
 
-      abort_message("edge is not a circle of longitude", __FILE__, __LINE__);
+      yac_internal_abort_message("edge is not a circle of longitude", __FILE__, __LINE__);
    }
 
    unsigned ab_goes_across_pole;
@@ -1422,8 +1432,8 @@ static int loncxlatc_ (struct edge edge_a, struct edge edge_b) {
  *   based on
  *   - http://geospatialmethods.org/spheres/GCIntersect.html
  **/
-int gcxlatc(struct edge edge_a, struct edge edge_b,
-            struct point * p, struct point * q) {
+int yac_gcxlatc(struct edge edge_a, struct edge edge_b,
+                struct point * p, struct point * q) {
 
    // if the great circle is nearly a lon circle, then the accuracy of the normal
    // computation gets messy, therefore we handle it as a lon circle...
@@ -1433,7 +1443,7 @@ int gcxlatc(struct edge edge_a, struct edge edge_b,
       edge_a.points[0].lon = edge_a.points[1].lon = (edge_a.points[0].lon + edge_a.points[1].lon) / 2.0;
       edge_a.edge_type = LON_CIRCLE;
 
-      return loncxlatc(edge_a, edge_b, p, q);
+      return yac_loncxlatc(edge_a, edge_b, p, q);
    }
 
    // if the great circle is the equator, we handle the great circle as a circle of latitude
@@ -1441,7 +1451,7 @@ int gcxlatc(struct edge edge_a, struct edge edge_b,
 
       edge_a.points[0].lat = edge_a.points[1].lat = 0;
       edge_a.edge_type = LAT_CIRCLE;
-      return latcxlatc(edge_a, edge_b, p, q);
+      return yac_latcxlatc(edge_a, edge_b, p, q);
    }
 
    double a[3], b[3], c[3], d[3], p_[3], q_[3];
@@ -1451,7 +1461,7 @@ int gcxlatc(struct edge edge_a, struct edge edge_b,
    LLtoXYZ(edge_b.points[0].lon, edge_b.points[0].lat, c);
    LLtoXYZ(edge_b.points[1].lon, edge_b.points[1].lat, d);
 
-   int ret_value = gcxlatc_vec(a, b, c, d, p_, q_);
+   int ret_value = yac_gcxlatc_vec(a, b, c, d, p_, q_);
 
    if (ret_value == -1) return -1;
 
@@ -1479,8 +1489,8 @@ int gcxlatc(struct edge edge_a, struct edge edge_b,
  *          p and q will be identically, but only the p bits will be set
  **/
 
-int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
-                double p[3], double q[3]) {
+int yac_gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
+                    double p[3], double q[3]) {
 
    unsigned result = 0;
 
@@ -1494,14 +1504,14 @@ int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
    // if the great circle is the equator
    if (fabs(a[2]) < tol && fabs(b[2]) < tol) {
 
-      return latcxlatc_vec(a, b, c, d, p, q);
+      return yac_latcxlatc_vec(a, b, c, d, p, q);
 
    // if the great circle is  a circle of longitude
    } else if (scale < tol || fabs(cross_ab[2]/scale) < tol ||
               fabs(fabs(a[2])-1.0) < 1e-13 ||
               fabs(fabs(b[2])-1.0) < 1e-13) {
 
-      return loncxlatc_vec(a, b, c, d, p, q);
+      return yac_loncxlatc_vec(a, b, c, d, p, q);
    }
 
    double t[3], s[3];
@@ -1551,7 +1561,7 @@ int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
       double c_ = t[0] * t[0] + t[1] * t[1] + c[2] * c[2] - 1.0;
 
       if (a_ == 0.0)
-         abort_message("internal error", __FILE__, __LINE__);
+         yac_internal_abort_message("internal error", __FILE__, __LINE__);
 
       double temp = b_ * b_ - 4.0 * a_ * c_;
 
@@ -1593,7 +1603,8 @@ int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
    return result;
 }
 
-static int gcxlatc_vec_(double a[3], double b[3], double c[3], double d[3]) {
+static
+int gcxlatc_vec_(double a[3], double b[3], double c[3], double d[3]) {
 
    double angle_ab = get_vector_angle(a, b);
    double angle_cd = get_vector_angle(c, d);
@@ -1658,7 +1669,7 @@ static int gcxlatc_vec_(double a[3], double b[3], double c[3], double d[3]) {
    }
 
    if (fabs(s[0]) < tol && fabs(s[1]) < tol)
-      abort_message("internal error", __FILE__, __LINE__);
+      yac_internal_abort_message("internal error", __FILE__, __LINE__);
 
    {
       // the intersection of the planes of both circles is defined by:
@@ -1711,8 +1722,8 @@ static int gcxlatc_vec_(double a[3], double b[3], double c[3], double d[3]) {
    }
 }
 
-int intersect (struct edge const edge_a, struct edge const edge_b,
-               struct point * intersection) {
+int yac_intersect (struct edge const edge_a, struct edge const edge_b,
+                   struct point * intersection) {
 
    int switch_edges;
 
@@ -1723,12 +1734,12 @@ int intersect (struct edge const edge_a, struct edge const edge_b,
    // if both edges are on circles of latitude
    if (edge_a.edge_type == LAT_CIRCLE && edge_b.edge_type == LAT_CIRCLE) {
 
-      intersect_func = latcxlatc;
+      intersect_func = yac_latcxlatc;
 
    // if both edges are on circle of longitude
    } else if (edge_a.edge_type == LON_CIRCLE && edge_b.edge_type == LON_CIRCLE) {
 
-      intersect_func = loncxlonc;
+      intersect_func = yac_loncxlonc;
 
    // if both edges are on great circles
    } else if ((edge_a.edge_type == GREAT_CIRCLE &&
@@ -1738,37 +1749,37 @@ int intersect (struct edge const edge_a, struct edge const edge_b,
        (edge_a.edge_type == GREAT_CIRCLE &&
         edge_b.edge_type == LON_CIRCLE)) {
 
-      intersect_func = gcxgc;
+      intersect_func = yac_gcxgc;
 
    // if one edge a is on a great circle and edge b on a circle of latitude
    } else if (edge_a.edge_type == GREAT_CIRCLE &&
               edge_b.edge_type == LAT_CIRCLE) {
 
-      intersect_func = gcxlatc;
+      intersect_func = yac_gcxlatc;
 
    // if one edge a is on a circle of latitude and edge b on a great circle
    } else if (edge_a.edge_type == LAT_CIRCLE &&
               edge_b.edge_type == GREAT_CIRCLE ) {
 
       switch_edges = 1;
-      intersect_func = gcxlatc;
+      intersect_func = yac_gcxlatc;
 
    // if one edge a is on a circle of longitude and edge b on a circle of latitude
    } else if (edge_a.edge_type == LON_CIRCLE &&
               edge_b.edge_type == LAT_CIRCLE) {
 
-      intersect_func = loncxlatc;
+      intersect_func = yac_loncxlatc;
 
    // if one edge a is on a circle of latitude and edge b on a circle of longitude
    } else if (edge_a.edge_type == LAT_CIRCLE &&
               edge_b.edge_type == LON_CIRCLE ) {
 
       switch_edges = 1;
-      intersect_func = loncxlatc;
+      intersect_func = yac_loncxlatc;
 
    } else {
 
-      abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
+      yac_internal_abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
       exit(EXIT_FAILURE);
    }
 
@@ -1803,9 +1814,9 @@ int intersect (struct edge const edge_a, struct edge const edge_b,
    return 0;
 }
 
-int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
-                   enum edge_type edge_type_b, double c[3], double d[3],
-                   double p[3], double q[3]) {
+int yac_intersect_vec (enum yac_edge_type edge_type_a, double a[3], double b[3],
+                       enum yac_edge_type edge_type_b, double c[3], double d[3],
+                       double p[3], double q[3]) {
 
    int switch_edges;
 
@@ -1817,13 +1828,13 @@ int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
    if (edge_type_a == LAT_CIRCLE &&
        edge_type_b == LAT_CIRCLE) {
 
-      intersect_func = latcxlatc_vec;
+      intersect_func = yac_latcxlatc_vec;
 
    // if both edges are on circle of longitude
    } else if (edge_type_a == LON_CIRCLE &&
               edge_type_b == LON_CIRCLE) {
 
-      intersect_func = loncxlonc_vec;
+      intersect_func = yac_loncxlonc_vec;
 
    // if both edges are on great circles
    } else if ((edge_type_a == GREAT_CIRCLE &&
@@ -1833,37 +1844,37 @@ int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
               (edge_type_a == GREAT_CIRCLE &&
                edge_type_b == LON_CIRCLE)) {
 
-      intersect_func = gcxgc_vec;
+      intersect_func = yac_gcxgc_vec;
 
    // if one edge a is on a great circle and edge b on a circle of latitude
    } else if (edge_type_a == GREAT_CIRCLE &&
               edge_type_b == LAT_CIRCLE) {
 
-      intersect_func = gcxlatc_vec;
+      intersect_func = yac_gcxlatc_vec;
 
    // if one edge a is on a circle of latitude and edge b on a great circle
    } else if (edge_type_a == LAT_CIRCLE &&
               edge_type_b == GREAT_CIRCLE ) {
 
       switch_edges = 1;
-      intersect_func = gcxlatc_vec;
+      intersect_func = yac_gcxlatc_vec;
 
    // if one edge a is on a circle of longitude and edge b on a circle of latitude
    } else if (edge_type_a == LON_CIRCLE &&
               edge_type_b == LAT_CIRCLE) {
 
-      intersect_func = loncxlatc_vec;
+      intersect_func = yac_loncxlatc_vec;
 
    // if one edge a is on a circle of latitude and edge b on a circle of longitude
    } else if (edge_type_a == LAT_CIRCLE &&
               edge_type_b == LON_CIRCLE ) {
 
       switch_edges = 1;
-      intersect_func = loncxlatc_vec;
+      intersect_func = yac_loncxlatc_vec;
 
    } else {
 
-      abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
+      yac_internal_abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
       exit(EXIT_FAILURE);
    }
 
@@ -1881,8 +1892,8 @@ int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
    return ret_value;
 }
 
-int do_intersect (struct edge edge_a, double a[3], double b[3],
-                  struct edge edge_b, double c[3], double d[3]) {
+int yac_do_intersect (struct edge edge_a, double a[3], double b[3],
+                      struct edge edge_b, double c[3], double d[3]) {
 
    int flag = ((edge_a.edge_type == LAT_CIRCLE)   << 0) |
               ((edge_a.edge_type == LON_CIRCLE)   << 1) |
@@ -1910,7 +1921,7 @@ int do_intersect (struct edge edge_a, double a[3], double b[3],
       case ((1 << 2) | (1 << 3)):
          return gcxlatc_vec_(a, b, c, d);
       default:
-         abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
+         yac_internal_abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
          exit(EXIT_FAILURE);
    };
 }
diff --git a/src/clipping/points.h b/src/clipping/points.h
index e3d75e1..6d4e23b 100644
--- a/src/clipping/points.h
+++ b/src/clipping/points.h
@@ -40,7 +40,7 @@
 
 #include "grid.h"
 
-enum location {
+enum yac_location {
 
    CELL =   0,
    CORNER = 1,
@@ -49,7 +49,7 @@ enum location {
 
 struct points {
 
-   enum location location;
+   enum yac_location location;
 
    double * coordinates_x, * coordinates_y;
 
@@ -58,7 +58,7 @@ struct points {
    struct grid * point_grid;
 };
 
-enum location get_location(int const location);
+enum yac_location yac_get_location(int const location);
 
 /**
  * initialises a struct points
@@ -73,8 +73,8 @@ enum location get_location(int const location);
  * \remarks - for EDGE points the coordinates need to have an entry for each edge (in
  *            the order of the local ids)
  */
-void init_points(struct points * points, struct grid * base_grid, enum location location,
-                 double * coordinates_x, double * coordinates_y);
+void yac_init_points(struct points * points, struct grid * base_grid, enum yac_location location,
+                     double * coordinates_x, double * coordinates_y);
 
 /**
  * returns a grid that has the points defined by the struct points as corners
@@ -83,21 +83,21 @@ void init_points(struct points * points, struct grid * base_grid, enum location
  *
  * \remarks does not work for EDGE
  */
-struct grid * get_point_grid(struct points * points);
-struct grid * get_base_grid(struct points * points);
+struct grid * yac_get_point_grid(struct points * points);
+struct grid * yac_get_base_grid(struct points * points);
 
-void get_coordinate_array_sizes (struct grid * grid, enum location location, unsigned * sizes);
+void yac_get_coordinate_array_sizes (struct grid * grid, enum yac_location location, unsigned * sizes);
 
 /**
  * returns the number of points in the struct points
  * @param[in] points
  * @return number of points
  */
-unsigned get_data_size(struct points points);
+unsigned yac_get_data_size(struct points points);
 
-void get_point_coordinates (struct points * points, unsigned local_point_id,
-                            double * coordinates);
+void yac_get_point_coordinates (struct points * points, unsigned local_point_id,
+                                double * coordinates);
 
-void free_points(struct points * points);
+void yac_free_points(struct points * points);
 
 #endif // POINTS_H
diff --git a/src/clipping/utils.c b/src/clipping/utils.c
index 5f001c7..d212a31 100644
--- a/src/clipping/utils.c
+++ b/src/clipping/utils.c
@@ -37,7 +37,7 @@
 static void ** pointer_lookup_table = NULL;
 static unsigned pointer_lookup_table_size = 0;
 
-unsigned pointer_to_unique_id(void * pointer) {
+unsigned yac_pointer_to_unique_id(void * pointer) {
 
    pointer_lookup_table = realloc (pointer_lookup_table,
       ++pointer_lookup_table_size * sizeof(pointer_lookup_table[0]));
@@ -47,7 +47,7 @@ unsigned pointer_to_unique_id(void * pointer) {
    return pointer_lookup_table_size - 1;
 }
 
-void * unique_id_to_pointer(unsigned id) {
+void * yac_unique_id_to_pointer(unsigned id) {
 
    if (id < pointer_lookup_table_size)
       return pointer_lookup_table[id];
@@ -55,14 +55,14 @@ void * unique_id_to_pointer(unsigned id) {
       return NULL;
 }
 
-void free_pointer_unique_lookup() {
+void yac_free_pointer_unique_lookup() {
 
   free(pointer_lookup_table);
   pointer_lookup_table = NULL;
   pointer_lookup_table_size = 0;
 }
 
-void abort_message ( char * text, char * file, int line )
+void yac_internal_abort_message ( char * text, char * file, int line )
 {
   fprintf(stderr, "%s \n", text); 
   fprintf(stderr, "Aborting in file %s, line %i ...\n", file, line );
@@ -70,7 +70,7 @@ void abort_message ( char * text, char * file, int line )
 }
 
 void yac_abort_message ( char * text, char * file, int line ) {
-	abort_message ( text, file, line );
+	yac_internal_abort_message ( text, file, line );
 }
 
 /* ------------------------------------
@@ -95,7 +95,7 @@ unsigned long hash(const char *str) {
 #define NHASH 29989 //Use a prime number!
 #define MULT 31
 
-unsigned int hash(const char *str) {
+unsigned int yac_hash(const char *str) {
   unsigned int h = 0;
   for(; *str; str++)
     h = MULT * h + *str;
diff --git a/src/clipping/utils.h b/src/clipping/utils.h
index bd6c56f..500eab2 100644
--- a/src/clipping/utils.h
+++ b/src/clipping/utils.h
@@ -47,35 +47,35 @@
  * @return unique value associated to pointer
  * @see unique_id_to_pointer
  */
-unsigned pointer_to_unique_id(void * pointer);
+unsigned yac_pointer_to_unique_id(void * pointer);
 
 /**
  * gives the pointer that is associated to the given id
  * @param[in] id unique index previously returned by pointer_to_unique_id
  * @return pointer the is associated to the given id \n NULL if the id is invalid
  */
-void *   unique_id_to_pointer(unsigned id);
+void * yac_unique_id_to_pointer(unsigned id);
 
 /**
  * frees all memory used for the pointer/unique_id conversion
  * \remarks this should only be called after the last call to 
- *          \ref pointer_to_unique_id and \ref unique_id_to_pointer, because afterwords
- *          \ref unique_id_to_pointer will not be able to return the respective pointers
+ *          \ref yac_pointer_to_unique_id and \ref yac_unique_id_to_pointer, because afterwards
+ *          \ref yac_unique_id_to_pointer will not be able to return the respective pointers
  *          for previously valid unique ids
  */
-void free_pointer_unique_lookup();
+void yac_free_pointer_unique_lookup();
 
 /**
  * prints a short error message and info from where it was called
  * followed by an exit. 
  */
-void abort_message ( char * text, char * file, int line );
+void yac_internal_abort_message ( char * text, char * file, int line );
 
 /** \example test_quicksort.c
  * This contains an example of how to use quicksort_index.
  */
 
-void quicksort_index ( int * a, int n, int * idx);
+void yac_quicksort_index ( int * a, int n, int * idx);
 
 /** \example test_mergesort.c
  *
@@ -89,16 +89,16 @@ void yac_mergesort(void* base, size_t num, size_t size,
  *
  * Hash function
  *
- * This algorithm (k=33) was first reported by dan bernstein many
+ * This algorithm (k=33) was first reported by Dan Bernstein many
  * years ago in comp.lang.c. another version of this algorithm (now
- * favored by bernstein) uses xor: hash(i) = hash(i - 1) * 33 ^
+ * favored by Bernstein) uses xor: hash(i) = hash(i - 1) * 33 ^
  * str[i]; the magic of number 33 (why it works better than many other
  * constants, prime or not) has never been adequately explained.
  *
  * Source: http://www.cse.yorku.ca/~oz/hash.html 
  */
 
-unsigned int hash(const char *str);
+unsigned int yac_hash(const char *str);
 
 /**
  * remove duplicated entries from a list of integers
diff --git a/src/commandline.c b/src/commandline.c
index a8e96e7..d1f0889 100644
--- a/src/commandline.c
+++ b/src/commandline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/compare.h b/src/compare.h
new file mode 100644
index 0000000..717d7b2
--- /dev/null
+++ b/src/compare.h
@@ -0,0 +1,53 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  See COPYING file for copying and redistribution conditions.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+*/
+
+#ifndef _COMPARE_H
+#define _COMPARE_H
+
+#if defined(HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <math.h>
+
+#if defined(__xlC__) /* performance problems on IBM */
+#ifndef DBL_IS_NAN
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#else
+#ifndef DBL_IS_NAN
+#if defined(HAVE_DECL_ISNAN)
+#  define DBL_IS_NAN(x)     (isnan(x))
+#elif defined(FP_NAN)
+#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
+#else
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#endif
+#endif
+
+#ifndef DBL_IS_EQUAL
+/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
+#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
+#endif
+
+#ifndef IS_EQUAL
+#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
+#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
+#endif
+
+#endif  /* _COMPARE_H */
diff --git a/src/config.h.in b/src/config.h.in
index 75feedd..f261a59 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -1,5 +1,8 @@
 /* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* CDO version */
+#undef CDO
+
 /* Compiler */
 #undef COMPILER
 
@@ -22,6 +25,9 @@
 /* Define to 1 if you have the <fftw3.h> header file. */
 #undef HAVE_FFTW3_H
 
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
 /* Define to 1 if you have the `gethostname' function. */
 #undef HAVE_GETHOSTNAME
 
@@ -130,6 +136,12 @@
 /* Define to 1 if you have a working `mmap' system call. */
 #undef HAVE_MMAP
 
+/* Define to 1 for NETCDF4/HDF5 support */
+#undef HAVE_NC4HDF5
+
+/* Define to 1 for NETCDF4/HDF5 threadsafe support */
+#undef HAVE_NC4HDF5_THREADSAFE
+
 /* Define to 1 for NETCDF2 support */
 #undef HAVE_NETCDF2
 
@@ -148,6 +160,9 @@
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
+/* Define to 1 if you have the `sqrtl' function. */
+#undef HAVE_SQRTL
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -190,6 +205,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the <wordexp.h> header file. */
+#undef HAVE_WORDEXP_H
+
 /* Define to 1 if you have the <zlib.h> header file. */
 #undef HAVE_ZLIB_H
 
@@ -242,3 +260,17 @@
 
 /* Define for large files, on AIX-style hosts. */
 #undef _LARGE_FILES
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+   __restrict__, even though the corresponding Sun C compiler ends up with
+   "#define restrict _Restrict" or "#define restrict __restrict__" in the
+   previous line.  Perhaps some future version of Sun C++ will work with
+   restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif
diff --git a/src/constants.c b/src/constants.c
new file mode 100644
index 0000000..214d4bf
--- /dev/null
+++ b/src/constants.c
@@ -0,0 +1,5 @@
+#include "constants.h"
+
+double PlanetRD      = C_EARTH_RD;
+double PlanetRadius  = C_EARTH_RADIUS;
+double PlanetGrav    = C_EARTH_GRAV;
diff --git a/src/constants.h b/src/constants.h
new file mode 100644
index 0000000..47f30d4
--- /dev/null
+++ b/src/constants.h
@@ -0,0 +1,39 @@
+#ifndef _CONSTANTS_H
+#define _CONSTANTS_H
+
+/* Thermodynamical constants adopted from ECMWF IFS-Code */
+
+#define  C_RKBOL         (1.380658e-23)     /* Boltzmann constant in J/K   */
+#define  C_RNAVO         (6.0221367e+23)    /* Avogadro constant in 1/mol  */
+#define  C_RMD           (28.9644)          /* molecular weight of dry air */
+#define  C_RMV           (18.0153)          /* molecular weight of water vapor */
+#define  C_R             (C_RKBOL * C_RNAVO)
+#define  C_RV            (1000. * C_R / C_RMV)
+
+#define  C_EARTH_RD      (1000. * C_R / C_RMD)
+#define  C_EARTH_RADIUS  (6371000.0)        /* radius of the Earth in m */
+#define  C_EARTH_GRAV    (9.80665)
+
+#define  C_MARS_RD       (189.0 )
+#define  C_MARS_RADIUS   (3400000.0)        /* radius of the Mars in m */
+#define  C_MARS_GRAV     (3.7)
+
+#define  C_RG            (1.0 / PlanetGrav)
+
+#define  C_RCPV          (4.0 * C_RV)
+#define  C_RETV          (C_RV / PlanetRD - 1.)
+#define  C_RCW           (4218.)            /* specific water heat capacity ?? */
+#define  C_RCS           (2106.)            /* specific ice heat capacity ?? */
+#define  C_RTT           (273.16)           /* melting temperature of ice/snow */
+#define  C_RLVTT         (2.5008e+6)        /* latent heat for vaporisation in J/kg */
+#define  C_RLSTT         (2.8345e+6)        /* latent heat for sublimation in J/kg */
+#define  C_RESTT         (611.14)
+#define  C_RCPD          (3.5 * PlanetRD)
+
+#define  C_TIMES_RHOH2O  (-333700000.0)
+
+extern double PlanetRD;
+extern double PlanetRadius;
+extern double PlanetGrav;
+
+#endif  /* _CONSTANTS_H */
diff --git a/src/datetime.c b/src/datetime.c
new file mode 100644
index 0000000..d086cfc
--- /dev/null
+++ b/src/datetime.c
@@ -0,0 +1,258 @@
+#include <string.h>
+#include <math.h>
+
+#include <cdi.h>
+#include "cdo.h"
+#include "datetime.h"
+
+static int timestat_date = -1;
+
+static
+void get_timestat_date(int *tstat_date)
+{
+  char *envstr;
+
+  envstr = getenv("TIMESTAT_DATE");
+  if ( envstr == NULL ) envstr = getenv("RUNSTAT_DATE");
+  if ( envstr )
+    {
+      int env_date = -1;
+      char envstrl[8];
+
+      memcpy(envstrl, envstr, 8);
+      envstrl[7] = 0;
+      strtolower(envstrl);
+
+      if      ( memcmp(envstrl, "first", 5)  == 0 )  env_date = TIMESTAT_FIRST;
+      else if ( memcmp(envstrl, "last", 4)   == 0 )  env_date = TIMESTAT_LAST;
+      else if ( memcmp(envstrl, "middle", 6) == 0 )  env_date = TIMESTAT_MEAN;
+
+      if ( env_date >= 0 )
+	{
+	  *tstat_date = env_date;
+
+	  if ( cdoVerbose ) cdoPrint("Set TIMESTAT_DATE to %s", envstr);
+	}
+    }
+}
+
+
+void dtlist_init(dtlist_type *dtlist)
+{
+  dtlist->nalloc     = 0;
+  dtlist->size       = 0;
+  dtlist->calendar   = CALENDAR_STANDARD;
+  dtlist->has_bounds = -1;
+  dtlist->stat       = TIMESTAT_LAST;
+  dtlist->dtinfo     = NULL;
+
+  if ( timestat_date == -1 )
+    {
+      timestat_date = 0;
+      get_timestat_date(&timestat_date);
+    }
+}
+
+
+dtlist_type *dtlist_new(void)
+{
+  dtlist_type *dtlist = (dtlist_type *) malloc(sizeof(dtlist_type));
+
+  dtlist_init(dtlist);
+
+  return dtlist;
+}
+
+
+void dtlist_delete(dtlist_type *dtlist)
+{
+  if ( dtlist->nalloc > 0 && dtlist->dtinfo )
+    free(dtlist->dtinfo);
+
+  free(dtlist);
+}
+
+
+void dtlist_taxisInqTimestep(dtlist_type *dtlist, int taxisID, int tsID)
+{
+  size_t NALLOC = 128;
+
+  if ( (size_t)tsID >= dtlist->nalloc )
+    {
+      dtlist->nalloc += NALLOC;
+      dtlist->dtinfo = (dtinfo_type *) realloc(dtlist->dtinfo, dtlist->nalloc*sizeof(dtinfo_type));
+    }
+
+  if ( (size_t)tsID >= dtlist->size ) dtlist->size = (size_t)tsID + 1;
+
+  dtlist->dtinfo[tsID].v.date = taxisInqVdate(taxisID);
+  dtlist->dtinfo[tsID].v.time = taxisInqVtime(taxisID);
+
+  if ( tsID == 0 && dtlist->has_bounds == -1 )
+    {
+      dtlist->has_bounds = 0;
+      if ( taxisHasBounds(taxisID) ) dtlist->has_bounds = 1;
+    }
+
+  if ( dtlist->has_bounds )
+    {
+      taxisInqVdateBounds(taxisID, &(dtlist->dtinfo[tsID].b[0].date), &(dtlist->dtinfo[tsID].b[1].date));
+      taxisInqVtimeBounds(taxisID, &(dtlist->dtinfo[tsID].b[0].time), &(dtlist->dtinfo[tsID].b[1].time));
+    }
+  else
+    {
+      dtlist->dtinfo[tsID].b[0].date = 0;
+      dtlist->dtinfo[tsID].b[1].date = 0;
+      dtlist->dtinfo[tsID].b[0].time = 0;
+      dtlist->dtinfo[tsID].b[1].time = 0;
+    }
+}
+
+
+void dtlist_taxisDefTimestep(dtlist_type *dtlist, int taxisID, int tsID)
+{
+  if ( tsID < 0 || (size_t)tsID >= dtlist->size )
+    cdoAbort("Internal error; tsID out of bounds!");
+
+  taxisDefVdate(taxisID, dtlist->dtinfo[tsID].v.date);
+  taxisDefVtime(taxisID, dtlist->dtinfo[tsID].v.time);
+  if ( dtlist->has_bounds )
+    {
+      taxisDefVdateBounds(taxisID, dtlist->dtinfo[tsID].b[0].date, dtlist->dtinfo[tsID].b[1].date);
+      taxisDefVtimeBounds(taxisID, dtlist->dtinfo[tsID].b[0].time, dtlist->dtinfo[tsID].b[1].time);
+    }
+}
+
+
+void dtlist_mean(dtlist_type *dtlist, int nsteps)
+{
+  int vdate, vtime;
+
+  if ( nsteps%2 == 0 )
+    {
+      int calendar = dtlist->calendar;
+
+      vdate = dtlist->dtinfo[nsteps/2-1].v.date;
+      vtime = dtlist->dtinfo[nsteps/2-1].v.time;
+      juldate_t juldate1 = juldate_encode(calendar, vdate, vtime);
+
+      vdate = dtlist->dtinfo[nsteps/2].v.date;
+      vtime = dtlist->dtinfo[nsteps/2].v.time;
+      juldate_t juldate2 = juldate_encode(calendar, vdate, vtime);
+
+      double seconds = juldate_to_seconds(juldate_sub(juldate2, juldate1)) / 2;
+      juldate_t juldatem = juldate_add_seconds((int)lround(seconds), juldate1);
+      juldate_decode(calendar, juldatem, &vdate, &vtime);
+    }
+  else
+    {
+      vdate = dtlist->dtinfo[nsteps/2].v.date;
+      vtime = dtlist->dtinfo[nsteps/2].v.time;
+    }
+
+  dtlist->timestat.v.date = vdate;
+  dtlist->timestat.v.time = vtime;
+}
+
+
+void dtlist_stat_taxisDefTimestep(dtlist_type *dtlist, int taxisID, int nsteps)
+{
+  if ( (size_t)nsteps > dtlist->size )
+    cdoAbort("Internal error; unexpected nsteps=%d (limit=%ld)!", nsteps, dtlist->size);
+
+  int stat = dtlist->stat;
+  if ( timestat_date > 0 ) stat = timestat_date;
+
+  if      ( stat == TIMESTAT_MEAN  ) dtlist_mean(dtlist, nsteps);
+  else if ( stat == TIMESTAT_FIRST ) dtlist->timestat.v = dtlist->dtinfo[0].v;
+  else if ( stat == TIMESTAT_LAST  ) dtlist->timestat.v = dtlist->dtinfo[nsteps-1].v;
+
+  if ( dtlist->has_bounds )
+    {
+      dtlist->timestat.b[0] = dtlist->dtinfo[0].b[0];
+      dtlist->timestat.b[1] = dtlist->dtinfo[nsteps-1].b[1];
+    }
+  else
+    {
+      dtlist->timestat.b[0] = dtlist->dtinfo[0].v;
+      dtlist->timestat.b[1] = dtlist->dtinfo[nsteps-1].v;
+    }
+
+  taxisDefVdate(taxisID, dtlist->timestat.v.date);
+  taxisDefVtime(taxisID, dtlist->timestat.v.time);
+  // if ( dtlist->has_bounds )
+    {
+      taxisDefVdateBounds(taxisID, dtlist->timestat.b[0].date, dtlist->timestat.b[1].date);
+      taxisDefVtimeBounds(taxisID, dtlist->timestat.b[0].time, dtlist->timestat.b[1].time);
+    }
+}
+
+
+void dtlist_shift(dtlist_type *dtlist)
+{
+  for ( size_t inp = 0; inp < dtlist->size-1; inp++ )
+    {
+      dtlist->dtinfo[inp] = dtlist->dtinfo[inp+1];
+    }
+}
+
+
+void dtlist_set_stat(dtlist_type *dtlist, int stat)
+{
+  dtlist->stat = stat;
+}
+
+
+void dtlist_set_calendar(dtlist_type *dtlist, int calendar)
+{
+  dtlist->calendar = calendar;
+}
+
+
+int dtlist_get_vdate(dtlist_type *dtlist, int tsID)
+{
+  if ( tsID < 0 || (size_t)tsID >= dtlist->size )
+    cdoAbort("Internal error; tsID out of bounds!");
+
+  return dtlist->dtinfo[tsID].v.date;
+}
+
+
+int dtlist_get_vtime(dtlist_type *dtlist, int tsID)
+{
+  if ( tsID < 0 || (size_t)tsID >= dtlist->size )
+    cdoAbort("Internal error; tsID out of bounds!");
+
+  return dtlist->dtinfo[tsID].v.time;
+}
+
+
+void datetime_avg(int calendar, int ndates, datetime_t *datetime)
+{
+  int vdate, vtime;
+  juldate_t juldate1, juldate2, juldatem;
+  double seconds;
+
+  if ( ndates%2 == 0 )
+    {
+      vdate = datetime[ndates/2-1].date;
+      vtime = datetime[ndates/2-1].time;
+      juldate1 = juldate_encode(calendar, vdate, vtime);
+
+      vdate = datetime[ndates/2].date;
+      vtime = datetime[ndates/2].time;
+      juldate2 = juldate_encode(calendar, vdate, vtime);
+
+      seconds = juldate_to_seconds(juldate_sub(juldate2, juldate1)) / 2;
+      juldatem = juldate_add_seconds((int)lround(seconds), juldate1);
+      juldate_decode(calendar, juldatem, &vdate, &vtime);
+    }
+  else
+    {
+      vdate = datetime[ndates/2].date;
+      vtime = datetime[ndates/2].time;
+    }
+
+  datetime[ndates].date = vdate;
+  datetime[ndates].time = vtime;
+}
diff --git a/src/datetime.h b/src/datetime.h
new file mode 100644
index 0000000..63b7202
--- /dev/null
+++ b/src/datetime.h
@@ -0,0 +1,63 @@
+#include <stdio.h>
+
+#define  TIMESTAT_FIRST  1
+#define  TIMESTAT_LAST   2
+#define  TIMESTAT_MEAN   3
+
+
+typedef struct {
+  int   julday;
+  int   secofday;
+} juldate_t;
+
+
+typedef struct {
+  int   date;
+  int   time;
+} datetime_t;
+
+
+typedef struct {
+  int   date;
+  int   time;
+} datetime_type;
+
+typedef struct
+{
+  datetime_type v;
+  datetime_type b[2];
+} dtinfo_type;
+
+typedef struct
+{
+  size_t       nalloc;
+  size_t       size;
+  int          has_bounds;
+  int          calendar;
+  int          stat;
+  int          timestat_date;
+  dtinfo_type  timestat;
+  dtinfo_type *dtinfo;
+} dtlist_type;
+
+
+
+juldate_t juldate_encode(int calendar, int date, int time);
+void      juldate_decode(int calendar, juldate_t juldate, int *date, int *time);
+juldate_t juldate_sub(juldate_t juldate2, juldate_t juldate1);
+juldate_t juldate_add_seconds(int seconds, juldate_t juldate);
+double    juldate_to_seconds(juldate_t juldate);
+
+
+void    datetime_avg(int dpy, int ndates, datetime_t *datetime);
+
+dtlist_type *dtlist_new(void);
+void dtlist_delete(dtlist_type *dtlist);
+void dtlist_shift(dtlist_type *dtlist);
+void dtlist_set_stat(dtlist_type *dtlist, int stat);
+void dtlist_set_calendar(dtlist_type *dtlist, int calendar);
+int  dtlist_get_vdate(dtlist_type *dtlist, int tsID);
+int  dtlist_get_vtime(dtlist_type *dtlist, int tsID);
+void dtlist_taxisInqTimestep(dtlist_type *dtlist, int taxisID, int tsID);
+void dtlist_taxisDefTimestep(dtlist_type *dtlist, int taxisID, int tsID);
+void dtlist_stat_taxisDefTimestep(dtlist_type *dtlist, int taxisID, int nsteps);
diff --git a/src/ecacore.c b/src/ecacore.c
old mode 100644
new mode 100755
index 64bab31..758bfcb
--- a/src/ecacore.c
+++ b/src/ecacore.c
@@ -415,7 +415,7 @@ void eca2(const ECA_REQUEST_2 *request)
   long nsets;
   int i;
   int istreamID1, istreamID2, ostreamID;
-  int ivlistID1, ivlistID2, ovlistID, itaxisID1, itaxisID2, otaxisID;
+  int ivlistID1, ivlistID2, ovlistID, itaxisID1, otaxisID;
   int nlevels;
   int *recVarID, *recLevelID;
   double missval1, missval2;
@@ -466,7 +466,6 @@ void eca2(const ECA_REQUEST_2 *request)
   if ( cdoOperatorF2(operatorID) == 16 ) vlistDefNtsteps(ovlistID, 1);
 
   itaxisID1 = vlistInqTaxis(ivlistID1);
-  itaxisID2 = vlistInqTaxis(ivlistID2);
   otaxisID = taxisCreate(TAXIS_RELATIVE);
   taxisDefTunit(otaxisID, TUNIT_MINUTE);
   //  taxisDefCalendar(otaxisID, CALENDAR_PROLEPTIC);
diff --git a/src/ecautil.c b/src/ecautil.c
old mode 100644
new mode 100755
diff --git a/src/expr.c b/src/expr.c
index 8f940ab..5754171 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,10 +12,27 @@
 #include "expr.h"
 #include "expr_yacc.h"
 
+#define    COMPLT(x,y)  ((x) < (y) ? 1 : 0)
+#define    COMPGT(x,y)  ((x) > (y) ? 1 : 0)
+#define    COMPLE(x,y)  ((x) <= (y) ? 1 : 0)
+#define    COMPGE(x,y)  ((x) >= (y) ? 1 : 0)
+#define    COMPNE(x,y)  (IS_NOT_EQUAL(x,y) ? 1 : 0)
+#define    COMPEQ(x,y)  (IS_EQUAL(x,y) ? 1 : 0)
+#define   COMPLEG(x,y)  ((x) < (y) ? -1 : ((x) > (y) ? 1 : 0))
+#define   COMPAND(x,y)  (IS_NOT_EQUAL(x,0) && IS_NOT_EQUAL(y,0) ? 1 : 0)
+#define    COMPOR(x,y)  (IS_NOT_EQUAL(x,0) || IS_NOT_EQUAL(y,0) ? 1 : 0)
+#define  MVCOMPLT(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPLT(x,y))
+#define  MVCOMPGT(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPGT(x,y))
+#define  MVCOMPLE(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPLE(x,y))
+#define  MVCOMPGE(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPGE(x,y))
+#define  MVCOMPNE(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPNE(x,y))
+#define  MVCOMPEQ(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPEQ(x,y))
+#define MVCOMPLEG(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPLEG(x,y))
+#define MVCOMPAND(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPAND(x,y))
+#define  MVCOMPOR(x,y)  (DBL_IS_EQUAL((x),missval1) ? missval1 : COMPOR(x,y))
 
-static double f_abs(double x)  { return (fabs(x));  }
 static double f_int(double x)  { return ((int)(x)); }
-static double f_nint(double x) { return (round(x));  }
+static double f_nint(double x) { return (round(x)); }
 static double f_sqr(double x)  { return (x*x);      }
 
 typedef struct {
@@ -28,7 +45,7 @@ func_t;
 static func_t fun_sym_tbl[] =
 {
   /* scalar functions */
-  {0, "abs",   f_abs},
+  {0, "abs",   fabs},
   {0, "floor", floor},
   {0, "ceil",  ceil},
   {0, "int",   f_int},
@@ -69,19 +86,20 @@ static int NumFunc = sizeof(fun_sym_tbl) / sizeof(fun_sym_tbl[0]);
 static
 nodeType *expr_con_con(int oper, nodeType *p1, nodeType *p2)
 {
-  nodeType *p;
-
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
+  double cval1 = p1->u.con.value;
+  double cval2 = p2->u.con.value;
+
   switch ( oper )
     {
-    case '+':  p->u.con.value = p1->u.con.value + p2->u.con.value; break;
-    case '-':  p->u.con.value = p1->u.con.value - p2->u.con.value; break;
-    case '*':  p->u.con.value = p1->u.con.value * p2->u.con.value; break;
-    case '/':  p->u.con.value = p1->u.con.value / p2->u.con.value; break;
-    case '^':  p->u.con.value = pow(p1->u.con.value, p2->u.con.value); break;
+    case '+':  cval1 = cval1 + cval2; break;
+    case '-':  cval1 = cval1 - cval2; break;
+    case '*':  cval1 = cval1 * cval2; break;
+    case '/':  cval1 = cval1 / cval2; break;
+    case '^':  cval1 = pow(cval1, cval2); break;
     default:   cdoAbort("%s: operator %c unsupported!", __func__, oper); break;
     }
 
@@ -91,23 +109,18 @@ nodeType *expr_con_con(int oper, nodeType *p1, nodeType *p2)
 static
 nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
 {
-  nodeType *p;
-  long ngp, i;
-  long nlev;
-  int nmiss;
-  int gridID, zaxisID;
-  double missval1, missval2;
+  int gridID   = p2->gridID;
+  int zaxisID  = p2->zaxisID;
+  int nmiss    = p2->nmiss;
+  double missval1 = p2->missval;
+  double missval2 = p2->missval;
 
-  gridID   = p2->gridID;
-  zaxisID  = p2->zaxisID;
-  nmiss    = p2->nmiss;
-  missval1 = p2->missval;
-  missval2 = p2->missval;
+  int ngp  = gridInqSize(gridID);
+  int nlev = zaxisInqSize(zaxisID);
+  long n   = ngp*nlev;
+  long i;
 
-  ngp  = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
-
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -116,63 +129,66 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
   p->zaxisID  = zaxisID;
   p->missval  = missval1;
 
-  p->data = (double*) malloc(ngp*nlev*sizeof(double));
+  p->data = (double*) malloc(n*sizeof(double));
+  double *restrict odat = p->data;
+  const double *restrict idat = p2->data;
+  double cval = p1->u.con.value;
 
   switch ( oper )
     {
     case '+':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = ADD(p1->u.con.value, p2->data[i]);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->u.con.value + p2->data[i];
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = ADD(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] = cval + idat[i];
       break;
     case '-':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = SUB(p1->u.con.value, p2->data[i]);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->u.con.value - p2->data[i];
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = SUB(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] = cval - idat[i];
       break;
     case '*':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = MUL(p1->u.con.value, p2->data[i]);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->u.con.value * p2->data[i];
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MUL(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] = cval * idat[i];
       break;
     case '/':
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = DIV(p1->u.con.value, p2->data[i]);
-	}
+      for ( i=0; i<n; ++i ) odat[i] = DIV(cval, idat[i]);
       break;
     case '^':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = POW(p1->u.con.value, p2->data[i]);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = pow(p1->u.con.value, p2->data[i]);
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = POW(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] = pow(cval, idat[i]);
+      break;
+    case '<':
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLT(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLT(cval, idat[i]);
+      break;
+    case '>':
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPGT(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPGT(cval, idat[i]);
+      break;
+    case LE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLE(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLE(cval, idat[i]);
+      break;
+    case GE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPGE(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPGE(cval, idat[i]);
+      break;
+    case NE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPNE(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPNE(cval, idat[i]);
+      break;
+    case EQ:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPEQ(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPEQ(cval, idat[i]);
+      break;
+    case LEG:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLEG(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLEG(cval, idat[i]);
+      break;
+    case AND:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPAND(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPAND(cval, idat[i]);
+    case OR:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPOR(cval, idat[i]);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPOR(cval, idat[i]);
       break;
     default:
       cdoAbort("%s: operator %c unsupported!", __func__, oper);
@@ -180,7 +196,7 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
     }
 
   nmiss = 0;
-  for ( i = 0; i < ngp*nlev; i++ )
+  for ( i = 0; i < n; i++ )
     if ( DBL_IS_EQUAL(p->data[i], missval1) ) nmiss++;
 
   p->nmiss = nmiss;
@@ -193,23 +209,18 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
 static
 nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
 {
-  nodeType *p;
-  long ngp, i;
-  long nlev;
-  int nmiss;
-  int gridID, zaxisID;
-  double missval1, missval2;
-
-  gridID   = p1->gridID;
-  zaxisID  = p1->zaxisID;
-  nmiss    = p1->nmiss;
-  missval1 = p1->missval;
-  missval2 = p1->missval;
+  int gridID   = p1->gridID;
+  int zaxisID  = p1->zaxisID;
+  int nmiss    = p1->nmiss;
+  double missval1 = p1->missval;
+  double missval2 = p1->missval;
 
-  ngp  = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
+  int ngp  = gridInqSize(gridID);
+  int nlev = zaxisInqSize(zaxisID);
+  long n   = ngp*nlev;
+  long i;
 
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -218,69 +229,68 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
   p->zaxisID  = zaxisID;
   p->missval  = missval1;
 
-  p->data = (double*) malloc(ngp*nlev*sizeof(double));
+  p->data = (double*) malloc(n*sizeof(double));
+  double *restrict odat = p->data;
+  const double *restrict idat = p1->data;
+  double cval = p2->u.con.value;
 
   switch ( oper )
     {
     case '+':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = ADD(p1->data[i], p2->u.con.value);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->data[i] + p2->u.con.value;
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = ADD(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] = idat[i] + cval;
       break;
     case '-':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = SUB(p1->data[i], p2->u.con.value);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->data[i] - p2->u.con.value;
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = SUB(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] = idat[i] - cval;
       break;
     case '*':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = MUL(p1->data[i], p2->u.con.value);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->data[i] * p2->u.con.value;
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MUL(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] = idat[i] * cval;
       break;
     case '/':
-      if ( nmiss > 0 || IS_EQUAL(p2->u.con.value, 0) )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = DIV(p1->data[i], p2->u.con.value);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = p1->data[i] / p2->u.con.value;
-	}
+      if ( nmiss || IS_EQUAL(cval, 0) ) for ( i=0; i<n; ++i ) odat[i] = DIV(idat[i], cval);
+      else                              for ( i=0; i<n; ++i ) odat[i] = idat[i] / cval;
       break;
     case '^':
-      if ( nmiss > 0 )
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = POW(p1->data[i], p2->u.con.value);
-	}
-      else
-	{
-	  for ( i = 0; i < ngp*nlev; i++ )
-	    p->data[i] = pow(p1->data[i], p2->u.con.value);
-	}
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = POW(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] = pow(idat[i], cval);
+      break;
+    case '<':
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLT(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLT(idat[i], cval);
+      break;
+    case '>':
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPGT(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPGT(idat[i], cval);
+      break;
+    case LE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLE(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLE(idat[i], cval);
+      break;
+    case GE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPGE(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPGE(idat[i], cval);
+      break;
+    case NE:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPNE(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPNE(idat[i], cval);
+      break;
+    case EQ:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPEQ(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPEQ(idat[i], cval);
+      break;
+    case LEG:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPLEG(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPLEG(idat[i], cval);
+      break;
+    case AND:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPAND(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPAND(idat[i], cval);
+      break;
+    case OR:
+      if ( nmiss ) for ( i=0; i<n; ++i ) odat[i] = MVCOMPOR(idat[i], cval);
+      else         for ( i=0; i<n; ++i ) odat[i] =   COMPOR(idat[i], cval);
       break;
     default:
       cdoAbort("%s: operator %c unsupported!", __func__, oper);
@@ -288,7 +298,7 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
     }
 
   nmiss = 0;
-  for ( i = 0; i < ngp*nlev; i++ )
+  for ( i = 0; i < n; i++ )
     if ( DBL_IS_EQUAL(p->data[i], missval1) ) nmiss++;
 
   p->nmiss = nmiss;
@@ -301,30 +311,27 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
 static
 nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 {
-  nodeType *p;
-  long ngp, ngp1, ngp2, i;
-  long nlev, nlev1, nlev2, k;
+  long i;
+  long nlev, k;
   long loff, loff1, loff2;
-  int nmiss, nmiss1, nmiss2;
-  double missval1, missval2;
+  int nmiss;
 
-  nmiss1   = p1->nmiss;
-  nmiss2   = p2->nmiss;
-  missval1 = p1->missval;
-  missval2 = p2->missval;
+  int nmiss1 = p1->nmiss;
+  int nmiss2 = p2->nmiss;
+  double missval1 = p1->missval;
+  double missval2 = p2->missval;
 
-  ngp1 = gridInqSize(p1->gridID);
-  ngp2 = gridInqSize(p2->gridID);
+  long ngp1 = gridInqSize(p1->gridID);
+  long ngp2 = gridInqSize(p2->gridID);
 
-  if ( ngp1 != ngp2 )
-    cdoAbort("Number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
+  if ( ngp1 != ngp2 ) cdoAbort("Number of grid points differ. ngp1 = %ld, ngp2 = %ld", ngp1, ngp2);
 
-  ngp = ngp1;
+  long ngp = ngp1;
 
-  nlev1 = zaxisInqSize(p1->zaxisID);
-  nlev2 = zaxisInqSize(p2->zaxisID);
+  long nlev1 = zaxisInqSize(p1->zaxisID);
+  long nlev2 = zaxisInqSize(p2->zaxisID);
 
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -366,75 +373,78 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
       if ( nlev2 == 1 ) loff2 = 0;
       else              loff2 = k*ngp;
 
+      const double *restrict idat1 = p1->data+loff1;
+      const double *restrict idat2 = p2->data+loff2;
+      double *restrict odat = p->data+loff;
+      int nmiss = nmiss1 > 0 || nmiss2 > 0;
+
       switch ( oper )
 	{
 	case '+':
-	  if ( nmiss1 > 0 || nmiss2 > 0 )
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = ADD(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
-	  else
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = p1->data[i+loff1] + p2->data[i+loff2];
-	    }
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = ADD(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] = idat1[i] + idat2[i];
 	  break;
 	case '-':
-	  if ( nmiss1 > 0 || nmiss2 > 0 )
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = SUB(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
-	  else
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = p1->data[i+loff1] - p2->data[i+loff2];
-	    }
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = SUB(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] = idat1[i] - idat2[i];
 	  break;
 	case '*':
-	  if ( nmiss1 > 0 || nmiss2 > 0 )
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = MUL(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
-	  else
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = p1->data[i+loff1] * p2->data[i+loff2];
-	    }
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MUL(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] = idat1[i] * idat2[i];
 	  break;
 	case '/':
-	  if ( nmiss1 > 0 || nmiss2 > 0 )
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = DIV(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = DIV(idat1[i], idat2[i]);
 	  else
 	    {
-	      for ( i = 0; i < ngp; i++ )
+	      for ( i = 0; i < ngp; ++i )
 		{
-		  if ( IS_EQUAL(p2->data[i+loff2], 0.) )
-		    p->data[i+loff] = missval1;
-		  else
-		    p->data[i+loff] = p1->data[i+loff1] / p2->data[i+loff2];
+		  if ( IS_EQUAL(idat2[i], 0.) ) odat[i] = missval1;
+		  else                          odat[i] = idat1[i] / idat2[i];
 		}
 	    }
 	  break;
 	case '^':
-	  if ( nmiss1 > 0 || nmiss2 > 0 )
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = POW(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
-	  else
-	    {
-	      for ( i = 0; i < ngp; i++ )
-		p->data[i+loff] = pow(p1->data[i+loff1], p2->data[i+loff2]);
-	    }
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = POW(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] = pow(idat1[i], idat2[i]);
+	  break;
+	case '<':
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPLT(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPLT(idat1[i], idat2[i]);
+	  break;
+	case '>':
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPGT(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPGT(idat1[i], idat2[i]);
+	  break;
+	case LE:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPLE(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPLE(idat1[i], idat2[i]);
+	  break;
+	case GE:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPGE(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPGE(idat1[i], idat2[i]);
+	  break;
+	case NE:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPNE(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPNE(idat1[i], idat2[i]);
+	  break;
+	case EQ:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPEQ(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPEQ(idat1[i], idat2[i]);
+	  break;
+	case LEG:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPLEG(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPLEG(idat1[i], idat2[i]);
+	  break;
+	case AND:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPAND(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPAND(idat1[i], idat2[i]);
+	  break;
+	case OR:
+	  if ( nmiss ) for ( i=0; i<ngp; ++i ) odat[i] = MVCOMPOR(idat1[i], idat2[i]);
+	  else         for ( i=0; i<ngp; ++i ) odat[i] =   COMPOR(idat1[i], idat2[i]);
 	  break;
 	default:
-	  cdoAbort("%s: operator %c unsupported!", __func__, oper);
+	  cdoAbort("%s: operator %d (%c) unsupported!", __func__, (int)oper, oper);
           break;
 	}
     }
@@ -514,11 +524,10 @@ nodeType *expr(int oper, nodeType *p1, nodeType *p2)
 static
 nodeType *ex_fun_con(char *fun, nodeType *p1)
 {
-  nodeType *p;
   int i;
   int funcID = -1;
 
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
@@ -541,23 +550,17 @@ nodeType *ex_fun_con(char *fun, nodeType *p1)
 static
 nodeType *ex_fun_var(char *fun, nodeType *p1)
 {
-  nodeType *p;
-  long ngp, i;
-  long nlev;
-  int gridID, zaxisID;
+  long i;
   int funcID = -1;
-  int nmiss;
-  double missval;
-
-  gridID  = p1->gridID;
-  zaxisID = p1->zaxisID;
-  nmiss   = p1->nmiss;
-  missval = p1->missval;
+  int gridID  = p1->gridID;
+  int zaxisID = p1->zaxisID;
+  int nmiss   = p1->nmiss;
+  double missval = p1->missval;
 
-  ngp  = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
+  long ngp  = gridInqSize(gridID);
+  long nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -634,22 +637,15 @@ nodeType *ex_fun(char *fun, nodeType *p1)
 static
 nodeType *ex_uminus_var(nodeType *p1)
 {
-  nodeType *p;
-  long ngp, i;
-  long nlev;
-  int nmiss;
-  int gridID, zaxisID;
-  double missval;
-
-  gridID   = p1->gridID;
-  zaxisID  = p1->zaxisID;
-  nmiss    = p1->nmiss;
-  missval  = p1->missval;
+  int gridID  = p1->gridID;
+  int zaxisID = p1->zaxisID;
+  int nmiss   = p1->nmiss;
+  double missval = p1->missval;
 
-  ngp  = gridInqSize(gridID);
-  nlev = zaxisInqSize(zaxisID);
+  long ngp  = gridInqSize(gridID);
+  long nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -662,12 +658,12 @@ nodeType *ex_uminus_var(nodeType *p1)
 
   if ( nmiss > 0 )
     {
-      for ( i = 0; i < ngp*nlev; i++ )
+      for ( long i = 0; i < ngp*nlev; i++ )
 	p->data[i] = DBL_IS_EQUAL(p1->data[i], missval) ? missval : -(p1->data[i]);
     }
   else
     {
-      for ( i = 0; i < ngp*nlev; i++ )
+      for ( long i = 0; i < ngp*nlev; i++ )
 	p->data[i] = -(p1->data[i]);
     }
 
@@ -679,9 +675,7 @@ nodeType *ex_uminus_var(nodeType *p1)
 static
 nodeType *ex_uminus_con(nodeType *p1)
 {
-  nodeType *p;
-
-  p = (nodeType*) malloc(sizeof(nodeType));
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
@@ -711,11 +705,135 @@ nodeType *ex_uminus(nodeType *p1)
   return (p);
 }
 
+static
+nodeType *ex_ifelse(nodeType *p1, nodeType *p2, nodeType *p3)
+{
+  if ( cdoVerbose ) printf("\t %s ? %s : %s\n", p1->u.var.nm, p2->u.var.nm, p3->u.var.nm);
+
+  if ( p1->type == typeCon ) cdoAbort("expr?expr:expr: First expression is a constant but must be a variable!");
+
+  int nmiss1 = p1->nmiss;
+  long ngp1 = gridInqSize(p1->gridID);
+  long nlev1 = zaxisInqSize(p1->zaxisID);
+  double missval1 = p1->missval;
+  double *pdata1 = p1->data;
+
+  long ngp = ngp1;
+  long nlev = nlev1;
+  nodeType *px = p1;
+
+  double missval2 = missval1;
+  double *pdata2;
+  long ngp2 = 1;
+  long nlev2 = 1;
+  
+  if ( p2->type == typeCon )
+    {
+      pdata2 = &p2->u.con.value;
+    }
+  else
+    {
+      ngp2 = gridInqSize(p2->gridID);
+      nlev2 = zaxisInqSize(p2->zaxisID);
+      missval2 = p2->missval;
+      pdata2 = p2->data;
+      if ( ngp2 > 1 && ngp2 != ngp1 )
+	cdoAbort("expr?expr:expr: Number of grid points differ. ngp1 = %ld, ngp2 = %ld", ngp1, ngp2);
+      if ( nlev2 > 1 && nlev2 != nlev )
+	{
+	  if ( nlev == 1 )
+	    {
+	      nlev = nlev2;
+	      px = p2;
+	    }
+	  else
+	    cdoAbort("expr?expr:expr: Number of levels differ. nlev = %ld, nlev2 = %ld", nlev, nlev2);
+	}
+    }
+
+  double missval3 = missval1;
+  double *pdata3;
+  long ngp3 = 1;
+  long nlev3 = 1;
+  
+  if ( p3->type == typeCon )
+    {
+      pdata3 = &p3->u.con.value;
+    }
+  else
+    {
+      ngp3 = gridInqSize(p3->gridID);
+      nlev3 = zaxisInqSize(p3->zaxisID);
+      missval3 = p3->missval;
+      pdata3 = p3->data;
+      if ( ngp3 > 1 && ngp3 != ngp1 )
+	cdoAbort("expr?expr:expr: Number of grid points differ. ngp1 = %ld, ngp3 = %ld", ngp1, ngp3);
+      if ( nlev3 > 1 && nlev3 != nlev )
+	{
+	  if ( nlev == 1 )
+	    {
+	      nlev = nlev3;
+	      px = p3;
+	    }
+	  else
+	    cdoAbort("expr?expr:expr: Number of levels differ. nlev = %ld, nlev3 = %ld", nlev, nlev3);
+	}
+    }
+
+  nodeType *p = (nodeType*) malloc(sizeof(nodeType));
+
+  p->type     = typeVar;
+  p->tmpvar   = 1;
+  p->u.var.nm = strdupx("tmp");
+
+  p->gridID  = px->gridID;
+  p->zaxisID = px->zaxisID;
+  p->missval = px->missval;
+
+  p->data = (double*) malloc(ngp*nlev*sizeof(double));
+
+  long loff, loff1, loff2, loff3;
+
+  for ( long k = 0; k < nlev; ++k )
+    {
+      loff = k*ngp;
+
+      if ( nlev1 == 1 ) loff1 = 0;
+      else              loff1 = k*ngp;
+
+      if ( nlev2 == 1 ) loff2 = 0;
+      else              loff2 = k*ngp;
+
+      if ( nlev3 == 1 ) loff3 = 0;
+      else              loff3 = k*ngp;
+
+      const double *restrict idat1 = pdata1+loff1;
+      const double *restrict idat2 = pdata2+loff2;
+      const double *restrict idat3 = pdata3+loff3;
+      double *restrict odat = p->data+loff;
+
+      double ival2 = idat2[0];
+      double ival3 = idat3[0];
+      for ( long i = 0; i < ngp; ++i ) 
+	{
+	  if ( ngp2 > 1 ) ival2 = idat2[i];
+	  if ( ngp3 > 1 ) ival3 = idat3[i];
+
+	  if ( nmiss1 && DBL_IS_EQUAL(idat1[i], missval1) )
+	    odat[i] = missval1;
+	  else if ( IS_NOT_EQUAL(idat1[i], 0) )
+	    odat[i] = DBL_IS_EQUAL(ival2, missval2) ? missval1 : ival2;
+	  else
+	    odat[i] = DBL_IS_EQUAL(ival3, missval3) ? missval1 : ival3;
+	}
+    }
+
+  return (p);
+}
+
 
 int exNode(nodeType *p, parse_parm_t *parse_arg)
 {
-  int k;              /* child number */
-
   if ( ! p ) return(0);
 
   /* node is leaf */
@@ -725,7 +843,7 @@ int exNode(nodeType *p, parse_parm_t *parse_arg)
     }
 
   /* node has children */
-  for ( k = 0; k < p->u.opr.nops; k++ )
+  for ( int k = 0; k < p->u.opr.nops; k++ )
     {
       exNode(p->u.opr.op[k], parse_arg);
     }
@@ -881,13 +999,13 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 		printf("\tpop var\t%s\t%s\n", p->u.opr.op[0]->u.var.nm, rnode->u.var.nm);
 
 	      nvars = vlistNvars(parse_arg->vlistID2);
-	      for ( varID = 0; varID < nvars; varID++ )
+	      for ( varID = nvars-1; varID >= 0; varID-- )
 		{
 		  vlistInqVarName(parse_arg->vlistID2, varID, varname);
 		  if ( strcmp(varname, p->u.opr.op[0]->u.var.nm) == 0 ) break;
 		}
 
-	      if ( varID == nvars )
+	      if ( varID < 0 )
 		{
 		  cdoAbort("Variable >%s< not found!", p->u.opr.op[0]->u.var.nm);
 		}
@@ -895,7 +1013,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 		{
 		  parse_arg->gridID2  = vlistInqVarGrid(parse_arg->vlistID2, varID);
 		  parse_arg->zaxisID2 = vlistInqVarZaxis(parse_arg->vlistID2, varID);
-		  parse_arg->tsteptype2  = vlistInqVarTsteptype(parse_arg->vlistID2, varID);
+		  parse_arg->tsteptype2 = vlistInqVarTsteptype(parse_arg->vlistID2, varID);
 		  missval  = vlistInqVarMissval(parse_arg->vlistID2, varID);
 	      
 		  p->gridID  = parse_arg->gridID2;
@@ -925,6 +1043,24 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	    }
 
 	  break;
+        case '?':    
+	  if ( parse_arg->init )
+	    {
+	      expr_run(p->u.opr.op[0], parse_arg);
+	      expr_run(p->u.opr.op[1], parse_arg);
+	      expr_run(p->u.opr.op[2], parse_arg);
+
+	      if ( parse_arg->debug )
+		printf("\t?:\n");
+	    }
+	  else
+	    {
+	      rnode = ex_ifelse(expr_run(p->u.opr.op[0], parse_arg),
+			        expr_run(p->u.opr.op[1], parse_arg),
+			        expr_run(p->u.opr.op[2], parse_arg));
+	    }
+
+	  break;
         default:
 	  if ( parse_arg->init )
 	    {
@@ -939,10 +1075,13 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 		  case '/':  printf("\tdiv\n"); break;
 		  case '<':  printf("\tcompLT\n"); break;
 		  case '>':  printf("\tcompGT\n"); break;
-		  case GE:   printf("\tcompGE\n"); break;
 		  case LE:   printf("\tcompLE\n"); break;
+		  case GE:   printf("\tcompGE\n"); break;
 		  case NE:   printf("\tcompNE\n"); break;
 		  case EQ:   printf("\tcompEQ\n"); break;
+		  case LEG:  printf("\tcompLEG\n"); break;
+		  case AND:  printf("\tcompAND\n"); break;
+		  case OR:   printf("\tcompOR\n"); break;
 		  }
 	    }
 	  else
diff --git a/src/expr_lex.c b/src/expr_lex.c
index f01d3f3..e931959 100644
--- a/src/expr_lex.c
+++ b/src/expr_lex.c
@@ -350,8 +350,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 14
-#define YY_END_OF_BUFFER 15
+#define YY_NUM_RULES 17
+#define YY_END_OF_BUFFER 18
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -359,26 +359,27 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_acclist[84] =
+static yyconst flex_int16_t yy_acclist[91] =
     {   0,
-        4,    4,   15,   13,   14,   12,   13,   14,   12,   14,
-       13,   14,    1,   13,   14,    7,   13,   14,    4,    7,
-       13,   14,    4,   13,   14,    7,   13,   14,    7,   13,
-       14,    7,   13,   14,    6,   13,   14,16389,    4,    6,
-       13,   14,16389,    6,   13,   14,16389,    6,   13,   14,
-    16389,   12,   11,    1,    4,    4,    4,    4,    9,   10,
-        8, 8197,    6,16389,    4,    6,16389,    6,16389,    4,
-        4,    4,    6,16389,    3,    6,16389,    6,16389,    4,
-        2,    6,16389
+        4,    4,   18,   16,   17,   15,   16,   17,   15,   17,
+       16,   17,    1,   16,   17,   16,   17,    7,   16,   17,
+        4,    7,   16,   17,    4,   16,   17,    7,   16,   17,
+        7,   16,   17,    7,   16,   17,    6,   16,   17,16389,
+        4,    6,   16,   17,16389,    6,   16,   17,16389,    6,
+       16,   17,16389,   16,   17,   15,   12,    1,   13,    4,
+        4,    4,    4,   10,   11,    9, 8197,    6,16389,    4,
+        6,16389,    6,16389,   14,    4,    4,    8,    4,    6,
+    16389,    3,    6,16389,    6,16389,    4,    2,    6,16389
     } ;
 
-static yyconst flex_int16_t yy_accept[47] =
+static yyconst flex_int16_t yy_accept[52] =
     {   0,
-        1,    2,    3,    4,    6,    9,   11,   13,   16,   19,
-       23,   26,   29,   32,   35,   39,   44,   48,   52,   53,
-       54,   55,   56,   57,   57,   58,   59,   59,   60,   61,
-       62,   62,   63,   65,   65,   68,   70,   70,   71,   72,
-       75,   78,   80,   81,   84,   84
+        1,    2,    3,    4,    6,    9,   11,   13,   16,   18,
+       21,   25,   28,   31,   34,   37,   41,   46,   50,   54,
+       56,   57,   58,   59,   60,   61,   62,   62,   63,   64,
+       64,   65,   66,   67,   67,   68,   70,   70,   73,   75,
+       76,   76,   77,   78,   79,   82,   85,   87,   88,   91,
+       91
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -386,17 +387,17 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    4,    5,    1,    6,    1,    1,    1,    1,    7,
-        8,    8,    9,    1,    9,   10,    8,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,    1,    8,   12,
-       13,   14,    1,    1,   15,   15,   15,   16,   17,   15,
-       15,   15,   18,   15,   15,   16,   19,   15,   15,   20,
-       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
-        1,    1,    1,    8,   21,    1,   15,   15,   15,   16,
-
-       22,   15,   15,   15,   15,   15,   15,   16,   15,   15,
-       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
-       15,   15,    8,    1,    8,    1,    1,    1,    1,    1,
+        1,    4,    5,    1,    6,    1,    1,    7,    1,    8,
+        9,    9,   10,    1,   10,   11,    9,   12,   12,   12,
+       12,   12,   12,   12,   12,   12,   12,    9,    9,   13,
+       14,   15,    9,    1,   16,   16,   16,   17,   18,   16,
+       16,   16,   19,   16,   16,   17,   20,   16,   16,   21,
+       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,
+        1,    1,    1,    9,   22,    1,   16,   16,   16,   17,
+
+       23,   16,   16,   16,   16,   16,   16,   17,   16,   16,
+       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,
+       16,   16,    9,   24,    9,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -413,61 +414,65 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[23] =
+static yyconst flex_int32_t yy_meta[25] =
     {   0,
-        1,    1,    2,    3,    1,    1,    3,    1,    1,    1,
-        3,    1,    1,    1,    3,    3,    3,    3,    3,    3,
-        3,    3
+        1,    1,    2,    3,    1,    1,    1,    3,    1,    1,
+        1,    3,    1,    1,    1,    3,    3,    3,    3,    3,
+        3,    3,    3,    1
     } ;
 
-static yyconst flex_int16_t yy_base[48] =
+static yyconst flex_int16_t yy_base[53] =
     {   0,
-        0,    0,   82,   83,   21,   24,   68,    0,   83,   18,
-       31,   67,   66,   65,   26,   32,   50,   39,   47,   83,
-        0,    0,   83,   47,    0,    0,   53,   83,   83,   83,
-       48,   83,   56,   65,   22,   46,   64,   21,   54,   52,
-       48,   50,   83,   24,   83,   71,   41
+        0,    0,   87,   88,   23,   26,   72,    0,   78,   88,
+       19,   32,   70,   69,   68,   30,   31,   52,   37,   57,
+       44,   88,    0,   88,    0,   88,   41,    0,    0,   42,
+       65,   88,   88,   53,   88,   57,   66,   23,   45,   88,
+       65,   53,   56,   88,   53,   49,   50,   88,   36,   88,
+       73,   29
     } ;
 
-static yyconst flex_int16_t yy_def[48] =
+static yyconst flex_int16_t yy_def[53] =
     {   0,
-       45,    1,   45,   45,   45,   45,   45,   46,   45,   45,
-       45,   45,   45,   45,   47,   47,   47,   47,   45,   45,
-       46,   10,   45,   45,   10,   11,   45,   45,   45,   45,
-       45,   45,   18,   45,   17,   18,   45,   45,   45,   18,
-       18,   18,   45,   18,    0,   45,   45
+       50,    1,   50,   50,   50,   50,   50,   51,   50,   50,
+       50,   50,   50,   50,   50,   52,   52,   52,   52,   50,
+       50,   50,   51,   50,   11,   50,   50,   11,   12,   50,
+       50,   50,   50,   50,   50,   19,   50,   18,   19,   50,
+       50,   50,   50,   50,   19,   19,   19,   50,   19,    0,
+       50,   50
     } ;
 
-static yyconst flex_int16_t yy_nxt[106] =
+static yyconst flex_int16_t yy_nxt[113] =
     {   0,
-        4,    5,    6,    5,    7,    8,    9,    9,    9,   10,
-       11,   12,   13,   14,   15,   16,   17,   15,   18,   15,
-       15,   17,   19,   19,   19,   19,   19,   19,   22,   31,
-       45,   38,   32,   23,   24,   31,   23,   40,   32,   24,
-       25,   26,   31,   33,   33,   32,   23,   27,   19,   19,
-       19,   31,   27,   31,   32,   37,   32,   38,   34,   36,
-       35,   34,   41,   39,   39,   42,   33,   44,   33,   43,
-       33,   21,   33,   21,   38,   39,   33,   30,   29,   28,
-       20,   45,    3,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-
-       45,   45,   45,   45,   45
+        4,    5,    6,    5,    7,    8,    9,   10,   10,   10,
+       11,   12,   13,   14,   15,   16,   17,   18,   16,   19,
+       16,   16,   18,   20,   21,   21,   21,   21,   21,   21,
+       25,   36,   50,   34,   34,   26,   27,   35,   35,   45,
+       34,   27,   28,   29,   35,   21,   21,   21,   26,   30,
+       41,   37,   42,   43,   30,   34,   34,   36,   39,   35,
+       35,   37,   46,   38,   42,   47,   36,   43,   49,   26,
+       36,   36,   48,   23,   36,   23,   42,   43,   36,   44,
+       40,   33,   32,   31,   24,   22,   50,    3,   50,   50,
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
+
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
+       50,   50
     } ;
 
-static yyconst flex_int16_t yy_chk[106] =
+static yyconst flex_int16_t yy_chk[113] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    5,    5,    5,    6,    6,    6,   10,   15,
-       35,   38,   15,   10,   10,   16,   38,   35,   16,   10,
-       11,   11,   18,   47,   44,   18,   11,   11,   19,   19,
-       19,   31,   11,   17,   31,   24,   17,   24,   17,   18,
-       17,   27,   36,   27,   39,   36,   36,   42,   41,   39,
-       42,   46,   40,   46,   37,   34,   33,   14,   13,   12,
-        7,    3,   45,   45,   45,   45,   45,   45,   45,   45,
-       45,   45,   45,   45,   45,   45,   45,   45,   45,   45,
-
-       45,   45,   45,   45,   45
+        1,    1,    1,    1,    5,    5,    5,    6,    6,    6,
+       11,   52,   38,   16,   17,   11,   11,   16,   17,   38,
+       19,   11,   12,   12,   19,   21,   21,   21,   12,   12,
+       27,   30,   27,   30,   12,   18,   34,   49,   19,   18,
+       34,   18,   39,   18,   42,   39,   39,   43,   47,   42,
+       46,   47,   43,   51,   45,   51,   41,   37,   36,   31,
+       20,   15,   14,   13,    9,    7,    3,   50,   50,   50,
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
+
+       50,   50,   50,   50,   50,   50,   50,   50,   50,   50,
+       50,   50
     } ;
 
 #define YY_TRAILING_MASK 0x2000
@@ -487,7 +492,8 @@ goto find_rule; \
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 #line 1 "expr_lex.l"
-#line 2 "expr_lex.l"
+/* flex -oexpr_lex.c expr_lex.l */
+#line 3 "expr_lex.l"
 #include <string.h>
 #include <stdlib.h>
 #include <math.h>
@@ -510,7 +516,7 @@ goto find_rule; \
    LPH [A-Za-z_] Alphabetic character
    LPHDGT [A-Za-z0-9_] Alphanumeric character
    XPN [eE][+-]?[0-9]+ Real number Exponent */
-#line 514 "expr_lex.c"
+#line 520 "expr_lex.c"
 
 #define INITIAL 0
 
@@ -756,10 +762,10 @@ YY_DECL
 	register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 35 "expr_lex.l"
+#line 36 "expr_lex.l"
 
 
-#line 763 "expr_lex.c"
+#line 769 "expr_lex.c"
 
     yylval = yylval_param;
 
@@ -819,14 +825,14 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 46 )
+				if ( yy_current_state >= 51 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			*yyg->yy_state_ptr++ = yy_current_state;
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 83 );
+		while ( yy_base[yy_current_state] != 88 );
 
 yy_find_action:
 		yy_current_state = *--yyg->yy_state_ptr;
@@ -875,12 +881,12 @@ do_action:	/* This label is used only to access EOF actions. */
 	{ /* beginning of action switch */
 case 1:
 YY_RULE_SETUP
-#line 37 "expr_lex.l"
+#line 38 "expr_lex.l"
 ; /* ignore comments */
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 39 "expr_lex.l"
+#line 40 "expr_lex.l"
 {
                 yylval->cvalue = M_PI;
                 return CONSTANT;
@@ -888,7 +894,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 44 "expr_lex.l"
+#line 45 "expr_lex.l"
 {
                 yylval->cvalue = M_E;
                 return CONSTANT;
@@ -896,7 +902,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 49 "expr_lex.l"
+#line 50 "expr_lex.l"
 {
                /* constant */
                /* NB: Tempted to prepend lexer expressions for floats and doubles with [+-]? 
@@ -908,7 +914,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 59 "expr_lex.l"
+#line 60 "expr_lex.l"
 {
                 yylval->fname = (char *) strdupx(yytext);
                 return FUNCTION;
@@ -916,7 +922,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 65 "expr_lex.l"
+#line 66 "expr_lex.l"
 {
                 yylval->varnm = (char *) strdupx(yytext);
                 return VARIABLE;
@@ -924,48 +930,63 @@ YY_RULE_SETUP
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 71 "expr_lex.l"
+#line 72 "expr_lex.l"
 {
                 return *yytext;
              }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 75 "expr_lex.l"
-return GE;
+#line 76 "expr_lex.l"
+return LEG;
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 76 "expr_lex.l"
-return LE;
+#line 77 "expr_lex.l"
+return GE;
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 77 "expr_lex.l"
-return EQ;
+#line 78 "expr_lex.l"
+return LE;
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 78 "expr_lex.l"
-return NE;
+#line 79 "expr_lex.l"
+return EQ;
 	YY_BREAK
 case 12:
-/* rule 12 can match eol */
 YY_RULE_SETUP
 #line 80 "expr_lex.l"
-;       /* ignore whitespace */
+return NE;
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
+#line 81 "expr_lex.l"
+return AND;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
 #line 82 "expr_lex.l"
+return OR;
+	YY_BREAK
+case 15:
+/* rule 15 can match eol */
+YY_RULE_SETUP
+#line 84 "expr_lex.l"
+;       /* ignore whitespace */
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 86 "expr_lex.l"
 yyerror(NULL, NULL, "Unknown character");
 	YY_BREAK
-case 14:
+case 17:
 YY_RULE_SETUP
-#line 83 "expr_lex.l"
+#line 87 "expr_lex.l"
 ECHO;
 	YY_BREAK
-#line 969 "expr_lex.c"
+#line 990 "expr_lex.c"
 			case YY_STATE_EOF(INITIAL):
 				yyterminate();
 
@@ -1228,7 +1249,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 46 )
+			if ( yy_current_state >= 51 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1252,11 +1273,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 46 )
+		if ( yy_current_state >= 51 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 45);
+	yy_is_jam = (yy_current_state == 50);
 	if ( ! yy_is_jam )
 		*yyg->yy_state_ptr++ = yy_current_state;
 
@@ -2043,7 +2064,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 
 void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
 {
-	return malloc( size );
+	return (void *) malloc( size );
 }
 
 void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
@@ -2055,7 +2076,7 @@ void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 */
-	return realloc( (char *) ptr, size );
+	return (void *) realloc( (char *) ptr, size );
 }
 
 void yyfree (void * ptr , yyscan_t yyscanner)
@@ -2065,7 +2086,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 83 "expr_lex.l"
+#line 87 "expr_lex.l"
 
 
 
diff --git a/src/expr_yacc.c b/src/expr_yacc.c
index b0c3c44..a26dbcd 100644
--- a/src/expr_yacc.c
+++ b/src/expr_yacc.c
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.7.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
 /* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.7"
+#define YYBISON_VERSION "2.7.12-4996"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -63,7 +63,7 @@
 
 /* Copy the first part of user declarations.  */
 /* Line 371 of yacc.c  */
-#line 1 "expr_yacc.y"
+#line 2 "expr_yacc.y"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -133,7 +133,10 @@ extern int yydebug;
      EQ = 262,
      LE = 263,
      GE = 264,
-     UMINUS = 265
+     LEG = 265,
+     OR = 266,
+     AND = 267,
+     UMINUS = 268
    };
 #endif
 /* Tokens.  */
@@ -144,7 +147,10 @@ extern int yydebug;
 #define EQ 262
 #define LE 263
 #define GE 264
-#define UMINUS 265
+#define LEG 265
+#define OR 266
+#define AND 267
+#define UMINUS 268
 
 
 
@@ -174,7 +180,7 @@ int yyparse ();
 /* Copy the second part of user declarations.  */
 
 /* Line 390 of yacc.c  */
-#line 178 "expr_yacc.c"
+#line 184 "expr_yacc.c"
 
 #ifdef short
 # undef short
@@ -235,6 +241,14 @@ typedef short int yytype_int16;
 # endif
 #endif
 
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+#  define __attribute__(Spec) /* empty */
+# endif
+#endif
+
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -242,6 +256,7 @@ typedef short int yytype_int16;
 # define YYUSE(E) /* empty */
 #endif
 
+
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
 # define YYID(N) (N)
@@ -394,20 +409,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   123
+#define YYLAST   182
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  24
+#define YYNTOKENS  29
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  6
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  27
+#define YYNRULES  31
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  51
+#define YYNSTATES  61
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   265
+#define YYMAXUTOK   268
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -419,15 +434,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      22,    23,    15,    13,     2,    14,     2,    16,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    19,
-       7,     8,     6,     2,     2,     2,     2,     2,     2,     2,
+      27,    28,    15,    13,     2,    14,     2,    16,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    21,    24,
+       7,    19,     6,    20,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    17,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,    22,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    20,     2,    21,     2,     2,     2,     2,
+       2,     2,     2,    25,     2,    26,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -441,7 +456,7 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     9,    10,    11,    12,    18
+       5,     8,     9,    10,    11,    12,    17,    18,    23
 };
 
 #if YYDEBUG
@@ -451,30 +466,33 @@ static const yytype_uint8 yyprhs[] =
 {
        0,     0,     3,     5,     8,     9,    11,    14,    19,    22,
       26,    28,    31,    33,    35,    38,    42,    46,    50,    54,
-      58,    62,    66,    70,    74,    78,    82,    86
+      58,    62,    66,    70,    74,    78,    82,    86,    90,    94,
+     100,   104
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      25,     0,    -1,    26,    -1,    26,    27,    -1,    -1,    19,
-      -1,    29,    19,    -1,     4,     8,    29,    19,    -1,     4,
-      19,    -1,    20,    28,    21,    -1,    27,    -1,    28,    27,
-      -1,     3,    -1,     4,    -1,    14,    29,    -1,    29,    13,
-      29,    -1,    29,    14,    29,    -1,    29,    15,    29,    -1,
-      29,    16,    29,    -1,    29,     7,    29,    -1,    29,     6,
-      29,    -1,    29,    17,    29,    -1,    29,    12,    29,    -1,
-      29,    11,    29,    -1,    29,     9,    29,    -1,    29,    10,
-      29,    -1,    22,    29,    23,    -1,     5,    22,    29,    23,
-      -1
+      30,     0,    -1,    31,    -1,    31,    32,    -1,    -1,    24,
+      -1,    34,    24,    -1,     4,    19,    34,    24,    -1,     4,
+      24,    -1,    25,    33,    26,    -1,    32,    -1,    33,    32,
+      -1,     3,    -1,     4,    -1,    14,    34,    -1,    34,    13,
+      34,    -1,    34,    14,    34,    -1,    34,    15,    34,    -1,
+      34,    16,    34,    -1,    34,     7,    34,    -1,    34,     6,
+      34,    -1,    34,    22,    34,    -1,    34,    11,    34,    -1,
+      34,    10,    34,    -1,    34,     8,    34,    -1,    34,     9,
+      34,    -1,    34,    12,    34,    -1,    34,    18,    34,    -1,
+      34,    17,    34,    -1,    34,    20,    34,    21,    34,    -1,
+      27,    34,    28,    -1,     5,    27,    34,    28,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    49,    49,    53,    54,    58,    59,    60,    61,    62,
-      66,    67,    71,    72,    73,    74,    75,    76,    77,    78,
-      79,    80,    81,    82,    83,    84,    85,    86
+       0,    53,    53,    57,    58,    62,    63,    64,    65,    66,
+      70,    71,    75,    76,    77,    78,    79,    80,    81,    82,
+      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
+      93,    94
 };
 #endif
 
@@ -484,9 +502,10 @@ static const yytype_uint8 yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "CONSTANT", "VARIABLE", "FUNCTION",
-  "'>'", "'<'", "'='", "NE", "EQ", "LE", "GE", "'+'", "'-'", "'*'", "'/'",
-  "'^'", "UMINUS", "';'", "'{'", "'}'", "'('", "')'", "$accept", "program",
-  "function", "stmt", "stmt_list", "expr", YY_NULL
+  "'>'", "'<'", "NE", "EQ", "LE", "GE", "LEG", "'+'", "'-'", "'*'", "'/'",
+  "OR", "AND", "'='", "'?'", "':'", "'^'", "UMINUS", "';'", "'{'", "'}'",
+  "'('", "')'", "$accept", "program", "function", "stmt", "stmt_list",
+  "expr", YY_NULL
 };
 #endif
 
@@ -495,18 +514,19 @@ static const char *const yytname[] =
    token YYLEX-NUM.  */
 static const yytype_uint16 yytoknum[] =
 {
-       0,   256,   257,   258,   259,   260,    62,    60,    61,   261,
-     262,   263,   264,    43,    45,    42,    47,    94,   265,    59,
-     123,   125,    40,    41
+       0,   256,   257,   258,   259,   260,    62,    60,   261,   262,
+     263,   264,   265,    43,    45,    42,    47,   266,   267,    61,
+      63,    58,    94,   268,    59,   123,   125,    40,    41
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    24,    25,    26,    26,    27,    27,    27,    27,    27,
-      28,    28,    29,    29,    29,    29,    29,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29,    29
+       0,    29,    30,    31,    31,    32,    32,    32,    32,    32,
+      33,    33,    34,    34,    34,    34,    34,    34,    34,    34,
+      34,    34,    34,    34,    34,    34,    34,    34,    34,    34,
+      34,    34
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -514,7 +534,8 @@ static const yytype_uint8 yyr2[] =
 {
        0,     2,     1,     2,     0,     1,     2,     4,     2,     3,
        1,     2,     1,     1,     2,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     4
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     5,
+       3,     4
 };
 
 /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@@ -525,9 +546,10 @@ static const yytype_uint8 yydefact[] =
        4,     0,     2,     1,    12,    13,     0,     0,     5,     0,
        0,     3,     0,     0,     8,     0,    13,    14,    10,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     6,     0,     0,     9,    11,    26,    20,    19,
-      24,    25,    23,    22,    15,    16,    17,    18,    21,     7,
-      27
+       0,     0,     0,     0,     0,     0,     6,     0,     0,     9,
+      11,    30,    20,    19,    24,    25,    23,    22,    26,    15,
+      16,    17,    18,    28,    27,     0,    21,     7,    31,     0,
+      29
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
@@ -538,21 +560,22 @@ static const yytype_int8 yydefgoto[] =
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -18
-static const yytype_int8 yypact[] =
+#define YYPACT_NINF -15
+static const yytype_int16 yypact[] =
 {
-     -18,     4,    26,   -18,   -18,    -6,   -17,    46,   -18,    26,
-      46,   -18,    90,    46,   -18,    46,   -18,   -18,   -18,    22,
-      60,    46,    46,    46,    46,    46,    46,    46,    46,    46,
-      46,    46,   -18,   104,    75,   -18,   -18,   -18,    39,    39,
-      39,    39,    39,    39,    17,    17,   -10,   -10,   -10,   -18,
-     -18
+     -15,     2,    33,   -15,   -15,    11,   -14,    36,   -15,    33,
+      36,   -15,   104,    36,   -15,    36,   -15,   -15,   -15,    29,
+      58,    36,    36,    36,    36,    36,    36,    36,    36,    36,
+      36,    36,    36,    36,    36,    36,   -15,   123,    81,   -15,
+     -15,   -15,   152,   152,   152,   152,   152,   152,   152,   160,
+     160,   -13,   -13,   -10,   -10,   142,     7,   -15,   -15,    36,
+     -10
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -18,   -18,   -18,    -8,   -18,    -7
+     -15,   -15,   -15,    -8,   -15,    -7
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -561,54 +584,67 @@ static const yytype_int8 yypgoto[] =
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
-      17,    18,    13,    20,     3,    15,    33,    31,    34,     0,
-       0,    36,     0,    14,    38,    39,    40,    41,    42,    43,
-      44,    45,    46,    47,    48,     4,     5,     6,     0,     4,
-       5,     6,    29,    30,    31,     0,     7,     0,     0,     0,
-       7,     8,     9,    35,    10,     8,     9,     0,    10,     4,
-      16,     6,    27,    28,    29,    30,    31,     0,     0,     0,
-       7,     0,     0,     0,     0,     0,    21,    22,    10,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,     0,     0,
-       0,    21,    22,    37,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,     0,     0,     0,    21,    22,    50,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,     0,    32,
-      21,    22,     0,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,     0,    49
+      17,    18,     3,    20,    32,    33,    37,    34,    38,    35,
+      34,    40,    35,    15,    42,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    35,
+      13,     0,     4,     5,     6,    14,     4,     5,     6,     4,
+      16,     6,     0,     7,     0,     0,     0,     7,     0,     0,
+       7,     0,    60,     8,     9,    39,    10,     8,     9,     0,
+      10,     0,     0,    10,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,     0,    34,     0,
+      35,     0,     0,     0,     0,     0,    41,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+       0,    34,     0,    35,     0,     0,     0,     0,     0,    58,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,     0,    34,     0,    35,     0,    36,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,     0,    34,     0,    35,     0,    57,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,     0,    34,    59,    35,    28,    29,    30,    31,    32,
+      33,     0,    34,     0,    35,    30,    31,    32,    33,     0,
+      34,     0,    35
 };
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-18)))
+  (!!((Yystate) == (-15)))
 
 #define yytable_value_is_error(Yytable_value) \
   YYID (0)
 
 static const yytype_int8 yycheck[] =
 {
-       7,     9,     8,    10,     0,    22,    13,    17,    15,    -1,
-      -1,    19,    -1,    19,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,     3,     4,     5,    -1,     3,
-       4,     5,    15,    16,    17,    -1,    14,    -1,    -1,    -1,
-      14,    19,    20,    21,    22,    19,    20,    -1,    22,     3,
-       4,     5,    13,    14,    15,    16,    17,    -1,    -1,    -1,
-      14,    -1,    -1,    -1,    -1,    -1,     6,     7,    22,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    -1,    -1,
-      -1,     6,     7,    23,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    -1,    -1,    -1,     6,     7,    23,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    -1,    19,
-       6,     7,    -1,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    -1,    19
+       7,     9,     0,    10,    17,    18,    13,    20,    15,    22,
+      20,    19,    22,    27,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    22,
+      19,    -1,     3,     4,     5,    24,     3,     4,     5,     3,
+       4,     5,    -1,    14,    -1,    -1,    -1,    14,    -1,    -1,
+      14,    -1,    59,    24,    25,    26,    27,    24,    25,    -1,
+      27,    -1,    -1,    27,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    -1,    20,    -1,
+      22,    -1,    -1,    -1,    -1,    -1,    28,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      -1,    20,    -1,    22,    -1,    -1,    -1,    -1,    -1,    28,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    -1,    20,    -1,    22,    -1,    24,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    -1,    20,    -1,    22,    -1,    24,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    -1,    20,    21,    22,    13,    14,    15,    16,    17,
+      18,    -1,    20,    -1,    22,    15,    16,    17,    18,    -1,
+      20,    -1,    22
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    25,    26,     0,     3,     4,     5,    14,    19,    20,
-      22,    27,    29,     8,    19,    22,     4,    29,    27,    28,
-      29,     6,     7,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    19,    29,    29,    21,    27,    23,    29,    29,
-      29,    29,    29,    29,    29,    29,    29,    29,    29,    19,
-      23
+       0,    30,    31,     0,     3,     4,     5,    14,    24,    25,
+      27,    32,    34,    19,    24,    27,     4,    34,    32,    33,
+      34,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    20,    22,    24,    34,    34,    26,
+      32,    28,    34,    34,    34,    34,    34,    34,    34,    34,
+      34,    34,    34,    34,    34,    34,    34,    24,    28,    21,
+      34
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -730,11 +766,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, parse_arg, scanner)
 # else
   YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-        break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -1132,12 +1164,7 @@ yydestruct (yymsg, yytype, yyvaluep, parse_arg, scanner)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-        break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -1435,158 +1462,182 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-/* Line 1792 of yacc.c  */
-#line 49 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 53 "expr_yacc.y"
     { return(0); }
     break;
 
   case 3:
-/* Line 1792 of yacc.c  */
-#line 53 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 57 "expr_yacc.y"
     { expr_run((yyvsp[(2) - (2)].nPtr), (parse_parm_t *) parse_arg); freeNode((yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 5:
-/* Line 1792 of yacc.c  */
-#line 58 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 62 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr(';', 2, NULL, NULL); }
     break;
 
   case 6:
-/* Line 1792 of yacc.c  */
-#line 59 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 63 "expr_yacc.y"
     { (yyval.nPtr) = (yyvsp[(1) - (2)].nPtr); }
     break;
 
   case 7:
-/* Line 1792 of yacc.c  */
-#line 60 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 64 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[(1) - (4)].varnm)), (yyvsp[(3) - (4)].nPtr)); }
     break;
 
   case 8:
-/* Line 1792 of yacc.c  */
-#line 61 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 65 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[(1) - (2)].varnm)), expr_var((yyvsp[(1) - (2)].varnm))); }
     break;
 
   case 9:
-/* Line 1792 of yacc.c  */
-#line 62 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 66 "expr_yacc.y"
     { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
     break;
 
   case 10:
-/* Line 1792 of yacc.c  */
-#line 66 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 70 "expr_yacc.y"
     { (yyval.nPtr) = (yyvsp[(1) - (1)].nPtr); }
     break;
 
   case 11:
-/* Line 1792 of yacc.c  */
-#line 67 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 71 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr(';', 2, (yyvsp[(1) - (2)].nPtr), (yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 12:
-/* Line 1792 of yacc.c  */
-#line 71 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 75 "expr_yacc.y"
     { (yyval.nPtr) = expr_con((yyvsp[(1) - (1)].cvalue)); }
     break;
 
   case 13:
-/* Line 1792 of yacc.c  */
-#line 72 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 76 "expr_yacc.y"
     { (yyval.nPtr) = expr_var((yyvsp[(1) - (1)].varnm)); }
     break;
 
   case 14:
-/* Line 1792 of yacc.c  */
-#line 73 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 77 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr(UMINUS, 1, (yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 15:
-/* Line 1792 of yacc.c  */
-#line 74 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 78 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('+', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 16:
-/* Line 1792 of yacc.c  */
-#line 75 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 79 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('-', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 17:
-/* Line 1792 of yacc.c  */
-#line 76 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 80 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('*', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 18:
-/* Line 1792 of yacc.c  */
-#line 77 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 81 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('/', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 19:
-/* Line 1792 of yacc.c  */
-#line 78 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 82 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('<', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 20:
-/* Line 1792 of yacc.c  */
-#line 79 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 83 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('>', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 21:
-/* Line 1792 of yacc.c  */
-#line 80 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 84 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('^', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 22:
-/* Line 1792 of yacc.c  */
-#line 81 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(GE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+/* Line 1787 of yacc.c  */
+#line 85 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(GE,  2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 23:
-/* Line 1792 of yacc.c  */
-#line 82 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(LE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+/* Line 1787 of yacc.c  */
+#line 86 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(LE,  2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 24:
-/* Line 1792 of yacc.c  */
-#line 83 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(NE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+/* Line 1787 of yacc.c  */
+#line 87 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(NE,  2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 25:
-/* Line 1792 of yacc.c  */
-#line 84 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(EQ, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+/* Line 1787 of yacc.c  */
+#line 88 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(EQ,  2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 26:
-/* Line 1792 of yacc.c  */
-#line 85 "expr_yacc.y"
-    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
+/* Line 1787 of yacc.c  */
+#line 89 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(LEG, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 27:
-/* Line 1792 of yacc.c  */
-#line 86 "expr_yacc.y"
+/* Line 1787 of yacc.c  */
+#line 90 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(AND, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    break;
+
+  case 28:
+/* Line 1787 of yacc.c  */
+#line 91 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(OR,  2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    break;
+
+  case 29:
+/* Line 1787 of yacc.c  */
+#line 92 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr('?', 3, (yyvsp[(1) - (5)].nPtr), (yyvsp[(3) - (5)].nPtr), (yyvsp[(5) - (5)].nPtr)); }
+    break;
+
+  case 30:
+/* Line 1787 of yacc.c  */
+#line 93 "expr_yacc.y"
+    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
+    break;
+
+  case 31:
+/* Line 1787 of yacc.c  */
+#line 94 "expr_yacc.y"
     { (yyval.nPtr) = expr_fun((yyvsp[(1) - (4)].fname), (yyvsp[(3) - (4)].nPtr)); }
     break;
 
 
-/* Line 1792 of yacc.c  */
-#line 1590 "expr_yacc.c"
+/* Line 1787 of yacc.c  */
+#line 1641 "expr_yacc.c"
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1817,8 +1868,8 @@ yyreturn:
 }
 
 
-/* Line 2055 of yacc.c  */
-#line 89 "expr_yacc.y"
+/* Line 2050 of yacc.c  */
+#line 97 "expr_yacc.y"
 
 
 #define SIZEOF_NODETYPE ((char *)&p->u.con - (char *)p)
@@ -1914,9 +1965,9 @@ void freeNode(nodeType *p)
   free (p);
 }
 
-void yyerror(void *parse_arg, void *scanner, char *s)
+void yyerror(void *parse_arg, void *scanner, char *errstr)
 {
-  fprintf(stdout, "%s\n", s);
+  fprintf(stdout, "%s!\n", errstr);
 }
 /*
 int main(void)
diff --git a/src/expr_yacc.h b/src/expr_yacc.h
index 067f8b8..bcb0677 100644
--- a/src/expr_yacc.h
+++ b/src/expr_yacc.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.7.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
 /* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -53,7 +53,10 @@ extern int yydebug;
      EQ = 262,
      LE = 263,
      GE = 264,
-     UMINUS = 265
+     LEG = 265,
+     OR = 266,
+     AND = 267,
+     UMINUS = 268
    };
 #endif
 /* Tokens.  */
@@ -64,7 +67,10 @@ extern int yydebug;
 #define EQ 262
 #define LE 263
 #define GE 264
-#define UMINUS 265
+#define LEG 265
+#define OR 266
+#define AND 267
+#define UMINUS 268
 
 
 
diff --git a/src/features.c b/src/features.c
index 6c33550..0e4dff9 100644
--- a/src/features.c
+++ b/src/features.c
@@ -21,6 +21,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "cdo_int.h" // HAVE_OPENMP4
+
 void printFeatures(void)
 {
   fprintf(stderr, "Features:");
@@ -29,9 +31,18 @@ void printFeatures(void)
 #endif
 #if defined(_OPENMP)
   fprintf(stderr, " OpenMP");
+#if defined(HAVE_OPENMP4)
+  fprintf(stderr, "4");
+#endif
 #endif
 #if  defined(HAVE_NETCDF4)
   fprintf(stderr, " NC4");
+#if  defined(HAVE_NC4HDF5)
+  fprintf(stderr, "/HDF5");
+#if  defined(HAVE_NC4HDF5_THREADSAFE)
+  fprintf(stderr, "/threadsafe");
+#endif
+#endif
 #endif
 #if  defined(HAVE_LIBNC_DAP)
   fprintf(stderr, " OPeNDAP");
diff --git a/src/field.c b/src/field.c
index 715daf6..a746f7b 100644
--- a/src/field.c
+++ b/src/field.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/field.h b/src/field.h
index d10d296..2f822bd 100644
--- a/src/field.h
+++ b/src/field.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/field2.c b/src/field2.c
index 8a37637..98f7e26 100644
--- a/src/field2.c
+++ b/src/field2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldc.c b/src/fieldc.c
index 9ec4a3b..782b5bb 100644
--- a/src/fieldc.c
+++ b/src/fieldc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldmer.c b/src/fieldmer.c
index 857c54a..6d77ba8 100644
--- a/src/fieldmer.c
+++ b/src/fieldmer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldzon.c b/src/fieldzon.c
index df16bb2..fd7cd0a 100644
--- a/src/fieldzon.c
+++ b/src/fieldzon.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/gradsdeslib.c b/src/gradsdeslib.c
index 9f98b18..9d47b25 100644
--- a/src/gradsdeslib.c
+++ b/src/gradsdeslib.c
@@ -95,7 +95,7 @@ int qflag=0;
     if(*ch == '\"' && qflag == 0 ) {
       qflag=1;
       } else if(*ch == '\"' && qflag == 1 ) {
-	qflag=0;
+        qflag=0;
       }
     if (i>64 && i<91 && qflag==0) {
       i+=32;
@@ -351,7 +351,7 @@ gaint swap,mo1,mo2;
 }
 
 static char *mons[12] = {"jan","feb","mar","apr","may","jun",
-			 "jul","aug","sep","oct","nov","dec"};
+                         "jul","aug","sep","oct","nov","dec"};
 
 /* Parse an absolute date/time value.  Format is:
 
@@ -445,9 +445,9 @@ char monam[5];
     if (*ch>='0' && *ch<='9') {
       /* use fullyear only if year 1 = 0001*/
       if(*(ch+2)>='0' && *(ch+2)<='9') {
-	/*mfcmn.*/fullyear=1;
+        /*mfcmn.*/fullyear=1;
       } else {
-	/*mfcmn.*/fullyear=0;
+        /*mfcmn.*/fullyear=0;
       }
       ch = intprs (ch,&val);
     } else {
@@ -949,7 +949,7 @@ gaint ib,i,j,k,len,flag;
 /* Given a file name template and a dt structure, fill in to get the file name */
 
 char *gafndt (char *fn, struct dt *dtim, struct dt *dtimi, gadouble *vals, 
-	      struct gachsub *pch1st, struct gaens *ens1st, gaint t, gaint e, gaint *flag) {
+              struct gachsub *pch1st, struct gaens *ens1st, gaint t, gaint e, gaint *flag) {
 struct gachsub *pchsub;
 struct gaens *ens;
 struct dt stim;
@@ -1145,7 +1145,7 @@ char *fnout, *in, *out, *work, *in2, *out2;
             return (NULL);
           }
           in2 = fnout; 
-	  out2 = work;
+          out2 = work;
           while (in2!=out) {
             *out2 = *in2;
             in2++; out2++;
@@ -1165,34 +1165,34 @@ char *fnout, *in, *out, *work, *in2, *out2;
     else if  (*in=='%' && *(in+1)=='e') {
       eused=1;
       if (ens == NULL) {
-	gree(fnout,"f242");
-	return (NULL);
+        gree(fnout,"f242");
+        return (NULL);
       } else {
-	/* advance through array of ensemble structures, till we reach ensemble 'e' */
-	i=1;
-	while (i!=e) { i++; ens++; }
-	len = strlen(ens->name);
-	if (len < 1) {
-	  gree(fnout,"f243");
-	  return (NULL);
-	}
-	olen += len;
-	work = (char *)galloc(olen,"work2");     /* Reallocate output string */
-	if (work==NULL) {
-	  gree(fnout,"f244");
-	  return (NULL);
-	}
-	in2 = fnout;            /* copy the string we've got so far */
-	out2 = work;
-	while (in2!=out) {
-	  *out2 = *in2;
-	  in2++; out2++;
-	}
-	gree(fnout,"f245");
-	fnout = work;
-	out = out2;
-	getwrd(out,ens->name,len);
-	out += len;
+        /* advance through array of ensemble structures, till we reach ensemble 'e' */
+        i=1;
+        while (i!=e) { i++; ens++; }
+        len = strlen(ens->name);
+        if (len < 1) {
+          gree(fnout,"f243");
+          return (NULL);
+        }
+        olen += len;
+        work = (char *)galloc(olen,"work2");     /* Reallocate output string */
+        if (work==NULL) {
+          gree(fnout,"f244");
+          return (NULL);
+        }
+        in2 = fnout;            /* copy the string we've got so far */
+        out2 = work;
+        while (in2!=out) {
+          *out2 = *in2;
+          in2++; out2++;
+        }
+        gree(fnout,"f245");
+        fnout = work;
+        out = out2;
+        getwrd(out,ens->name,len);
+        out += len;
       }
       in+=2;
     }
@@ -1269,618 +1269,618 @@ int read_gradsdes(char *filename, dsets_t *pfi)
       reclen = (int)strlen(rec);
       jj = 0;
       while ( jj<reclen && rec[0]==' ' ) 
-	{
-	  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
-	  jj++;
-	}
+        {
+          for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+          jj++;
+        }
       /* replace newline with null at end of record */
       for (ichar = (int)strlen(rec) - 1 ;  ichar >= 0 ;  --ichar)
-	{
-	  if (rec[ichar] == '\n') {
-	    rec[ichar] = '\0' ;
-	    break ; 
-	  }
-	}
+        {
+          if (rec[ichar] == '\n') {
+            rec[ichar] = '\0' ;
+            break ; 
+          }
+        }
       /* Keep mixed case and lower case versions of rec handy */
       strcpy (mrec,rec);   
       lowcas(rec);
       
       if (!isalnum(mrec[0]))
-	{
-	  /* check if comment contains attribute metadata */
-	  /*
-	  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0))
-	    {
-	      if ((ddfattr(mrec,pfi)) == -1) goto retrn;
-	    }
-	  */
-	}
+        {
+          /* check if comment contains attribute metadata */
+          /*
+          if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0))
+            {
+              if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+            }
+          */
+        }
       else if (cmpwrd("byteswapped",rec))
-	{
-	  pfi->bswap = 1;
-	}
+        {
+          pfi->bswap = 1;
+        }
       else if (cmpwrd("fileheader",rec))
-	{
-	  if ( (ch=nxtwrd(rec))==NULL )
-	    {
-	      gaprnt (1,"Description file warning: Missing fileheader length\n");
-	    }
-	  else
-	    {
-	      ch = longprs(ch,&(pfi->fhdr));
-	      if (ch==NULL)
-		{
-		  gaprnt (1,"Fileheader record invalid\n");
-		  pfi->fhdr = 0;
-		}
-	    }
-	} 
+        {
+          if ( (ch=nxtwrd(rec))==NULL )
+            {
+              gaprnt (1,"Description file warning: Missing fileheader length\n");
+            }
+          else
+            {
+              ch = longprs(ch,&(pfi->fhdr));
+              if (ch==NULL)
+                {
+                  gaprnt (1,"Fileheader record invalid\n");
+                  pfi->fhdr = 0;
+                }
+            }
+        } 
       else if (cmpwrd("xyheader",rec)) 
-	{
-	  if ( (ch=nxtwrd(rec))==NULL )
-	    {
-	      gaprnt (1,"Description file warning: Missing xy grid header length\n");
-	    } 
-	  else 
-	    {
-	      ch = longprs(ch,&(pfi->xyhdr));
-	      if (ch==NULL)
-		{
-		  gaprnt (1,"xy grid header length invalid\n");
-		  pfi->xyhdr = 0;
-		}
-	      else
-		{
-		  pfi->xyhdr = pfi->xyhdr/4;
-		}
-	    }
-	} 
+        {
+          if ( (ch=nxtwrd(rec))==NULL )
+            {
+              gaprnt (1,"Description file warning: Missing xy grid header length\n");
+            } 
+          else 
+            {
+              ch = longprs(ch,&(pfi->xyhdr));
+              if (ch==NULL)
+                {
+                  gaprnt (1,"xy grid header length invalid\n");
+                  pfi->xyhdr = 0;
+                }
+              else
+                {
+                  pfi->xyhdr = pfi->xyhdr/4;
+                }
+            }
+        } 
       else if (cmpwrd("format",rec) || cmpwrd("options",rec))
-	{
-	  if ( (ch=nxtwrd(rec))==NULL )
-	    {
-	      gaprnt (1,"Description file warning: Missing options keyword\n");
-	    }
-	  else
-	    {
-	      while (ch!=NULL)
-		{
-		  if (cmpwrd("sequential",ch)) pfi->seqflg = 1;
-		  else if (cmpwrd("yrev",ch)) pfi->yrflg = 1;
-		  else if (cmpwrd("zrev",ch)) pfi->zrflg = 1;
-		  else if (cmpwrd("template",ch)) pfi->tmplat = 1;
-		  else if (cmpwrd("flt64",ch)) pfi->flt64 = 1;
-		  else if (cmpwrd("byteswapped",ch)) pfi->bswap = 1;
+        {
+          if ( (ch=nxtwrd(rec))==NULL )
+            {
+              gaprnt (1,"Description file warning: Missing options keyword\n");
+            }
+          else
+            {
+              while (ch!=NULL)
+                {
+                  if (cmpwrd("sequential",ch)) pfi->seqflg = 1;
+                  else if (cmpwrd("yrev",ch)) pfi->yrflg = 1;
+                  else if (cmpwrd("zrev",ch)) pfi->zrflg = 1;
+                  else if (cmpwrd("template",ch)) pfi->tmplat = 1;
+                  else if (cmpwrd("flt64",ch)) pfi->flt64 = 1;
+                  else if (cmpwrd("byteswapped",ch)) pfi->bswap = 1;
 #if GRIB2
-		  else if (cmpwrd("pascals",ch)) pfi->pa2mb = 1;
+                  else if (cmpwrd("pascals",ch)) pfi->pa2mb = 1;
 #endif
-		  else if (cmpwrd("365_day_calendar",ch))
-		    {
-		      pfi->calendar=1;
-		    }
-		  else if (cmpwrd("big_endian",ch))
-		    {
-		      if (!BYTEORDER) pfi->bswap = 1;
-		    }
-		  else if (cmpwrd("little_endian",ch))
-		    {
-		      if (BYTEORDER) pfi->bswap = 1;
-		    }
-		  else {
-		    gaprnt (0,"Open Error:  Data file type invalid\n");
-		    goto err9;
-		  }
-		  ch = nxtwrd(ch);
-		}
-	    }
-	}
+                  else if (cmpwrd("365_day_calendar",ch))
+                    {
+                      pfi->calendar=1;
+                    }
+                  else if (cmpwrd("big_endian",ch))
+                    {
+                      if (!BYTEORDER) pfi->bswap = 1;
+                    }
+                  else if (cmpwrd("little_endian",ch))
+                    {
+                      if (BYTEORDER) pfi->bswap = 1;
+                    }
+                  else {
+                    gaprnt (0,"Open Error:  Data file type invalid\n");
+                    goto err9;
+                  }
+                  ch = nxtwrd(ch);
+                }
+            }
+        }
       else if (cmpwrd("trailerbytes",rec))
-	{
-	  if ( (ch=nxtwrd(rec))==NULL )
-	    {
-	      gaprnt (1,"Trailerbytes record invalid\n");
-	    }
-	  else 
-	    {
-	      ch = intprs(ch,&trlb);
-	      if (ch==NULL)
-		{
-		  gaprnt (1,"Trailerbytes record invalid\n");
-		  trlb = 0;
-		}
-	      else 
-		{
-		  trlb = trlb/4;
-		}
-	    }
-	}
+        {
+          if ( (ch=nxtwrd(rec))==NULL )
+            {
+              gaprnt (1,"Trailerbytes record invalid\n");
+            }
+          else 
+            {
+              ch = intprs(ch,&trlb);
+              if (ch==NULL)
+                {
+                  gaprnt (1,"Trailerbytes record invalid\n");
+                  trlb = 0;
+                }
+              else 
+                {
+                  trlb = trlb/4;
+                }
+            }
+        }
       else if (cmpwrd("headerbytes",rec)|| cmpwrd("theader",rec))
-	{
-	  if ( (ch=nxtwrd(rec))==NULL )
-	    {
-	      gaprnt (1,"headerbytes/theader record invalid\n");
-	    }
-	  else 
-	    {
-	      ch = intprs(ch,&hdrb);
-	      if (ch==NULL)
-		{
-		  gaprnt (1,"headerbytes/theader record invalid\n");
-		  hdrb = 0;
-		}
-	      else
-		{
-		  hdrb = hdrb/4;
-		}
-	    }
-	}
+        {
+          if ( (ch=nxtwrd(rec))==NULL )
+            {
+              gaprnt (1,"headerbytes/theader record invalid\n");
+            }
+          else 
+            {
+              ch = intprs(ch,&hdrb);
+              if (ch==NULL)
+                {
+                  gaprnt (1,"headerbytes/theader record invalid\n");
+                  hdrb = 0;
+                }
+              else
+                {
+                  hdrb = hdrb/4;
+                }
+            }
+        }
       /* Handle the chsub records.  time1, time2, then a string,  multiple times */
       else if (cmpwrd("chsub",rec))
-	{
-	  /* point to first block in chain */
-	  pchsub = pfi->pchsub1;    
-	  if (pchsub!=NULL)
-	    {
-	      while (pchsub->forw!=NULL) {
-		pchsub = pchsub->forw;       /* advance to end of chain */
-	      }
-	    }
-	  flag = 0;
-	  ch = mrec;
-	  while (1) 
-	    {
-	      if ( (ch=nxtwrd(ch)) == NULL ) break;
-	      flag = 1;
-	      if ( (ch = intprs(ch,&tim1)) == NULL) break;
-	      if ( (ch=nxtwrd(ch)) == NULL ) break;
-	      if (*ch=='*' && (*(ch+1)==' '||*(ch+1)=='\t')) tim2 = -99;
-	      else if ( (ch = intprs(ch,&tim2)) == NULL) break;
-	      if ( (ch=nxtwrd(ch)) == NULL ) break;
-	      flag = 0;
-	      if (pchsub) 
-		{   /* chain exists */
-		  pchsub->forw = (struct gachsub *)galloc(sizeof(struct gachsub),"chsubnew");
-		  if (pchsub->forw==NULL) {
-		    gaprnt(0,"Open Error: memory allocation failed for pchsub\n");
-		    goto err8; 
-		  }
-		  pchsub = pchsub->forw;
-		  pchsub->forw = NULL;
-		} 
-	      else 
-		{        /* start a new chain */
-		  pfi->pchsub1 = (struct gachsub *)galloc(sizeof(struct gachsub),"chsub1");
-		  if (pfi->pchsub1==NULL)  {
-		    gaprnt(0,"Open Error: memory allocation failed for pchsub1\n");
-		    goto err8; 
-		  }
-		  pchsub = pfi->pchsub1;
-		  pchsub->forw = NULL;
-		}
-	      len = wrdlen(ch);
-	      if ((pchsub->ch = (char *)galloc(len+1,"chsubstr")) == NULL) goto err8;
-	      getwrd(pchsub->ch,ch,len);
-	      pchsub->t1 = tim1;
-	      pchsub->t2 = tim2;
-	    }
-	  if (flag) 
-	    {
-	      gaprnt (1,"Description file warning: Invalid chsub record; Ignored\n");
-	    }
-	}
+        {
+          /* point to first block in chain */
+          pchsub = pfi->pchsub1;    
+          if (pchsub!=NULL)
+            {
+              while (pchsub->forw!=NULL) {
+                pchsub = pchsub->forw;       /* advance to end of chain */
+              }
+            }
+          flag = 0;
+          ch = mrec;
+          while (1) 
+            {
+              if ( (ch=nxtwrd(ch)) == NULL ) break;
+              flag = 1;
+              if ( (ch = intprs(ch,&tim1)) == NULL) break;
+              if ( (ch=nxtwrd(ch)) == NULL ) break;
+              if (*ch=='*' && (*(ch+1)==' '||*(ch+1)=='\t')) tim2 = -99;
+              else if ( (ch = intprs(ch,&tim2)) == NULL) break;
+              if ( (ch=nxtwrd(ch)) == NULL ) break;
+              flag = 0;
+              if (pchsub) 
+                {   /* chain exists */
+                  pchsub->forw = (struct gachsub *)galloc(sizeof(struct gachsub),"chsubnew");
+                  if (pchsub->forw==NULL) {
+                    gaprnt(0,"Open Error: memory allocation failed for pchsub\n");
+                    goto err8; 
+                  }
+                  pchsub = pchsub->forw;
+                  pchsub->forw = NULL;
+                } 
+              else 
+                {        /* start a new chain */
+                  pfi->pchsub1 = (struct gachsub *)galloc(sizeof(struct gachsub),"chsub1");
+                  if (pfi->pchsub1==NULL)  {
+                    gaprnt(0,"Open Error: memory allocation failed for pchsub1\n");
+                    goto err8; 
+                  }
+                  pchsub = pfi->pchsub1;
+                  pchsub->forw = NULL;
+                }
+              len = wrdlen(ch);
+              if ((pchsub->ch = (char *)galloc(len+1,"chsubstr")) == NULL) goto err8;
+              getwrd(pchsub->ch,ch,len);
+              pchsub->t1 = tim1;
+              pchsub->t2 = tim2;
+            }
+          if (flag) 
+            {
+              gaprnt (1,"Description file warning: Invalid chsub record; Ignored\n");
+            }
+        }
       else if (cmpwrd("title",rec))
-	{
-	  if ( (ch=nxtwrd(mrec))==NULL )
-	    {
-	      gaprnt (1,"Description file warning: Missing title string\n");
-	    } 
-	  else
-	    {
-	      getstr (pfi->title,ch,MAX_NAMELEN);
-	      flgs[7] = 0;
-	    }
-	} 
+        {
+          if ( (ch=nxtwrd(mrec))==NULL )
+            {
+              gaprnt (1,"Description file warning: Missing title string\n");
+            } 
+          else
+            {
+              getstr (pfi->title,ch,MAX_NAMELEN);
+              flgs[7] = 0;
+            }
+        } 
       else if (cmpwrd("dset",rec))
-	{
-	  ch = nxtwrd(mrec);
-	  if (ch==NULL) 
-	    {
-	      gaprnt (0,"Descriptor File Error:  Data file name is missing\n");
-	      goto err9;
-	    }
-	  if (*ch=='^' || *ch=='$')
-	    {
-	      fnmexp (pfi->name,ch,filename);
-	    } 
-	  else 
-	    {
-	      getwrd (pfi->name,ch,MAX_NAMELEN);
-	    }
-	  flgs[5] = 0;
-	}   
+        {
+          ch = nxtwrd(mrec);
+          if (ch==NULL) 
+            {
+              gaprnt (0,"Descriptor File Error:  Data file name is missing\n");
+              goto err9;
+            }
+          if (*ch=='^' || *ch=='$')
+            {
+              fnmexp (pfi->name,ch,filename);
+            } 
+          else 
+            {
+              getwrd (pfi->name,ch,MAX_NAMELEN);
+            }
+          flgs[5] = 0;
+        }   
       else if (cmpwrd("undef",rec))
-	{
-	  ch = nxtwrd(mrec);
-	  if (ch==NULL)
-	    {
-	      gaprnt (0,"Open Error:  Missing undef value\n");
-	      goto err9;
-	    }
+        {
+          ch = nxtwrd(mrec);
+          if (ch==NULL)
+            {
+              gaprnt (0,"Open Error:  Missing undef value\n");
+              goto err9;
+            }
       
-	  pos = getdbl(ch,&(pfi->undef));
-	  if (pos==NULL)
-	    {
-	      gaprnt (0,"Open Error:  Invalid undef value\n");
-	      goto err9;
-	    } 
-
-	  pfi->ulow = fabs(pfi->undef/EPSILON);
-	  pfi->uhi  = pfi->undef + pfi->ulow;
-	  pfi->ulow = pfi->undef - pfi->ulow;
-	  flgs[4] = 0;
-	}
+          pos = getdbl(ch,&(pfi->undef));
+          if (pos==NULL)
+            {
+              gaprnt (0,"Open Error:  Invalid undef value\n");
+              goto err9;
+            } 
+
+          pfi->ulow = fabs(pfi->undef/EPSILON);
+          pfi->uhi  = pfi->undef + pfi->ulow;
+          pfi->ulow = pfi->undef - pfi->ulow;
+          flgs[4] = 0;
+        }
       else if (cmpwrd("xdef",rec))
-	{
-	  if (pfi->type == 2) continue;
-	  if ( (ch = nxtwrd(rec)) == NULL) goto err1;
-	  if ( (pos = intprs(ch,&(pfi->dnum[0])))==NULL) goto err1;
-	  if (pfi->dnum[0]<1) 
-	    {
-	      sprintf(pout,"Warning: Invalid XDEF syntax in %s -- Changing size of X axis from %d to 1 \n",
-		      pfi->dnam,pfi->dnum[0]);
-	      gaprnt (1,pout);
-	      pfi->dnum[0] = 1;
-	    }
-	  if (*pos!=' ') goto err1;
-	  if ( (ch = nxtwrd(ch))==NULL) goto err2;
-	  if (cmpwrd("linear",ch)) 
-	    {
-	      rc = deflin(ch, pfi, 0, 0);
-	      if (rc==-1) goto err8; 
-	      if (rc) goto err9;
-	      v2 = *(pfi->grvals[0]);
-	      v1 = *(pfi->grvals[0]+1) + v2;
-	      temp = v1+((gadouble)(pfi->dnum[0]))*v2;
-	      temp=temp-360.0;
-	      if (fabs(temp-v1)<0.01) pfi->wrap = 1;
-	    }
-	  else if (cmpwrd("levels",ch))
-	    {
-	      rc = deflev (ch, rec, pfi, 0);
-	      if (rc==-1)  goto err8; 
-	      if (rc) goto err9;
-	    } else goto err2;
-	  flgs[0] = 0;
-	} 
+        {
+          if (pfi->type == 2) continue;
+          if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+          if ( (pos = intprs(ch,&(pfi->dnum[0])))==NULL) goto err1;
+          if (pfi->dnum[0]<1) 
+            {
+              sprintf(pout,"Warning: Invalid XDEF syntax in %s -- Changing size of X axis from %d to 1 \n",
+                      pfi->dnam,pfi->dnum[0]);
+              gaprnt (1,pout);
+              pfi->dnum[0] = 1;
+            }
+          if (*pos!=' ') goto err1;
+          if ( (ch = nxtwrd(ch))==NULL) goto err2;
+          if (cmpwrd("linear",ch)) 
+            {
+              rc = deflin(ch, pfi, 0, 0);
+              if (rc==-1) goto err8; 
+              if (rc) goto err9;
+              v2 = *(pfi->grvals[0]);
+              v1 = *(pfi->grvals[0]+1) + v2;
+              temp = v1+((gadouble)(pfi->dnum[0]))*v2;
+              temp=temp-360.0;
+              if (fabs(temp-v1)<0.01) pfi->wrap = 1;
+            }
+          else if (cmpwrd("levels",ch))
+            {
+              rc = deflev (ch, rec, pfi, 0);
+              if (rc==-1)  goto err8; 
+              if (rc) goto err9;
+            } else goto err2;
+          flgs[0] = 0;
+        } 
       else if (cmpwrd("ydef",rec))
-	{
-	  if (pfi->type == 2) continue;
-	  if ( (ch = nxtwrd(rec)) == NULL) goto err1;
-	  if ( (pos = intprs(ch,&(pfi->dnum[1])))==NULL) goto err1;
-	  if (pfi->dnum[1]<1)
-	    {
-	      sprintf(pout,"Warning: Invalid YDEF syntax in %s -- Changing size of Y axis from %d to 1 \n",
-		      pfi->dnam,pfi->dnum[1]);
-	      gaprnt (1,pout);
-	      pfi->dnum[1] = 1;
-	    }
-	  if (*pos!=' ') goto err1;
-	  if ( (ch = nxtwrd(ch))==NULL) goto err2;
-	  if (cmpwrd("linear",ch))
-	    {
-	      rc = deflin(ch, pfi, 1, 0);
-	      if (rc==-1) goto err8; 
-	      if (rc) goto err9;
-	    }
-	  else if (cmpwrd("levels",ch))
-	    {
-	      rc = deflev (ch, rec, pfi, 1);
-	      if (rc==-1) goto err8;
-	      if (rc) goto err9;
-	    }
-	  flgs[1] = 0;
-	}
+        {
+          if (pfi->type == 2) continue;
+          if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+          if ( (pos = intprs(ch,&(pfi->dnum[1])))==NULL) goto err1;
+          if (pfi->dnum[1]<1)
+            {
+              sprintf(pout,"Warning: Invalid YDEF syntax in %s -- Changing size of Y axis from %d to 1 \n",
+                      pfi->dnam,pfi->dnum[1]);
+              gaprnt (1,pout);
+              pfi->dnum[1] = 1;
+            }
+          if (*pos!=' ') goto err1;
+          if ( (ch = nxtwrd(ch))==NULL) goto err2;
+          if (cmpwrd("linear",ch))
+            {
+              rc = deflin(ch, pfi, 1, 0);
+              if (rc==-1) goto err8; 
+              if (rc) goto err9;
+            }
+          else if (cmpwrd("levels",ch))
+            {
+              rc = deflev (ch, rec, pfi, 1);
+              if (rc==-1) goto err8;
+              if (rc) goto err9;
+            }
+          flgs[1] = 0;
+        }
       else if (cmpwrd("zdef",rec))
-	{
-	  if (pfi->type == 2) continue;
-	  if ( (ch = nxtwrd(rec)) == NULL) goto err1;
-	  if ( (pos = intprs(ch,&(pfi->dnum[2])))==NULL) goto err1;
-	  if (pfi->dnum[2]<1)
-	    {
-	      sprintf(pout,"Warning: Invalid ZDEF syntax in %s -- Changing size of Z axis from %d to 1 \n",
-		      pfi->dnam,pfi->dnum[2]);
-	      gaprnt (1,pout);
-	      pfi->dnum[2] = 1;
-	    }
-	  if (*pos!=' ') goto err1;
-	  if ( (ch = nxtwrd(ch))==NULL) goto err2;
-	  if (cmpwrd("linear",ch))
-	    {
-	      rc = deflin(ch, pfi, 2, 0);
-	      if (rc==-1) goto err8; 
-	      if (rc) goto err9;
-	    }
-	  else if (cmpwrd("levels",ch))
-	    {
-	      rc = deflev (ch, rec, pfi, 2);
-	      if (rc==-1) goto err8; 
-	      if (rc) goto err9;
-	    } else goto err2;
-	  flgs[2] = 0;
-	}
+        {
+          if (pfi->type == 2) continue;
+          if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+          if ( (pos = intprs(ch,&(pfi->dnum[2])))==NULL) goto err1;
+          if (pfi->dnum[2]<1)
+            {
+              sprintf(pout,"Warning: Invalid ZDEF syntax in %s -- Changing size of Z axis from %d to 1 \n",
+                      pfi->dnam,pfi->dnum[2]);
+              gaprnt (1,pout);
+              pfi->dnum[2] = 1;
+            }
+          if (*pos!=' ') goto err1;
+          if ( (ch = nxtwrd(ch))==NULL) goto err2;
+          if (cmpwrd("linear",ch))
+            {
+              rc = deflin(ch, pfi, 2, 0);
+              if (rc==-1) goto err8; 
+              if (rc) goto err9;
+            }
+          else if (cmpwrd("levels",ch))
+            {
+              rc = deflev (ch, rec, pfi, 2);
+              if (rc==-1) goto err8; 
+              if (rc) goto err9;
+            } else goto err2;
+          flgs[2] = 0;
+        }
       else if (cmpwrd("tdef",rec))
-	{
-	  if ( (ch = nxtwrd(rec)) == NULL) goto err1;
-	  if ( (pos = intprs(ch,&(pfi->dnum[3])))==NULL) goto err1;
-	  if (pfi->dnum[3]<1)
-	    {
-	      sprintf(pout,"Warning: Invalid TDEF syntax in %s -- Changing size of T axis from %d to 1 \n",
-		      pfi->dnam,pfi->dnum[3]);
-	      gaprnt (1,pout);
-	      pfi->dnum[3] = 1;
-	    }
-	  if (*pos!=' ') goto err1;
-	  if ( (ch = nxtwrd(ch))==NULL) goto err2;
-	  if (cmpwrd("linear",ch))
-	    {
-	      if ( (ch = nxtwrd(ch))==NULL) goto err3a_tdef;
-	      tdef.yr = -1000;
-	      tdef.mo = -1000;
-	      tdef.dy = -1000;
-	      if ( (pos = adtprs(ch,&tdef,&dt1))==NULL) goto err3b_tdef;
-	      if (*pos!=' ' || dt1.yr == -1000 || dt1.mo == -1000.0 ||
-		  dt1.dy == -1000) goto err3c_tdef;
-	      if ( (ch = nxtwrd(ch))==NULL) goto err4a_tdef;
-	      if ( (pos = rdtprs(ch,&dt2))==NULL) goto err4b_tdef;
-	      v1 = (dt2.yr * 12) + dt2.mo;
-	      v2 = (dt2.dy * 1440) + (dt2.hr * 60) + dt2.mn;
-	      /* check if 0 dt */
-	      if ( (v1 == 0) && (v2 == 0) ) goto err4c_tdef;  
-	      if ((vals = (gadouble *)galloc(sizeof(gadouble)*8,"tvals5")) == NULL) goto err8; 
-	      *(vals) = dt1.yr;
-	      *(vals+1) = dt1.mo;
-	      *(vals+2) = dt1.dy;
-	      *(vals+3) = dt1.hr;
-	      *(vals+4) = dt1.mn;
-	      *(vals+5) = v1;
-	      *(vals+6) = v2;
-	      *(vals+7) = -999.9;
-	      pfi->grvals[3] = vals;
-	      pfi->abvals[3] = vals;
-	      pfi->linear[3] = 1;
-	    } else goto err2;
-	  flgs[3] = 0;
-	}
+        {
+          if ( (ch = nxtwrd(rec)) == NULL) goto err1;
+          if ( (pos = intprs(ch,&(pfi->dnum[3])))==NULL) goto err1;
+          if (pfi->dnum[3]<1)
+            {
+              sprintf(pout,"Warning: Invalid TDEF syntax in %s -- Changing size of T axis from %d to 1 \n",
+                      pfi->dnam,pfi->dnum[3]);
+              gaprnt (1,pout);
+              pfi->dnum[3] = 1;
+            }
+          if (*pos!=' ') goto err1;
+          if ( (ch = nxtwrd(ch))==NULL) goto err2;
+          if (cmpwrd("linear",ch))
+            {
+              if ( (ch = nxtwrd(ch))==NULL) goto err3a_tdef;
+              tdef.yr = -1000;
+              tdef.mo = -1000;
+              tdef.dy = -1000;
+              if ( (pos = adtprs(ch,&tdef,&dt1))==NULL) goto err3b_tdef;
+              if (*pos!=' ' || dt1.yr == -1000 || dt1.mo == -1000.0 ||
+                  dt1.dy == -1000) goto err3c_tdef;
+              if ( (ch = nxtwrd(ch))==NULL) goto err4a_tdef;
+              if ( (pos = rdtprs(ch,&dt2))==NULL) goto err4b_tdef;
+              v1 = (dt2.yr * 12) + dt2.mo;
+              v2 = (dt2.dy * 1440) + (dt2.hr * 60) + dt2.mn;
+              /* check if 0 dt */
+              if ( (v1 == 0) && (v2 == 0) ) goto err4c_tdef;  
+              if ((vals = (gadouble *)galloc(sizeof(gadouble)*8,"tvals5")) == NULL) goto err8; 
+              *(vals) = dt1.yr;
+              *(vals+1) = dt1.mo;
+              *(vals+2) = dt1.dy;
+              *(vals+3) = dt1.hr;
+              *(vals+4) = dt1.mn;
+              *(vals+5) = v1;
+              *(vals+6) = v2;
+              *(vals+7) = -999.9;
+              pfi->grvals[3] = vals;
+              pfi->abvals[3] = vals;
+              pfi->linear[3] = 1;
+            } else goto err2;
+          flgs[3] = 0;
+        }
       else if (cmpwrd("vars",rec))
-	{
-	  if ( (ch = nxtwrd(rec)) == NULL) goto err5;
-	  if ( (pos = intprs(ch,&(pfi->vnum)))==NULL) goto err5;
-	  size = pfi->vnum * (sizeof(struct gavar) + 7 );
-	  if ((pvar = (struct gavar *)galloc(size,"pvar2")) == NULL) goto err8;
-	  pfi->pvar1 = pvar;
-	  i = 0;
-	  while (i<pfi->vnum)
-	    {
-	      /* initialize variables in the pvar structure */
-	      pvar->offset = 0; 
-	      pvar->recoff = 0;
-	      pvar->ncvid = -999;
-	      pvar->sdvid = -999;
-	      pvar->levels = 0;
-	      pvar->dfrm = 0;
-	      pvar->var_t = 0;
-	      pvar->scale = 1;
-	      pvar->add = 0;  
-	      pvar->undef= -9.99E33; 
-	      pvar->vecpair = -999;
-	      pvar->isu = 0;
-	      pvar->isdvar = 0;
-	      pvar->nvardims = 0; 
-
-	      /* get the complete variable declaration */
-	      if (fgets(rec,512,descr)==NULL) 
-		{
-		  gaprnt (0,"Open Error:  Unexpected EOF reading variables\n");
-		  sprintf (pout, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
-		  gaprnt (2,pout);
-		  goto retrn;
-		}
-	      /* remove any leading blanks from rec */
-	      reclen = strlen(rec);
-	      jj = 0;
-	      while (jj<reclen && rec[0]==' ')
-		{
-		  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
-		  jj++;
-		}
-	      /* replace newline with null at end of record */
-	      for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar)
-		{
-		  if (rec[ichar] == '\n')
-		    {
-		      rec[ichar] = '\0' ;
-		      break ; 
-		    }
-		}
-	      /* Keep mixed case and lower case versions of rec handy */
-	      strcpy (mrec,rec);
-	      lowcas(rec);
-	      /* Allow comments between VARS and ENDVARS */
-	      if (!isalnum(*(mrec)))
-		{
-		  /* Parse comment if it contains attribute metadata  */
-		  /*
-		  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
-		    if ((ddfattr(mrec,pfi)) == -1) goto retrn;
-		    else continue;
-		  }
-		  else */continue; 
-		}
-	      if (cmpwrd("endvars",rec))
-		{
-		  gaprnt (0,"Open Error:  Unexpected ENDVARS record\n");
-		  sprintf (pout, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
-		  gaprnt (2,pout);
-		  goto err9;
-		}
-	
-	      /* get abbrv and full variable name if there */
-	      if ((getvnm(pvar, mrec))!=0) goto err6;
-
-	      /* parse the levels fields */
-	      if ( (ch=nxtwrd(rec))==NULL) goto err6;
-	      /* begin with 8th element of units aray for levels values */
-	      for (j=0;j<16;j++) pvar->units[j] = -999;
-	      j = 8;          
-	      while (1) 
-		{
-		  if (j==8) {
-		    /* first element is num levels */
-		    if ((ch=intprs(ch,&(pvar->levels)))==NULL) goto err6;      
-		  }
-		  else {
-		    /* remaining elements are grib2 level codes */
-		    if ((ch=getdbl(ch,&(pvar->units[j-1])))==NULL) goto err6;  
-		  }
-		  /* advance through comma-delimited list of levels args */
-		  while (*ch==' ') ch++;
-		  if (*ch=='\0' || *ch=='\n') goto err6;
-		  if (*ch!=',') break;
-		  ch++;
-		  while (*ch==',') { ch++; j++;}  /* advance past back to back commas */
-		  while (*ch==' ') ch++;
-		  if (*ch=='\0' || *ch=='\n') goto err6;
-		  j++;
-		  if (j>15) goto err6;
-		}
-
-	      /* parse the units fields; begin with 0th element for variable units */
-	      j = 0;
-	      pvar->nvardims=0;
-	      while (1)
-		{
-		  if (*ch=='x'||*ch=='y'||*ch=='z'||*ch=='t'||*ch=='e')
-		    { 
-		      if (*(ch+1)!=',' && *(ch+1)!=' ') goto err6;
-		      if (*ch=='x') { pvar->units[j] = -100; pvar->nvardims++; }
-		      if (*ch=='y') { pvar->units[j] = -101; pvar->nvardims++; }
-		      if (*ch=='z') { pvar->units[j] = -102; pvar->nvardims++; }
-		      if (*ch=='t') { pvar->units[j] = -103; pvar->nvardims++; }
-		      if (*ch=='e') { pvar->units[j] = -104; pvar->nvardims++; }
-		      ch++;
-		    } 
-		  else 
-		    {
-		      if ( (ch=getdbl(ch,&(pvar->units[j])))==NULL ) goto err6;
-		      /* no negative array indices for ncflag files */
-		      if ((pfi->ncflg) && (pvar->units[j] < 0))  goto err6;   
-		    }
-		  while (*ch==' ') ch++;
-		  if (*ch=='\0' || *ch=='\n') goto err6;
-		  if (*ch!=',') break;
-		  ch++;
-		  while (*ch==' ') ch++;
-		  if (*ch=='\0' || *ch=='\n') goto err6;
-		  j++;
-		  if (j>8) goto err6;
-		}
-
-	      /* parse the variable description */
-	      getstr (pvar->varnm,mrec+(ch-rec),127);
-
-
-	      /* var_t is for data files with dimension sequence: X, Y, Z, T, V */
-	      if (((int)pvar->units[0]==-1) && 
-		  ((int)pvar->units[1]==20)) 
-		pvar->var_t = 1;
-
-	      /* non-float data types */
-	      if (((int)pvar->units[0]==-1) && 
-		  ((int)pvar->units[1]==40))
-		{
-
-		  if ((int)pvar->units[2]== 1) pvar->dfrm = 1;
-		  if ((int)pvar->units[2]== 2)
-		    {
-		      pvar->dfrm = 2;
-		      if ((int)pvar->units[3]==-1) pvar->dfrm = -2;
-		    }
-		  if ((int)pvar->units[2]== 4) pvar->dfrm = 4;
-		}
-
-	      i++; pvar++;
-	    }
-
-	  /* Get ENDVARS statement and any additional comments */
-	  if (fgets(rec,512,descr)==NULL) {
-	    gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
-	    goto retrn;
-	  }
-	  /* Remove any leading blanks from rec */
-	  reclen = strlen(rec);
-	  jj = 0;
-	  while (jj<reclen && rec[0]==' ') {
-	    for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
-	    jj++;
-	  }
-	  /* replace newline with null at end of record */
-	  for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
-	    if (rec[ichar] == '\n') {
-	      rec[ichar] = '\0' ;
-	      break ; 
-	    }
-	  }
-	  /* Keep mixed case and lower case versions handy */
-	  strcpy (mrec,rec);
-	  lowcas(rec);
-	  while (!cmpwrd("endvars",rec)) 
-	    {
-	      /* see if it's an attribute comment */
-	      if (!isalnum(*(mrec))) {
-		/*
-		if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
-		  if ((ddfattr(mrec,pfi)) == -1) goto retrn;
-		}
-		*/
-	      }
-	      else {
-		sprintf(pout,"Open Error:  Looking for \"endvars\", found \"%s\" instead.\n",rec);
-		gaprnt (0,pout);
-		goto err9;
-	      }
-	      /* get a new record */
-	      if (fgets(rec,512,descr)==NULL) {
-		gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
-		goto retrn;
-	      }
-	      /* Remove any leading blanks from new record */
-	      reclen = strlen(rec);
-	      jj = 0;
-	      while (jj<reclen && rec[0]==' ') {
-		for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
-		jj++;
-	      }
-	      /* replace newline with null at end of record */
-	      for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
-		if (rec[ichar] == '\n') {
-		  rec[ichar] = '\0' ;
-		  break ; 
-		}
-	      }
-	      /* Keep mixed case and lower case versions handy */
-	      strcpy (mrec,rec);
-	      lowcas(rec);
-	    }
-	  /* vars block parsed without error */
-	  flgs[6] = 0;
-
-	} 
+        {
+          if ( (ch = nxtwrd(rec)) == NULL) goto err5;
+          if ( (pos = intprs(ch,&(pfi->vnum)))==NULL) goto err5;
+          size = pfi->vnum * (sizeof(struct gavar) + 7 );
+          if ((pvar = (struct gavar *)galloc(size,"pvar2")) == NULL) goto err8;
+          pfi->pvar1 = pvar;
+          i = 0;
+          while (i<pfi->vnum)
+            {
+              /* initialize variables in the pvar structure */
+              pvar->offset = 0; 
+              pvar->recoff = 0;
+              pvar->ncvid = -999;
+              pvar->sdvid = -999;
+              pvar->levels = 0;
+              pvar->dfrm = 0;
+              pvar->var_t = 0;
+              pvar->scale = 1;
+              pvar->add = 0;  
+              pvar->undef= -9.99E33; 
+              pvar->vecpair = -999;
+              pvar->isu = 0;
+              pvar->isdvar = 0;
+              pvar->nvardims = 0; 
+
+              /* get the complete variable declaration */
+              if (fgets(rec,512,descr)==NULL) 
+                {
+                  gaprnt (0,"Open Error:  Unexpected EOF reading variables\n");
+                  sprintf (pout, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+                  gaprnt (2,pout);
+                  goto retrn;
+                }
+              /* remove any leading blanks from rec */
+              reclen = strlen(rec);
+              jj = 0;
+              while (jj<reclen && rec[0]==' ')
+                {
+                  for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+                  jj++;
+                }
+              /* replace newline with null at end of record */
+              for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar)
+                {
+                  if (rec[ichar] == '\n')
+                    {
+                      rec[ichar] = '\0' ;
+                      break ; 
+                    }
+                }
+              /* Keep mixed case and lower case versions of rec handy */
+              strcpy (mrec,rec);
+              lowcas(rec);
+              /* Allow comments between VARS and ENDVARS */
+              if (!isalnum(*(mrec)))
+                {
+                  /* Parse comment if it contains attribute metadata  */
+                  /*
+                  if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+                    if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+                    else continue;
+                  }
+                  else */continue; 
+                }
+              if (cmpwrd("endvars",rec))
+                {
+                  gaprnt (0,"Open Error:  Unexpected ENDVARS record\n");
+                  sprintf (pout, "Was expecting %i records.  Found %i.\n", pfi->vnum, i);
+                  gaprnt (2,pout);
+                  goto err9;
+                }
+        
+              /* get abbrv and full variable name if there */
+              if ((getvnm(pvar, mrec))!=0) goto err6;
+
+              /* parse the levels fields */
+              if ( (ch=nxtwrd(rec))==NULL) goto err6;
+              /* begin with 8th element of units aray for levels values */
+              for (j=0;j<16;j++) pvar->units[j] = -999;
+              j = 8;          
+              while (1) 
+                {
+                  if (j==8) {
+                    /* first element is num levels */
+                    if ((ch=intprs(ch,&(pvar->levels)))==NULL) goto err6;      
+                  }
+                  else {
+                    /* remaining elements are grib2 level codes */
+                    if ((ch=getdbl(ch,&(pvar->units[j-1])))==NULL) goto err6;  
+                  }
+                  /* advance through comma-delimited list of levels args */
+                  while (*ch==' ') ch++;
+                  if (*ch=='\0' || *ch=='\n') goto err6;
+                  if (*ch!=',') break;
+                  ch++;
+                  while (*ch==',') { ch++; j++;}  /* advance past back to back commas */
+                  while (*ch==' ') ch++;
+                  if (*ch=='\0' || *ch=='\n') goto err6;
+                  j++;
+                  if (j>15) goto err6;
+                }
+
+              /* parse the units fields; begin with 0th element for variable units */
+              j = 0;
+              pvar->nvardims=0;
+              while (1)
+                {
+                  if (*ch=='x'||*ch=='y'||*ch=='z'||*ch=='t'||*ch=='e')
+                    { 
+                      if (*(ch+1)!=',' && *(ch+1)!=' ') goto err6;
+                      if (*ch=='x') { pvar->units[j] = -100; pvar->nvardims++; }
+                      if (*ch=='y') { pvar->units[j] = -101; pvar->nvardims++; }
+                      if (*ch=='z') { pvar->units[j] = -102; pvar->nvardims++; }
+                      if (*ch=='t') { pvar->units[j] = -103; pvar->nvardims++; }
+                      if (*ch=='e') { pvar->units[j] = -104; pvar->nvardims++; }
+                      ch++;
+                    } 
+                  else 
+                    {
+                      if ( (ch=getdbl(ch,&(pvar->units[j])))==NULL ) goto err6;
+                      /* no negative array indices for ncflag files */
+                      if ((pfi->ncflg) && (pvar->units[j] < 0))  goto err6;   
+                    }
+                  while (*ch==' ') ch++;
+                  if (*ch=='\0' || *ch=='\n') goto err6;
+                  if (*ch!=',') break;
+                  ch++;
+                  while (*ch==' ') ch++;
+                  if (*ch=='\0' || *ch=='\n') goto err6;
+                  j++;
+                  if (j>8) goto err6;
+                }
+
+              /* parse the variable description */
+              getstr (pvar->varnm,mrec+(ch-rec),127);
+
+
+              /* var_t is for data files with dimension sequence: X, Y, Z, T, V */
+              if (((int)pvar->units[0]==-1) && 
+                  ((int)pvar->units[1]==20)) 
+                pvar->var_t = 1;
+
+              /* non-float data types */
+              if (((int)pvar->units[0]==-1) && 
+                  ((int)pvar->units[1]==40))
+                {
+
+                  if ((int)pvar->units[2]== 1) pvar->dfrm = 1;
+                  if ((int)pvar->units[2]== 2)
+                    {
+                      pvar->dfrm = 2;
+                      if ((int)pvar->units[3]==-1) pvar->dfrm = -2;
+                    }
+                  if ((int)pvar->units[2]== 4) pvar->dfrm = 4;
+                }
+
+              i++; pvar++;
+            }
+
+          /* Get ENDVARS statement and any additional comments */
+          if (fgets(rec,512,descr)==NULL) {
+            gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
+            goto retrn;
+          }
+          /* Remove any leading blanks from rec */
+          reclen = strlen(rec);
+          jj = 0;
+          while (jj<reclen && rec[0]==' ') {
+            for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+            jj++;
+          }
+          /* replace newline with null at end of record */
+          for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+            if (rec[ichar] == '\n') {
+              rec[ichar] = '\0' ;
+              break ; 
+            }
+          }
+          /* Keep mixed case and lower case versions handy */
+          strcpy (mrec,rec);
+          lowcas(rec);
+          while (!cmpwrd("endvars",rec)) 
+            {
+              /* see if it's an attribute comment */
+              if (!isalnum(*(mrec))) {
+                /*
+                if ((strncmp("*:attr",mrec,6)==0) || (strncmp("@",mrec,1)==0)) {
+                  if ((ddfattr(mrec,pfi)) == -1) goto retrn;
+                }
+                */
+              }
+              else {
+                sprintf(pout,"Open Error:  Looking for \"endvars\", found \"%s\" instead.\n",rec);
+                gaprnt (0,pout);
+                goto err9;
+              }
+              /* get a new record */
+              if (fgets(rec,512,descr)==NULL) {
+                gaprnt (0,"Open Error:  Missing ENDVARS statement.\n");
+                goto retrn;
+              }
+              /* Remove any leading blanks from new record */
+              reclen = strlen(rec);
+              jj = 0;
+              while (jj<reclen && rec[0]==' ') {
+                for (ii=0; ii<reclen; ii++) rec[ii] = rec[ii+1];
+                jj++;
+              }
+              /* replace newline with null at end of record */
+              for (ichar = strlen(rec) - 1 ;  ichar >= 0 ;  --ichar) {
+                if (rec[ichar] == '\n') {
+                  rec[ichar] = '\0' ;
+                  break ; 
+                }
+              }
+              /* Keep mixed case and lower case versions handy */
+              strcpy (mrec,rec);
+              lowcas(rec);
+            }
+          /* vars block parsed without error */
+          flgs[6] = 0;
+
+        } 
       else
-	{
-	  /* parse error of .ctl file */
-	  gaprnt (0,"Open Error:  Unknown keyword in description file\n");
-	  goto err9;
-	}
+        {
+          /* parse error of .ctl file */
+          gaprnt (0,"Open Error:  Unknown keyword in description file\n");
+          goto err9;
+        }
     }
 
   /* Done scanning!
@@ -1910,8 +1910,8 @@ int read_gradsdes(char *filename, dsets_t *pfi)
       /* Allocate memory and initialize one ensemble structure */
       ens = (struct gaens *)galloc(sizeof(struct gaens),"ens5");
       if (ens==NULL) {
-	gaprnt(0,"Open Error: memory allocation failed for default ens\n");
-	goto err8;
+        gaprnt(0,"Open Error: memory allocation failed for default ens\n");
+        goto err8;
       }
       pfi->ens1 = ens;
       sprintf(ens->name,"1");
@@ -1926,16 +1926,16 @@ int read_gradsdes(char *filename, dsets_t *pfi)
   for (j=1; j<=pfi->vnum; j++) {
     if ((int)pvar->units[0]==-1 && (int)pvar->units[1]==20) {
       if (pfi->tmplat) {
-	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions cannot be templated together\n");
-	err=1;
+        gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions cannot be templated together\n");
+        err=1;
       }
       if (hdrb>0) {
-	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with time headers\n");
-	err=1;
+        gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with time headers\n");
+        err=1;
       }
       if (trlb>0) {
-	gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with TRAILERBYTES\n");
-	err=1;
+        gaprnt(0,"Open Error: Variables with transposed VAR-T dimensions are incompatible with TRAILERBYTES\n");
+        err=1;
       }
     }
     pvar++;
@@ -1953,10 +1953,10 @@ int read_gradsdes(char *filename, dsets_t *pfi)
     /* add the XY header to gsiz */
     if (pfi->xyhdr) {
       if (pvar->dfrm == 1) {
-	pfi->xyhdr = pfi->xyhdr*4/1;          
+        pfi->xyhdr = pfi->xyhdr*4/1;          
       } 
       else if (pvar->dfrm ==  2 || pvar->dfrm == -2 ) {
-	pfi->xyhdr = pfi->xyhdr*4/2;
+        pfi->xyhdr = pfi->xyhdr*4/2;
       }
       else if (pfi->flt64) {
         pfi->xyhdr = pfi->xyhdr*4/8;
@@ -1977,41 +1977,41 @@ int read_gradsdes(char *filename, dsets_t *pfi)
     if (pfi->seqflg) {
       /* pad the grid size with 2 4-byte chunks */
       if (pvar->dfrm == 1) {
-	pfi->gsiz += 8;
+        pfi->gsiz += 8;
       } 
       else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
-	pfi->gsiz += 4;
+        pfi->gsiz += 4;
       } 
       else {
-	if (pfi->flt64)
-	  pfi->gsiz += 1;
-	else
-	  pfi->gsiz += 2;             
+        if (pfi->flt64)
+          pfi->gsiz += 1;
+        else
+          pfi->gsiz += 2;             
       }
       /* pad the header with 2 4-byte chunks*/
       if (hdrb>0) {
-	if (pvar->dfrm == 1) {
-	  hdrb = hdrb + 8;
-	} 
-	else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
-	  hdrb = hdrb + 4;
-	} 
-	else {
-	  hdrb += 2; 
-	}
+        if (pvar->dfrm == 1) {
+          hdrb = hdrb + 8;
+        } 
+        else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
+          hdrb = hdrb + 4;
+        } 
+        else {
+          hdrb += 2; 
+        }
       }
       /* how far we have to go into the file before getting to 1st var */
       if (pvar->dfrm == 1) {
-	pvar->offset = 4+hdrb;
-	acum = 4+hdrb;
+        pvar->offset = 4+hdrb;
+        acum = 4+hdrb;
       } 
       else if (pvar->dfrm == 2 || pvar->dfrm == -2 ) {
-	pvar->offset = 2+hdrb;
-	acum = 2+hdrb;
+        pvar->offset = 2+hdrb;
+        acum = 2+hdrb;
       } 
       else {
-	pvar->offset = 1+hdrb;
-	acum = 1+hdrb;
+        pvar->offset = 1+hdrb;
+        acum = 1+hdrb;
       } 
     }
     else {
@@ -2029,10 +2029,10 @@ int read_gradsdes(char *filename, dsets_t *pfi)
 
     for (i=1; i<pfi->vnum; i++) {
       if (pvar->var_t) {   
-	acum = acum + levs*(pfi->gsiz)*(pfi->dnum[3]); 
+        acum = acum + levs*(pfi->gsiz)*(pfi->dnum[3]); 
       } else {                              
-	acum = acum + (levs*pfi->gsiz);
-	acumstride = acum ;
+        acum = acum + (levs*pfi->gsiz);
+        acumstride = acum ;
       }
       recacm += levs;
       pvar->offset = acum;
@@ -2065,9 +2065,9 @@ int read_gradsdes(char *filename, dsets_t *pfi)
     if (pfi->calendar != /*mfcmn.*/cal365) {
       gaprnt(0,"Attempt to change the global calendar...\n");
       if (/*mfcmn.*/cal365) {
-	gaprnt(0,"The calendar is NOW 365 DAYS and you attempted to open a standard calendar file\n");
+        gaprnt(0,"The calendar is NOW 365 DAYS and you attempted to open a standard calendar file\n");
       } else {
-	gaprnt(0,"The calendar is NOW STANDARD and you attempted to open a 365-day calendar file\n");
+        gaprnt(0,"The calendar is NOW STANDARD and you attempted to open a 365-day calendar file\n");
       }
       goto retrn;
     }
@@ -2080,15 +2080,15 @@ int read_gradsdes(char *filename, dsets_t *pfi)
   if (pfi->tmplat) 
     {
       /* The fnums array is the size of the time axis 
-	 multiplied by the size of the ensemble axis. 
-	 It contains the t index which generates the filename 
-	 that contains the data for each timestep.
-	 If the ensemble has no data file for a given time, 
-	 the fnums value will be -1 */
+         multiplied by the size of the ensemble axis. 
+         It contains the t index which generates the filename 
+         that contains the data for each timestep.
+         If the ensemble has no data file for a given time, 
+         the fnums value will be -1 */
       pfi->fnums = (gaint *)galloc(sizeof(gaint)*pfi->dnum[3]*pfi->dnum[4],"fnums1");   
       if (pfi->fnums==NULL) {
-	gaprnt(0,"Open Error: memory allocation failed for fnums\n");
-	goto err8;
+        gaprnt(0,"Open Error: memory allocation failed for fnums\n");
+        goto err8;
       }
       /* get dt structure for t=1 */
       gr2t(pfi->grvals[3],1.0,&tdefi); 
@@ -2096,85 +2096,85 @@ int read_gradsdes(char *filename, dsets_t *pfi)
       ens=pfi->ens1;
       e=1;
       while (e<=pfi->dnum[4])
-	{
-	  j = -1; 
-	  t=1;
-	  /* set fnums value to -1 for time steps before ensemble initial time */
-	  while (t<ens->gt) {
-	    pfi->fnums[t-1] = j;                                                    
-	    t++;
-	  }
-	  j = ens->gt;
-	  /* get dt structure for ensemble initial time */
-	  gr2t(pfi->grvals[3],ens->gt,&tdefe);
-	  /* get filename for initial time of current ensemble member  */
-	  ch = gafndt(pfi->name,&tdefe,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,ens->gt,e,&flag);   
-	  if (ch==NULL) {
-	    sprintf(pout,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,ens->gt);
-	    gaprnt(0,pout);
-	    goto err8;
-	  }
-	  /* set the pfi->tmplat flag to the flag returned by gafndt */
-	  if (flag==0) {
-	    gaprnt(1,"Warning: OPTIONS keyword \"template\" is used, but the \n");
-	    gaprnt(1,"   DSET entry contains no substitution templates.\n");
-	    pfi->tmplat = 1;
-	  } else {
-	    pfi->tmplat = flag; 
-	  }
-	  /* for non-indexed, non-netcdf/hdf, gridded data */
-	  if (pfi->type==1) {                /* gridded data   */
-	    if (pfi->ncflg==0) {             /* not netcdf/hdf */
-	      if (pfi->idxflg==0) {          /* not indexed    */
-		if ((flag==1) && (pfi->dnum[4]>1)) {
-		  gaprnt(0,"Open Error: If the data type is gridded binary, \n");
-		  gaprnt(0,"  and the E dimension size is greater than 1 \n");
-		  gaprnt(0,"  and templating in the T dimension is used,\n");
-		  gaprnt(0,"  then templating in the E dimension must also be used.\n");
-		  goto retrn;
-		}
-	      }
-	      else if (pfi->idxflg==1) {     /* GRIB1 */
-		if ((flag<2) && (pfi->dnum[4]>1)) {
-		  gaprnt(0,"Open Error: If the data type is GRIB1 \n");
-		  gaprnt(0,"  and the E dimension size is greater than 1 \n");
-		  gaprnt(0,"  then templating in the E dimension must be used.\n");
-		  goto retrn;
-		}
-	      }
-	    }
-	  }
-	  pfi->fnums[t-1] = j;                                                    
-	  /* loop over remaining valid times for this ensemble */
-	  for (t=ens->gt+1; t<ens->gt+ens->length; t++) {
-	    /* get filename for time index=t ens=e */
-	    gr2t(pfi->grvals[3],(gadouble)t,&tdef);
-	    pos = gafndt(pfi->name,&tdef,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,t,e,&flag);  
-	    if (pos==NULL) {
-	      sprintf(pout,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,t);
-	      gaprnt(0,pout);
-	      goto err8;
-	    }
-	    if (strcmp(ch,pos)!=0) {    /* filename has changed */
-	      j = t;   
-	      gree(ch,"f176");
-	      ch = pos;
-	    }
-	    else {
-	      gree(pos,"f176a");
-	    }
-	    pfi->fnums[+t-1] = j;                                                    
-	  }
-	  gree(ch,"f177");
-	  
-	  /* set fnums value to -1 for time steps after ensemble final time */
-	  j = -1;
-	  while (t<=pfi->dnum[3]) {
-	    pfi->fnums[t-1] = j;                                                    
-	    t++;
-	  }
-	  e++; ens++;
-	}
+        {
+          j = -1; 
+          t=1;
+          /* set fnums value to -1 for time steps before ensemble initial time */
+          while (t<ens->gt) {
+            pfi->fnums[t-1] = j;                                                    
+            t++;
+          }
+          j = ens->gt;
+          /* get dt structure for ensemble initial time */
+          gr2t(pfi->grvals[3],ens->gt,&tdefe);
+          /* get filename for initial time of current ensemble member  */
+          ch = gafndt(pfi->name,&tdefe,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,ens->gt,e,&flag);   
+          if (ch==NULL) {
+            sprintf(pout,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,ens->gt);
+            gaprnt(0,pout);
+            goto err8;
+          }
+          /* set the pfi->tmplat flag to the flag returned by gafndt */
+          if (flag==0) {
+            gaprnt(1,"Warning: OPTIONS keyword \"template\" is used, but the \n");
+            gaprnt(1,"   DSET entry contains no substitution templates.\n");
+            pfi->tmplat = 1;
+          } else {
+            pfi->tmplat = flag; 
+          }
+          /* for non-indexed, non-netcdf/hdf, gridded data */
+          if (pfi->type==1) {                /* gridded data   */
+            if (pfi->ncflg==0) {             /* not netcdf/hdf */
+              if (pfi->idxflg==0) {          /* not indexed    */
+                if ((flag==1) && (pfi->dnum[4]>1)) {
+                  gaprnt(0,"Open Error: If the data type is gridded binary, \n");
+                  gaprnt(0,"  and the E dimension size is greater than 1 \n");
+                  gaprnt(0,"  and templating in the T dimension is used,\n");
+                  gaprnt(0,"  then templating in the E dimension must also be used.\n");
+                  goto retrn;
+                }
+              }
+              else if (pfi->idxflg==1) {     /* GRIB1 */
+                if ((flag<2) && (pfi->dnum[4]>1)) {
+                  gaprnt(0,"Open Error: If the data type is GRIB1 \n");
+                  gaprnt(0,"  and the E dimension size is greater than 1 \n");
+                  gaprnt(0,"  then templating in the E dimension must be used.\n");
+                  goto retrn;
+                }
+              }
+            }
+          }
+          pfi->fnums[t-1] = j;                                                    
+          /* loop over remaining valid times for this ensemble */
+          for (t=ens->gt+1; t<ens->gt+ens->length; t++) {
+            /* get filename for time index=t ens=e */
+            gr2t(pfi->grvals[3],(gadouble)t,&tdef);
+            pos = gafndt(pfi->name,&tdef,&tdefe,pfi->abvals[3],pfi->pchsub1,pfi->ens1,t,e,&flag);  
+            if (pos==NULL) {
+              sprintf(pout,"Open Error: couldn't determine data file name for e=%d t=%d\n",e,t);
+              gaprnt(0,pout);
+              goto err8;
+            }
+            if (strcmp(ch,pos)!=0) {    /* filename has changed */
+              j = t;   
+              gree(ch,"f176");
+              ch = pos;
+            }
+            else {
+              gree(pos,"f176a");
+            }
+            pfi->fnums[+t-1] = j;                                                    
+          }
+          gree(ch,"f177");
+          
+          /* set fnums value to -1 for time steps after ensemble final time */
+          j = -1;
+          while (t<=pfi->dnum[3]) {
+            pfi->fnums[t-1] = j;                                                    
+            t++;
+          }
+          e++; ens++;
+        }
       pfi->fnumc = 0;
       pfi->fnume = 0;
     }
diff --git a/src/gradsdeslib.h b/src/gradsdeslib.h
index 3e805c1..49168f0 100644
--- a/src/gradsdeslib.h
+++ b/src/gradsdeslib.h
@@ -35,9 +35,9 @@ struct gavar {
   char abbrv[16];              /* Variable abbreviation.               */
   char longnm[257];            /* netcdf/hdf var name if different     */
   gadouble units[16];          /* Units indicator.                     
-				  Vals 0-7 are for variable codes:
-				  grib, non-float data, nc/hdf dims
-				  Vals  8-11 are for grib level codes  */
+                                  Vals 0-7 are for variable codes:
+                                  grib, non-float data, nc/hdf dims
+                                  Vals  8-11 are for grib level codes  */
   gaint offset;                /* Offset in grid elements of the start
                                   of this variable within a time group
                                   within this file.                    */
@@ -49,8 +49,8 @@ struct gavar {
                                   0 is special and indiates one grid is
                                   available for the surface only.      */
   gaint dfrm;                  /* format  type indicator
-  				  1 - unsigned char
-				  4 - int  			       */
+                                  1 - unsigned char
+                                  4 - int                              */
   gaint var_t ;                /* variable t transform                 */
   gadouble scale;              /* scale factor for unpacking data      */
   gadouble add;                /* offset value for unpacking data      */
@@ -59,7 +59,7 @@ struct gavar {
   gaint isu;                   /* Variable is the u-component of a vector pair */
   gaint isdvar;                /* Variable is a valid data variable (for SDF files) */
   gaint nvardims;              /* Number of variable dimensions        */
-  gaint vardimids[100];        /* Variable dimension IDs. 	       */
+  gaint vardimids[100];        /* Variable dimension IDs.                */
 };
 
 /* Sructure for string substitution in templating -- the %ch template.  
@@ -116,8 +116,8 @@ typedef struct {
   gaint dnum[5];               /* Dimension sizes for this file.        */
   gaint vnum;                  /* Number of variables.                  */
   struct gavar *pvar1;         /* Pointer to an array of structures.
-				  Each structure in the array has info
-				  about the specific variable.          */
+                                  Each structure in the array has info
+                                  about the specific variable.          */
   struct gaens *ens1;          /* pointer to array of ensemble structures */
   gaint wrap;                  /* The grid globally 'wraps' in X        */
   gadouble (*gr2ab[5]) (double *, double);
@@ -160,7 +160,7 @@ gadouble gr2lev (gadouble *, gadouble);
 gadouble lev2gr (gadouble *, gadouble);
 void gr2t (gadouble *, gadouble, struct dt *);
 char *gafndt (char *, struct dt *, struct dt *, gadouble *, 
-	      struct gachsub *, struct gaens *, gaint, gaint, gaint *);
+              struct gachsub *, struct gaens *, gaint, gaint, gaint *);
 
 gaint cmpwrd (char *ch1, char *ch2);
 char *intprs (char *ch, int *val);
diff --git a/src/grid.c b/src/grid.c
index b18c5f9..f5cd0d2 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -55,11 +55,11 @@ void scale_vec(double scalefactor, long nvals, double *restrict values)
 
 void grid_to_radian(const char *units, long nvals, double *restrict values, const char *description)
 {
-  if ( strcompare(units, "degree") == 0 )
+  if ( cmpstr(units, "degree") == 0 )
     {
       scale_vec(DEG2RAD, nvals, values);
     }
-  else if ( strcompare(units, "radian") == 0 )
+  else if ( cmpstr(units, "radian") == 0 )
     {
       /* No conversion necessary */
     }
@@ -72,11 +72,11 @@ void grid_to_radian(const char *units, long nvals, double *restrict values, cons
 
 void grid_to_degree(const char *units, long nvals, double *restrict values, const char *description)
 {
-  if ( strcompare(units, "radian") == 0 )
+  if ( cmpstr(units, "radian") == 0 )
     {
       for ( long n = 0; n < nvals; ++n ) values[n] *= RAD2DEG;
     }
-  else if ( strcompare(units, "degree") == 0 )
+  else if ( cmpstr(units, "degree") == 0 )
     {
       /* No conversion necessary */
     }
diff --git a/src/grid_area.c b/src/grid_area.c
index b480cca..7b29b93 100644
--- a/src/grid_area.c
+++ b/src/grid_area.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -402,34 +402,11 @@ int gridGenArea(int gridID, double* area)
 	}
     }
   
-  /* Convert lat/lon units if required */
-  if ( memcmp(xunitstr, "radian", 6) == 0 )
-    {
-      /* No conversion necessary */
-    }
-  else if ( memcmp(xunitstr, "degree", 6) == 0 )
-    {
-      for ( i = 0; i < gridsize; ++i ) grid_center_lon[i] *= DEG2RAD;
-      for ( i = 0; i < gridsize*nv; ++i ) grid_corner_lon[i] *= DEG2RAD;
-    }
-  else
-    {
-      cdoWarning("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
-    }
+  grid_to_radian(xunitstr, gridsize,    grid_center_lon, "grid1 center longitudes");
+  grid_to_radian(xunitstr, gridsize*nv, grid_corner_lon, "grid1 corner longitudes");
 
-  if ( memcmp(yunitstr, "radian", 6) == 0 )
-    {
-      /* No conversion necessary */
-    }
-  else if ( memcmp(yunitstr, "degree", 6) == 0 )
-    {
-      for ( i = 0; i < gridsize; ++i ) grid_center_lat[i] *= DEG2RAD;
-      for ( i = 0; i < gridsize*nv; ++i ) grid_corner_lat[i] *= DEG2RAD;
-    }
-  else
-    {
-      cdoWarning("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
-    }
+  grid_to_radian(yunitstr, gridsize,    grid_center_lat, "grid1 center latitudes");
+  grid_to_radian(yunitstr, gridsize*nv, grid_corner_lat, "grid1 corner latitudes");
 
   if ( lgriddestroy ) gridDestroy(gridID);
 
diff --git a/src/griddes.c b/src/griddes.c
index 6b1f916..b0eab75 100644
--- a/src/griddes.c
+++ b/src/griddes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -39,8 +39,6 @@
 #include "error.h"
 #include "dtypes.h"
 
-#define  cmpstr(s1, s2, len)  (memcmp(s1, s2, len = strlen(s2)))
-
 /*
 int  extInqPrec(int fileID);
 
@@ -701,229 +699,229 @@ int gridFromFile(FILE *gfp, const char *dname)
       pline = line;
       while ( isspace((int) *pline) ) pline++;
       if ( pline[0] == '\0' ) continue;
-      if ( cmpstr(pline, "gridtype", len) == 0 )
+      if ( cmpstrlen(pline, "gridtype", len) == 0 )
 	{
 	  pline = skipSeparator(pline + len);
-	  if ( cmpstr(pline, "lonlat", len)  == 0 ||
-	       cmpstr(pline, "latlon", len)  == 0 )
+	  if ( cmpstrlen(pline, "lonlat", len)  == 0 ||
+	       cmpstrlen(pline, "latlon", len)  == 0 )
 	    {
 	      grid.type = GRID_LONLAT;
 	      grid.nvertex = 2;
 	    }
-	  else if ( cmpstr(pline, "gaussian", len)  == 0 )
+	  else if ( cmpstrlen(pline, "gaussian", len)  == 0 )
 	    {
 	      grid.type = GRID_GAUSSIAN;
 	      grid.nvertex = 2;
 	    }
-	  else if ( cmpstr(pline, "curvilinear", len)  == 0 )
+	  else if ( cmpstrlen(pline, "curvilinear", len)  == 0 )
 	    {
 	      grid.type = GRID_CURVILINEAR;
 	      grid.nvertex = 4;
 	    }
-	  else if ( cmpstr(pline, "spectral", len)  == 0 )
+	  else if ( cmpstrlen(pline, "spectral", len)  == 0 )
 	    grid.type = GRID_SPECTRAL;
-	  else if ( cmpstr(pline, "unstructured", len)  == 0 )
+	  else if ( cmpstrlen(pline, "unstructured", len)  == 0 )
 	    grid.type = GRID_UNSTRUCTURED;
-	  else if ( cmpstr(pline, "cell", len)  == 0 )
+	  else if ( cmpstrlen(pline, "cell", len)  == 0 )
 	    grid.type = GRID_UNSTRUCTURED;
-	  else if ( cmpstr(pline, "gme", len)  == 0 )
+	  else if ( cmpstrlen(pline, "gme", len)  == 0 )
 	    grid.type = GRID_GME;
-	  else if ( cmpstr(pline, "lcc2", len)  == 0 )
+	  else if ( cmpstrlen(pline, "lcc2", len)  == 0 )
 	    grid.type = GRID_LCC2;
-	  else if ( cmpstr(pline, "lcc", len)  == 0 )
+	  else if ( cmpstrlen(pline, "lcc", len)  == 0 )
 	    grid.type = GRID_LCC;
-	  else if ( cmpstr(pline, "lambert", len)  == 0 )
+	  else if ( cmpstrlen(pline, "lambert", len)  == 0 )
 	    grid.type = GRID_LCC;
-	  else if ( cmpstr(pline, "sinusoidal", len)  == 0 )
+	  else if ( cmpstrlen(pline, "sinusoidal", len)  == 0 )
 	    grid.type = GRID_SINUSOIDAL;
-	  else if ( cmpstr(pline, "laea", len)  == 0 )
+	  else if ( cmpstrlen(pline, "laea", len)  == 0 )
 	    grid.type = GRID_LAEA;
-	  else if ( cmpstr(pline, "generic", len)  == 0 )
+	  else if ( cmpstrlen(pline, "generic", len)  == 0 )
 	    grid.type = GRID_GENERIC;
 	  else
 	    cdoAbort("Invalid grid name : %s (grid description file: %s)", pline, dname);
 	}
-      else if ( cmpstr(pline, "gridprec", len)  == 0 )
+      else if ( cmpstrlen(pline, "gridprec", len)  == 0 )
 	{
 	  grid.prec = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "gridsize", len)  == 0 )
+      else if ( cmpstrlen(pline, "gridsize", len)  == 0 )
 	{
 	  grid.size = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "truncation", len)  == 0 )
+      else if ( cmpstrlen(pline, "truncation", len)  == 0 )
 	{
 	  grid.ntr = atoi(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "np", len)  == 0 )
+      else if ( cmpstrlen(pline, "np", len)  == 0 )
 	{
 	  grid.np = atoi(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "complexpacking", len)  == 0 )
+      else if ( cmpstrlen(pline, "complexpacking", len)  == 0 )
 	{
 	  grid.lcomplex = atoi(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "xname", len)  == 0 )
+      else if ( cmpstrlen(pline, "xname", len)  == 0 )
 	{
 	  strcpy(grid.xname, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "xlongname", len)  == 0 )
+      else if ( cmpstrlen(pline, "xlongname", len)  == 0 )
 	{
 	  strcpy(grid.xlongname, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "xunits", len)  == 0 )
+      else if ( cmpstrlen(pline, "xunits", len)  == 0 )
 	{
 	  strcpy(grid.xunits, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "yname", len)  == 0 )
+      else if ( cmpstrlen(pline, "yname", len)  == 0 )
 	{
 	  strcpy(grid.yname, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "ylongname", len)  == 0 )
+      else if ( cmpstrlen(pline, "ylongname", len)  == 0 )
 	{
 	  strcpy(grid.ylongname, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "yunits", len)  == 0 )
+      else if ( cmpstrlen(pline, "yunits", len)  == 0 )
 	{
 	  strcpy(grid.yunits, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "nvertex", len)  == 0 )
+      else if ( cmpstrlen(pline, "nvertex", len)  == 0 )
 	{
 	  grid.nvertex = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "ni", len)  == 0 )
+      else if ( cmpstrlen(pline, "ni", len)  == 0 )
 	{
 	  grid.ni = atol(skipSeparator(pline + len));
           grid.nd = 10;
 	}
-      else if ( cmpstr(pline, "position", len)  == 0 )
+      else if ( cmpstrlen(pline, "position", len)  == 0 )
 	{
 	  grid.position = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "number", len)  == 0 )
+      else if ( cmpstrlen(pline, "number", len)  == 0 )
 	{
 	  grid.number = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "path", len)  == 0 )
+      else if ( cmpstrlen(pline, "path", len)  == 0 )
 	{
 	  strcpy(grid.path, skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "uuid", len)  == 0 )
+      else if ( cmpstrlen(pline, "uuid", len)  == 0 )
 	{
 	  char uuidOfHGridStr[256];
 	  strcpy(uuidOfHGridStr, skipSeparator(pline + len));
 	  str2uuid(uuidOfHGridStr, grid.uuid);
 	}
-      else if ( cmpstr(pline, "xsize", len)  == 0 )
+      else if ( cmpstrlen(pline, "xsize", len)  == 0 )
 	{
 	  grid.xsize = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "nlon", len)  == 0 )
+      else if ( cmpstrlen(pline, "nlon", len)  == 0 )
 	{
 	  grid.xsize = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "ysize", len)  == 0 )
+      else if ( cmpstrlen(pline, "ysize", len)  == 0 )
 	{
 	  grid.ysize = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "nlat", len)  == 0 )
+      else if ( cmpstrlen(pline, "nlat", len)  == 0 )
 	{
 	  grid.ysize = atol(skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "xfirst", len)  == 0 )
+      else if ( cmpstrlen(pline, "xfirst", len)  == 0 )
 	{
 	  grid.xfirst = readflt(dname, "xfirst", skipSeparator(pline + len));
 	  grid.def_xfirst = TRUE;
 	}
-      else if ( cmpstr(pline, "lonfirst", len)  == 0 )
+      else if ( cmpstrlen(pline, "lonfirst", len)  == 0 )
 	{
 	  grid.xfirst = readflt(dname, "lonfirst", skipSeparator(pline + len));
 	  grid.def_xfirst = TRUE;
 	}
-      else if ( cmpstr(pline, "yfirst", len)  == 0 )
+      else if ( cmpstrlen(pline, "yfirst", len)  == 0 )
 	{
 	  grid.yfirst = readflt(dname, "yfirst", skipSeparator(pline + len));
 	  grid.def_yfirst = TRUE;
 	}
-      else if ( cmpstr(pline, "latfirst", len)  == 0 )
+      else if ( cmpstrlen(pline, "latfirst", len)  == 0 )
 	{
 	  grid.yfirst = readflt(dname, "latfirst", skipSeparator(pline + len));
 	  grid.def_yfirst = TRUE;
 	}
-      else if ( cmpstr(pline, "xlast", len)  == 0 )
+      else if ( cmpstrlen(pline, "xlast", len)  == 0 )
 	{
 	  grid.xlast = readflt(dname, "xlast", skipSeparator(pline + len));
 	  grid.def_xlast = TRUE;
 	}
-      else if ( cmpstr(pline, "lonlast", len)  == 0 )
+      else if ( cmpstrlen(pline, "lonlast", len)  == 0 )
 	{
 	  grid.xlast = readflt(dname, "lonlast", skipSeparator(pline + len));
 	  grid.def_xlast = TRUE;
 	}
-      else if ( cmpstr(pline, "ylast", len)  == 0 )
+      else if ( cmpstrlen(pline, "ylast", len)  == 0 )
 	{
 	  grid.ylast = readflt(dname, "ylast", skipSeparator(pline + len));
 	  grid.def_ylast = TRUE;
 	}
-      else if ( cmpstr(pline, "latlast", len)  == 0 )
+      else if ( cmpstrlen(pline, "latlast", len)  == 0 )
 	{
 	  grid.ylast = readflt(dname, "latlast", skipSeparator(pline + len));
 	  grid.def_ylast = TRUE;
 	}
-      else if ( cmpstr(pline, "xinc", len)  == 0 )
+      else if ( cmpstrlen(pline, "xinc", len)  == 0 )
 	{
 	  grid.xinc = readflt(dname, "xinc", skipSeparator(pline + len));
 	  grid.def_xinc = TRUE;
 	}
-      else if ( cmpstr(pline, "loninc", len)  == 0 )
+      else if ( cmpstrlen(pline, "loninc", len)  == 0 )
 	{
 	  grid.xinc = readflt(dname, "loninc", skipSeparator(pline + len));
 	  grid.def_xinc = TRUE;
 	}
-      else if ( cmpstr(pline, "yinc", len)  == 0 )
+      else if ( cmpstrlen(pline, "yinc", len)  == 0 )
 	{
 	  grid.yinc = readflt(dname, "yinc", skipSeparator(pline + len));
 	  grid.def_yinc = TRUE;
 	}
-      else if ( cmpstr(pline, "latinc", len)  == 0 )
+      else if ( cmpstrlen(pline, "latinc", len)  == 0 )
 	{
 	  grid.yinc = readflt(dname, "latinc", skipSeparator(pline + len));
 	  grid.def_yinc = TRUE;
 	}
-      else if ( cmpstr(pline, "originLon", len)  == 0 )
+      else if ( cmpstrlen(pline, "originLon", len)  == 0 )
 	{
 	  grid.originLon = readflt(dname, "originLon", skipSeparator(pline + len));
 	  grid.def_originLon = TRUE;
 	}
-      else if ( cmpstr(pline, "originLat", len)  == 0 )
+      else if ( cmpstrlen(pline, "originLat", len)  == 0 )
 	{
 	  grid.originLat = readflt(dname, "originLat", skipSeparator(pline + len));
 	  grid.def_originLat = TRUE;
 	}
-      else if ( cmpstr(pline, "lonParY", len)  == 0 )
+      else if ( cmpstrlen(pline, "lonParY", len)  == 0 )
 	{
 	  grid.lonParY = readflt(dname, "lonParY", skipSeparator(pline + len));
 	  grid.def_lonParY = TRUE;
 	}
-      else if ( cmpstr(pline, "lat1", len)  == 0 )
+      else if ( cmpstrlen(pline, "lat1", len)  == 0 )
 	{
 	  grid.lat1 = readflt(dname, "lat1", skipSeparator(pline + len));
 	  grid.def_lat1 = TRUE;
 	}
-      else if ( cmpstr(pline, "lat2", len)  == 0 )
+      else if ( cmpstrlen(pline, "lat2", len)  == 0 )
 	{
 	  grid.lat2 = readflt(dname, "lat2", skipSeparator(pline + len));
 	  grid.def_lat2 = TRUE;
 	}
-      else if ( cmpstr(pline, "projection", len)  == 0 )
+      else if ( cmpstrlen(pline, "projection", len)  == 0 )
 	{
 	  pline = skipSeparator(pline + len);
-	  if      ( cmpstr(pline, "north", len) == 0 )
+	  if      ( cmpstrlen(pline, "north", len) == 0 )
 	    {
 	      grid.projflag = 0;
 	      grid.scanflag = 64;
 	    }
-	  else if ( cmpstr(pline, "south", len) == 0 )
+	  else if ( cmpstrlen(pline, "south", len) == 0 )
 	    {
 	      grid.projflag = 128;
 	      grid.scanflag = 64;
@@ -931,56 +929,56 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  else
 	    cdoAbort("Invalid projection : %s (grid description file: %s)", pline, dname);
 	}
-      else if ( cmpstr(pline, "lon_0", len)  == 0 )
+      else if ( cmpstrlen(pline, "lon_0", len)  == 0 )
 	{
 	  grid.lon_0 = readflt(dname, "lon_0", skipSeparator(pline + len));
 	  grid.def_lon_0 = TRUE;
 	}
-      else if ( cmpstr(pline, "lat_0", len)  == 0 )
+      else if ( cmpstrlen(pline, "lat_0", len)  == 0 )
 	{
 	  grid.lat_0 = readflt(dname, "lat_0", skipSeparator(pline + len));
 	  grid.def_lat_0 = TRUE;
 	}
-      else if ( cmpstr(pline, "lat_1", len)  == 0 )
+      else if ( cmpstrlen(pline, "lat_1", len)  == 0 )
 	{
 	  grid.lat_1 = readflt(dname, "lat_1", skipSeparator(pline + len));
 	  grid.def_lat_1 = TRUE;
 	}
-      else if ( cmpstr(pline, "lat_2", len)  == 0 )
+      else if ( cmpstrlen(pline, "lat_2", len)  == 0 )
 	{
 	  grid.lat_2 = readflt(dname, "lat_2", skipSeparator(pline + len));
 	  grid.def_lat_2 = TRUE;
 	}
-      else if ( cmpstr(pline, "xnpole", len)  == 0 )
+      else if ( cmpstrlen(pline, "xnpole", len)  == 0 )
 	{
 	  grid.xpole = readflt(dname, "xnpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
-      else if ( cmpstr(pline, "lonpole", len)  == 0 )
+      else if ( cmpstrlen(pline, "lonpole", len)  == 0 )
 	{
 	  grid.xpole = readflt(dname, "lonpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
-      else if ( cmpstr(pline, "ynpole", len)  == 0 )
+      else if ( cmpstrlen(pline, "ynpole", len)  == 0 )
 	{
 	  grid.ypole = readflt(dname, "ynpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
-      else if ( cmpstr(pline, "latpole", len)  == 0 )
+      else if ( cmpstrlen(pline, "latpole", len)  == 0 )
 	{
 	  grid.ypole = readflt(dname, "latpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
-      else if ( cmpstr(pline, "angle", len)  == 0 )
+      else if ( cmpstrlen(pline, "angle", len)  == 0 )
 	{
 	  grid.angle = readflt(dname, "angle", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
-      else if ( cmpstr(pline, "a", len)  == 0 )
+      else if ( cmpstrlen(pline, "a", len)  == 0 )
 	{
 	  grid.a = readflt(dname, "a", skipSeparator(pline + len));
 	}
-      else if ( cmpstr(pline, "gridlatlon", len)  == 0 )
+      else if ( cmpstrlen(pline, "gridlatlon", len)  == 0 )
 	{
 	  int i;
 	  double flat = 0, flon = 0;
@@ -998,7 +996,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	      grid.xvals[i] = flon;
 	    }
 	}
-      else if ( cmpstr(pline, "mask", len)  == 0 )
+      else if ( cmpstrlen(pline, "mask", len)  == 0 )
 	{
 	  int i = 0;
 	  long lval;
@@ -1038,7 +1036,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  else
 	    cdoAbort("gridsize undefined (grid description file: %s)!", dname);
 	}
-      else if ( cmpstr(pline, "xvals", len)  == 0 )
+      else if ( cmpstrlen(pline, "xvals", len)  == 0 )
 	{
 	  int i = 0;
 	  double fval;
@@ -1073,7 +1071,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  else
 	    cdoAbort("xsize or gridsize undefined (grid description file: %s)!", dname);
 	}
-      else if ( cmpstr(pline, "yvals", len)  == 0 )
+      else if ( cmpstrlen(pline, "yvals", len)  == 0 )
 	{
 	  int i = 0;
 	  double fval;
@@ -1108,7 +1106,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  else
 	    cdoAbort("ysize or gridsize undefined (grid description file: %s)!", dname);
 	}
-      else if ( cmpstr(pline, "xbounds", len)  == 0 )
+      else if ( cmpstrlen(pline, "xbounds", len)  == 0 )
 	{
 	  int i = 0;
 	  double fval;
@@ -1151,7 +1149,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	      if ( grid.nvertex == 0 ) cdoAbort("nvertex undefined (grid description file: %s)!", dname);
 	    }
 	}
-      else if ( cmpstr(pline, "ybounds", len)  == 0 )
+      else if ( cmpstrlen(pline, "ybounds", len)  == 0 )
 	{
 	  int i = 0;
 	  double fval;
@@ -1531,10 +1529,10 @@ int gridFromName(const char *gridname)
 	{
 	  grid.ntr = atoi(pline);
 	  while ( isdigit((int) *pline) ) pline++;
-	  if      ( cmpstr(pline, "grid", len) == 0 ) grid.type = GRID_GAUSSIAN;
-	  else if ( cmpstr(pline, "zon",  len) == 0 ) grid.type = GRID_GAUSSIAN;
-	  else if ( cmpstr(pline, "spec", len) == 0 ) grid.type = GRID_SPECTRAL;
-	  else if ( cmpstr(pline, "",     len) == 0 ) grid.type = GRID_SPECTRAL;
+	  if      ( cmpstrlen(pline, "grid", len) == 0 ) grid.type = GRID_GAUSSIAN;
+	  else if ( cmpstrlen(pline, "zon",  len) == 0 ) grid.type = GRID_GAUSSIAN;
+	  else if ( cmpstrlen(pline, "spec", len) == 0 ) grid.type = GRID_SPECTRAL;
+	  else if ( cmpstrlen(pline, "",     len) == 0 ) grid.type = GRID_SPECTRAL;
       
 	  if ( pline[len] != 0 ) return (gridID);
 
@@ -1542,7 +1540,7 @@ int gridFromName(const char *gridname)
 	    {
 	      grid.ysize = ntr2nlat_linear(grid.ntr);
 	      grid.np    = grid.ysize/2;
-	      if ( cmpstr(pline, "zon",  len) == 0 )
+	      if ( cmpstrlen(pline, "zon",  len) == 0 )
 		grid.xsize = 1;
 	      else
 		grid.xsize = compNlon(grid.ysize);
@@ -1559,10 +1557,10 @@ int gridFromName(const char *gridname)
 	{
 	  grid.ntr = atoi(pline);
 	  while ( isdigit((int) *pline) ) pline++;
-	  if      ( cmpstr(pline, "grid", len) == 0 ) grid.type = GRID_GAUSSIAN;
-	  else if ( cmpstr(pline, "zon",  len) == 0 ) grid.type = GRID_GAUSSIAN;
-	  else if ( cmpstr(pline, "spec", len) == 0 ) grid.type = GRID_SPECTRAL;
-	  else if ( cmpstr(pline, "",     len) == 0 ) grid.type = GRID_SPECTRAL;
+	  if      ( cmpstrlen(pline, "grid", len) == 0 ) grid.type = GRID_GAUSSIAN;
+	  else if ( cmpstrlen(pline, "zon",  len) == 0 ) grid.type = GRID_GAUSSIAN;
+	  else if ( cmpstrlen(pline, "spec", len) == 0 ) grid.type = GRID_SPECTRAL;
+	  else if ( cmpstrlen(pline, "",     len) == 0 ) grid.type = GRID_SPECTRAL;
      
 	  if ( pline[len] != 0 ) return (gridID);
 
@@ -1570,7 +1568,7 @@ int gridFromName(const char *gridname)
 	    {
 	      grid.ysize = ntr2nlat(grid.ntr);
 	      grid.np    = grid.ysize/2;
-	      if ( cmpstr(pline, "zon",  len) == 0 )
+	      if ( cmpstrlen(pline, "zon",  len) == 0 )
 		grid.xsize = 1;
 	      else
 		grid.xsize = compNlon(grid.ysize);
@@ -1660,7 +1658,7 @@ int gridFromName(const char *gridname)
 	  long np = strtol(pline, &endptr, 10);
 	  pline = endptr;
 
-	  if ( cmpstr(pline, "zon",  len) == 0 )
+	  if ( cmpstrlen(pline, "zon",  len) == 0 )
 	    {
 	      grid.xsize = 1;
 	      pline += 3;
@@ -1791,7 +1789,7 @@ int cdoDefineGrid(const char *gridfile)
 
       close(fileno);
 
-      if ( cmpstr(buffer, "CDF", len) == 0 )
+      if ( cmpstrlen(buffer, "CDF", len) == 0 )
 	{
 	  if ( cdoDebug ) cdoPrint("Grid from netCDF file");
 	  gridID = gridFromNCfile(filename);
@@ -1799,7 +1797,7 @@ int cdoDefineGrid(const char *gridfile)
 
       if ( gridID == -1 )
 	{
-	  if ( cmpstr(buffer+1, "HDF", len) == 0 )
+	  if ( cmpstrlen(buffer+1, "HDF", len) == 0 )
 	    {
 	      if ( cdoDebug ) cdoPrint("Grid from HDF5 file");
 	      gridID = gridFromH5file(filename);
@@ -1808,7 +1806,7 @@ int cdoDefineGrid(const char *gridfile)
 
       if ( gridID == -1 )
 	{
-	  if ( cmpstr(buffer+1, "HDF", len) == 0 )
+	  if ( cmpstrlen(buffer+1, "HDF", len) == 0 )
 	    {
 	      if ( cdoDebug ) cdoPrint("Grid from netCDF4 file");
 	      gridID = gridFromNCfile(filename);
diff --git a/src/gridreference.c b/src/gridreference.c
index ddd8f71..e05a1d0 100644
--- a/src/gridreference.c
+++ b/src/gridreference.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -196,7 +196,6 @@ int referenceToGrid(int gridID1)
       status = search_file("./", gridpath);
       if ( status != 0 )
 	{
-	  extern char *cdoGridSearchDir;
 	  if ( cdoGridSearchDir != NULL)
 	    {
 	      strcpy(gridpath, cdoGridSearchDir);
diff --git a/src/institution.c b/src/institution.c
index 5a1676f..a2a1065 100644
--- a/src/institution.c
+++ b/src/institution.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,8 +29,6 @@
 #define UNDEFID  CDI_UNDEFID
 #endif
 
-int cdoDefaultInstID = UNDEFID;
-
 static
 int readInstitution(const char *instfile)
 {
diff --git a/src/interpol.c b/src/interpol.c
index 142429d..5e08408 100644
--- a/src/interpol.c
+++ b/src/interpol.c
@@ -632,8 +632,8 @@ void intconarr2(double missval, int lon_is_circular,
 	  if ( weight[k] > 0 )
 	    {
 	      if ( cdoVerbose )
-		printf("tgt_grid_add %ld, src_grid_add %ld,  weight[n] %g, tgt_area  %g\n", i, index1,  weight[k], tgt_area);
-	      //printf("tgt_grid_add %ld, n %ld, src_grid_add %ld,  weight[n] %g, tgt_area  %g\n", i, k, index1,  weight[k], tgt_area);
+		printf("tgt_cell_add %ld, src_cell_add %ld,  weight[n] %g, tgt_area  %g\n", i, index1,  weight[k], tgt_area);
+	      //printf("tgt_cell_add %ld, n %ld, src_cell_add %ld,  weight[n] %g, tgt_area  %g\n", i, k, index1,  weight[k], tgt_area);
 	      field[i] += fieldm[index1] * weight[k];
 	    }
 	  /*
diff --git a/src/kvlist.c b/src/kvlist.c
index e9032b5..ccc9b75 100644
--- a/src/kvlist.c
+++ b/src/kvlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/kvlist.h b/src/kvlist.h
index 663f490..3d0ca33 100644
--- a/src/kvlist.h
+++ b/src/kvlist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/list.c b/src/list.c
index 2af5a89..b2ca445 100644
--- a/src/list.c
+++ b/src/list.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <float.h>
+#include "cdo_int.h"
 #include "dmemory.h"
 #include "list.h"
 
@@ -128,10 +129,9 @@ int get_ival(const char *intstr, int idefault, int istart, int iend, int *ilast)
       if ( ! (isdigit(intstr[i]) || intstr[i] == '-') )
 	{
 	  if ( intstr[i] == '/' )
-	    ival = atoi(intstr+i+1);
+	    ival = parameter2intlist(intstr+i+1);
 	  else
-	    fprintf(stderr, "Syntax error in >%.*s<! Character %c not allowed.\n",
-		    iend, intstr, intstr[i]);
+	    fprintf(stderr, "Syntax error in >%.*s<! Character %c not allowed.\n", iend, intstr, intstr[i]);
 	  break;
 	}
     }
@@ -148,7 +148,7 @@ void split_intstring(const char *intstr, int *first, int *last, int *inc)
   int istrlen;
 
   istrlen = strlen(intstr);
-  *first = atoi(intstr);
+  *first = parameter2intlist(intstr);
   *last  = *first;
   *inc   = 1;
 
@@ -214,7 +214,7 @@ int args2fltlist(int argc, char **argv, LIST *list)
 	    tmp_val = -DBL_MAX;
 	  else  
 	  */                                    
-	    tmp_val = atof(argv[iarg]);
+	    tmp_val = parameter2double(argv[iarg]);
 
 	  listSetFlt(list, nint++, tmp_val);
 	}
diff --git a/src/list.h b/src/list.h
index 705d888..49a9fe2 100644
--- a/src/list.h
+++ b/src/list.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/modules.c b/src/modules.c
index 9ce3864..9af638b 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -43,6 +43,7 @@ modules_t;
 
 
 void *Adisit(void *argument);
+void *Afterburner(void *argument);
 void *Arith(void *argument);
 void *Arithc(void *argument);
 void *Arithdays(void *argument);
@@ -198,7 +199,8 @@ void *Tstepcount(void *argument);
 void *Vardup(void *argument);
 void *Vargen(void *argument);
 void *Varrms(void *argument);
-void *Vertint(void *argument);
+void *Vertintml(void *argument);
+void *Vertintap(void *argument);
 void *Vertstat(void *argument);
 void *Vertwind(void *argument);
 void *Wind(void *argument);
@@ -272,7 +274,8 @@ void *Maggraph(void *argument);
 #endif
 
 
-#define  AdisitOperators        {"adisit","adipot"}
+#define  AdisitOperators        {"adisit", "adipot"}
+#define  AfterburnerOperators   {"afterburner", "after"}
 #define  ArithOperators         {"add",  "sub",  "mul",  "div", "min", "max", "atan2"}
 #define  ArithcOperators        {"addc", "subc", "mulc", "divc", "mod"}
 #define  ArithdaysOperators     {"muldpm", "divdpm", "muldpy", "divdpy", "muldoy"}
@@ -386,7 +389,7 @@ void *Maggraph(void *argument);
 #define  SelboxOperators        {"sellonlatbox", "selindexbox"}
 #define  SelectOperators        {"select", "delete"}
 #define  SelvarOperators        {"selparam", "selcode", "selname", "selstdname", "sellevel", "sellevidx", "selgrid", \
-                                 "selzaxis", "seltabnum", "delparam", "delcode", "delname", "selltype"}
+                                 "selzaxis", "selzaxisname", "seltabnum", "delparam", "delcode", "delname", "selltype"}
 #define  SeloperatorOperators   {"seloperator"}
 #define  SelrecOperators        {"selrec"}
 #define  SeltimeOperators       {"seltimestep", "selyear", "selseas", "selmon", "selday", "selhour", "seldate", \
@@ -402,7 +405,7 @@ void *Maggraph(void *argument);
 #define  SetrcanameOperators    {"setrcaname"}
 #define  SettimeOperators       {"setyear", "setmon", "setday", "setdate", "settime", "settunits", \
                                  "settaxis", "setreftime", "setcalendar", "shifttime"}
-#define  SetzaxisOperators      {"setzaxis"}
+#define  SetzaxisOperators      {"setzaxis", "genlevelbounds"}
 #define  ShowinfoOperators      {"showyear", "showmon", "showdate", "showtime", "showtimestamp", "showcode", "showunit", \
                                  "showparam", "showname", "showstdname", "showlevel", "showltype", "showformat"}
 #define  SinfoOperators         {"sinfo", "sinfop", "sinfon", "sinfoc", "seinfo", "seinfop", "seinfon", "seinfoc"}
@@ -416,7 +419,7 @@ void *Maggraph(void *argument);
 #define  SplitrecOperators      {"splitrec"}
 #define  SplitselOperators      {"splitsel"}
 #define  SplittimeOperators     {"splithour", "splitday", "splitmon", "splitseas"}
-#define  SplityearOperators     {"splityear"}
+#define  SplityearOperators     {"splityear", "splityearmon"}
 #define  SSOparOperators        {"ssopar"}
 #define  SubtrendOperators      {"subtrend"}
 #define  TeeOperators           {"tee"}
@@ -456,8 +459,9 @@ void *Maggraph(void *argument);
 #define  VardupOperators        {"pardup", "parmul"}
 #define  VargenOperators        {"random", "const", "sincos", "coshill", "for", "topo", "temp", "mask", "stdatm"}
 #define  VarrmsOperators        {"varrms"}
-#define  VertintOperators       {"ml2pl", "ml2hl", "ml2plx", "ml2hlx", "ml2pl_lp", "ml2hl_lp", "ml2plx_lp", "ml2hlx_lp"}
-#define  VertstatOperators      {"vertmin", "vertmax", "vertsum", "vertmean", "vertavg", "vertvar", "vertstd"}
+#define  VertintmlOperators     {"ml2pl", "ml2hl", "ml2plx", "ml2hlx", "ml2pl_lp", "ml2hl_lp", "ml2plx_lp", "ml2hlx_lp"}
+#define  VertintapOperators     {"ap2pl", "ap2plx", "ap2pl_lp", "ap2plx_lp"}
+#define  VertstatOperators      {"vertmin", "vertmax", "vertsum", "vertint", "vertmean", "vertavg", "vertvar", "vertstd"}
 #define  VertwindOperators      {"vertwind"}
 #define  WindOperators          {"uv2dv", "uv2dvl", "dv2uv", "dv2uvl", "dv2ps"}
 #define  WritegridOperators     {"writegrid"}
@@ -472,6 +476,7 @@ void *Maggraph(void *argument);
 #define  YhourarithOperators    {"yhouradd", "yhoursub", "yhourmul", "yhourdiv"}
 #define  YhourstatOperators     {"yhourmin", "yhourmax", "yhoursum", "yhourmean", "yhouravg", "yhourstd", "yhourstd1", "yhourvar", "yhourvar1"}
 #define  YmonarithOperators     {"ymonadd", "ymonsub", "ymonmul", "ymondiv"}
+#define  YseasarithOperators    {"yseasadd", "yseassub", "yseasmul", "yseasdiv"}
 #define  YmonpctlOperators      {"ymonpctl"}
 #define  YmonstatOperators      {"ymonmin", "ymonmax", "ymonsum", "ymonmean", "ymonavg", "ymonstd", "ymonstd1", "ymonvar", "ymonvar1"}
 #define  YseaspctlOperators     {"yseaspctl"}
@@ -542,6 +547,7 @@ static modules_t Modules[] =
                                                                type       in  out
   */
   { Adisit,         AdisitHelp,        AdisitOperators,        CDI_REAL,  1,  1 },
+  { Afterburner,    AfterburnerHelp,   AfterburnerOperators,   CDI_REAL, -1,  1 },
   { Arith,          ArithHelp,         ArithOperators,         CDI_REAL,  2,  1 },
   { Arithc,         ArithcHelp,        ArithcOperators,        CDI_REAL,  1,  1 },
   { Arithdays,      ArithdaysHelp,     ArithdaysOperators,     CDI_REAL,  1,  1 },
@@ -641,7 +647,7 @@ static modules_t Modules[] =
   { Replace,        ReplaceHelp,       ReplaceOperators,       CDI_REAL,  2,  1 },
   { Replacevalues,  ReplacevaluesHelp, ReplacevaluesOperators, CDI_REAL,  1,  1 },
   { Rhopot,         RhopotHelp,        RhopotOperators,        CDI_REAL,  1,  1 },
-  { Rotuv,          RotuvHelp,         RotuvOperators,         CDI_REAL,  1,  1 },
+  { Rotuv,          RotuvbHelp,        RotuvOperators,         CDI_REAL,  1,  1 },
   { Runpctl,        RunpctlHelp,       RunpctlOperators,       CDI_REAL,  1,  1 },
   { Runstat,        RunstatHelp,       RunstatOperators,       CDI_REAL,  1,  1 },
   { Seascount,      NULL,              SeascountOperators,     CDI_BOTH,  1,  1 },
@@ -716,7 +722,8 @@ static modules_t Modules[] =
   { Vardup,         NULL,              VardupOperators,        CDI_REAL,  1,  1 },
   { Vargen,         VargenHelp,        VargenOperators,        CDI_REAL,  0,  1 },
   { Varrms,         NULL,              VarrmsOperators,        CDI_REAL,  2,  1 },
-  { Vertint,        IntvertHelp,       VertintOperators,       CDI_REAL,  1,  1 },
+  { Vertintml,      IntvertHelp,       VertintmlOperators,     CDI_REAL,  1,  1 },
+  { Vertintap,      NULL,              VertintapOperators,     CDI_REAL,  1,  1 },
   { Vertstat,       VertstatHelp,      VertstatOperators,      CDI_REAL,  1,  1 },
   { Vertwind,       NULL,              VertwindOperators,      CDI_REAL,  1,  1 },
   { Wind,           WindHelp,          WindOperators,          CDI_REAL,  1,  1 },
@@ -732,6 +739,7 @@ static modules_t Modules[] =
   { Yhourarith,     YhourarithHelp,    YhourarithOperators,    CDI_REAL,  2,  1 },
   { Yhourstat,      YhourstatHelp,     YhourstatOperators,     CDI_REAL,  1,  1 },
   { Ymonarith,      YmonarithHelp,     YmonarithOperators,     CDI_REAL,  2,  1 },
+  { Ymonarith,      YseasarithHelp,    YseasarithOperators,    CDI_REAL,  2,  1 },
   { Ymonpctl,       YmonpctlHelp,      YmonpctlOperators,      CDI_REAL,  3,  1 },
   { Ymonstat,       YmonstatHelp,      YmonstatOperators,      CDI_REAL,  1,  1 },
   { Yseaspctl,      YseaspctlHelp,     YseaspctlOperators,     CDI_REAL,  3,  1 },
@@ -822,7 +830,6 @@ static char *opalias[][2] =
   {"scatter",             "distgrid"   },
   {"showvar",             "showname"   },
   {"selgridname",         "selgrid"    },
-  {"selzaxisname",        "selzaxis"   },
   {"selvar",              "selname"    },
   {"setvar",              "setname"    },
   {"setpartabv",          "setpartabn" },
diff --git a/src/modules.h b/src/modules.h
index b2cdf30..8a1f1cf 100644
--- a/src/modules.h
+++ b/src/modules.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/namelist.c b/src/namelist.c
index e08c844..066243d 100644
--- a/src/namelist.c
+++ b/src/namelist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/namelist.h b/src/namelist.h
index c4465f4..57a82e5 100644
--- a/src/namelist.h
+++ b/src/namelist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/operator_help.h b/src/operator_help.h
index cf68222..31473ba 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -277,7 +277,7 @@ static char *MergeHelp[] = {
     "",
     "ENVIRONMENT",
     "    SKIP_SAME_TIME",
-    "        If set to 1, skips all timesteps with a double entry of the same timestamp.",
+    "        If set to 1, skips all consecutive timesteps with a double entry of the same timestamp.",
     NULL
 };
 
@@ -287,20 +287,21 @@ static char *SplitHelp[] = {
     "    splittabnum - Split a dataset",
     "",
     "SYNOPSIS",
-    "    <operator>[,swap]  ifile obase",
+    "    <operator>[,params]  ifile obase",
     "",
     "DESCRIPTION",
     "    This module splits ifile into pieces. The output files will be named <obase><xxx><suffix>",
     "    where suffix is the filename extension derived from the file format. xxx and the contents ",
     "    of the output files depends on the chosen operator. ",
+    "    params is a comma separated list of processing parameters.",
     "",
     "OPERATORS",
     "    splitcode    Split code numbers",
     "                 Splits a dataset into pieces, one for each different code number.",
     "                 xxx will have three digits with the code number.",
-    "    splitparam   Split parammeter identifiers",
-    "                 Splits a dataset into pieces, one for each different parammeter identifier.",
-    "                 xxx will be a string with the parammeter identifier.",
+    "    splitparam   Split parameter identifiers",
+    "                 Splits a dataset into pieces, one for each different parameter identifier.",
+    "                 xxx will be a string with the parameter identifier.",
     "    splitname    Split variable names",
     "                 Splits a dataset into pieces, one for each variable name.",
     "                 xxx will be a string with the variable name.",
@@ -318,7 +319,8 @@ static char *SplitHelp[] = {
     "                 xxx will have three digits with the GRIB1 parameter table number.",
     "",
     "PARAMETER",
-    "    swap  STRING  Swap the position of obase and xxx in the output filename",
+    "    swap            STRING  Swap the position of obase and xxx in the output filename",
+    "    uuid=<attname>  STRING  Add a UUID as global attribute <attname> to each output file",
     "",
     "ENVIRONMENT",
     "    CDO_FILE_SUFFIX",
@@ -330,7 +332,7 @@ static char *SplitHelp[] = {
 
 static char *SplittimeHelp[] = {
     "NAME",
-    "    splithour, splitday, splitseas, splityear, splitmon - ",
+    "    splithour, splitday, splitseas, splityear, splityearmon, splitmon - ",
     "    Split timesteps of a dataset",
     "",
     "SYNOPSIS",
@@ -343,21 +345,24 @@ static char *SplittimeHelp[] = {
     "    xxx and the contents of the output files depends on the chosen operator. ",
     "",
     "OPERATORS",
-    "    splithour  Split hours",
-    "               Splits a file into pieces, one for each different hour.",
-    "               xxx will have two digits with the hour.",
-    "    splitday   Split days",
-    "               Splits a file into pieces, one for each different day.",
-    "               xxx will have two digits with the day.",
-    "    splitseas  Split seasons",
-    "               Splits a file into pieces, one for each different season.",
-    "               xxx will have three characters with the season.",
-    "    splityear  Split years",
-    "               Splits a file into pieces, one for each different year.",
-    "               xxx will have four digits with the year.",
-    "    splitmon   Split months",
-    "               Splits a file into pieces, one for each different month.",
-    "               xxx will have two digits with the month.",
+    "    splithour     Split hours",
+    "                  Splits a file into pieces, one for each different hour.",
+    "                  xxx will have two digits with the hour.",
+    "    splitday      Split days",
+    "                  Splits a file into pieces, one for each different day.",
+    "                  xxx will have two digits with the day.",
+    "    splitseas     Split seasons",
+    "                  Splits a file into pieces, one for each different season.",
+    "                  xxx will have three characters with the season.",
+    "    splityear     Split years",
+    "                  Splits a file into pieces, one for each different year.",
+    "                  xxx will have four digits with the year (YYYY).",
+    "    splityearmon  Split in years and months",
+    "                  Splits a file into pieces, one for each different year and month.",
+    "                  xxx will have six digits with the year and month (YYYYMM).",
+    "    splitmon      Split months",
+    "                  Splits a file into pieces, one for each different month.",
+    "                  xxx will have two digits with the month.",
     "",
     "PARAMETER",
     "    format  STRING  C-style format for strftime() (e.g. %B for the full month name)",
@@ -453,7 +458,7 @@ static char *SelectHelp[] = {
     "    ifiles is an arbitrary number of input files. All input files need to have ",
     "    the same structure with the same variables on different timesteps.",
     "    The fields selected depends on the chosen parameters. Parameter is a comma",
-    "    separated list of key-value pairs.",
+    "    separated list of key-value pairs. Wildcards can be used for string parameter.",
     "",
     "OPERATORS",
     "    select  Select fields",
@@ -468,6 +473,9 @@ static char *SelectHelp[] = {
     "    ltype             INTEGER Comma separated list of GRIB level types.",
     "    levidx            INTEGER Comma separated list of index of levels.",
     "    level             FLOAT   Comma separated list of vertical levels.",
+    "    date              STRING  Comma separated list of dates (format YYYY-MM-DDThh:mm:ss).",
+    "    startdate         STRING  Start date (format YYYY-MM-DDThh:mm:ss).",
+    "    enddate           STRING  End date (format YYYY-MM-DDThh:mm:ss).",
     "    minute            INTEGER Comma separated list of minutes.",
     "    hour              INTEGER Comma separated list of hours.",
     "    day               INTEGER Comma separated list of days.",
@@ -481,7 +489,7 @@ static char *SelectHelp[] = {
 static char *SelvarHelp[] = {
     "NAME",
     "    selparam, delparam, selcode, delcode, selname, delname, selstdname, sellevel, ",
-    "    sellevidx, selgrid, selzaxis, selltype, seltabnum - Select fields",
+    "    sellevidx, selgrid, selzaxis, selzaxisname, selltype, seltabnum - Select fields",
     "",
     "SYNOPSIS",
     "    <operator>,params  ifile ofile",
@@ -494,6 +502,7 @@ static char *SelvarHelp[] = {
     "    sellevidx,levidx  ifile ofile",
     "    selgrid,grids  ifile ofile",
     "    selzaxis,zaxes  ifile ofile",
+    "    selzaxisname,zaxisnames  ifile ofile",
     "    selltype,ltypes  ifile ofile",
     "    seltabnum,tabnums  ifile ofile",
     "",
@@ -502,44 +511,47 @@ static char *SelvarHelp[] = {
     "    The fields selected depends on the chosen operator and the parameters.",
     "",
     "OPERATORS",
-    "    selparam    Select parameters by identifier",
-    "                Selects all fields with parameter identifiers in a user given list.",
-    "    delparam    Delete parameters by identifier",
-    "                Deletes all fields with parameter identifiers in a user given list.",
-    "    selcode     Select parameters by code number",
-    "                Selects all fields with code numbers in a user given list.",
-    "    delcode     Delete parameters by code number",
-    "                Deletes all fields with code numbers in a user given list.",
-    "    selname     Select parameters by name",
-    "                Selects all fields with parameter names in a user given list.",
-    "    delname     Delete parameters by name",
-    "                Deletes all fields with parameter names in a user given list.",
-    "    selstdname  Select parameters by standard name",
-    "                Selects all fields with standard names in a user given list.",
-    "    sellevel    Select levels",
-    "                Selects all fields with levels in a user given list.",
-    "    sellevidx   Select levels by index",
-    "                Selects all fields with index of levels in a user given list.",
-    "    selgrid     Select grids",
-    "                Selects all fields with grids in a user given list.",
-    "    selzaxis    Select z-axes",
-    "                Selects all fields with z-axes in a user given list.",
-    "    selltype    Select GRIB level types",
-    "                Selects all fields with GRIB level type in a user given list.",
-    "    seltabnum   Select parameter table numbers",
-    "                Selects all fields with parameter table numbers in a user given list.",
+    "    selparam      Select parameters by identifier",
+    "                  Selects all fields with parameter identifiers in a user given list.",
+    "    delparam      Delete parameters by identifier",
+    "                  Deletes all fields with parameter identifiers in a user given list.",
+    "    selcode       Select parameters by code number",
+    "                  Selects all fields with code numbers in a user given list.",
+    "    delcode       Delete parameters by code number",
+    "                  Deletes all fields with code numbers in a user given list.",
+    "    selname       Select parameters by name",
+    "                  Selects all fields with parameter names in a user given list.",
+    "    delname       Delete parameters by name",
+    "                  Deletes all fields with parameter names in a user given list.",
+    "    selstdname    Select parameters by standard name",
+    "                  Selects all fields with standard names in a user given list.",
+    "    sellevel      Select levels",
+    "                  Selects all fields with levels in a user given list.",
+    "    sellevidx     Select levels by index",
+    "                  Selects all fields with index of levels in a user given list.",
+    "    selgrid       Select grids",
+    "                  Selects all fields with grids in a user given list.",
+    "    selzaxis      Select z-axes",
+    "                  Selects all fields with z-axes in a user given list.",
+    "    selzaxisname  Select z-axes by name",
+    "                  Selects all fields with z-axis names in a user given list.",
+    "    selltype      Select GRIB level types",
+    "                  Selects all fields with GRIB level type in a user given list.",
+    "    seltabnum     Select parameter table numbers",
+    "                  Selects all fields with parameter table numbers in a user given list.",
     "",
     "PARAMETER",
-    "    params    INTEGER  Comma separated list of parameter identifiers",
-    "    codes     INTEGER  Comma separated list of code numbers",
-    "    names     STRING   Comma separated list of variable names",
-    "    stdnames  STRING   Comma separated list of standard names",
-    "    levels    FLOAT    Comma separated list of vertical levels",
-    "    levidx    INTEGER  Comma separated list of index of levels",
-    "    ltypes    INTEGER  Comma separated list of GRIB level types",
-    "    grids     STRING   Comma separated list of grid names or numbers",
-    "    zaxes     STRING   Comma separated list of z-axis names or numbers",
-    "    tabnums   INTEGER  Comma separated list of parameter table numbers",
+    "    params      INTEGER  Comma separated list of parameter identifiers",
+    "    codes       INTEGER  Comma separated list of code numbers",
+    "    names       STRING   Comma separated list of variable names",
+    "    stdnames    STRING   Comma separated list of standard names",
+    "    levels      FLOAT    Comma separated list of vertical levels",
+    "    levidx      INTEGER  Comma separated list of index of levels",
+    "    ltypes      INTEGER  Comma separated list of GRIB level types",
+    "    grids       STRING   Comma separated list of grid names or numbers",
+    "    zaxes       STRING   Comma separated list of z-axis types or numbers",
+    "    zaxisnames  STRING   Comma separated list of z-axis names",
+    "    tabnums     INTEGER  Comma separated list of parameter table numbers",
     NULL
 };
 
@@ -796,7 +808,7 @@ static char *SetpartabHelp[] = {
     "    setpartabp, setpartabn - Set parameter table",
     "",
     "SYNOPSIS",
-    "    <operator>,table  ifile ofile",
+    "    <operator>,table[,convert]  ifile ofile",
     "",
     "DESCRIPTION",
     "    This module transforms data and metadata of ifile via a parameter table and writes the result to ofile.",
@@ -824,6 +836,7 @@ static char *SetpartabHelp[] = {
     "     ok_max_mean_abs & FLOAT       & Maximum absolute mean",
     "     factor          & FLOAT       & Scale factor",
     "     delete          & INTEGER     & Set to 1 to delete variable",
+    "     convert         & INTEGER     & Set to 1 to convert the unit if necessary",
     "    ",
     "    The search key for the variable depends on the operator. Use setpartabn to search variables by the name.",
     "    This is typically used for netCDF datasets. The operator setpartabp searches variables by the parameter ID.",
@@ -835,7 +848,8 @@ static char *SetpartabHelp[] = {
     "                Search variables by name.",
     "",
     "PARAMETER",
-    "    table  STRING   Parameter table file or name",
+    "    table    STRING   Parameter table file or name",
+    "    convert  STRING   Converts the units if necessary",
     NULL
 };
 
@@ -1006,10 +1020,11 @@ static char *SetgridHelp[] = {
     "                 as the size of the target grid description.",
     "    setgridtype  Set grid type",
     "                 Sets the grid type of all input fields. The following grid types are available:",
-    "                 curvilinear "    "                 Converts regular grid to curvilinear grid",
-    "                 unstructured"    "                 Converts grid type to unstructured grid",
-    "                 dereference "    "                 Dereference a reference to a grid",
-    "                 regular     "    "                 Converts reduced Gaussian grid to regular Gaussian grid",
+    "                 curvilinear "    "    Converts a regular grid to a curvilinear grid",
+    "                 unstructured"    "    Converts a regular or curvilinear grid to an unstructured grid",
+    "                 dereference "    "    Dereference a reference to a grid",
+    "                 regular     "    "    Converts a reduced Gaussian grid to a regular Gaussian grid",
+    "                 lonlat      "    "    Converts a regular lonlat grid stored as a curvilinear grid back to a lonlat grid",
     "    setgridarea  Set grid cell area",
     "                 Sets the grid cell area. The parameter gridarea is the path to a data file,",
     "                 the first field is used as grid cell area. The input fields need to have the same",
@@ -1018,24 +1033,32 @@ static char *SetgridHelp[] = {
     "",
     "PARAMETER",
     "    grid      STRING  Grid description file or name",
-    "    gridtype  STRING  Grid type (curvilinear, unstructured, regular or dereference)",
+    "    gridtype  STRING  Grid type (curvilinear, unstructured, regular, lonlat or dereference)",
     "    gridarea  STRING  Data file, the first field is used as grid cell area",
     NULL
 };
 
 static char *SetzaxisHelp[] = {
     "NAME",
-    "    setzaxis - Set z-axis type",
+    "    setzaxis, genlevelbounds - Set z-axis information",
     "",
     "SYNOPSIS",
     "    setzaxis,zaxis  ifile ofile",
+    "    genlevelbounds[,zbot[,ztop]]  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This operator sets the z-axis description of all variables with the",
-    "    same number of level as the new z-axis.",
+    "    This module modifies the metadata of the vertical grid.",
+    "",
+    "OPERATORS",
+    "    setzaxis        Set z-axis",
+    "                    This operator sets the z-axis description of all variables with the same number of level as the new z-axis.",
+    "    genlevelbounds  Generate level bounds",
+    "                    Generates the layer bounds of the z-axis.",
     "",
     "PARAMETER",
     "    zaxis  STRING  Z-axis description file or name of the target z-axis",
+    "    zbot   FLOAT   Specifying the bottom of the vertical column. Must have the same units as z-axis. ",
+    "    ztop   FLOAT   Specifying the top of the vertical column. Must have the same units as z-axis. ",
     NULL
 };
 
@@ -1250,19 +1273,42 @@ static char *SetmissHelp[] = {
 
 static char *ExprHelp[] = {
     "NAME",
-    "    expr, exprf - Evaluate expressions",
+    "    expr, exprf, aexpr, aexprf - Evaluate expressions",
     "",
     "SYNOPSIS",
     "    expr,instr  ifile ofile",
     "    exprf,filename  ifile ofile",
+    "    aexpr,instr  ifile ofile",
+    "    aexprf,filename  ifile ofile",
     "",
     "DESCRIPTION",
     "    This module arithmetically processes every timestep of the input dataset.",
     "    Each individual assignment statement have to end with a semi-colon.",
-    "    The basic arithmetic operations addition +, subtraction -, multiplication *,",
-    "    division / and exponentiation ^ can be used.",
+    "    ",
+    "    The following operators are supported:",
+    "    ",
+    "     Operator   & Meaning             & Example   & Result ",
+    "         =      & assignment          & x = y     & Assigns y to x",
+    "         +      & addition            & x + y     & Sum of x and y",
+    "         -      & subtraction         & x - y     & Difference of x and y    ",
+    "         *      & multiplication      & x * y     & Product of x and y ",
+    "         /      & division            & x / y     & Quotient of x and y",
+    "         ^      & exponentiation      & x ^ y     & Exponentiates x with y ",
+    "         ==     & equal to            & x == y    & 1, if x equal to y; else 0",
+    "         !=     & not equal to        & x != y    & 1, if x not equal to y; else 0",
+    "         >      & greater than        & x > y     & 1, if x greater than y; else 0",
+    "         <      & less than           & x < y     & 1, if x less than y; else 0",
+    "         >=     & greater equal       & x >= y    & 1, if x greater equal y; else 0",
+    "         <=     & less equal          & x <= y    & 1, if x less equal y; else 0",
+    "         <=>    & less equal greater  & x <=> y   & -1, if x less y; 1, if x greater y; else 0 ",
+    "         &&     & logical AND         & x && y    & 1, if x and y not equal 0; else 0",
+    "         ||     & logical OR          & x || y    & 1, if x or y not equal 0; else 0",
+    "         ?:     & ternary conditional & x ? y : z & y, if x not equal 0, else z ",
+    "    ",
     "    The following intrinsic functions are available:",
     "    abs(x)  "    "    Absolute value of x",
+    "    floor(x)"    "    Round to largest integral value not greater than x",
+    "    ceil(x) "    "    Round to smallest integral value not less than x",
     "    int(x)  "    "    Integer value of x",
     "    nint(x) "    "    Nearest integer value of x",
     "    sqr(x)  "    "    Square of x",
@@ -1278,13 +1324,17 @@ static char *ExprHelp[] = {
     "    atan(x) "    "    Arc-tangent of x, where x is specified in radians",
     "",
     "OPERATORS",
-    "    expr   Evaluate expressions",
-    "           The processing instructions are read from the parameter.",
-    "    exprf  Evaluate expressions from script file",
-    "           Contrary to expr the processing instructions are read from a file.",
+    "    expr    Evaluate expressions",
+    "            The processing instructions are read from the parameter.",
+    "    exprf   Evaluate expressions script",
+    "            Contrary to expr the processing instructions are read from a file.",
+    "    aexpr   Evaluate expressions and append results",
+    "            Same as expr, but keep input variables and append results",
+    "    aexprf  Evaluate expression script and append results",
+    "            Same as exprf, but keep input variables and append results",
     "",
     "PARAMETER",
-    "    instr     STRING  Processing instructions (without spaces!)",
+    "    instr     STRING  Processing instructions (need to be 'quoted' in most cases)",
     "    filename  STRING  File with processing instructions",
     NULL
 };
@@ -1422,30 +1472,30 @@ static char *MonarithHelp[] = {
     NULL
 };
 
-static char *YmonarithHelp[] = {
+static char *YhourarithHelp[] = {
     "NAME",
-    "    ymonadd, ymonsub, ymonmul, ymondiv - Multi-year monthly arithmetic",
+    "    yhouradd, yhoursub, yhourmul, yhourdiv - Multi-year hourly arithmetic",
     "",
     "SYNOPSIS",
     "    <operator>  ifile1 ifile2 ofile",
     "",
     "DESCRIPTION",
     "    This module performs simple arithmetic of a time series and one",
-    "    timestep with the same month of year. For each field in ifile1",
+    "    timestep with the same hour and day of year. For each field in ifile1",
     "    the corresponding field of the timestep in ifile2 with the",
-    "    same month of year is used. The header information in ifile1",
+    "    same hour and day of year is used. The header information in ifile1",
     "    have to be the same as in ifile2. Usually ifile2 is generated",
-    "    by an operator of the module YMONSTAT.",
+    "    by an operator of the module YHOURSTAT.",
     "",
     "OPERATORS",
-    "    ymonadd  Add multi-year monthly time series",
-    "             Adds a time series and a multi-year monthly time series.",
-    "    ymonsub  Subtract multi-year monthly time series",
-    "             Subtracts a time series and a multi-year monthly time series.",
-    "    ymonmul  Multiply multi-year monthly time series",
-    "             Multiplies a time series and a multi-year monthly time series.",
-    "    ymondiv  Divide multi-year monthly time series",
-    "             Divides a time series and a multi-year monthly time series.",
+    "    yhouradd  Add multi-year hourly time series",
+    "              Adds a time series and a multi-year hourly time series.",
+    "    yhoursub  Subtract multi-year hourly time series",
+    "              Subtracts a time series and a multi-year hourly time series.",
+    "    yhourmul  Multiply multi-year hourly time series",
+    "              Multiplies a time series and a multi-year hourly time series.",
+    "    yhourdiv  Divide multi-year hourly time series",
+    "              Divides a time series and a multi-year hourly time series.",
     NULL
 };
 
@@ -1476,30 +1526,55 @@ static char *YdayarithHelp[] = {
     NULL
 };
 
-static char *YhourarithHelp[] = {
+static char *YmonarithHelp[] = {
     "NAME",
-    "    yhouradd, yhoursub, yhourmul, yhourdiv - Multi-year hourly arithmetic",
+    "    ymonadd, ymonsub, ymonmul, ymondiv - Multi-year monthly arithmetic",
     "",
     "SYNOPSIS",
     "    <operator>  ifile1 ifile2 ofile",
     "",
     "DESCRIPTION",
-    "    This module performs simple arithmetic of a time series and one",
-    "    timestep with the same hour and day of year. For each field in ifile1",
-    "    the corresponding field of the timestep in ifile2 with the",
-    "    same hour and day of year is used. The header information in ifile1",
-    "    have to be the same as in ifile2. Usually ifile2 is generated",
-    "    by an operator of the module YHOURSTAT.",
+    "    This module performs simple arithmetic of a time series and one timestep",
+    "    with the same month of year. For each field in ifile1 the corresponding",
+    "    field of the timestep in ifile2 with the same month of year is used.",
+    "    The header information in ifile1 have to be the same as in ifile2.",
+    "    Usually ifile2 is generated by an operator of the module YMONSTAT.",
     "",
     "OPERATORS",
-    "    yhouradd  Add multi-year hourly time series",
-    "              Adds a time series and a multi-year hourly time series.",
-    "    yhoursub  Subtract multi-year hourly time series",
-    "              Subtracts a time series and a multi-year hourly time series.",
-    "    yhourmul  Multiply multi-year hourly time series",
-    "              Multiplies a time series and a multi-year hourly time series.",
-    "    yhourdiv  Divide multi-year hourly time series",
-    "              Divides a time series and a multi-year hourly time series.",
+    "    ymonadd  Add multi-year monthly time series",
+    "             Adds a time series and a multi-year monthly time series.",
+    "    ymonsub  Subtract multi-year monthly time series",
+    "             Subtracts a time series and a multi-year monthly time series.",
+    "    ymonmul  Multiply multi-year monthly time series",
+    "             Multiplies a time series and a multi-year monthly time series.",
+    "    ymondiv  Divide multi-year monthly time series",
+    "             Divides a time series and a multi-year monthly time series.",
+    NULL
+};
+
+static char *YseasarithHelp[] = {
+    "NAME",
+    "    yseasadd, yseassub, yseasmul, yseasdiv - Multi-year seasonal arithmetic",
+    "",
+    "SYNOPSIS",
+    "    <operator>  ifile1 ifile2 ofile",
+    "",
+    "DESCRIPTION",
+    "    This module performs simple arithmetic of a time series and one timestep",
+    "    with the same season. For each field in ifile1 the corresponding",
+    "    field of the timestep in ifile2 with the same season is used.",
+    "    The header information in ifile1 have to be the same as in ifile2.",
+    "    Usually ifile2 is generated by an operator of the module YSEASSTAT.",
+    "",
+    "OPERATORS",
+    "    yseasadd  Add multi-year seasonal time series",
+    "              Adds a time series and a multi-year seasonal time series.",
+    "    yseassub  Subtract multi-year seasonal time series",
+    "              Subtracts a time series and a multi-year seasonal time series.",
+    "    yseasmul  Multiply multi-year seasonal time series",
+    "              Multiplies a time series and a multi-year seasonal time series.",
+    "    yseasdiv  Divide multi-year seasonal time series",
+    "              Divides a time series and a multi-year seasonal time series.",
     NULL
 };
 
@@ -1787,10 +1862,9 @@ static char *ZonstatHelp[] = {
     "",
     "DESCRIPTION",
     "    This module computes zonal statistical values of the input fields.",
-    "    According to the chosen operator the zonal minimum, maximum, ",
-    "    sum, average, variance, standard deviation or a certain percentile",
-    "    is written to ofile. All input fields need to have the same",
-    "    regular lon/lat grid. ",
+    "    According to the chosen operator the zonal minimum, maximum, sum, average,",
+    "    variance, standard deviation or a certain percentile is written to ofile.",
+    "    This operator requires all variables on the same regular lon/lat grid.",
     "",
     "OPERATORS",
     "    zonmin   Zonal minimum",
@@ -1826,10 +1900,9 @@ static char *MerstatHelp[] = {
     "",
     "DESCRIPTION",
     "    This module computes meridional statistical values of the input fields.",
-    "    According to the chosen operator the meridional minimum, maximum,",
-    "    sum, average, variance, standard deviation or a certain percentile is",
-    "    written to ofile. All input fields need to have the same regular lon/lat",
-    "    grid. ",
+    "    According to the chosen operator the meridional minimum, maximum, sum, average,",
+    "    variance, standard deviation or a certain percentile is written to ofile.",
+    "    This operator requires all variables on the same regular lon/lat grid.",
     "",
     "OPERATORS",
     "    mermin   Meridional minimum",
@@ -1904,9 +1977,9 @@ static char *VertstatHelp[] = {
     "    vertsum   Vertical sum",
     "              For every gridpoint the sum over all levels is computed.",
     "    vertmean  Vertical mean",
-    "              For every gridpoint the arithmetical mean over all levels is computed.",
+    "              For every gridpoint the layer weighted mean over all levels is computed.",
     "    vertavg   Vertical average",
-    "              For every gridpoint the arithmetical average over all levels is computed.",
+    "              For every gridpoint the layer weighted average over all levels is computed.",
     "    vertvar   Vertical variance",
     "              For every gridpoint the variance over all levels is computed.",
     "    vertstd   Vertical standard deviation",
@@ -1926,7 +1999,7 @@ static char *TimselstatHelp[] = {
     "    This module computes statistical values for a selected number of timesteps. According to ",
     "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of ",
     "    the selected timesteps is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    timselmin   Time range minimum",
@@ -1995,7 +2068,7 @@ static char *TimselpctlHelp[] = {
     "    respectively. The default number of histogram bins is 101. The default can be overridden by setting the",
     "    environment variable CDO_PCTL_NBINS to a different value. The files ifile2 and ifile3 ",
     "    should be the result of corresponding timselmin and timselmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    For every adjacent sequence t1, ...., tn of timesteps of the same ",
     "    selected time range it is",
     "    ",
@@ -2025,7 +2098,7 @@ static char *RunstatHelp[] = {
     "    This module computes running statistical values over a selected number of timesteps. Depending on ",
     "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of a selected ",
     "    number of consecutive timesteps read from ifile is written to ofile. ",
-    "    The date information in ofile is the date of the middle contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    runmin   Running minimum",
@@ -2059,8 +2132,8 @@ static char *RunstatHelp[] = {
     "    nts  INTEGER  Number of timesteps",
     "",
     "ENVIRONMENT",
-    "    TIMESTAT_DATE",
-    "        Sets the date information in ofile to the \"first\", \"last\" or \"middle\" contributing timestep in ifile.",
+    "    CDO_TIMESTAT_DATE",
+    "        Sets the time stamp in ofile to the \"first\", \"middle\" or \"last\" contributing timestep of ifile.",
     NULL
 };
 
@@ -2069,11 +2142,11 @@ static char *RunpctlHelp[] = {
     "    runpctl - Running percentile values",
     "",
     "SYNOPSIS",
-    "    runpctl,p,nts  ifile1 ofile",
+    "    runpctl,p,nts  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This module computes running percentiles over a selected number of timesteps in ifile1.",
-    "    The date information in ofile is the date of the timestep in the middle of the contributing timesteps in ifile1.",
+    "    This module computes running percentiles over a selected number of timesteps in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "    ",
     "    o(t+(nts-1)/2,x) = pth percentile {i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
     "",
@@ -2095,7 +2168,7 @@ static char *TimstatHelp[] = {
     "    This module computes statistical  values over all timesteps in ifile. Depending on ",
     "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of ",
     "    all timesteps read from ifile is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    timmin   Time minimum",
@@ -2140,8 +2213,7 @@ static char *TimpctlHelp[] = {
     "    The default number of histogram bins is 101. The default can be overridden by setting the",
     "    environment variable CDO_PCTL_NBINS to a different value. The files ifile2 and ifile3",
     "    should be the result of corresponding timmin and timmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the last contributing ",
-    "    timestep in ifile1.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    ",
     "    o(1,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
     "",
@@ -2166,8 +2238,7 @@ static char *HourstatHelp[] = {
     "    This module computes statistical values over timesteps of the same hour.",
     "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
     "    or standard deviation of timesteps of the same hour is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    hourmin   Hourly minimum",
@@ -2224,8 +2295,7 @@ static char *HourpctlHelp[] = {
     "    environment variable CDO_PCTL_NBINS to a different value. The files",
     "    ifile2 and ifile3 should be the result of corresponding",
     "    hourmin and hourmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
     "    ",
     "    o(t,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
@@ -2251,8 +2321,7 @@ static char *DaystatHelp[] = {
     "    This module computes statistical values over timesteps of the same day.",
     "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
     "    or standard deviation of timesteps of the same day is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    daymin   Daily minimum",
@@ -2309,8 +2378,7 @@ static char *DaypctlHelp[] = {
     "    environment variable CDO_PCTL_NBINS. The files ifile2 and",
     "    ifile3 should be the result of corresponding daymin and daymax",
     "    operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
     "    ",
     "    o(t,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
@@ -2336,8 +2404,7 @@ static char *MonstatHelp[] = {
     "    This module computes statistical values over timesteps of the same month.",
     "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
     "    or standard deviation of timesteps of the same month is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    monmin   Monthly minimum",
@@ -2394,8 +2461,7 @@ static char *MonpctlHelp[] = {
     "    environment variable CDO_PCTL_NBINS to a different value. The files",
     "    ifile2 and ifile3 should be the result of corresponding",
     "    monmin and monmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is:",
     "    ",
     "    o(t,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
@@ -2419,15 +2485,15 @@ static char *YearmonmeanHelp[] = {
     "DESCRIPTION",
     "    This operator computes the yearly mean of a monthly time series.",
     "    Each month is weighted with the number of days per month. ",
-    "    The date information in ofile is the date of the middle contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "    ",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "    ",
     "    o(t,x) = mean{i(t',x), t_1<t'<=t_n}",
     "",
     "ENVIRONMENT",
-    "    TIMESTAT_DATE",
-    "        Sets the date information in ofile to the \"first\", \"last\" or \"middle\" contributing timestep in ifile.",
+    "    CDO_TIMESTAT_DATE",
+    "        Sets the date information in ofile to the \"first\", \"middle\" or \"last\" contributing timestep of ifile.",
     NULL
 };
 
@@ -2443,8 +2509,7 @@ static char *YearstatHelp[] = {
     "    This module computes statistical values over timesteps of the same year.",
     "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
     "    or standard deviation of timesteps of the same year is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
     "",
     "OPERATORS",
     "    yearmin   Yearly minimum",
@@ -2504,8 +2569,7 @@ static char *YearpctlHelp[] = {
     "    environment variable CDO_PCTL_NBINS to a different value. The files",
     "    ifile2 and ifile3 should be the result of corresponding",
     "    yearmin and yearmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "    ",
     "    o(t,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
@@ -2531,10 +2595,9 @@ static char *SeasstatHelp[] = {
     "    This module computes statistical values over timesteps of the same season.",
     "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
     "    or standard deviation of timesteps of the same season is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile. Be careful about the first and the last ",
-    "    output timestep , they may be incorrect values if the seasons have incomplete ",
-    "    timesteps.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile.",
+    "    Be careful about the first and the last output timestep , they may be incorrect values ",
+    "    if the seasons have incomplete timesteps.",
     "",
     "OPERATORS",
     "    seasmin   Seasonal minimum",
@@ -2577,16 +2640,13 @@ static char *SeaspctlHelp[] = {
     "",
     "DESCRIPTION",
     "    This operator computes percentiles over all timesteps in ifile1 of the same season.",
-    "    The algorithm uses histograms with minimum and maximum bounds given in",
-    "    ifile2 and ifile3, respectively. The default number of",
-    "    histogram bins is 101. The default can be overridden by setting the",
-    "    environment variable CDO_PCTL_NBINS to a different value. The files",
-    "    ifile2 and ifile3 should be the result of corresponding",
-    "    seasmin and seasmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1. Be careful about the first",
-    "    and the last output timestep , they may be incorrect values if the seasons",
-    "    have incomplete timesteps.",
+    "    The algorithm uses histograms with minimum and maximum bounds given in ifile2 and ifile3,",
+    "    respectively. The default number of histogram bins is 101. The default can be overridden by setting ",
+    "    the environment variable CDO_PCTL_NBINS to a different value. The files ifile2 and ",
+    "    ifile3 should be the result of corresponding seasmin and seasmax operations, respectively.",
+    "    The time stamp in ofile is from the middle contributing timestep of ifile1.",
+    "    Be careful about the first and the last output timestep , they may be incorrect values ",
+    "    if the seasons have incomplete timesteps.",
     "    For every adjacent sequence t_1, ...,t_n of timesteps of the same season it is",
     "    ",
     "    o(t,x) = pth percentile {i(t',x), t1 < t' <= tn}",
@@ -2733,14 +2793,12 @@ static char *YdaypctlHelp[] = {
     "",
     "DESCRIPTION",
     "    This operator writes a certain percentile of each day of year in ifile1 to ofile.",
-    "    The algorithm uses histograms with minimum and maximum bounds given in",
-    "    ifile2 and ifile3, respectively. The default number of",
-    "    histogram bins is 101. The default can be overridden by setting the",
-    "    environment variable CDO_PCTL_NBINS to a different value. The files",
-    "    ifile2 and ifile3 should be the result of corresponding",
-    "    ydaymin and ydaymax operations, respectively.",
-    "    The date information in an output field is the date of the last",
-    "    contributing input field.",
+    "    The algorithm uses histograms with minimum and maximum bounds given in ifile2 and",
+    "    ifile3, respectively. The default number of histogram bins is 101. The default can be",
+    "    overridden by setting the environment variable CDO_PCTL_NBINS to a different value.",
+    "    The files ifile2 and ifile3 should be the result of corresponding ydaymin and",
+    "    ydaymax operations, respectively.",
+    "    The date information in an output field is the date of the last contributing input field.",
     "    ",
     "    o(001,x) = pth percentile {i(t,x), day(i(t)) = 001}",
     "                     ...",
@@ -3218,7 +3276,6 @@ static char *EOFsHelp[] = {
     "    After execution ofile1 will contain all eigen-values and ofile2 the",
     "    eigenvectors e_j. All EOFs and eigen-values are computed. However, only the first ",
     "    neof EOFs are written to ofile2. Nonetheless, ofile1 contains all eigen-values. ",
-    "    Note, thate the resulting EOF in ofile2 is e_j and thus not weighted for consistency.",
     "    ",
     "    Missing values are not fully supported. Support is only checked for non-changing",
     "    masks of missing values in time. Although there still will be results, they are",
@@ -3239,11 +3296,11 @@ static char *EOFsHelp[] = {
     "        Is used to choose the algorithm for eigenvalue calculation. Options are 'jacobi' for ",
     "        a one-sided parallel jacobi-algorithm (only executed in parallel if -P flag is set)",
     "        and  'danielson_lanczos' for a non-parallel d/l algorithm. The default setting is 'jacobi'.",
-    "        ",
+    "    CDO_WEIGHT_MODE",
+    "        It is used to set the weight mode. The default is 'on'. Set it to 'off' for a non weighted version.",
     "    MAX_JACOBI_ITER",
     "        Is the maximum integer number of annihilation sweeps that is executed if the ",
     "        jacobi-algorithm is used to compute the eigen values. The default value is 12.",
-    "        ",
     "    FNORM_PRECISION",
     "        Is the Frobenius norm of the matrix consisting of an annihilation pair",
     "        of eigenvectors that is used to determine if the eigenvectors have reached ",
@@ -3262,16 +3319,15 @@ static char *EofcoeffHelp[] = {
     "",
     "DESCRIPTION",
     "    This module calculates the time series of the principal coefficients for given EOF",
-    "    (empirical orthogonal functions) and data. Time steps in ifile1 are ",
-    "    assumed to be the EOFs, Time steps in ifile2 are assumed to be the",
-    "    time series. Weights are taken into account, which is why EOF output is not weighted. ",
-    "    Note, that this operator calculates a weighted dot product of the fields in",
-    "    ifile1 and ifile2.",
+    "    (empirical orthogonal functions) and data. Time steps in ifile1 are assumed to be the EOFs,",
+    "    time steps in ifile2 are assumed to be the time series.",
+    "    Note, that this operator calculates a weighted dot product of the fields in ifile1 and ifile2.",
+    "    For consistency set the environment variable CDO_WEIGHT_MODE=off when using eof or eof3d.",
     "    ",
     "    There will be a separate file containing a time series of principal coefficients",
-    "    with time information from ifile2 for each EOF in ifile1. Output files",
-    "    will be numbered as <obase><neof><suffix> where neof+1 is the number of the",
-    "    EOF (timestep) in ifile1 and suffix is the filename extension derived from the file format. ",
+    "    with time information from ifile2 for each EOF in ifile1. Output files will be",
+    "    numbered as <obase><neof><suffix> where neof+1 is the number of the EOF (timestep)",
+    "    in ifile1 and suffix is the filename extension derived from the file format. ",
     "",
     "ENVIRONMENT",
     "    CDO_FILE_SUFFIX",
@@ -3319,18 +3375,20 @@ static char *RemapgridHelp[] = {
     "    grid  STRING  Target grid description file or name",
     "",
     "ENVIRONMENT",
-    "    CDO_REMAP_NORMALIZE_OPT",
-    "        This variable is used to choose the normalization of the conservative ",
-    "        remapping. By default @env{CDO_REMAP_NORMALIZE_OPT} is set to 'fracarea' and will",
-    "        include the destination area fraction in the output weights; other ",
-    "        options are 'none' and 'destarea' (for more information see {SCRIP}).",
-    "    REMAP_EXTRAPOLATE      ",
+    "    CDO_REMAP_NORM   ",
+    "        This variable is used to choose the normalization of the conservative interpolation. ",
+    "        By default @env{CDO_REMAP_NORM} is set to 'fracarea'. 'fracarea' uses the sum of the",
+    "        non-masked source cell intersected areas to normalize each target cell field value.",
+    "        This results in a reasonable flux value but the flux is not locally conserved.",
+    "        The option 'destarea' uses the total target cell area to normalize each target cell",
+    "        field value. Local flux conservation is ensured, but unreasonable flux values may result.",
+    "    REMAP_EXTRAPOLATE",
     "        This variable is used to switch the extrapolation feature 'on' or 'off'.",
     "        By default the extrapolation is enabled for remapdis, remapnn and for circular grids.",
-    "    REMAP_AREA_MIN         ",
+    "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
-    "    CDO_REMAP_SEARCH_RADIUS",
+    "    CDO_REMAP_RADIUS ",
     "        Remap search radius in degree, default 180 degree.",
     "",
     "NOTE",
@@ -3386,25 +3444,26 @@ static char *GenweightsHelp[] = {
     "    grid  STRING  Target grid description file or name",
     "",
     "ENVIRONMENT",
-    "    CDO_REMAP_NORMALIZE_OPT",
-    "        This variable is used to choose the normalization of the conservative ",
-    "        interpolation. By default @env{CDO_REMAP_NORMALIZE_OPT} is set to 'fracarea' and will",
-    "        include the destination area fraction in the output weights; other ",
-    "        options are 'none' and 'destarea' (for more information see {SCRIP}).",
-    "    REMAP_EXTRAPOLATE      ",
+    "    CDO_REMAP_NORM   ",
+    "        This variable is used to choose the normalization of the conservative interpolation. ",
+    "        By default @env{CDO_REMAP_NORM} is set to 'fracarea'. 'fracarea' uses the sum of the",
+    "        non-masked source cell intersected areas to normalize each target cell field value.",
+    "        This results in a reasonable flux value but the flux is not locally conserved.",
+    "        The option 'destarea' uses the total target cell area to normalize each target cell",
+    "        field value. Local flux conservation is ensured, but unreasonable flux values may result.",
+    "    REMAP_EXTRAPOLATE",
     "        This variable is used to switch the extrapolation feature 'on' or 'off'.",
     "        By default the extrapolation is enabled for remapdis, remapnn",
     "        and for circular grids.",
-    "    REMAP_AREA_MIN         ",
+    "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
-    "    CDO_REMAP_SEARCH_RADIUS",
+    "    CDO_REMAP_RADIUS ",
     "        Remap search radius in degree, default 180 degree.",
     "",
     "NOTE",
-    "    For this module the author has converted the original Fortran 90 SCRIP ",
-    "    software to ANSI C99. If there are any problems send a bug report to CDO and",
-    "    not to SCRIP!",
+    "    For this module the author has converted the original Fortran 90 SCRIP software to ",
+    "    ANSI C99. If there are any problems send a bug report to CDO and not to SCRIP!",
     NULL
 };
 
@@ -3420,32 +3479,32 @@ static char *RemapHelp[] = {
     "    the interpolation weights of one input grid are read from a netCDF file. More weights ",
     "    are computed if the input fields are on different grids. The netCDF file with the ",
     "    weights should follow the SCRIP convention. Normally these weights come from ",
-    "    a previous call to module GENWEIGHTS or were created by the original",
-    "    SCRIP package.",
+    "    a previous call to module GENWEIGHTS or were created by the original SCRIP package.",
     "",
     "PARAMETER",
     "    grid     STRING  Target grid description file or name",
     "    weights  STRING  Interpolation weights (SCRIP netCDF file)",
     "",
     "ENVIRONMENT",
-    "    CDO_REMAP_NORMALIZE_OPT",
-    "        This variable is used to choose the normalization of the conservative ",
-    "        interpolation. By default @env{CDO_REMAP_NORMALIZE_OPT} is set to 'fracarea' and will",
-    "        include the destination area fraction in the output weights; other ",
-    "        options are 'none' and 'destarea' (for more information see {SCRIP}).",
-    "    REMAP_EXTRAPOLATE      ",
+    "    CDO_REMAP_NORM   ",
+    "        This variable is used to choose the normalization of the conservative interpolation. ",
+    "        By default @env{CDO_REMAP_NORM} is set to 'fracarea'. 'fracarea' uses the sum of the",
+    "        non-masked source cell intersected areas to normalize each target cell field value.",
+    "        This results in a reasonable flux value but the flux is not locally conserved.",
+    "        The option 'destarea' uses the total target cell area to normalize each target cell",
+    "        field value. Local flux conservation is ensured, but unreasonable flux values may result.",
+    "    REMAP_EXTRAPOLATE",
     "        This variable is used to switch the extrapolation feature 'on' or 'off'.",
     "        By default the extrapolation is enabled for remapdis, remapnn and for circular grids.",
-    "    REMAP_AREA_MIN         ",
+    "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
-    "    CDO_REMAP_SEARCH_RADIUS",
+    "    CDO_REMAP_RADIUS ",
     "        Remap search radius in degree, default 180 degree.",
     "",
     "NOTE",
-    "    For this module the author has converted the original Fortran 90 SCRIP ",
-    "    software to ANSI C99. If there are any problems send a bug report to CDO and",
-    "    not to SCRIP!",
+    "    For this module the author has converted the original Fortran 90 SCRIP software to",
+    "    ANSI C99. If there are any problems send a bug report to CDO and not to SCRIP!",
     NULL
 };
 
@@ -3478,7 +3537,7 @@ static char *RemapetaHelp[] = {
     "    is done linearly. After the interpolation both profiles are merged. With the resulting ",
     "    temperature/pressure correction the hydrostatic equation is integrated again and adjusted to the ",
     "    reference level finding the final surface pressure correction. A more detailed description of",
-    "    the interpolation can be found in INTERA. All input fields have to be on the same horizontal grid.",
+    "    the interpolation can be found in INTERA. This operator requires all variables on the same horizontal grid.",
     "",
     "PARAMETER",
     "    vct  STRING  File name of an ASCII dataset with the vertical coordinate table",
@@ -3524,7 +3583,8 @@ static char *IntvertHelp[] = {
     "    or netCDF CF standard name.",
     "    Supported parameter tables are: WMO standard table number 2 and ECMWF local table number 128.",
     "    Use the alias  ml2plx/ml2hlx or the environment variable EXTRAPOLATE",
-    "    to extrapolate missing values. All input fields have to be on the same horizontal grid.",
+    "    to extrapolate missing values. This operator requires all variables on the same horizontal grid.",
+    "    ",
     "",
     "OPERATORS",
     "    ml2pl  Model to pressure level interpolation",
@@ -3615,8 +3675,7 @@ static char *InttimeHelp[] = {
     "              The user has to define the start date/time with an optional increment.",
     "    intntime  Interpolation between timesteps",
     "              This operator performs linear interpolation between timesteps.",
-    "              The user has to define the number of timesteps from one timestep",
-    "              to the next.",
+    "              The user has to define the number of timesteps from one timestep to the next.",
     "",
     "PARAMETER",
     "    date  STRING  Start date (format YYYY-MM-DD)",
@@ -3705,7 +3764,8 @@ static char *WindHelp[] = {
     "DESCRIPTION",
     "    This module converts relative divergence and vorticity to U and V wind and vice versa.",
     "    Divergence and vorticity are spherical harmonic coefficients in spectral space and",
-    "    U and V are on a regular Gaussian grid.",
+    "    U and V are on a regular Gaussian grid. The Gaussian latitudes needs to be ordered from",
+    "    north to south.",
     "",
     "OPERATORS",
     "    dv2uv   Divergence and vorticity to U and V wind",
@@ -3982,6 +4042,99 @@ static char *GradsdesHelp[] = {
     NULL
 };
 
+static char *AfterburnerHelp[] = {
+    "NAME",
+    "    after - ECHAM standard post processor",
+    "",
+    "SYNOPSIS",
+    "    after  ifiles ofile",
+    "",
+    "DESCRIPTION",
+    "    The \"afterburner\" is the standard post processor for ECHAM data which provides the following operations:",
+    "    ",
+    "    - Extract specified variables and levels",
+    "    - Compute derived variables",
+    "    - Transform spectral data to Gaussian grid representation",
+    "    - Vertical interpolation to pressure levels",
+    "    - Compute temporal means",
+    "    ",
+    "    This operator reads selection parameters as namelist from stdin.",
+    "    Use the UNIX redirection \"<namelistfile\" to read the namelist from file.",
+    "",
+    "NAMELIST",
+    "    Namelist parameter and there defaults:",
+    "      TYPE=0, CODE=-1, LEVEL=-1, INTERVAL=0, MEAN=0, EXTRAPOLATE=0",
+    "    ",
+    "    TYPE controls the transformation and vertical interpolation. Transforming spectral data to Gaussian grid",
+    "    representation and vertical interpolation to pressure levels are performed in a chain of steps.",
+    "    The TYPE parameter may be used to stop the chain at a certain step. Valid values are:",
+    "    ",
+    "      TYPE  =  0 : Hybrid   level spectral coefficients",
+    "      TYPE  = 10 : Hybrid   level fourier  coefficients",
+    "      TYPE  = 11 : Hybrid   level zonal mean sections",
+    "      TYPE  = 20 : Hybrid   level gauss grids",
+    "      TYPE  = 30 : Pressure level gauss grids",
+    "      TYPE  = 40 : Pressure level fourier  coefficients",
+    "      TYPE  = 41 : Pressure level zonal mean sections",
+    "      TYPE  = 50 : Pressure level spectral coefficients",
+    "      TYPE  = 60 : Pressure level fourier  coefficients",
+    "      TYPE  = 61 : Pressure level zonal mean sections",
+    "      TYPE  = 70 : Pressure level gauss grids",
+    "    ",
+    "    Vorticity, divergence, streamfunction and velocity potential need special treatment in the vertical transformation.",
+    "    They are not available as types 30, 40 and 41. If you select one of these combinations, type is automatically",
+    "    switched to the equivalent types 70, 60 and 61. The type of all other variables will be switched too, because ",
+    "    the type is a global parameter.",
+    "    ",
+    "    CODE selects the variables by the ECHAM GRIB1 code number (1-255). The default value -1 processes all detected codes.",
+    "    Derived variables computed by the afterburner:",
+    "    ",
+    "    Code  & Name      & Longname                       & Level       & Needed Codes/Computation",
+    "     34   & low_cld   & low cloud                      & single      & 223 on modellevel  ",
+    "     35   & mid_cld   & mid cloud                      & single      & 223 on modellevel  ",
+    "     36   & hih_cld   & high cloud                     & single      & 223 on modellevel  ",
+    "     131  & u         & u-velocity                     & atm (ml+pl) & 138, 155           ",
+    "     132  & v         & v-velocity                     & atm (ml+pl) & 138, 155           ",
+    "     135  & omega     & vertical velocity              & atm (ml+pl) & 138, 152, 155      ",
+    "     148  & stream    & streamfunction                 & atm (ml+pl) & 131, 132           ",
+    "     149  & velopot   & velocity potential             & atm (ml+pl) & 131, 132           ",
+    "     151  & slp       & mean sea level pressure        & surface     & 129, 130, 152       ",
+    "     156  & geopoth   & geopotential height            & atm (ml+pl) & 129, 130, 133, 152 ",
+    "     157  & rhumidity & relative humidity              & atm (ml+pl) & 130, 133, 152      ",
+    "     189  & sclfs     & surface solar cloud forcing    & surface     & 176-185            ",
+    "     190  & tclfs     & surface thermal cloud forcing  & surface     & 177-186            ",
+    "     191  & sclf0     & top solar cloud forcing        & surface     & 178-187             ",
+    "     192  & tclf0     & top thermal cloud forcing      & surface     & 179-188            ",
+    "     259  & windspeed & windspeed                      & atm (ml+pl) & sqrt(u*u+v*v)      ",
+    "     260  & precip    & total precipitation            & surface     & 142+143            ",
+    "    ",
+    "    LEVEL selects the hybrid or pressure levels. The allowed values depends on the parameter TYPE.",
+    "    The default value -1 processes all detected levels.",
+    "    ",
+    "    INTERVAL selects the processing interval. The default value 0 process data on monthly intervals.",
+    "    INTERVAL=1 sets the interval to daily.",
+    "    ",
+    "    MEAN=1 compute and write monthly or daily mean fields. The default value 0 writes out all timesteps.",
+    "    ",
+    "    EXTRAPOLATE=0 switch of the extrapolation of missing values during the interpolation from model to pressure",
+    "    level (only available with MEAN=0 and TYPE=30). The default value 1 extrapolate missing values.",
+    "    ",
+    "    Possible combinations of TYPE, CODE and MEAN:",
+    "    ",
+    "          TYPE   & CODE                    & MEAN",
+    "        0/10/11  & 130  temperature        &  0",
+    "        0/10/11  & 131  u-velocity         &  0",
+    "        0/10/11  & 132  v-velocity         &  0",
+    "        0/10/11  & 133  specific humidity  &  0",
+    "        0/10/11  & 138  vorticity          &  0",
+    "        0/10/11  & 148  streamfunction     &  0",
+    "        0/10/11  & 149  velocity potential &  0",
+    "        0/10/11  & 152  LnPs               &  0",
+    "        0/10/11  & 155  divergence         &  0",
+    "         >11     & all codes               &  0/1",
+    NULL
+};
+
 static char *FilterHelp[] = {
     "NAME",
     "    bandpass, lowpass, highpass - Time series filtering",
@@ -4171,7 +4324,7 @@ static char *VargenHelp[] = {
     NULL
 };
 
-static char *RotuvHelp[] = {
+static char *RotuvbHelp[] = {
     "NAME",
     "    rotuvb - Rotation",
     "",
diff --git a/src/pipe.c b/src/pipe.c
index 0d69599..fcab419 100644
--- a/src/pipe.c
+++ b/src/pipe.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pipe.h b/src/pipe.h
index 880989f..8bb7891 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/printinfo.h b/src/printinfo.h
index 3b94efa..997f893 100644
--- a/src/printinfo.h
+++ b/src/printinfo.h
@@ -3,6 +3,30 @@
 
 void uuid2str(const unsigned char uuid[CDI_UUID_SIZE], char *uuidstr);
 
+static inline
+int cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+{
+  static unsigned char uuid_nil[CDI_UUID_SIZE];
+  return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
+}
+
+
+void datetime2str(int date, int time, char *datetimestr, int maxlen)
+{
+  int year, month, day;
+  int hour, minute, second;
+  int len;
+
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
+
+  len = sprintf(datetimestr, DATE_FORMAT "T" TIME_FORMAT, year, month, day, hour, minute, second);
+
+  if ( len > ( maxlen-1) )
+    fprintf(stderr, "Internal problem (%s): sizeof input string is too small!\n", __func__);
+}
+
+
 void date2str(int date, char *datestr, int maxlen)
 {
   int year, month, day;
@@ -222,7 +246,7 @@ void printGridInfo(int vlistID)
 	      latpole = gridInqYpole(gridID);
 	      angle   = gridInqAngle(gridID);
 	      fprintf(stdout, "%33s : lon=%g  lat=%g", "northpole", lonpole, latpole);
-	      if ( angle > 0 ) fprintf(stdout, "  angle=%g", angle);
+	      if ( IS_NOT_EQUAL(angle, 0) ) fprintf(stdout, "  angle=%g", angle);
 	      fprintf(stdout, "\n");
 	    }
 
@@ -368,7 +392,7 @@ void printGridInfo(int vlistID)
 	}
 
       gridInqUUID(gridID, uuidOfHGrid);
-      if ( uuidOfHGrid[0] != 0 )
+      if ( !cdiUUIDIsNull(uuidOfHGrid) )
         {
           char uuidOfHGridStr[37];
           uuid2str(uuidOfHGrid, uuidOfHGridStr);
@@ -471,7 +495,7 @@ void printZaxisInfo(int vlistID)
 
           unsigned char uuidOfVGrid[CDI_UUID_SIZE];
           zaxisInqUUID(zaxisID, uuidOfVGrid);
-          if ( uuidOfVGrid[0] != 0 )
+          if ( !cdiUUIDIsNull(uuidOfVGrid) )
             {
               char uuidOfVGridStr[37];
               uuid2str(uuidOfVGrid, uuidOfVGridStr);
diff --git a/src/process.c b/src/process.c
index eb564a1..4def4b8 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,9 @@
 #if defined(HAVE_GLOB_H)
 #include <glob.h>
 #endif
+#if defined(HAVE_WORDEXP_H)
+#include <wordexp.h>
+#endif
 
 #include "cdo.h"
 #include "cdo_int.h"
@@ -151,9 +154,9 @@ int processSelf(void)
   if ( processID == NumProcess )
     {
       if ( NumProcess > 0 )
-	Error("Internal problem, process not found!");
+        Error("Internal problem, process not found!");
       else
-	processID = 0;
+        processID = 0;
     }
 
   pthread_mutex_unlock(&processMutex);  
@@ -306,7 +309,6 @@ const char *processInqOpername(void)
 void processDefPrompt(char *opername)
 {
   int processID = processSelf();
-  extern char *Progname;
 
   if ( processID == 0 )
     sprintf(Process[processID].prompt, "%s %s", Progname, opername);
@@ -337,34 +339,41 @@ int get_glob_flags(void)
 
   return (glob_flags);
 }
+#endif
 
-/* Convert a wildcard pattern into a list of blank-separated filenames which match the wildcard. */
+#if defined(HAVE_WORDEXP_H)
+/* Convert a shell pattern into a list of filenames. */
 static
-argument_t *glob_pattern(const char *restrict wildcard)
+argument_t *glob_pattern(const char *restrict string)
 {
   size_t cnt, length = 0;
-  int glob_flags = get_glob_flags();
-  glob_t glob_results;
+  int flags = WRDE_UNDEF;
   char **p;
+
+  wordexp_t glob_results;
   argument_t *argument = NULL;
 
-  glob(wildcard, glob_flags, 0, &glob_results);
+  // glob the input argument or do even more shell magic
+  wordexp(string, &glob_results, flags);
 
-  /* How much space do we need?  */
-  for ( p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; cnt; p++, cnt-- )
-    length += strlen(*p) + 1;
+  // How much space do we need?
+  for ( p = glob_results.we_wordv, cnt = glob_results.we_wordc; cnt; p++, cnt-- )
+    {
+      length += strlen(*p) + 1;
+    }
 
-  /* Allocate the space and generate the list.  */
-  argument = argument_new(glob_results.gl_pathc, length);
+  // Allocate the space and generate the list.
+  argument = argument_new(glob_results.we_wordc, length);
 
-  for ( cnt = 0; cnt < glob_results.gl_pathc; cnt++ )
+  // put all generated filenames into the argument_t data structure
+  for ( cnt = 0; cnt < glob_results.we_wordc; cnt++ )
     {
-      argument->argv[cnt] = strdupx(glob_results.gl_pathv[cnt]);
-      strcat(argument->args, glob_results.gl_pathv[cnt]);
-      if ( cnt < glob_results.gl_pathc-1 ) strcat(argument->args, " ");
+      argument->argv[cnt] = strdupx(glob_results.we_wordv[cnt]);
+      strcat(argument->args, glob_results.we_wordv[cnt]);
+      if ( cnt < glob_results.we_wordc-1 ) strcat(argument->args, " ");
     }
 
-  globfree(&glob_results);
+  wordfree(&glob_results);
 
   return argument;
 }
@@ -411,14 +420,14 @@ char *getOperatorArg(const char *xoperator)
       commapos = strchr(xoperator, ',');
 
       if ( commapos )
-	{
-	  len = strlen(commapos+1);
-	  if ( len )
-	    {
-	      operatorArg = (char*) malloc(len+1);
-	      strcpy(operatorArg, commapos+1);
-	    }
-	}
+        {
+          len = strlen(commapos+1);
+          if ( len )
+            {
+              operatorArg = (char*) malloc(len+1);
+              strcpy(operatorArg, commapos+1);
+            }
+        }
     }
 
   return (operatorArg);
@@ -461,16 +470,16 @@ int skipInputStreams(int argc, char *argv[], int globArgc, int nstreams)
   while ( nstreams > 0 )
     {
       if ( globArgc >= argc )
-	{
-	  cdoAbort("Too few arguments. Check command line!");
-	  break;
-	}
+        {
+          cdoAbort("Too few arguments. Check command line!");
+          break;
+        }
       if ( argv[globArgc][0] == '-' )
-	{
-	  globArgc = getGlobArgc(argc, argv, globArgc);
-	}
+        {
+          globArgc = getGlobArgc(argc, argv, globArgc);
+        }
       else
-	globArgc++;
+        globArgc++;
 
       nstreams--;
     }
@@ -487,11 +496,11 @@ int getStreamCnt(int argc, char *argv[])
   while ( globArgc < argc )
     {
       if ( argv[globArgc][0] == '-' )
-	{
-	  globArgc = getGlobArgc(argc, argv, globArgc);
-	}
+        {
+          globArgc = getGlobArgc(argc, argv, globArgc);
+        }
       else
-	globArgc++;
+        globArgc++;
 
       streamCnt++;
     }
@@ -512,44 +521,44 @@ void setStreamNames(int argc, char *argv[])
   while ( globArgc < argc )
     {
       if ( argv[globArgc][0] == '-' )
-	{
-	  globArgcStart = globArgc;
-
-	  globArgc = getGlobArgc(argc, argv, globArgc);
-	  len = 0;
-	  for ( i = globArgcStart; i < globArgc; i++ ) len += strlen(argv[i]) + 1;
-	  streamname = (char*) calloc(1, len);
-	  for ( i = globArgcStart; i < globArgc; i++ )
-	    {
-	      strcat(streamname, argv[i]);
-	      if ( i < globArgc-1 ) strcat(streamname, " ");
-	    }
-	  for ( i = 1; i < len-1; i++ ) if ( streamname[i] == '\0' ) streamname[i] = ' ';
-	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
-	  ac = globArgc - globArgcStart;
-	  //printf("setStreamNames:  ac %d  streamname1: %s\n", ac, streamname);
-	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
-	  for ( i = 0; i < ac; ++i )
-	    Process[processID].streamNames[Process[processID].streamCnt].argv[i] = argv[i+globArgcStart];
-	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
-	  Process[processID].streamCnt++;
-	  //printf("setStreamNames:  streamname1: %s\n", streamname);
-	}
+        {
+          globArgcStart = globArgc;
+
+          globArgc = getGlobArgc(argc, argv, globArgc);
+          len = 0;
+          for ( i = globArgcStart; i < globArgc; i++ ) len += strlen(argv[i]) + 1;
+          streamname = (char*) calloc(1, len);
+          for ( i = globArgcStart; i < globArgc; i++ )
+            {
+              strcat(streamname, argv[i]);
+              if ( i < globArgc-1 ) strcat(streamname, " ");
+            }
+          for ( i = 1; i < len-1; i++ ) if ( streamname[i] == '\0' ) streamname[i] = ' ';
+          Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+          ac = globArgc - globArgcStart;
+          //printf("setStreamNames:  ac %d  streamname1: %s\n", ac, streamname);
+          Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+          for ( i = 0; i < ac; ++i )
+            Process[processID].streamNames[Process[processID].streamCnt].argv[i] = argv[i+globArgcStart];
+          Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
+          Process[processID].streamCnt++;
+          //printf("setStreamNames:  streamname1: %s\n", streamname);
+        }
       else
-	{
-	  len = strlen(argv[globArgc]) + 1;
-	  streamname = (char*) malloc(len);
-	  strcpy(streamname, argv[globArgc]);
-	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
-	  ac = 1;
-	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
-	  Process[processID].streamNames[Process[processID].streamCnt].argv[0] = argv[globArgc];
-	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
-	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
-	  Process[processID].streamCnt++;
-	  //printf("setStreamNames:  streamname2: %s\n", streamname);
-	  globArgc++;
-	}
+        {
+          len = strlen(argv[globArgc]) + 1;
+          streamname = (char*) malloc(len);
+          strcpy(streamname, argv[globArgc]);
+          Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+          ac = 1;
+          Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+          Process[processID].streamNames[Process[processID].streamCnt].argv[0] = argv[globArgc];
+          Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
+          Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+          Process[processID].streamCnt++;
+          //printf("setStreamNames:  streamname2: %s\n", streamname);
+          globArgc++;
+        }
     }
 }
 
@@ -563,14 +572,14 @@ int find_wildcard(const char *string, size_t len)
       if ( string[0] == '~' ) status = 1;
 
       if ( status == 0 )
-	{
-	  for ( size_t i = 0; i < len; ++i )
-	    if ( string[i] == '?' || string[i] == '*' || string[i] == '[' )
-	      {
-		status = 1;
-		break;
-	      }
-	}
+        {
+          for ( size_t i = 0; i < len; ++i )
+            if ( string[i] == '?' || string[i] == '*' || string[i] == '[' )
+              {
+                status = 1;
+                break;
+              }
+        }
     }
 
   return status;
@@ -603,50 +612,46 @@ int expand_wildcards(int processID, int streamCnt)
 {
   const char *streamname0 = Process[processID].streamNames[0].args;
 
-  if ( find_wildcard(streamname0, strlen(streamname0)) )
+  if ( streamname0[0] == '-' ) return 1;
+
+#if defined(HAVE_WORDEXP_H)
+  argument_t *glob_arg = glob_pattern(streamname0);
+
+  // skip if the input argument starts with an operator (starts with -)
+  // otherwise adapt streams if there are several files (>1)
+  // in case of one filename skip, no adaption needed
+  if ( glob_arg->argc > 1 && glob_arg->argv[0][0] != '-' )
     {
-#if defined(HAVE_GLOB_H)
-      argument_t *glob_arg = glob_pattern(streamname0);
-
-      if ( strcmp(streamname0, glob_arg->args) != 0 )
-	{
-	  int i;
-	  streamCnt = streamCnt - 1 + glob_arg->argc;
-
-	  free(Process[processID].streamNames[0].argv);
-	  free(Process[processID].streamNames[0].args);
-
-	  Process[processID].streamNames = (argument_t*) realloc(Process[processID].streamNames, streamCnt*sizeof(argument_t));
-	      
-	  // move output streams to the end
-	  for ( i = 1; i < Process[processID].streamCnt; ++i )
-	    Process[processID].streamNames[i+glob_arg->argc-1] = Process[processID].streamNames[i];
-
-	  for ( i = 0; i < glob_arg->argc; ++i )
-	    {
-	      // printf("add %d %s\n", i, glob_arg->argv[i]);
-	      Process[processID].streamNames[i].argv    = (char **) malloc(sizeof(char *));
-	      Process[processID].streamNames[i].argc    = 1;
-	      Process[processID].streamNames[i].argv[0] = strdupx(glob_arg->argv[i]);
-	      Process[processID].streamNames[i].args    = strdupx(glob_arg->argv[i]);
-	    }
-	  
-	  Process[processID].streamCnt = streamCnt;
-	  /*
-	  for ( i = 0; i < Process[processID].streamCnt; ++i )
-	    printf("expand_wildcards: ostream %d <%s>\n", i+1, Process[processID].streamNames[i].args);
-	  */
-	}
-
-      free(glob_arg);
-#else
-      cdoAbort("Wildcards support not compiled in!");
-#endif
+      int i;
+      streamCnt = streamCnt - 1 + glob_arg->argc;
+
+      free(Process[processID].streamNames[0].argv);
+      free(Process[processID].streamNames[0].args);
+
+      Process[processID].streamNames = (argument_t*) realloc(Process[processID].streamNames, streamCnt*sizeof(argument_t));
+          
+      // move output streams to the end
+      for ( i = 1; i < Process[processID].streamCnt; ++i )
+        Process[processID].streamNames[i+glob_arg->argc-1] = Process[processID].streamNames[i];
+
+      for ( i = 0; i < glob_arg->argc; ++i )
+        {
+          Process[processID].streamNames[i].argv    = (char **) malloc(sizeof(char *));
+          Process[processID].streamNames[i].argc    = 1;
+          Process[processID].streamNames[i].argv[0] = strdupx(glob_arg->argv[i]);
+          Process[processID].streamNames[i].args    = strdupx(glob_arg->argv[i]);
+        }
+      
+      Process[processID].streamCnt = streamCnt;
     }
 
+  free(glob_arg);
+#endif
+
   return 1;
 }
 
+
 static
 int checkStreamCnt(void)
 {
@@ -691,27 +696,26 @@ int checkStreamCnt(void)
 
   if ( Process[processID].streamCnt > streamCnt )
     cdoAbort("Too many streams!"
-	     " Operator needs %d input and %d output streams.", streamInCnt, streamOutCnt);
+             " Operator needs %d input and %d output streams.", streamInCnt, streamOutCnt);
 
   if ( Process[processID].streamCnt < streamCnt )
     cdoAbort("Too few streams specified!"
-	     " Operator needs %d input and %d output streams.", streamInCnt, streamOutCnt);
-
+             " Operator needs %d input and %d output streams.", streamInCnt, streamOutCnt);
 
   for ( i = streamInCnt; i < streamCnt; i++ )
     {
       if ( Process[processID].streamNames[i].args[0] == '-' )
-	{
-	  cdoAbort("Output file name %s must not begin with \"-\"!\n",
-		   Process[processID].streamNames[i].args);
-	}
+        {
+          cdoAbort("Output file name %s must not begin with \"-\"!\n",
+                   Process[processID].streamNames[i].args);
+        }
       else if ( !obase )
-	{
-	  for ( j = 0; j < streamInCnt; j++ ) /* does not work with files in pipes */
-	    if ( strcmp(Process[processID].streamNames[i].args, Process[processID].streamNames[j].args) == 0 )
-	      cdoAbort("Output file name %s is equal to input file name"
-		       " on position %d!\n", Process[processID].streamNames[i].args, j+1);
-	}
+        {
+          for ( j = 0; j < streamInCnt; j++ ) /* does not work with files in pipes */
+            if ( strcmp(Process[processID].streamNames[i].args, Process[processID].streamNames[j].args) == 0 )
+              cdoAbort("Output file name %s is equal to input file name"
+                       " on position %d!\n", Process[processID].streamNames[i].args, j+1);
+        }
     }
 
   if ( streamInCnt == 1 && streamInCnt0 == -1 )
@@ -779,16 +783,16 @@ void processDefArgument(void *vargument)
 
       commapos = operatorArg;
       while ( (commapos = strchr(commapos, ',')) != NULL )
-	{
-	  *commapos++ = '\0';
-	  if ( strlen(commapos) )
-	    {
-	      if ( oargc >= MAX_OARGC )
-		cdoAbort("Too many parameter (limit=%d)!", MAX_OARGC);
-
-	      oargv[oargc++] = commapos;
-	    }
-	}
+        {
+          *commapos++ = '\0';
+          if ( strlen(commapos) )
+            {
+              if ( oargc >= MAX_OARGC )
+                cdoAbort("Too many parameter (limit=%d)!", MAX_OARGC);
+
+              oargv[oargc++] = commapos;
+            }
+        }
       Process[processID].oargc = oargc;
     }
 
@@ -899,48 +903,48 @@ void operatorInputArg(const char *enter)
       int lreadline = 1;
 
       if ( enter )
-	{
-	  set_text_color(stderr, BRIGHT, MAGENTA);
-	  fprintf(stderr, "%-16s : ", processInqPrompt());
-	  reset_text_color(stderr);
-	  // set_text_color(stderr, BLINK, BLACK);
-	  fprintf(stderr, "Enter %s > ", enter);
-	  // reset_text_color(stderr);
-	}
+        {
+          set_text_color(stderr, BRIGHT, MAGENTA);
+          fprintf(stderr, "%-16s : ", processInqPrompt());
+          reset_text_color(stderr);
+          // set_text_color(stderr, BLINK, BLACK);
+          fprintf(stderr, "Enter %s > ", enter);
+          // reset_text_color(stderr);
+        }
 
       while ( lreadline )
-	{
-	  readline(stdin, pline, 1024);
-
-	  lreadline = 0;
-	  while ( 1 )
-	    {
-	      pos = 0;
-	      while ( pline[pos] == ' ' || pline[pos] == ',' ) pos++;
-	      pline += pos;
-	      linelen = strlen(pline);
-	      if ( linelen > 0 )
-		{
-		  if ( pline[0] == '\\' )
-		    {
-		      lreadline = 1;
-		      break;
-		    }
-		  len = 0;
-		  while ( pline[len] != ' '  && pline[len] != ',' &&
-			  pline[len] != '\\' && len < linelen ) len++;
-
-		  Process[processID].oargv[oargc] = (char*) malloc(len+1);
-		  memcpy(Process[processID].oargv[oargc], pline, len);
-		  Process[processID].oargv[oargc][len] = '\0';
-		  oargc++;
-
-		  pline += len;
-		}
-	      else
-		break;
-	    }
-	}
+        {
+          readline(stdin, pline, 1024);
+
+          lreadline = 0;
+          while ( 1 )
+            {
+              pos = 0;
+              while ( pline[pos] == ' ' || pline[pos] == ',' ) pos++;
+              pline += pos;
+              linelen = strlen(pline);
+              if ( linelen > 0 )
+                {
+                  if ( pline[0] == '\\' )
+                    {
+                      lreadline = 1;
+                      break;
+                    }
+                  len = 0;
+                  while ( pline[len] != ' '  && pline[len] != ',' &&
+                          pline[len] != '\\' && len < linelen ) len++;
+
+                  Process[processID].oargv[oargc] = (char*) malloc(len+1);
+                  memcpy(Process[processID].oargv[oargc], pline, len);
+                  Process[processID].oargv[oargc][len] = '\0';
+                  oargc++;
+
+                  pline += len;
+                }
+              else
+                break;
+            }
+        }
 
       Process[processID].oargc = oargc;
     }
@@ -978,11 +982,11 @@ int cdoOperatorID(void)
   if ( Process[processID].noper > 0 )
     {
       for ( operID = 0; operID < Process[processID].noper; operID++ )
-	if ( Process[processID].oper[operID].name )
-	  if ( strcmp(Process[processID].operatorName, Process[processID].oper[operID].name) == 0 ) break;
+        if ( Process[processID].oper[operID].name )
+          if ( strcmp(Process[processID].operatorName, Process[processID].oper[operID].name) == 0 ) break;
 
       if ( operID == Process[processID].noper )
-	cdoAbort("Operator not callable by this name!");
+        cdoAbort("Operator not callable by this name!");
     }
   else
     {
diff --git a/src/process.h b/src/process.h
index 77cb7f9..5b0e830 100644
--- a/src/process.h
+++ b/src/process.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pstream.c b/src/pstream.c
index 1fe4c4d..9e3f028 100644
--- a/src/pstream.c
+++ b/src/pstream.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -45,8 +45,6 @@ int pclose(FILE *stream);
 #include "dmemory.h"
 
 
-extern int timer_read, timer_write;
-
 static int PSTREAM_Debug = 0;
 
 #define  MAX_PSTREAMS  4096
@@ -407,7 +405,6 @@ int pstreamOpenRead(const argument_t *argument)
     }
   else
     {
-      extern int cdoDefaultFileType/*, cdoDefaultInstID*/;
       size_t len, i;
       int nfiles = 1, j;
       char *filename = NULL;
@@ -422,8 +419,8 @@ int pstreamOpenRead(const argument_t *argument)
 	{
 	  pch = &argument->args[i+1];
 	  len -= (i+1);
-	  if ( len && ( memcmp(argument->args, "filelist:", 9) == 0 || 
-			memcmp(argument->args, "flist:", 6) == 0 ) )
+	  if ( len && ( strncmp(argument->args, "filelist:", 9) == 0 || 
+			strncmp(argument->args, "flist:", 6) == 0 ) )
 	    {
 	      for ( i = 0; i < len; i++ ) if ( pch[i] == ',' ) nfiles++;
 
@@ -488,7 +485,7 @@ int pstreamOpenRead(const argument_t *argument)
 		    }
 		}
 	    }
-	  else if ( len && memcmp(argument->args, "ls:", 3) == 0 )
+	  else if ( len && strncmp(argument->args, "ls:", 3) == 0 )
 	    {
 	      char line[4096];
 	      char command[4096];
@@ -636,7 +633,7 @@ int pstreamOpenWrite(const argument_t *argument, int filetype)
 
   PSTREAM_INIT();
 
-  ispipe = memcmp(argument->args, "(pipe", 5) == 0;
+  ispipe = strncmp(argument->args, "(pipe", 5) == 0;
 
   if ( ispipe )
     {
@@ -654,7 +651,6 @@ int pstreamOpenWrite(const argument_t *argument, int filetype)
     }
   else
     {
-      /* extern int cdoDefaultInstID; */
       char *filename = (char*) malloc(strlen(argument->args)+1);
 
       pstreamptr = pstream_new_entry();
@@ -750,7 +746,7 @@ int pstreamOpenAppend(const argument_t *argument)
   int ispipe;
   pstream_t *pstreamptr;
 
-  ispipe = memcmp(argument->args, "(pipe", 5) == 0;
+  ispipe = strncmp(argument->args, "(pipe", 5) == 0;
 
   if ( ispipe )
     {
@@ -942,8 +938,6 @@ int pstreamInqVlist(int pstreamID)
   else
 #endif
     {
-      extern int cdoDefaultTimeType;
-
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_start(timer_read);
 #if defined(HAVE_LIBPTHREAD)
       if ( cdoLockIO ) pthread_mutex_lock(&streamMutex);
@@ -977,7 +971,6 @@ const char *cdoComment(void)
   static char comment[256];
   static int init = 0;
   int size = 0;
-  extern char CDO_Version[];
 
   if ( ! init )
     {
@@ -1359,8 +1352,6 @@ int pstreamInqTimestep(int pstreamID, int tsID)
   else
 #endif
     {
-      extern int cdoDefaultTimeType;
-
       if ( pstreamptr->mfiles ) tsID -= pstreamptr->tsID0;
 
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_start(timer_read);
@@ -1457,7 +1448,6 @@ void pstreamDefTimestep(int pstreamID, int tsID)
   else
 #endif
     {
-      extern int cdoDefaultTimeType;
       if ( tsID == 0 && cdoDefaultTimeType != CDI_UNDEFID )
 	{
 	  int taxisID, vlistID;
@@ -1652,7 +1642,6 @@ void cdoFinish(void)
       int mu[] = {'b', 'k', 'm', 'g', 't'};
       int muindex = 0;
       long memmax;
-      extern int cdoLogOff;
 
       memmax = memTotal();
       while ( memmax > 9999 )
diff --git a/src/pstream.h b/src/pstream.h
index 7a988f8..4550d4b 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -18,9 +18,10 @@
 #ifndef _PSTREAM_H
 #define _PSTREAM_H
 
+#include "pstream_write.h"
+
 #include <sys/types.h> /* off_t */
 
-#define  streamOpenWrite          pstreamOpenWrite
 #define  streamOpenRead           pstreamOpenRead
 #define  streamOpenAppend         pstreamOpenAppend
 #define  streamClose              pstreamClose
@@ -29,16 +30,11 @@
 #define  streamInqByteorder       pstreamInqByteorder
 
 #define  streamInqVlist           pstreamInqVlist
-#define  streamDefVlist           pstreamDefVlist
 
-#define  streamDefTimestep        pstreamDefTimestep
 #define  streamInqTimestep        pstreamInqTimestep
 
-#define  streamDefRecord          pstreamDefRecord
 #define  streamInqRecord          pstreamInqRecord
 
-#define  streamWriteRecord        pstreamWriteRecord
-#define  streamWriteRecordF       pstreamWriteRecordF
 #define  streamReadRecord         pstreamReadRecord
 
 #define  streamCopyRecord         pstreamCopyRecord
@@ -48,7 +44,6 @@
 #define  vlistCopyFlag            cdoVlistCopyFlag
 
 
-int     pstreamOpenWrite(const argument_t *argument, int filetype);
 int     pstreamOpenRead(const argument_t *argument);
 int     pstreamOpenAppend(const argument_t *argument);
 void    pstreamClose(int pstreamID);
@@ -56,17 +51,12 @@ void    pstreamClose(int pstreamID);
 int     pstreamInqFiletype(int pstreamID);
 int     pstreamInqByteorder(int pstreamID);
 
-void    pstreamDefVlist(int pstreamID, int vlistID);
 int     pstreamInqVlist(int pstreamID);
 
-void    pstreamDefTimestep(int pstreamID, int tsID);
 int     pstreamInqTimestep(int pstreamID, int tsID);
 
-void    pstreamDefRecord(int pstreamID, int  varID, int  levelID);
 int     pstreamInqRecord(int pstreamID, int *varID, int *levelID);
 
-void    pstreamWriteRecord(int pstreamID, double *data, int nmiss);
-void    pstreamWriteRecordF(int pstreamID, float *data, int nmiss);
 void    pstreamReadRecord(int pstreamID, double *data, int *nmiss);
 void    pstreamCopyRecord(int pstreamIDdest, int pstreamIDsrc);
 
@@ -74,6 +64,4 @@ void    pstreamInqGRIBinfo(int pstreamID, int *intnum, float *fltnum, off_t *big
 
 void    cdoVlistCopyFlag(int vlistID2, int vlistID1);
 
-
-
 #endif  /* _PSTREAM_H */
diff --git a/src/pstream_int.h b/src/pstream_int.h
index acb6ec6..daa5f49 100644
--- a/src/pstream_int.h
+++ b/src/pstream_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pstream_write.h b/src/pstream_write.h
new file mode 100644
index 0000000..3feb228
--- /dev/null
+++ b/src/pstream_write.h
@@ -0,0 +1,45 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  See COPYING file for copying and redistribution conditions.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+*/
+
+#ifndef _PSTREAM_WRITE_H
+#define _PSTREAM_WRITE_H
+
+#define  streamOpenWrite          pstreamOpenWrite
+
+#define  streamDefVlist           pstreamDefVlist
+
+#define  streamDefTimestep        pstreamDefTimestep
+
+#define  streamDefRecord          pstreamDefRecord
+
+#define  streamWriteRecord        pstreamWriteRecord
+#define  streamWriteRecordF       pstreamWriteRecordF
+
+
+int     pstreamOpenWrite(const argument_t *argument, int filetype);
+void    pstreamClose(int pstreamID);
+
+void    pstreamDefVlist(int pstreamID, int vlistID);
+
+void    pstreamDefTimestep(int pstreamID, int tsID);
+
+void    pstreamDefRecord(int pstreamID, int  varID, int  levelID);
+
+void    pstreamWriteRecord(int pstreamID, double *data, int nmiss);
+void    pstreamWriteRecordF(int pstreamID, float *data, int nmiss);
+
+#endif  /* _PSTREAM_WRITE_H */
diff --git a/src/readline.c b/src/readline.c
index 2502529..c74cebc 100644
--- a/src/readline.c
+++ b/src/readline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/remap.h b/src/remap.h
index 0fbdc21..439bc5a 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -138,8 +138,8 @@ typedef struct {
   int      norm_opt;         /* option for normalization (conserv only)  */
   int      resize_increment; /* default amount to increase array size    */
 
-  int*     src_grid_add;     /* source grid address for each link        */
-  int*     tgt_grid_add;     /* target grid address for each link        */
+  int*     src_cell_add;     /* source grid address for each link        */
+  int*     tgt_cell_add;     /* target grid address for each link        */
 
   double*  wts;              /* map weights for each link [max_links*num_wts] */
 
@@ -211,11 +211,9 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
 void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type, int *num_neighbors,
 		      int *remap_order, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 
-void store_link_bilin(remapvars_t *rv, int dst_add, int src_add[4], double weights[4]);
-
 void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats, const restr_t* restrict cell_bound_box, int* restrict bin_addr);
 void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type);
-long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr2,
+long get_srch_cells(long tgt_cell_add, long nbins, int *bin_addr1, int *bin_addr2,
 		    restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, long src_grid_size, int *srch_add);
 
 int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
diff --git a/src/remap_bicubic_scrip.c b/src/remap_bicubic_scrip.c
index 6c250b6..079d1dd 100644
--- a/src/remap_bicubic_scrip.c
+++ b/src/remap_bicubic_scrip.c
@@ -2,6 +2,7 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "remap.h"
+#include "remap_store_link.h"
 
 
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -10,60 +11,24 @@
 /*                                                                         */
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 
-/*
-  This routine stores the address and weight for four links associated with one destination 
-  point in the appropriate address and weight arrays and resizes those arrays if necessary.
-*/
-static
-void store_link_bicub(remapvars_t *rv, int dst_add, int src_add[4], double weights[4][4])
-{
-  /*
-    Input variables:
-    int dst_add          ! address on destination grid
-    int src_add[4]       ! addresses on source grid
-    double weights[4][4] ! array of remapping weights for these links
-  */
-  long n, k;
-  long nlink;
-
-  /*
-     Increment number of links and check to see if remap arrays need
-     to be increased to accomodate the new link. Then store the link.
-  */
-  nlink = rv->num_links;
-  rv->num_links += 4;
-
-  if ( rv->num_links >= rv->max_links ) 
-    resize_remap_vars(rv, rv->resize_increment);
-
-  for ( n = 0; n < 4; ++n )
-    {
-      rv->src_grid_add[nlink+n] = src_add[n];
-      rv->tgt_grid_add[nlink+n] = dst_add;
-      for ( k = 0; k < 4; ++k )
-	rv->wts[4*(nlink+n)+k] = weights[k][n];
-    }
-
-} /* store_link_bicub */
-
 static
 void set_bicubic_weights(double iw, double jw, double wgts[4][4])
 {
   wgts[0][0] = (1.-jw*jw*(3.-2.*jw))  * (1.-iw*iw*(3.-2.*iw));
-  wgts[0][1] = (1.-jw*jw*(3.-2.*jw))  *     iw*iw*(3.-2.*iw);
-  wgts[0][2] =     jw*jw*(3.-2.*jw)   *     iw*iw*(3.-2.*iw);
-  wgts[0][3] =     jw*jw*(3.-2.*jw)   * (1.-iw*iw*(3.-2.*iw));
-  wgts[1][0] = (1.-jw*jw*(3.-2.*jw))  *     iw*(iw-1.)*(iw-1.);
+  wgts[1][0] = (1.-jw*jw*(3.-2.*jw))  *     iw*iw*(3.-2.*iw);
+  wgts[2][0] =     jw*jw*(3.-2.*jw)   *     iw*iw*(3.-2.*iw);
+  wgts[3][0] =     jw*jw*(3.-2.*jw)   * (1.-iw*iw*(3.-2.*iw));
+  wgts[0][1] = (1.-jw*jw*(3.-2.*jw))  *     iw*(iw-1.)*(iw-1.);
   wgts[1][1] = (1.-jw*jw*(3.-2.*jw))  *     iw*iw*(iw-1.);
-  wgts[1][2] =     jw*jw*(3.-2.*jw)   *     iw*iw*(iw-1.);
-  wgts[1][3] =     jw*jw*(3.-2.*jw)   *     iw*(iw-1.)*(iw-1.);
-  wgts[2][0] =     jw*(jw-1.)*(jw-1.) * (1.-iw*iw*(3.-2.*iw));
-  wgts[2][1] =     jw*(jw-1.)*(jw-1.) *     iw*iw*(3.-2.*iw);
+  wgts[2][1] =     jw*jw*(3.-2.*jw)   *     iw*iw*(iw-1.);
+  wgts[3][1] =     jw*jw*(3.-2.*jw)   *     iw*(iw-1.)*(iw-1.);
+  wgts[0][2] =     jw*(jw-1.)*(jw-1.) * (1.-iw*iw*(3.-2.*iw));
+  wgts[1][2] =     jw*(jw-1.)*(jw-1.) *     iw*iw*(3.-2.*iw);
   wgts[2][2] =     jw*jw*(jw-1.)      *     iw*iw*(3.-2.*iw);
-  wgts[2][3] =     jw*jw*(jw-1.)      * (1.-iw*iw*(3.-2.*iw));
-  wgts[3][0] =     iw*(iw-1.)*(iw-1.) *     jw*(jw-1.)*(jw-1.);
-  wgts[3][1] =     iw*iw*(iw-1.)      *     jw*(jw-1.)*(jw-1.);
-  wgts[3][2] =     iw*iw*(iw-1.)      *     jw*jw*(jw-1.);
+  wgts[3][2] =     jw*jw*(jw-1.)      * (1.-iw*iw*(3.-2.*iw));
+  wgts[0][3] =     iw*(iw-1.)*(iw-1.) *     jw*(jw-1.)*(jw-1.);
+  wgts[1][3] =     iw*iw*(iw-1.)      *     jw*(jw-1.)*(jw-1.);
+  wgts[2][3] =     iw*iw*(iw-1.)      *     jw*jw*(jw-1.);
   wgts[3][3] =     iw*(iw-1.)*(iw-1.) *     jw*jw*(jw-1.);
 }
 
@@ -76,10 +41,10 @@ void renormalize_weights(const double src_lats[4], double wgts[4][4])
   double sum_wgts = 0.0; /* sum of weights for normalization */
   /* 2012-05-08 Uwe Schulzweida: using absolute value of src_lats (bug fix) */
   for ( n = 0; n < 4; ++n ) sum_wgts  += fabs(src_lats[n]);
-  for ( n = 0; n < 4; ++n ) wgts[0][n] = fabs(src_lats[n])/sum_wgts;
-  for ( n = 0; n < 4; ++n ) wgts[1][n] = 0.;
-  for ( n = 0; n < 4; ++n ) wgts[2][n] = 0.;
-  for ( n = 0; n < 4; ++n ) wgts[3][n] = 0.;
+  for ( n = 0; n < 4; ++n ) wgts[n][0] = fabs(src_lats[n])/sum_wgts;
+  for ( n = 0; n < 4; ++n ) wgts[n][1] = 0.;
+  for ( n = 0; n < 4; ++n ) wgts[n][2] = 0.;
+  for ( n = 0; n < 4; ++n ) wgts[n][3] = 0.;
 }
 
 static
@@ -95,67 +60,16 @@ void bicubic_warning(void)
     }
 }
 
-typedef struct
-{
-  int add;
-  double wgts[4];
-}
-addwgts_t;
-
-static
-int cmpwgts(const void *s1, const void *s2)
-{
-  int cmp = 0;
-  const addwgts_t* c1 = (const addwgts_t*) s1;
-  const addwgts_t* c2 = (const addwgts_t*) s2;
-
-  if      ( c1->add < c2->add ) cmp = -1;
-  else if ( c1->add > c2->add ) cmp =  1;
-
-  return (cmp);
-}
-
-static
-void sort_bicubic_adds(int src_add[4], double wgts[4][4])
-{
-  int n;
-  addwgts_t addwgts[4];
-
-  for ( n = 1; n < 4; ++n )
-    if ( src_add[n] < src_add[n-1] ) break;
-  if ( n == 4 ) return;
-
-  for ( n = 0; n < 4; ++n )
-    {
-      addwgts[n].add     = src_add[n];
-      addwgts[n].wgts[0] = wgts[0][n];
-      addwgts[n].wgts[1] = wgts[1][n];
-      addwgts[n].wgts[2] = wgts[2][n];
-      addwgts[n].wgts[3] = wgts[3][n];
-    }
-
-  qsort(addwgts, 4, sizeof(addwgts_t), cmpwgts);
-
-  for ( n = 0; n < 4; ++n )
-    {
-      src_add[n] = addwgts[n].add;
-      wgts[0][n] = addwgts[n].wgts[0];
-      wgts[1][n] = addwgts[n].wgts[1];
-      wgts[2][n] = addwgts[n].wgts[2];
-      wgts[3][n] = addwgts[n].wgts[3];
-    }  
-}
-
 static
 void bicubic_remap(double* restrict tgt_point, const double* restrict src_array, double wgts[4][4], const int src_add[4],
 		   const double* restrict grad1, const double* restrict grad2, const double* restrict grad3)
 {
   *tgt_point = 0.;
   for ( int n = 0; n < 4; ++n )
-    *tgt_point += src_array[src_add[n]]*wgts[0][n] +
-                      grad1[src_add[n]]*wgts[1][n] +
-                      grad2[src_add[n]]*wgts[2][n] +
-                      grad3[src_add[n]]*wgts[3][n];  
+    *tgt_point += src_array[src_add[n]]*wgts[n][0] +
+                      grad1[src_add[n]]*wgts[n][1] +
+                      grad2[src_add[n]]*wgts[n][2] +
+                      grad3[src_add[n]]*wgts[n][3];  
 }
 
 /*
@@ -169,37 +83,40 @@ void scrip_remap_weights_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 {
   /*   Local variables */
   int  search_result;
-  long tgt_grid_size;
-  long dst_add;        /*  destination addresss                   */
+  long tgt_cell_add;        /*  destination addresss                   */
   int src_add[4];      /*  address for the four source points     */
   double src_lats[4];  /*  latitudes  of four bilinear corners    */
   double src_lons[4];  /*  longitudes of four bilinear corners    */
   double wgts[4][4];   /*  bicubic weights for four corners       */
   double plat, plon;   /*  lat/lon coords of destination point    */
-  double findex = 0;
+  extern int timer_remap_bic;
   int remap_grid_type = src_grid->remap_grid_type;
 
   if ( cdoVerbose ) cdoPrint("Called %s()", __func__);
 
-  progressInit();
+  if ( cdoTimer ) timer_start(timer_remap_bic);
 
-  tgt_grid_size = tgt_grid->size;
+  progressInit();
 
   /* Compute mappings from source to target grid */
 
   if ( src_grid->rank != 2 )
     cdoAbort("Can not do bicubic interpolation when source grid rank != 2"); 
 
+  long tgt_grid_size = tgt_grid->size;
+
+  weightlinks4_t *weightlinks = (weightlinks4_t *) malloc(tgt_grid_size*sizeof(weightlinks4_t));
+
   /* Loop over destination grid */
 
+  double findex = 0;
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
-  private(dst_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result) \
-  schedule(dynamic,1)
+  shared(ompNumThreads, cdoVerbose, weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
+  private(tgt_cell_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)
 #endif
-  /* grid_loop1 */
-  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int lprogress = 1;
       if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -210,10 +127,12 @@ void scrip_remap_weights_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      if ( ! tgt_grid->mask[dst_add] ) continue;
+      weightlinks[tgt_cell_add].nlinks = 0;	
 
-      plat = tgt_grid->cell_center_lat[dst_add];
-      plon = tgt_grid->cell_center_lon[dst_add];
+      if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
+
+      plat = tgt_grid->cell_center_lat[tgt_cell_add];
+      plon = tgt_grid->cell_center_lon[tgt_cell_add];
 
       /* Find nearest square of grid points on source grid  */
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -238,19 +157,14 @@ void scrip_remap_weights_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          tgt_grid->cell_frac[dst_add] = 1.;
+          tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
           if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 	      set_bicubic_weights(iw, jw, wgts);
 
-	      sort_bicubic_adds(src_add, wgts);
-
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      store_link_bicub(rv, dst_add, src_add, wgts);
+	      store_weightlinks4(4, src_add, wgts, tgt_cell_add, weightlinks);
 	    }
           else
 	    {
@@ -270,17 +184,18 @@ void scrip_remap_weights_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	    {
 	      renormalize_weights(src_lats, wgts);
 
-	      tgt_grid->cell_frac[dst_add] = 1.;
-
-	      sort_bicubic_adds(src_add, wgts);
+	      tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      store_link_bicub(rv, dst_add, src_add, wgts);
+	      store_weightlinks4(4, src_add, wgts, tgt_cell_add, weightlinks);
 	    }
         }
-    } /* grid_loop1 */
+    }
+
+  if ( cdoTimer ) timer_stop(timer_remap_bic);
+
+  weightlinks2remaplinks4(tgt_grid_size, weightlinks, rv);
+
+  if ( weightlinks ) free(weightlinks);
 
 } /* scrip_remap_weights_bicubic */
 
@@ -295,44 +210,41 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
 {
   /*   Local variables */
   int  search_result;
-  long tgt_grid_size;
-  long dst_add;        /*  destination addresss                 */
+  long tgt_cell_add;        /*  destination addresss                 */
   int src_add[4];      /*  address for the four source points   */
   double src_lats[4];  /*  latitudes  of four bilinear corners  */
   double src_lons[4];  /*  longitudes of four bilinear corners  */
   double wgts[4][4];   /*  bicubic weights for four corners     */
   double plat, plon;   /*  lat/lon coords of destination point  */
-  double findex = 0;
-  double *grad1_lat, *grad1_lon, *grad1_latlon;
   int remap_grid_type = src_grid->remap_grid_type;
 
   if ( cdoVerbose ) cdoPrint("Called %s()", __func__);
 
   progressInit();
 
-  tgt_grid_size = tgt_grid->size;
+  long tgt_grid_size = tgt_grid->size;
 
   /* Compute mappings from source to target grid */
 
   if ( src_grid->rank != 2 )
     cdoAbort("Can not do bicubic interpolation when source grid rank != 2"); 
 
-  grad1_lat    = (double*) malloc(src_grid->size*sizeof(double));
-  grad1_lon    = (double*) malloc(src_grid->size*sizeof(double));
-  grad1_latlon = (double*) malloc(src_grid->size*sizeof(double));
+  double *grad1_lat    = (double*) malloc(src_grid->size*sizeof(double));
+  double *grad1_lon    = (double*) malloc(src_grid->size*sizeof(double));
+  double *grad1_latlon = (double*) malloc(src_grid->size*sizeof(double));
 
   remap_gradients(*src_grid, src_array, grad1_lat, grad1_lon, grad1_latlon);
 
   /* Loop over destination grid */
 
+  double findex = 0;
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, grad1_lat, grad1_lon, grad1_latlon, findex) \
-  private(dst_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result) \
-  schedule(dynamic,1)
+  shared(ompNumThreads, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, grad1_lat, grad1_lon, grad1_latlon, findex) \
+  private(tgt_cell_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)
 #endif
-  /* grid_loop1 */
-  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int lprogress = 1;
       if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -343,12 +255,12 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      tgt_array[dst_add] = missval;
+      tgt_array[tgt_cell_add] = missval;
 
-      if ( ! tgt_grid->mask[dst_add] ) continue;
+      if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
 
-      plat = tgt_grid->cell_center_lat[dst_add];
-      plon = tgt_grid->cell_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[tgt_cell_add];
+      plon = tgt_grid->cell_center_lon[tgt_cell_add];
 
       /* Find nearest square of grid points on source grid  */
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -373,16 +285,16 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          tgt_grid->cell_frac[dst_add] = 1.;
+          tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
           if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 	      set_bicubic_weights(iw, jw, wgts);
 
-	      sort_bicubic_adds(src_add, wgts);
+	      sort_add_and_wgts4(4, src_add, wgts);
 
-	      bicubic_remap(&tgt_array[dst_add], src_array, wgts, src_add, grad1_lat, grad1_lon, grad1_latlon);
+	      bicubic_remap(&tgt_array[tgt_cell_add], src_array, wgts, src_add, grad1_lat, grad1_lon, grad1_latlon);
 	    }
           else
 	    {
@@ -402,14 +314,14 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
 	    {
 	      renormalize_weights(src_lats, wgts);
 
-	      tgt_grid->cell_frac[dst_add] = 1.;
+	      tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
-	      sort_bicubic_adds(src_add, wgts);
+	      sort_add_and_wgts4(4, src_add, wgts);
 
-	      bicubic_remap(&tgt_array[dst_add], src_array, wgts, src_add, grad1_lat, grad1_lon, grad1_latlon);
+	      bicubic_remap(&tgt_array[tgt_cell_add], src_array, wgts, src_add, grad1_lat, grad1_lon, grad1_latlon);
 	    }
         }
-    } /* grid_loop1 */
+    }
 
   free(grad1_lat);
   free(grad1_lon);
diff --git a/src/remap_bilinear_scrip.c b/src/remap_bilinear_scrip.c
index 9626fdd..cea2d4e 100644
--- a/src/remap_bilinear_scrip.c
+++ b/src/remap_bilinear_scrip.c
@@ -2,6 +2,7 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "remap.h"
+#include "remap_store_link.h"
 
 
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -10,40 +11,6 @@
 /*                                                                         */
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 
-/*
-  This routine stores the address and weight for four links associated with one destination
-  point in the appropriate address and weight arrays and resizes those arrays if necessary.
-*/
-void store_link_bilin(remapvars_t *rv, int dst_add, int src_add[4], double weights[4])
-{
-  /*
-    Input variables:
-    int dst_add       ! address on destination grid
-    int src_add[4]    ! addresses on source grid
-    double weights[4] ! array of remapping weights for these links
-  */
-  long n;
-  long nlink;
-
-  /*
-     Increment number of links and check to see if remap arrays need
-     to be increased to accomodate the new link. Then store the link.
-  */
-  nlink = rv->num_links;
-  rv->num_links += 4;
-
-  if ( rv->num_links >= rv->max_links ) 
-    resize_remap_vars(rv, rv->resize_increment);
-
-  for ( n = 0; n < 4; ++n )
-    {
-      rv->src_grid_add[nlink+n] = src_add[n];
-      rv->tgt_grid_add[nlink+n] = dst_add;
-      rv->wts         [nlink+n] = weights[n];
-    }
-
-} /* store_link_bilin */
-
 
 int find_ij_weights(double plon, double plat, double* restrict src_lats, double* restrict src_lons, double *ig, double *jg)
 {
@@ -178,57 +145,13 @@ void bilinear_warning(double plon, double plat, double iw, double jw, int* src_a
     }
 }
 
-typedef struct
-{
-  int add;
-  double wgts;
-}
-addwgts_t;
-
-static
-int cmpwgts(const void *s1, const void *s2)
-{
-  int cmp = 0;
-  const addwgts_t* c1 = (const addwgts_t*) s1;
-  const addwgts_t* c2 = (const addwgts_t*) s2;
-
-  if      ( c1->add < c2->add ) cmp = -1;
-  else if ( c1->add > c2->add ) cmp =  1;
-
-  return (cmp);
-}
-
-static
-void sort_bilinear_adds(int src_add[4], double wgts[4])
-{
-  int n;
-  addwgts_t addwgts[4];
-
-  for ( n = 1; n < 4; ++n )
-    if ( src_add[n] < src_add[n-1] ) break;
-  if ( n == 4 ) return;
-
-  for ( n = 0; n < 4; ++n )
-    {
-      addwgts[n].add  = src_add[n];
-      addwgts[n].wgts = wgts[n];
-    }
-
-  qsort(addwgts, 4, sizeof(addwgts_t), cmpwgts);
-
-  for ( n = 0; n < 4; ++n )
-    {
-      src_add[n] = addwgts[n].add;
-      wgts[n]    = addwgts[n].wgts;
-    }  
-}
-
 static
 void bilinear_remap(double* restrict tgt_point, const double* restrict src_array, const double wgts[4], const int src_add[4])
 {
   // *tgt_point = 0.;
   // for ( int n = 0; n < 4; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
-  *tgt_point = src_array[src_add[0]]*wgts[0] + src_array[src_add[1]]*wgts[1] + src_array[src_add[2]]*wgts[2] + src_array[src_add[3]]*wgts[3];
+  *tgt_point = src_array[src_add[0]]*wgts[0] + src_array[src_add[1]]*wgts[1]
+             + src_array[src_add[2]]*wgts[2] + src_array[src_add[3]]*wgts[3];
 }
 
 /*
@@ -242,14 +165,12 @@ void scrip_remap_weights_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid,
 {
   /*   Local variables */
   int  search_result;
-  long tgt_grid_size;
-  long dst_add;                  /*  destination addresss                   */
+  long tgt_cell_add;             /*  destination addresss                   */
   int src_add[4];                /*  address for the four source points     */
   double src_lats[4];            /*  latitudes  of four bilinear corners    */
   double src_lons[4];            /*  longitudes of four bilinear corners    */
   double wgts[4];                /*  bilinear weights for four corners      */
   double plat, plon;             /*  lat/lon coords of destination point    */
-  double findex = 0;
   extern int timer_remap_bil;
   int remap_grid_type = src_grid->remap_grid_type;
 
@@ -259,23 +180,26 @@ void scrip_remap_weights_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid,
 
   progressInit();
 
-  tgt_grid_size = tgt_grid->size;
-
   /* Compute mappings from source to target grid */
 
   if ( src_grid->rank != 2 )
     cdoAbort("Can not do bilinear interpolation when source grid rank != 2"); 
 
+  long tgt_grid_size = tgt_grid->size;
+
+  weightlinks_t *weightlinks = (weightlinks_t *) malloc(tgt_grid_size*sizeof(weightlinks_t));
+
+  double findex = 0;
+
   /* Loop over destination grid */
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
-  private(dst_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)    \
+  shared(ompNumThreads, cdoVerbose, weightlinks, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, findex) \
+  private(tgt_cell_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)    \
   schedule(static)
 #endif
-  /* grid_loop1 */
-  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int lprogress = 1;
       if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -286,10 +210,12 @@ void scrip_remap_weights_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid,
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      if ( ! tgt_grid->mask[dst_add] ) continue;
+      weightlinks[tgt_cell_add].nlinks = 0;	
+
+      if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
 
-      plat = tgt_grid->cell_center_lat[dst_add];
-      plon = tgt_grid->cell_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[tgt_cell_add];
+      plon = tgt_grid->cell_center_lon[tgt_cell_add];
 
       /* Find nearest square of grid points on source grid  */
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -314,19 +240,14 @@ void scrip_remap_weights_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid,
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          tgt_grid->cell_frac[dst_add] = 1.;
+          tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
           if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 	      set_bilinear_weights(iw, jw, wgts);
 
-	      sort_bilinear_adds(src_add, wgts);
-
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      store_link_bilin(rv, dst_add, src_add, wgts);
+	      store_weightlinks(4, src_add, wgts, tgt_cell_add, weightlinks);
 	    }
           else
 	    {
@@ -346,17 +267,16 @@ void scrip_remap_weights_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid,
 	    {
 	      renormalize_weights(src_lats, wgts);
 
-	      tgt_grid->cell_frac[dst_add] = 1.;
-
-	      sort_bilinear_adds(src_add, wgts);
+	      tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      store_link_bilin(rv, dst_add, src_add, wgts);
+	      store_weightlinks(4, src_add, wgts, tgt_cell_add, weightlinks);
 	    }
         }
-    } /* grid_loop1 */
+    }
+
+  weightlinks2remaplinks(tgt_grid_size, weightlinks, rv);
+
+  if ( weightlinks ) free(weightlinks);
 
   if ( cdoTimer ) timer_stop(timer_remap_bil);
 } /* scrip_remap_weights_bilinear */
@@ -373,13 +293,12 @@ void scrip_remap_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid, const do
   /*   Local variables */
   int  search_result;
   long tgt_grid_size;
-  long dst_add;                  /*  destination addresss */
+  long tgt_cell_add;             /*  destination addresss                   */
   int src_add[4];                /*  address for the four source points     */
   double src_lats[4];            /*  latitudes  of four bilinear corners    */
   double src_lons[4];            /*  longitudes of four bilinear corners    */
   double wgts[4];                /*  bilinear weights for four corners      */
   double plat, plon;             /*  lat/lon coords of destination point    */
-  double findex = 0;
   extern int timer_remap_bil;
   int remap_grid_type = src_grid->remap_grid_type;
 
@@ -396,16 +315,17 @@ void scrip_remap_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid, const do
   if ( src_grid->rank != 2 )
     cdoAbort("Can not do bilinear interpolation when source grid rank != 2"); 
 
+  double findex = 0;
+
   /* Loop over destination grid */
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, cdoSilentMode, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, findex) \
-  private(dst_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)    \
+  shared(ompNumThreads, cdoVerbose, cdoSilentMode, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, src_array, tgt_array, missval, findex) \
+  private(tgt_cell_add, src_add, src_lats, src_lons, wgts, plat, plon, search_result)    \
   schedule(static)
 #endif
-  /* grid_loop1 */
-  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int lprogress = 1;
       if ( cdo_omp_get_thread_num() != 0 ) lprogress = 0;
@@ -419,12 +339,12 @@ void scrip_remap_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid, const do
 	  if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 	}
 
-      tgt_array[dst_add] = missval;
+      tgt_array[tgt_cell_add] = missval;
 
-      if ( ! tgt_grid->mask[dst_add] ) continue;
+      if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
 
-      plat = tgt_grid->cell_center_lat[dst_add];
-      plon = tgt_grid->cell_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[tgt_cell_add];
+      plon = tgt_grid->cell_center_lon[tgt_cell_add];
 
       /* Find nearest square of grid points on source grid  */
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -449,16 +369,16 @@ void scrip_remap_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid, const do
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          tgt_grid->cell_frac[dst_add] = 1.;
+          tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
           if ( find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw) )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 	      set_bilinear_weights(iw, jw, wgts);
 
-	      sort_bilinear_adds(src_add, wgts);
+	      sort_add_and_wgts(4, src_add, wgts);
 
-	      bilinear_remap(&tgt_array[dst_add], src_array, wgts, src_add);
+	      bilinear_remap(&tgt_array[tgt_cell_add], src_array, wgts, src_add);
 	    }
           else
 	    {
@@ -478,14 +398,14 @@ void scrip_remap_bilinear(remapgrid_t* src_grid, remapgrid_t* tgt_grid, const do
 	    {
 	      renormalize_weights(src_lats, wgts);
 
-	      tgt_grid->cell_frac[dst_add] = 1.;
+	      tgt_grid->cell_frac[tgt_cell_add] = 1.;
 
-	      sort_bilinear_adds(src_add, wgts);
+	      sort_add_and_wgts(4, src_add, wgts);
 
-	      bilinear_remap(&tgt_array[dst_add], src_array, wgts, src_add);
+	      bilinear_remap(&tgt_array[tgt_cell_add], src_array, wgts, src_add);
 	    }
         }
-    } /* grid_loop1 */
+    }
 
   if ( cdoTimer ) timer_stop(timer_remap_bil);
 } /* scrip_remap_bilinear */
diff --git a/src/remap_conserv.c b/src/remap_conserv.c
index 50ecb43..528fca6 100644
--- a/src/remap_conserv.c
+++ b/src/remap_conserv.c
@@ -5,50 +5,6 @@
 #include "remap_store_link.h"
 
 
-
-/*
-    This routine stores the address and weight for this link in the appropriate 
-    address and weight arrays and resizes those arrays if necessary.
-*/
-static
-void store_link_conserv(remapvars_t* rv, long add1, long add2, long num_wts, double* weights)
-{
-  /*
-    Input variables:
-    int  add1         ! address on source grid
-    int  add2         ! address on target grid
-    double weights[]  ! array of remapping weights for this link
-  */
-  /* Local variables */
-  long nlink; /* link index */
-  long i;
-
-  /*  If all weights are ZERO, do not bother storing the link */
-
-  if ( num_wts == 3 )
-    {
-      if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) ) return;
-    }
-  else
-    {
-      if ( IS_EQUAL(weights[0], 0) ) return;
-    }
-    
-  nlink = rv->num_links;
-
-  rv->num_links++;
-  if ( rv->num_links >= rv->max_links )
-    resize_remap_vars(rv, rv->resize_increment);
-
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
-
-  for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] = weights[i];	      
-
-}  /* store_link_conserv */
-
-
-
 int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm, const double *restrict xm);
 
 static
@@ -304,7 +260,7 @@ void boundbox_from_corners1r(long ic, long nc, const double *restrict corner_lon
 static
 double gridcell_area(struct grid_cell cell)
 {
-  return huiliers_area(cell);
+  return yac_huiliers_area(cell);
 }
 
 static
@@ -316,7 +272,7 @@ void cdo_compute_overlap_areas(unsigned N,
 {
   /* Do the clipping and get the cell for the overlapping area */
 
-  cell_clipping(N, source_cells, target_cell, overlap_buffer);
+  yac_cell_clipping(N, source_cells, target_cell, overlap_buffer);
 
   /* Get the partial areas for the overlapping regions */
 
@@ -400,13 +356,13 @@ void cdo_compute_concave_overlap_areas(unsigned N,
     {.coordinates_x   = (double[3]){-1, -1, -1},
      .coordinates_y   = (double[3]){-1, -1, -1},
      .coordinates_xyz = (double[3*3]){-1, -1, -1},
-     .edge_type       = (enum edge_type[3]) {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE},
+     .edge_type       = (enum yac_edge_type[3]) {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE},
      .num_corners     = 3};
   */
   double coordinates_x[3] = {-1, -1, -1};
   double coordinates_y[3] = {-1, -1, -1};
   double coordinates_xyz[9] = {-1, -1, -1};
-  enum edge_type edge_types[3] = {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE};
+  enum yac_edge_type edge_types[3] = {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE};
   struct grid_cell target_partial_cell =
     {.coordinates_x   = coordinates_x,
      .coordinates_y   = coordinates_y,
@@ -468,7 +424,7 @@ void cdo_compute_concave_overlap_areas(unsigned N,
       target_partial_cell.coordinates_xyz[1+3*2] = target_cell.coordinates_xyz[1+3*corner_b];
       target_partial_cell.coordinates_xyz[2+3*2] = target_cell.coordinates_xyz[2+3*corner_b];
 
-      cell_clipping(N, source_cell, target_partial_cell, overlap_buffer);
+      yac_cell_clipping(N, source_cell, target_partial_cell, overlap_buffer);
 
       /* Get the partial areas for the overlapping regions as sum over the partial target cells. */
 
@@ -549,7 +505,7 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv)
   long n;
   long num_wts = rv->num_wts;
   long num_links = rv->num_links;
-  long tgt_grid_add;       /* current linear address for target grid cell   */
+  long tgt_cell_add;       /* current linear address for target grid cell   */
   double norm_factor = 0;  /* factor for normalizing wts */
 
   if ( rv->norm_opt == NORM_OPT_DESTAREA )
@@ -560,14 +516,14 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv)
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(num_wts, num_links, rv, tgt_grid)	\
-  private(n, tgt_grid_add, norm_factor)
+  private(n, tgt_cell_add, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
-	  tgt_grid_add = rv->tgt_grid_add[n];
+	  tgt_cell_add = rv->tgt_cell_add[n];
 
-          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_grid_add], 0) )
-	    norm_factor = ONE/tgt_grid->cell_area[tgt_grid_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_cell_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_area[tgt_cell_add];
           else
             norm_factor = ZERO;
 
@@ -582,14 +538,14 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv)
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(num_wts, num_links, rv, tgt_grid)	\
-  private(n, tgt_grid_add, norm_factor)
+  private(n, tgt_cell_add, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
-	  tgt_grid_add = rv->tgt_grid_add[n];
+	  tgt_cell_add = rv->tgt_cell_add[n];
 
-          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_grid_add], 0) )
-	    norm_factor = ONE/tgt_grid->cell_frac[tgt_grid_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_cell_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_frac[tgt_cell_add];
           else
             norm_factor = ZERO;
 
@@ -601,6 +557,7 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv)
     }
 }
 
+
 void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /* local variables */
@@ -608,14 +565,12 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
   int    lcheck = TRUE;
 
   long   ioffset;
-  long   src_grid_size;
-  long   tgt_grid_size;
   long   src_num_cell_corners;
   long   tgt_num_cell_corners;
-  long   src_grid_add;       /* current linear address for source grid cell   */
-  long   tgt_grid_add;       /* current linear address for target grid cell   */
-  long   n, k;               /* generic counters                        */
-  long   nbins, num_links;
+  long   src_cell_add;       /* current linear address for source grid cell   */
+  long   tgt_cell_add;       /* current linear address for target grid cell   */
+  long   k;                  /* generic counters                        */
+  long   nbins;
   long   num_wts;
   long   max_srch_cells;     /* num cells in restricted search arrays  */
   long   num_srch_cells;     /* num cells in restricted search arrays  */
@@ -624,8 +579,6 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
   int    i;
 
   /* Variables necessary if segment manages to hit pole */
-  double findex = 0;
-  long num_weights = 0;
   long nx = 0, ny = 0;
   int src_remap_grid_type = src_grid->remap_grid_type;
   int tgt_remap_grid_type = tgt_grid->remap_grid_type;
@@ -642,8 +595,8 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 
   if ( cdoTimer ) timer_start(timer_remap_con);
 
-  src_grid_size = src_grid->size;
-  tgt_grid_size = tgt_grid->size;
+  long src_grid_size = src_grid->size;
+  long tgt_grid_size = tgt_grid->size;
 
   src_num_cell_corners = src_grid->num_cell_corners;
   tgt_num_cell_corners = tgt_grid->num_cell_corners;
@@ -651,13 +604,13 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
   int max_num_cell_corners = src_num_cell_corners;
   if ( tgt_num_cell_corners > max_num_cell_corners ) max_num_cell_corners = tgt_num_cell_corners;
 
-  enum edge_type great_circle_type[32];
+  enum yac_edge_type great_circle_type[32];
   for ( int i = 0; i < max_num_cell_corners; ++i ) great_circle_type[i] = GREAT_CIRCLE;
 
-  enum edge_type lonlat_circle_type[] = {LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE};
+  enum yac_edge_type lonlat_circle_type[] = {LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE};
 
-  enum edge_type *src_edge_type = great_circle_type;
-  enum edge_type *tgt_edge_type = great_circle_type;
+  enum yac_edge_type *src_edge_type = great_circle_type;
+  enum yac_edge_type *tgt_edge_type = great_circle_type;
 
   enum cell_type target_cell_type = UNDEF_CELL;
 
@@ -745,23 +698,30 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       //printf("src_grid   lon: %g %g lat: %g %g\n", RAD2DEG*src_grid_bound_box[2],RAD2DEG*src_grid_bound_box[3],RAD2DEG*src_grid_bound_box[0],RAD2DEG*src_grid_bound_box[1] );
     }
 
-  findex = 0;
+  weightlinks_t *weightlinks = (weightlinks_t *) malloc(tgt_grid_size*sizeof(weightlinks_t));
+  
+  double findex = 0;
 
   int sum_srch_cells = 0;
   int sum_srch_cells2 = 0;
 
+  /* Loop over destination grid */
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared) \
-  shared(ompNumThreads, cdoTimer, lyac, nbins, num_wts, nx, src_remap_grid_type, tgt_remap_grid_type, src_grid_bound_box,	\
+  shared(ompNumThreads, lyac, nbins, num_wts, src_remap_grid_type, tgt_remap_grid_type, src_grid_bound_box,	\
 	 src_edge_type, tgt_edge_type, partial_areas2, partial_weights2,  \
          rv, cdoVerbose, max_srch_cells2, tgt_num_cell_corners, target_cell_type, \
-	 srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, \
+         weightlinks, \
+         srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size,	\
 	 overlap_buffer2, src_grid_cells2, srch_add2, tgt_grid_cell2, findex, sum_srch_cells, sum_srch_cells2) \
-  private(srch_add, tgt_grid_cell, tgt_area, n, k, num_weights, num_srch_cells, max_srch_cells,  \
-	  partial_areas, partial_weights, overlap_buffer, src_grid_cells, src_grid_add, tgt_grid_add, ioffset)
+  private(srch_add, tgt_grid_cell, tgt_area, k, num_srch_cells, max_srch_cells,  \
+	  partial_areas, partial_weights, overlap_buffer, src_grid_cells, src_cell_add, tgt_cell_add, ioffset)
 #endif
-  for ( tgt_grid_add = 0; tgt_grid_add < tgt_grid_size; ++tgt_grid_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
+      double partial_weight;
+      long n, num_weights, num_weights_old;
       int ompthID = cdo_omp_get_thread_num();
       int lprogress = 1;
       if ( ompthID != 0 ) lprogress = 0;
@@ -772,6 +732,8 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
+      weightlinks[tgt_cell_add].nlinks = 0;	
+
       srch_add = srch_add2[ompthID];
       tgt_grid_cell = tgt_grid_cell2[ompthID];
 
@@ -780,11 +742,11 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D && tgt_remap_grid_type == REMAP_GRID_TYPE_REG2D )
 	{
 	  double tgt_cell_bound_box[4];
-	  boundbox_from_corners_reg2d(tgt_grid_add, tgt_grid->dims, tgt_grid->reg2d_corner_lon, tgt_grid->reg2d_corner_lat, tgt_cell_bound_box);
+	  boundbox_from_corners_reg2d(tgt_cell_add, tgt_grid->dims, tgt_grid->reg2d_corner_lon, tgt_grid->reg2d_corner_lat, tgt_cell_bound_box);
 	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
 	  if ( 0 && cdoVerbose )
 	    printf("bound_box %ld  lon: %g %g lat: %g %g\n",
-		   tgt_grid_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
+		   tgt_cell_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
 	  num_srch_cells = get_srch_cells_reg2d(src_grid->dims, src_grid->reg2d_corner_lat, src_grid->reg2d_corner_lon,
 						tgt_cell_bound_box, srch_add);
 
@@ -795,11 +757,11 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       else if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
 	{
 	  double tgt_cell_bound_box[4];
-	  boundbox_from_corners1(tgt_grid_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box);
+	  boundbox_from_corners1(tgt_cell_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box);
 	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
 	  if ( 0 && cdoVerbose )
 	    printf("bound_box %ld  lon: %g %g lat: %g %g\n",
-		   tgt_grid_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
+		   tgt_cell_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
 	  num_srch_cells = get_srch_cells_reg2d(src_grid->dims, src_grid->reg2d_corner_lat, src_grid->reg2d_corner_lon,
 						tgt_cell_bound_box, srch_add);
 
@@ -810,16 +772,16 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       else
 	{
 	  restr_t tgt_cell_bound_box_r[4];
-	  boundbox_from_corners1r(tgt_grid_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box_r);
+	  boundbox_from_corners1r(tgt_cell_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box_r);
 
-	  num_srch_cells = get_srch_cells(tgt_grid_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
+	  num_srch_cells = get_srch_cells(tgt_cell_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
 					  tgt_cell_bound_box_r, src_grid->cell_bound_box, src_grid_size, srch_add);
 	}
 
       if ( 0 && cdoVerbose ) sum_srch_cells += num_srch_cells;
 
       if ( 0 && cdoVerbose )
-	printf("tgt_grid_add %ld  num_srch_cells %ld\n", tgt_grid_add, num_srch_cells);
+	printf("tgt_cell_add %ld  num_srch_cells %ld\n", tgt_cell_add, num_srch_cells);
 
       if ( num_srch_cells == 0 ) continue;
 
@@ -828,8 +790,8 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  long nx = tgt_grid->dims[0];
 	  long ix, iy;
 
-	  iy = tgt_grid_add/nx;
-	  ix = tgt_grid_add - iy*nx;
+	  iy = tgt_cell_add/nx;
+	  ix = tgt_cell_add - iy*nx;
 
 	  tgt_grid_cell->coordinates_x[0] = tgt_grid->reg2d_corner_lon[ix  ];
 	  tgt_grid_cell->coordinates_y[0] = tgt_grid->reg2d_corner_lat[iy  ];
@@ -844,17 +806,17 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	{
 	  for ( int ic = 0; ic < tgt_num_cell_corners; ++ic )
 	    {
-	      tgt_grid_cell->coordinates_x[ic] = tgt_grid->cell_corner_lon[tgt_grid_add*tgt_num_cell_corners+ic];
-	      tgt_grid_cell->coordinates_y[ic] = tgt_grid->cell_corner_lat[tgt_grid_add*tgt_num_cell_corners+ic];
+	      tgt_grid_cell->coordinates_x[ic] = tgt_grid->cell_corner_lon[tgt_cell_add*tgt_num_cell_corners+ic];
+	      tgt_grid_cell->coordinates_y[ic] = tgt_grid->cell_corner_lat[tgt_cell_add*tgt_num_cell_corners+ic];
 	    }
 	}
       
       for ( int ic = 0; ic < tgt_num_cell_corners; ++ic )
 	LLtoXYZ(tgt_grid_cell->coordinates_x[ic], tgt_grid_cell->coordinates_y[ic], tgt_grid_cell->coordinates_xyz+ic*3);
 
-      //printf("target: %ld\n", tgt_grid_add);
+      //printf("target: %ld\n", tgt_cell_add);
       if ( lyac )
-        if ( tgt_grid_add == 174752 )
+        if ( tgt_cell_add == 174752 )
 	  {
 	    for ( int n = 0; n < tgt_num_cell_corners; ++n )
 	      {
@@ -919,14 +881,14 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	{
 	  long srch_corners_new = srch_corners;
 
-	  src_grid_add = srch_add[n];
+	  src_cell_add = srch_add[n];
 
 	  if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
 	    {
 	      int ix, iy;
 
-	      iy = src_grid_add/nx;
-	      ix = src_grid_add - iy*nx;
+	      iy = src_cell_add/nx;
+	      ix = src_cell_add - iy*nx;
 
 	      src_grid_cells[n].coordinates_x[0] = src_grid->reg2d_corner_lon[ix  ];
 	      src_grid_cells[n].coordinates_y[0] = src_grid->reg2d_corner_lat[iy  ];
@@ -945,7 +907,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	    }
 	  else
 	    {
-	      ioffset = src_grid_add*srch_corners;
+	      ioffset = src_cell_add*srch_corners;
 	      /*
 	      for ( k = srch_corners-1; k > 0; --k )
 		{
@@ -953,7 +915,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 		       IS_NOT_EQUAL(src_grid->cell_corner_lat[ioffset+k], src_grid->cell_corner_lat[ioffset+k-1]) )
 		    break;
 		}
-	      if ( k != srch_corners-1 ) printf("%ld %ld %ld %ld\n", tgt_grid_add, n, srch_corners, k+1);
+	      if ( k != srch_corners-1 ) printf("%ld %ld %ld %ld\n", tgt_cell_add, n, srch_corners, k+1);
 
 	      if ( k != srch_corners-1 )
 		{
@@ -985,7 +947,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	    LLtoXYZ(src_grid_cells[n].coordinates_x[ic], src_grid_cells[n].coordinates_y[ic], src_grid_cells[n].coordinates_xyz+ic*3);
 
 	  if ( lyac )
-	    if ( tgt_grid_add == 174752 )
+	    if ( tgt_cell_add == 174752 )
 	    {
 	      // printf("n %d\n", (int)n);
 	      for ( k = 0; k < srch_corners_new; ++k )
@@ -1009,8 +971,8 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	}
       else
 	{
-	  double cell_center_lon = tgt_grid->cell_center_lon[tgt_grid_add];
-	  double cell_center_lat = tgt_grid->cell_center_lat[tgt_grid_add];
+	  double cell_center_lon = tgt_grid->cell_center_lon[tgt_cell_add];
+	  double cell_center_lat = tgt_grid->cell_center_lat[tgt_cell_add];
 	  cdo_compute_concave_overlap_areas(num_srch_cells, overlap_buffer, src_grid_cells, *tgt_grid_cell, cell_center_lon, cell_center_lat, partial_areas);
 	}
 
@@ -1021,7 +983,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	{
 	  if ( partial_areas[n] > 0 )
 	    {
-	      //printf(">>>>   %d %d %g %g\n", (int)tgt_grid_add, srch_add[n], tgt_area, partial_areas[n]);
+	      //printf(">>>>   %d %d %g %g\n", (int)tgt_cell_add, srch_add[n], tgt_area, partial_areas[n]);
 	      partial_areas[num_weights] = partial_areas[n];
 	      srch_add[num_weights] = srch_add[n];
 	      num_weights++;
@@ -1033,53 +995,78 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       for ( n = 0; n < num_weights; ++n )
 	partial_weights[n] = partial_areas[n] / tgt_area;
 
-      correct_weights(num_weights, partial_weights);
+      if ( rv->norm_opt == NORM_OPT_FRACAREA )
+	yac_correct_weights((unsigned)num_weights, partial_weights);
 
       for ( n = 0; n < num_weights; ++n )
 	partial_weights[n] *= tgt_area;
       //#endif
 
-      for ( n = 0; n < num_weights; ++n )
+      num_weights_old = num_weights;
+      for ( num_weights = 0, n = 0; n < num_weights_old; ++n )
 	{
-	  src_grid_add = srch_add[n];
+	  src_cell_add = srch_add[n];
 
 	  if ( 0 && cdoVerbose )
-	    printf("tgt_grid_add %ld, src_grid_add %ld,  partial_weights[n] %g, tgt_area  %g\n", tgt_grid_add, src_grid_add, partial_weights[n], tgt_area);
+	    printf("tgt_cell_add %ld, src_cell_add %ld,  partial_weights[n] %g, tgt_area  %g\n", tgt_cell_add, src_cell_add, partial_weights[n], tgt_area);
+
+	  if ( partial_weights[n] <= 0. ) src_cell_add = -1;
+	  if ( src_cell_add != -1 )
+	    {
+	      partial_weights[num_weights] = partial_weights[n];
+	      srch_add[num_weights] = src_cell_add;
+	      num_weights++;
+	    }
+	}
+
+      for ( n = 0; n < num_weights; ++n )
+	{
+	  partial_weight = partial_weights[n];
+
+	  src_cell_add = srch_add[n];
+
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+	  src_grid->cell_area[src_cell_add] += partial_weight;
+	}
 
-	  // src_grid_add = n;
-	  if ( partial_weights[n] <= 0. ) src_grid_add = -1;
+
+      num_weights_old = num_weights;
+      for ( num_weights = 0, n = 0; n < num_weights_old; ++n )
+	{
+	  src_cell_add = srch_add[n];
 
 	  /*
 	    Store the appropriate addresses and weights. 
 	    Also add contributions to cell areas.
 	    The source grid mask is the master mask
 	  */
-	  if ( src_grid_add != -1 )
+	  if ( src_grid->mask[src_cell_add] )
 	    {
-	      if ( src_grid->mask[src_grid_add] )
-		{
+	      partial_weights[num_weights] = partial_weights[n];
+	      srch_add[num_weights] = src_cell_add;
+	      num_weights++;
+	    }
+	}
 
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-		  {
-		    store_link_conserv(rv, src_grid_add, tgt_grid_add, num_wts, &partial_weights[n]);
+      for ( n = 0; n < num_weights; ++n )
+	{
+	  partial_weight = partial_weights[n];
+	  src_cell_add = srch_add[n];
 
-		    src_grid->cell_frac[src_grid_add] += partial_weights[n];
-		  }
-		  tgt_grid->cell_frac[tgt_grid_add] += partial_weights[n];
-		}
 #if defined(_OPENMP)
-#pragma omp critical
+#pragma omp atomic
 #endif
-	      {
-		src_grid->cell_area[src_grid_add] += partial_weights[n];
-	      }
-	    }
+	  src_grid->cell_frac[src_cell_add] += partial_weight;
+		  
+	  tgt_grid->cell_frac[tgt_cell_add] += partial_weight;
 	}
-      
-      tgt_grid->cell_area[tgt_grid_add] = tgt_area; 
-      // printf("area %d %g %g\n", tgt_grid_add, tgt_grid->cell_area[tgt_grid_add], tgt_area);
+
+      store_weightlinks(num_weights, srch_add, partial_weights, tgt_cell_add, weightlinks);
+
+      tgt_grid->cell_area[tgt_cell_add] = tgt_area; 
+      // printf("area %d %g %g\n", tgt_cell_add, tgt_grid->cell_area[tgt_cell_add], tgt_area);
     }
 
   if ( 0 && cdoVerbose )
@@ -1089,6 +1076,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
     }
 
   /* Finished with all cells: deallocate search arrays */
+  long n;
 
   for ( i = 0; i < ompNumThreads; ++i )
     {
@@ -1099,6 +1087,7 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	      free(overlap_buffer2[i][n].coordinates_x);
 	      free(overlap_buffer2[i][n].coordinates_y);
 	      if ( overlap_buffer2[i][n].coordinates_xyz ) free(overlap_buffer2[i][n].coordinates_xyz);
+	      if ( overlap_buffer2[i][n].edge_type ) free(overlap_buffer2[i][n].edge_type);
 	    }
 	}
       for ( n = 0; n < max_srch_cells2[i]; n++ )
@@ -1121,10 +1110,14 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       free(srch_add2[i]);
     }
 
+  weightlinks2remaplinks(tgt_grid_size, weightlinks, rv);
+
+  if ( weightlinks ) free(weightlinks);
+
   /* Normalize using destination area if requested */
   normalize_weights(tgt_grid, rv);
 
-  num_links = rv->num_links;
+  long num_links = rv->num_links;
 
   if ( cdoVerbose )
     cdoPrint("Total number of links = %ld", rv->num_links);
@@ -1153,16 +1146,16 @@ void remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 
       for ( n = 0; n < num_links; ++n )
 	{
-	  src_grid_add = rv->src_grid_add[n];
-	  tgt_grid_add = rv->tgt_grid_add[n];
+	  src_cell_add = rv->src_cell_add[n];
+	  tgt_cell_add = rv->tgt_cell_add[n];
 
 	  if ( rv->wts[n*num_wts] < -0.01 )
 	    cdoPrint("Map weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     src_grid_add, tgt_grid_add, n, rv->wts[n*num_wts]);
+		     src_cell_add, tgt_cell_add, n, rv->wts[n*num_wts]);
 
 	  if ( rv->norm_opt != NORM_OPT_NONE && rv->wts[n*num_wts] > 1.01 )
 	    cdoPrint("Map weight > 1! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     src_grid_add, tgt_grid_add, n, rv->wts[n*num_wts]);
+		     src_cell_add, tgt_cell_add, n, rv->wts[n*num_wts]);
 	}
     } // lcheck
 
diff --git a/src/remap_conserv_scrip.c b/src/remap_conserv_scrip.c
index 8a6bd7a..5813b19 100644
--- a/src/remap_conserv_scrip.c
+++ b/src/remap_conserv_scrip.c
@@ -10,7 +10,7 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "remap.h"
-#include "remap_store_link.h"
+#include "remap_store_link_cnsrv.h"
 #include "util.h"  /* progressStatus */
 
 /* #define  BABY_STEP  0.001 */ /* original value */
@@ -1004,8 +1004,8 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
   long num_wts;
   long src_grid_size;
   long tgt_grid_size;
-  long src_grid_add;       /* current linear address for source grid cell   */
-  long tgt_grid_add;       /* current linear address for target grid cell   */
+  long src_cell_add;       /* current linear address for source grid cell   */
+  long tgt_cell_add;       /* current linear address for target grid cell   */
   double weights[6];       /* local wgt array */
 
   num_wts = rv->num_wts;
@@ -1021,51 +1021,51 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
   weights[4] =  PI*PI;
   weights[5] =  ZERO;
 
-  src_grid_add = -1;
+  src_cell_add = -1;
   /* pole_loop1 */
   for ( n = 0; n < src_grid_size; ++n )
     if ( src_grid->cell_area[n] < -THREE*PIH && src_grid->cell_center_lat[n] > ZERO )
       {
-	src_grid_add = n;
+	src_cell_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  tgt_grid_add = -1;
+  tgt_cell_add = -1;
   /* pole_loop2 */
   for ( n = 0; n < tgt_grid_size; ++n )
     if ( tgt_grid->cell_area[n] < -THREE*PIH && tgt_grid->cell_center_lat[n] > ZERO )
       {
-	tgt_grid_add = n;
+	tgt_cell_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  if ( src_grid_add != -1 )
+  if ( src_cell_add != -1 )
     {
-      src_grid->cell_area[src_grid_add] += weights[0];
-      src_centroid_lat[src_grid_add]    += weights[1];
-      src_centroid_lon[src_grid_add]    += weights[2];
+      src_grid->cell_area[src_cell_add] += weights[0];
+      src_centroid_lat[src_cell_add]    += weights[1];
+      src_centroid_lon[src_cell_add]    += weights[2];
     }
 
-  if ( tgt_grid_add != -1 )
+  if ( tgt_cell_add != -1 )
     {
-      tgt_grid->cell_area[tgt_grid_add] += weights[3];
-      tgt_centroid_lat[tgt_grid_add]    += weights[4];
-      tgt_centroid_lon[tgt_grid_add]    += weights[5];
+      tgt_grid->cell_area[tgt_cell_add] += weights[3];
+      tgt_centroid_lat[tgt_cell_add]    += weights[4];
+      tgt_centroid_lon[tgt_cell_add]    += weights[5];
     }
 
-  if ( src_grid_add != -1 && tgt_grid_add != -1 )
+  if ( src_cell_add != -1 && tgt_cell_add != -1 )
     {
       if ( remap_store_link_fast )
-	store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
+	store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
       else
-	store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
+	store_link_cnsrv(rv, src_cell_add, tgt_cell_add, weights, link_add1, link_add2);
 
-      src_grid->cell_frac[src_grid_add] += weights[0];
-      tgt_grid->cell_frac[tgt_grid_add] += weights[3];
+      src_grid->cell_frac[src_cell_add] += weights[0];
+      tgt_grid->cell_frac[tgt_cell_add] += weights[3];
     }
 
   /* South Pole */
@@ -1076,51 +1076,51 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
   weights[4] = -PI*PI;
   weights[5] =  ZERO;
 
-  src_grid_add = -1;
+  src_cell_add = -1;
   /* pole_loop3 */
   for ( n = 0; n < src_grid_size; ++n )
     if ( src_grid->cell_area[n] < -THREE*PIH && src_grid->cell_center_lat[n] < ZERO )
       {
-	src_grid_add = n;
+	src_cell_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  tgt_grid_add = -1;
+  tgt_cell_add = -1;
   /* pole_loop4 */
   for ( n = 0; n < tgt_grid_size; ++n )
     if ( tgt_grid->cell_area[n] < -THREE*PIH && tgt_grid->cell_center_lat[n] < ZERO )
       {
-	tgt_grid_add = n;
+	tgt_cell_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  if ( src_grid_add != -1 )
+  if ( src_cell_add != -1 )
     {
-      src_grid->cell_area[src_grid_add] += weights[0];
-      src_centroid_lat[src_grid_add]    += weights[1];
-      src_centroid_lon[src_grid_add]    += weights[2];
+      src_grid->cell_area[src_cell_add] += weights[0];
+      src_centroid_lat[src_cell_add]    += weights[1];
+      src_centroid_lon[src_cell_add]    += weights[2];
     }
 
-  if ( tgt_grid_add != -1 )
+  if ( tgt_cell_add != -1 )
     {
-      tgt_grid->cell_area[tgt_grid_add] += weights[3];
-      tgt_centroid_lat[tgt_grid_add]    += weights[4];
-      tgt_centroid_lon[tgt_grid_add]    += weights[5];
+      tgt_grid->cell_area[tgt_cell_add] += weights[3];
+      tgt_centroid_lat[tgt_cell_add]    += weights[4];
+      tgt_centroid_lon[tgt_cell_add]    += weights[5];
     }
 
-  if ( src_grid_add != -1 && tgt_grid_add != -1 )
+  if ( src_cell_add != -1 && tgt_cell_add != -1 )
     {
       if ( remap_store_link_fast )
-	store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
+	store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
       else
-	store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
+	store_link_cnsrv(rv, src_cell_add, tgt_cell_add, weights, link_add1, link_add2);
 
-      src_grid->cell_frac[src_grid_add] += weights[0];
-      tgt_grid->cell_frac[tgt_grid_add] += weights[3];
+      src_grid->cell_frac[src_cell_add] += weights[0];
+      tgt_grid->cell_frac[tgt_cell_add] += weights[3];
     }
 }
 
@@ -1140,8 +1140,8 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv, double *src_centr
   /* Include centroids in weights and normalize using destination area if requested */
   long n;
   long num_links = rv->num_links;
-  long src_grid_add;       /* current linear address for source grid cell   */
-  long tgt_grid_add;       /* current linear address for target grid cell   */
+  long src_cell_add;       /* current linear address for source grid cell   */
+  long tgt_cell_add;       /* current linear address for target grid cell   */
   double *weights = rv->wts;
   double norm_factor = 0;  /* factor for normalizing wts */
 
@@ -1153,18 +1153,18 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv, double *src_centr
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(num_links, rv, weights, tgt_grid, src_centroid_lat, src_centroid_lon)		\
-  private(n, src_grid_add, tgt_grid_add, norm_factor)
+  private(n, src_cell_add, tgt_cell_add, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
-	  src_grid_add = rv->src_grid_add[n]; tgt_grid_add = rv->tgt_grid_add[n];
+	  src_cell_add = rv->src_cell_add[n]; tgt_cell_add = rv->tgt_cell_add[n];
 
-          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_grid_add], 0) )
-	    norm_factor = ONE/tgt_grid->cell_area[tgt_grid_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_cell_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_area[tgt_cell_add];
           else
             norm_factor = ZERO;
 
-	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_grid_add], src_centroid_lon[src_grid_add]);
+	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_cell_add], src_centroid_lon[src_cell_add]);
 	}
     }
   else if ( rv->norm_opt == NORM_OPT_FRACAREA )
@@ -1175,18 +1175,18 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv, double *src_centr
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(num_links, rv, weights, tgt_grid, src_centroid_lat, src_centroid_lon)		\
-  private(n, src_grid_add, tgt_grid_add, norm_factor)
+  private(n, src_cell_add, tgt_cell_add, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
-	  src_grid_add = rv->src_grid_add[n]; tgt_grid_add = rv->tgt_grid_add[n];
+	  src_cell_add = rv->src_cell_add[n]; tgt_cell_add = rv->tgt_cell_add[n];
 
-          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_grid_add], 0) )
-	    norm_factor = ONE/tgt_grid->cell_frac[tgt_grid_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_cell_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_frac[tgt_cell_add];
           else
             norm_factor = ZERO;
 
-	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_grid_add], src_centroid_lon[src_grid_add]);
+	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_cell_add], src_centroid_lon[src_cell_add]);
 	}
     }
   else if ( rv->norm_opt == NORM_OPT_NONE )
@@ -1197,15 +1197,15 @@ void normalize_weights(remapgrid_t *tgt_grid, remapvars_t *rv, double *src_centr
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(num_links, rv, weights, tgt_grid, src_centroid_lat, src_centroid_lon)	\
-  private(n, src_grid_add, norm_factor)
+  private(n, src_cell_add, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
-	  src_grid_add = rv->src_grid_add[n];;
+	  src_cell_add = rv->src_cell_add[n];;
 
           norm_factor = ONE;
 
-	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_grid_add], src_centroid_lon[src_grid_add]);
+	  norm_weight(norm_factor, &weights[n*3], src_centroid_lat[src_cell_add], src_centroid_lon[src_cell_add]);
 	}
     }
 }
@@ -1232,8 +1232,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
   long tgt_grid_size;
   long src_num_cell_corners;
   long tgt_num_cell_corners;
-  long src_grid_add;       /* current linear address for source grid cell   */
-  long tgt_grid_add;       /* current linear address for target grid cell   */
+  long src_cell_add;       /* current linear address for source grid cell   */
+  long tgt_cell_add;       /* current linear address for target grid cell   */
   long n, k;            /* generic counters                        */
   long corner;          /* corner of cell that segment starts from */
   long next_corn;       /* corner of cell that segment ends on     */
@@ -1380,17 +1380,17 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared) \
-  shared(ompNumThreads, cdoTimer, nbins, num_wts, src_centroid_lon, src_centroid_lat, \
+  shared(ompNumThreads, nbins, num_wts, src_centroid_lon, src_centroid_lat, \
          remap_store_link_fast, grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
 	 srch_corner_lat2, srch_corner_lon2, max_srch_cells2, 		\
 	 src_num_cell_corners,	srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add2, findex) \
   private(srch_add, n, k, num_srch_cells, max_srch_cells, 	\
-	  src_grid_add, tgt_grid_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
+	  src_cell_add, tgt_cell_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
 	  weights, intrsct_lat, intrsct_lon, intrsct_lat_off, intrsct_lon_off, intrsct_x, intrsct_y, \
 	  last_loc, lcoinc, lthresh, luse_last, avoid_pole_count, avoid_pole_offset)
 #endif
-  for ( src_grid_add = 0; src_grid_add < src_grid_size; ++src_grid_add )
+  for ( src_cell_add = 0; src_cell_add < src_grid_size; ++src_cell_add )
     {
       int ompthID = cdo_omp_get_thread_num();
       int lprogress = 1;
@@ -1410,8 +1410,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       avoid_pole_offset = TINY;
 
       /* Get search cells */
-      num_srch_cells = get_srch_cells(src_grid_add, nbins, src_grid->bin_addr, tgt_grid->bin_addr,
-				      src_grid->cell_bound_box+src_grid_add*4, tgt_grid->cell_bound_box, tgt_grid_size, srch_add);
+      num_srch_cells = get_srch_cells(src_cell_add, nbins, src_grid->bin_addr, tgt_grid->bin_addr,
+				      src_grid->cell_bound_box+src_cell_add*4, tgt_grid->cell_bound_box, tgt_grid_size, srch_add);
 
       if ( num_srch_cells == 0 ) continue;
 
@@ -1436,8 +1436,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       /* gather1 */
       for ( n = 0; n < num_srch_cells; ++n )
 	{
-	  tgt_grid_add = srch_add[n];
-	  ioffset = tgt_grid_add*srch_corners;
+	  tgt_cell_add = srch_add[n];
+	  ioffset = tgt_cell_add*srch_corners;
 
 	  nsrch_corners = n*srch_corners;
 	  for ( k = 0; k < srch_corners; k++ )
@@ -1449,7 +1449,7 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
       /* Integrate around this cell */
 
-      ioffset = src_grid_add*src_num_cell_corners;
+      ioffset = src_cell_add*src_num_cell_corners;
 
       for ( corner = 0; corner < src_num_cell_corners; ++corner )
 	{
@@ -1494,7 +1494,7 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      num_subseg++;
 	      if ( num_subseg >= max_subseg )
 		cdoAbort("Integration stalled: num_subseg exceeded limit (grid1[%d]: lon1=%g lon2=%g lat1=%g lat2=%g)!",
-			 src_grid_add, beglon, endlon, beglat, endlat);
+			 src_cell_add, beglon, endlon, beglat, endlat);
 
 	      /* Uwe Schulzweida: skip very small regions */
 	      if ( num_subseg%1000 == 0 )
@@ -1503,14 +1503,14 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 		    {
 		      if ( cdoVerbose )
 			cdoPrint("Skip very small region (grid1[%d]): lon=%g dlon=%g lat=%g dlat=%g",
-				 src_grid_add, beglon, endlon-beglon, beglat, endlat-beglat);
+				 src_cell_add, beglon, endlon-beglon, beglat, endlat-beglat);
 		      break;
 		    }
 		}
 
 	      /* Find next intersection of this segment with a gridline on grid 2. */
 
-	      intersection(&tgt_grid_add, &intrsct_lat, &intrsct_lon, &lcoinc,
+	      intersection(&tgt_cell_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			   beglat, beglon, endlat, endlon, begseg, 
 			   lbegin, lrevers,
 			   num_srch_cells, srch_corners, srch_add,
@@ -1523,12 +1523,12 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 	      /* Compute line integral for this subsegment. */
 
-	      if ( tgt_grid_add != -1 )
+	      if ( tgt_cell_add != -1 )
 		line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-			      src_grid->cell_center_lon[src_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
+			      src_grid->cell_center_lon[src_cell_add], tgt_grid->cell_center_lon[tgt_cell_add]);
 	      else
 		line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-			      src_grid->cell_center_lon[src_grid_add], src_grid->cell_center_lon[src_grid_add]);
+			      src_grid->cell_center_lon[src_cell_add], src_grid->cell_center_lon[src_cell_add]);
 
 	      /* If integrating in reverse order, change sign of weights */
 
@@ -1538,26 +1538,26 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 		Store the appropriate addresses and weights. 
 		Also add contributions to cell areas and centroids.
 	      */
-	      if ( tgt_grid_add != -1 )
-		if ( src_grid->mask[src_grid_add] )
+	      if ( tgt_cell_add != -1 )
+		if ( src_grid->mask[src_cell_add] )
 		  {
 #if defined(_OPENMP)
 #pragma omp critical
 #endif
 		    {
 		      if ( remap_store_link_fast )
-			store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
+			store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
 		      else
-			store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
+			store_link_cnsrv(rv, src_cell_add, tgt_cell_add, weights, link_add1, link_add2);
 
-		      tgt_grid->cell_frac[tgt_grid_add] += weights[3];
+		      tgt_grid->cell_frac[tgt_cell_add] += weights[3];
 		    }
-		    src_grid->cell_frac[src_grid_add] += weights[0];
+		    src_grid->cell_frac[src_cell_add] += weights[0];
 		  }
 
-	      src_grid->cell_area[src_grid_add] += weights[0];
-	      src_centroid_lat[src_grid_add] += weights[1];
-	      src_centroid_lon[src_grid_add] += weights[2];
+	      src_grid->cell_area[src_cell_add] += weights[0];
+	      src_centroid_lat[src_cell_add] += weights[1];
+	      src_centroid_lon[src_cell_add] += weights[2];
 
 	      /* Reset beglat and beglon for next subsegment. */
 	      beglat = intrsct_lat;
@@ -1605,17 +1605,17 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared) \
-  shared(ompNumThreads, cdoTimer, nbins, num_wts, tgt_centroid_lon, tgt_centroid_lat, \
+  shared(ompNumThreads, nbins, num_wts, tgt_centroid_lon, tgt_centroid_lat, \
          remap_store_link_fast, grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
 	 srch_corner_lat2, srch_corner_lon2, max_srch_cells2, 		\
 	 tgt_num_cell_corners, srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add2, findex) \
   private(srch_add, n, k, num_srch_cells, max_srch_cells,	\
-	  src_grid_add, tgt_grid_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
+	  src_cell_add, tgt_cell_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
 	  weights, intrsct_lat, intrsct_lon, intrsct_lat_off, intrsct_lon_off, intrsct_x, intrsct_y, \
 	  last_loc, lcoinc, lthresh, luse_last, avoid_pole_count, avoid_pole_offset)
 #endif
-  for ( tgt_grid_add = 0; tgt_grid_add < tgt_grid_size; ++tgt_grid_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int ompthID = cdo_omp_get_thread_num();
       int lprogress = 1;
@@ -1635,8 +1635,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       avoid_pole_offset = TINY;
 
       /* Get search cells */
-      num_srch_cells = get_srch_cells(tgt_grid_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
-				      tgt_grid->cell_bound_box+tgt_grid_add*4, src_grid->cell_bound_box, src_grid_size, srch_add);
+      num_srch_cells = get_srch_cells(tgt_cell_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
+				      tgt_grid->cell_bound_box+tgt_cell_add*4, src_grid->cell_bound_box, src_grid_size, srch_add);
 
       if ( num_srch_cells == 0 ) continue;
 
@@ -1661,8 +1661,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       /* gather2 */
       for ( n = 0; n < num_srch_cells; ++n )
 	{
-	  src_grid_add = srch_add[n];
-	  ioffset = src_grid_add*srch_corners;
+	  src_cell_add = srch_add[n];
+	  ioffset = src_cell_add*srch_corners;
 
 	  nsrch_corners = n*srch_corners;
 	  for ( k = 0; k < srch_corners; ++k )
@@ -1674,7 +1674,7 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
       /* Integrate around this cell */
 
-      ioffset = tgt_grid_add*tgt_num_cell_corners;
+      ioffset = tgt_cell_add*tgt_num_cell_corners;
 
       for ( corner = 0; corner < tgt_num_cell_corners; ++corner )
 	{
@@ -1719,7 +1719,7 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      num_subseg++;
 	      if ( num_subseg >= max_subseg )
 		cdoAbort("Integration stalled: num_subseg exceeded limit (grid2[%d]: lon1=%g lon2=%g lat1=%g lat2=%g)!",
-			 tgt_grid_add, beglon, endlon, beglat, endlat);
+			 tgt_cell_add, beglon, endlon, beglat, endlat);
 
 	      /* Uwe Schulzweida: skip very small regions */
 	      if ( num_subseg%1000 == 0 )
@@ -1728,14 +1728,14 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 		    {
 		      if ( cdoVerbose )
 			cdoPrint("Skip very small region (grid2[%d]): lon=%g dlon=%g lat=%g dlat=%g",
-				 tgt_grid_add, beglon, endlon-beglon, beglat, endlat-beglat);
+				 tgt_cell_add, beglon, endlon-beglon, beglat, endlat-beglat);
 		      break;
 		    }
 		}
 
 	      /* Find next intersection of this segment with a gridline on grid 2. */
 
-	      intersection(&src_grid_add, &intrsct_lat, &intrsct_lon, &lcoinc,
+	      intersection(&src_cell_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			   beglat, beglon, endlat, endlon, begseg,
 			   lbegin, lrevers,
 			   num_srch_cells, srch_corners, srch_add,
@@ -1748,12 +1748,12 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 	      /* Compute line integral for this subsegment. */
 
-	      if ( src_grid_add != -1 )
+	      if ( src_cell_add != -1 )
 		line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-			      src_grid->cell_center_lon[src_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
+			      src_grid->cell_center_lon[src_cell_add], tgt_grid->cell_center_lon[tgt_cell_add]);
 	      else
 		line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-			      tgt_grid->cell_center_lon[tgt_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
+			      tgt_grid->cell_center_lon[tgt_cell_add], tgt_grid->cell_center_lon[tgt_cell_add]);
 
 	      /* If integrating in reverse order, change sign of weights */
 
@@ -1766,26 +1766,26 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 		because they have been captured in the previous loop.
 		The source grid mask is the master mask
 	      */
-	      if ( ! lcoinc && src_grid_add != -1 )
-		if ( src_grid->mask[src_grid_add] )
+	      if ( ! lcoinc && src_cell_add != -1 )
+		if ( src_grid->mask[src_cell_add] )
 		  {
 #if defined(_OPENMP)
 #pragma omp critical
 #endif
 		    {
 		      if ( remap_store_link_fast )
-			store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
+			store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
 		      else
-			store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
+			store_link_cnsrv(rv, src_cell_add, tgt_cell_add, weights, link_add1, link_add2);
 
-		      src_grid->cell_frac[src_grid_add] += weights[0];
+		      src_grid->cell_frac[src_cell_add] += weights[0];
 		    }
-		    tgt_grid->cell_frac[tgt_grid_add] += weights[3];
+		    tgt_grid->cell_frac[tgt_cell_add] += weights[3];
 		  }
 
-	      tgt_grid->cell_area[tgt_grid_add] += weights[3];
-	      tgt_centroid_lat[tgt_grid_add] += weights[4];
-	      tgt_centroid_lon[tgt_grid_add] += weights[5];
+	      tgt_grid->cell_area[tgt_cell_add] += weights[3];
+	      tgt_centroid_lat[tgt_cell_add] += weights[4];
+	      tgt_centroid_lon[tgt_cell_add] += weights[5];
 
 	      /* Reset beglat and beglon for next subsegment. */
 	      beglat = intrsct_lat;
@@ -1871,8 +1871,8 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 		  rv->wts[3*i+1] = rv->wts[3*(i+nd)+1];
 		  rv->wts[3*i+2] = rv->wts[3*(i+nd)+2];
 		  
-		  rv->src_grid_add[i] = rv->src_grid_add[i+nd];
-		  rv->tgt_grid_add[i] = rv->tgt_grid_add[i+nd];
+		  rv->src_cell_add[i] = rv->src_cell_add[i+nd];
+		  rv->tgt_cell_add[i] = rv->tgt_cell_add[i+nd];
 		}
 	    }
 	}
@@ -1926,25 +1926,25 @@ void scrip_remap_weights_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
       for ( n = 0; n < num_links; ++n )
 	{
-	  src_grid_add = rv->src_grid_add[n];
-	  tgt_grid_add = rv->tgt_grid_add[n];
+	  src_cell_add = rv->src_cell_add[n];
+	  tgt_cell_add = rv->tgt_cell_add[n];
 
 	  if ( rv->wts[3*n] < -0.01 )
 	    cdoPrint("Map weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     src_grid_add, tgt_grid_add, n, rv->wts[3*n]);
+		     src_cell_add, tgt_cell_add, n, rv->wts[3*n]);
 
 	  if ( rv->norm_opt != NORM_OPT_NONE && rv->wts[3*n] > 1.01 )
 	    cdoPrint("Map weight > 1! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     src_grid_add, tgt_grid_add, n, rv->wts[3*n]);
+		     src_cell_add, tgt_cell_add, n, rv->wts[3*n]);
 	}
 
       for ( n = 0; n < num_links; ++n )
 	{
-	  tgt_grid_add = rv->tgt_grid_add[n];
-	  tgt_centroid_lat[tgt_grid_add] += rv->wts[3*n];
+	  tgt_cell_add = rv->tgt_cell_add[n];
+	  tgt_centroid_lat[tgt_cell_add] += rv->wts[3*n];
 	}
 
-      /* 2012-01-24 Uwe Schulzweida: changed [tgt_grid_add] to [n] (bug fix) */
+      /* 2012-01-24 Uwe Schulzweida: changed [tgt_cell_add] to [n] (bug fix) */
       for ( n = 0; n < tgt_grid_size; ++n )
 	{
 	  if ( rv->norm_opt == NORM_OPT_DESTAREA )
diff --git a/src/remap_distwgt_scrip.c b/src/remap_distwgt_scrip.c
index ade6039..552c959 100644
--- a/src/remap_distwgt_scrip.c
+++ b/src/remap_distwgt_scrip.c
@@ -2,6 +2,8 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "remap.h"
+#include "remap_store_link.h"
+
 
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 /*                                                                         */
@@ -238,10 +240,26 @@ void grid_search_nbr_reg2d(int num_neighbors, remapgrid_t *src_grid, int *restri
   else if ( src_grid->lextrapolate )
     {
       int search_result;
-      search_result = grid_search_reg2d_nn(nx, ny, nbr_add, nbr_dist, plat, plon, src_center_lat, src_center_lon);
-      
+
+      if ( num_neighbors < 4 )
+	{
+	  int nbr4_add[4];
+	  double nbr4_dist[4];
+	  for ( n = 0; n < num_neighbors; ++n ) nbr4_add[n] = -1;
+	  search_result = grid_search_reg2d_nn(nx, ny, nbr4_add, nbr4_dist, plat, plon, src_center_lat, src_center_lon);
+	  if ( search_result < 0 )
+	    {
+	      for ( n = 0; n < num_neighbors; ++n ) nbr_add[n]  = nbr4_add[n];
+	      for ( n = 0; n < num_neighbors; ++n ) nbr_dist[n] = nbr4_dist[n];
+	    }
+	}
+      else
+	{
+	  search_result = grid_search_reg2d_nn(nx, ny, nbr_add, nbr_dist, plat, plon, src_center_lat, src_center_lon);
+	}
+
       if ( search_result >= 0 )
-	for ( n = 0; n < 4; ++n ) nbr_add[n] = -1;
+	for ( n = 0; n < num_neighbors; ++n ) nbr_add[n] = -1;
     }
 }  /*  grid_search_nbr_reg2d  */
 
@@ -278,11 +296,8 @@ void grid_search_nbr(int num_neighbors, remapgrid_t *src_grid, int *restrict nbr
   get_restrict_add(src_grid, plat, src_bin_add, &min_add, &max_add);
 
   /* Initialize distance and address arrays */
-  for ( n = 0; n < num_neighbors; ++n )
-    {
-      nbr_add[n]  = -1;
-      nbr_dist[n] = BIGNUM;
-    }
+  for ( n = 0; n < num_neighbors; ++n ) nbr_add[n]  = -1;
+  for ( n = 0; n < num_neighbors; ++n ) nbr_dist[n] = BIGNUM;
 
   int i, ndist = max_add - min_add + 1;
 
@@ -312,7 +327,8 @@ void grid_search_nbr(int num_neighbors, remapgrid_t *src_grid, int *restrict nbr
     }
   ndist = j;
 
-#if defined(_OPENMP) && _OPENMP >= OPENMP4
+#if defined(HAVE_OPENMP4)
+  //#pragma omp simd aligned(dist:16)
 #pragma omp simd
 #endif
   for ( j = 0; j < ndist; ++j )
@@ -329,84 +345,6 @@ void grid_search_nbr(int num_neighbors, remapgrid_t *src_grid, int *restrict nbr
 }  /*  grid_search_nbr  */
 
 /*
-  This routine stores the address and weight for this link in the appropriate 
-  address and weight arrays and resizes those arrays if necessary.
-*/
-static
-void store_link_nbr(remapvars_t *rv, int add1, int add2, double weights)
-{
-  /*
-    Input variables:
-    int  add1         ! address on source grid
-    int  add2         ! address on target grid
-    double weights    ! remapping weight for this link
-  */
-  long nlink;
-
-  /*
-     Increment number of links and check to see if remap arrays need
-     to be increased to accomodate the new link. Then store the link.
-  */
-  nlink = rv->num_links;
-  rv->num_links++;
-
-  if ( rv->num_links >= rv->max_links ) 
-    resize_remap_vars(rv, rv->resize_increment);
-
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
-  rv->wts[nlink]          = weights;
-
-} /* store_link_nbr */
-
-typedef struct
-{
-  int add;
-  double wgts;
-}
-addwgts_t;
-
-static
-int cmpwgts(const void *s1, const void *s2)
-{
-  int cmp = 0;
-  const addwgts_t *c1 = s1;
-  const addwgts_t *c2 = s2;
-
-  if      ( c1->add < c2->add ) cmp = -1;
-  else if ( c1->add > c2->add ) cmp =  1;
-
-  return (cmp);
-}
-
-static
-void sort_dist_adds(int nadds, int src_add[], double wgts[])
-{
-  int n;
-  addwgts_t addwgts[nadds];
-
-  if ( nadds <= 1 ) return;
-
-  for ( n = 1; n < nadds; ++n )
-    if ( src_add[n] < src_add[n-1] ) break;
-  if ( n == nadds ) return;
-
-  for ( n = 0; n < nadds; ++n )
-    {
-      addwgts[n].add  = src_add[n];
-      addwgts[n].wgts = wgts[n];
-    }
-
-  qsort(addwgts, nadds, sizeof(addwgts_t), cmpwgts);
-
-  for ( n = 0; n < nadds; ++n )
-    {
-      src_add[n] = addwgts[n].add;
-      wgts[n]    = addwgts[n].wgts;
-    }  
-}
-
-/*
   -----------------------------------------------------------------------------------------
 
    This routine computes the inverse-distance weights for a nearest-neighbor interpolation.
@@ -416,16 +354,12 @@ void sort_dist_adds(int nadds, int src_add[], double wgts[])
 void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /*  Local variables */
-
-  long src_grid_size;
-  long tgt_grid_size;
   long n, nadds;
-  long dst_add;                   /* destination address                         */
+  long tgt_cell_add;              /* destination address                         */
   double dist_tot;                /* sum of neighbor distances (for normalizing) */
   double *coslat, *sinlat;        /* cosine, sine of grid lats (for distance)    */
   double *coslon, *sinlon;        /* cosine, sine of grid lons (for distance)    */
   double plat, plon;              /* lat/lon coords of destination point         */
-  double findex = 0;
   int remap_grid_type = src_grid->remap_grid_type;
 
   if ( cdoVerbose ) cdoPrint("Called %s()", __func__);
@@ -434,8 +368,10 @@ void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remap
 
   /* Compute mappings from source to target grid */
 
-  src_grid_size = src_grid->size;
-  tgt_grid_size = tgt_grid->size;
+  long src_grid_size = src_grid->size;
+  long tgt_grid_size = tgt_grid->size;
+
+  weightlinks_t *weightlinks = (weightlinks_t *) malloc(tgt_grid_size*sizeof(weightlinks_t));
 
   /* Compute cos, sin of lat/lon on source grid for distance calculations */
 
@@ -489,13 +425,15 @@ void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remap
     }
 
   /* Loop over destination grid  */
+
+  double findex = 0;
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, num_neighbors, remap_grid_type, src_grid, tgt_grid, rv, tgt_grid_size, coslat, coslon, sinlat, sinlon, findex) \
-  private(dst_add, n, nadds, dist_tot, plat, plon) \
-  schedule(dynamic,1)
+  shared(ompNumThreads, weightlinks, num_neighbors, remap_grid_type, src_grid, tgt_grid, rv, tgt_grid_size, coslat, coslon, sinlat, sinlon, findex) \
+  private(tgt_cell_add, n, nadds, dist_tot, plat, plon)
 #endif
-  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int nbr_mask[num_neighbors];    /* mask at nearest neighbors                   */
       int nbr_add[num_neighbors];     /* source address at nearest neighbors         */
@@ -509,10 +447,12 @@ void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remap
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      if ( ! tgt_grid->mask[dst_add] ) continue;
+      weightlinks[tgt_cell_add].nlinks = 0;	
+
+      if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
 	
-      plat = tgt_grid->cell_center_lat[dst_add];
-      plon = tgt_grid->cell_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[tgt_cell_add];
+      plon = tgt_grid->cell_center_lon[tgt_cell_add];
 
       /* Find nearest grid points on source grid and distances to each point */
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
@@ -530,7 +470,7 @@ void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remap
       dist_tot = 0.;
       for ( n = 0; n < num_neighbors; ++n )
 	{
-	  // printf("dst_add %ld %ld %d %g\n", dst_add, n, nbr_add[n], nbr_dist[n]);
+	  // printf("tgt_cell_add %ld %ld %d %g\n", tgt_cell_add, n, nbr_add[n], nbr_dist[n]);
 	  nbr_mask[n] = FALSE;
 
 	  /* Uwe Schulzweida: check if nbr_add is valid */
@@ -554,25 +494,20 @@ void scrip_remap_weights_distwgt(int num_neighbors, remapgrid_t *src_grid, remap
 	      nbr_add[nadds]  = nbr_add[n];
 	      nadds++;
 
-	      tgt_grid->cell_frac[dst_add] = ONE;
+	      tgt_grid->cell_frac[tgt_cell_add] = ONE;
 	    }
 	}
 
-      sort_dist_adds(nadds, nbr_add, nbr_dist);
-
-      for ( n = 0; n < nadds; ++n )
-	{
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      store_link_nbr(rv, nbr_add[n], dst_add, nbr_dist[n]);
-	}
-
-    } /* for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add ) */
+      store_weightlinks(nadds, nbr_add, nbr_dist, tgt_cell_add, weightlinks);
+    }
 
   free(coslat);
   free(coslon);
   free(sinlat);
   free(sinlon);
 
+  weightlinks2remaplinks(tgt_grid_size, weightlinks, rv);
+
+  if ( weightlinks ) free(weightlinks);
+
 }  /* scrip_remap_weights_distwgt */
diff --git a/src/remap_scrip_io.c b/src/remap_scrip_io.c
index 30ba236..dbadc58 100644
--- a/src/remap_scrip_io.c
+++ b/src/remap_scrip_io.c
@@ -371,12 +371,12 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
 
   for ( i = 0; i < rv.num_links; i++ )
     {
-      rv.src_grid_add[i]++;
-      rv.tgt_grid_add[i]++;
+      rv.src_cell_add[i]++;
+      rv.tgt_cell_add[i]++;
     }
 
-  nce(nc_put_var_int(nc_file_id, nc_srcadd_id, rv.src_grid_add));
-  nce(nc_put_var_int(nc_file_id, nc_dstadd_id, rv.tgt_grid_add));
+  nce(nc_put_var_int(nc_file_id, nc_srcadd_id, rv.src_cell_add));
+  nce(nc_put_var_int(nc_file_id, nc_dstadd_id, rv.tgt_cell_add));
 
   nce(nc_put_var_double(nc_file_id, nc_rmpmatrix_id, rv.wts));
 
@@ -500,10 +500,10 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   *submap_type = SUBMAP_TYPE_NONE;
   *remap_order = 1;
 
-  if ( strcompare(map_method, "Conservative") == 0 )
+  if ( cmpstr(map_method, "Conservative") == 0 )
     {
       int iatt;
-      if ( strcompare(map_method, "Conservative remapping using clipping on sphere") == 0 )
+      if ( cmpstr(map_method, "Conservative remapping using clipping on sphere") == 0 )
 	rv->map_type = MAP_TYPE_CONSERV_YAC;
       else
 	rv->map_type = MAP_TYPE_CONSERV;
@@ -511,19 +511,19 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
       status = nc_get_att_int(nc_file_id, NC_GLOBAL, "remap_order", &iatt);
       if ( status == NC_NOERR ) *remap_order = iatt;
     }
-  else if ( strcompare(map_method, "Bilinear") == 0 ) rv->map_type = MAP_TYPE_BILINEAR;
-  else if ( strcompare(map_method, "Bicubic")  == 0 ) rv->map_type = MAP_TYPE_BICUBIC;
-  else if ( strcompare(map_method, "Distance") == 0 )
+  else if ( cmpstr(map_method, "Bilinear") == 0 ) rv->map_type = MAP_TYPE_BILINEAR;
+  else if ( cmpstr(map_method, "Bicubic")  == 0 ) rv->map_type = MAP_TYPE_BICUBIC;
+  else if ( cmpstr(map_method, "Distance") == 0 )
     {
       rv->map_type = MAP_TYPE_DISTWGT;
       *num_neighbors = 4;
     }
-  else if ( strcompare(map_method, "Nearest") == 0 )
+  else if ( cmpstr(map_method, "Nearest") == 0 )
     {
       rv->map_type = MAP_TYPE_DISTWGT;
       *num_neighbors = 1;
     }
-  else if ( strcompare(map_method, "Largest") == 0 )
+  else if ( cmpstr(map_method, "Largest") == 0 )
     {
       rv->map_type = MAP_TYPE_CONSERV;
       *submap_type = SUBMAP_TYPE_LAF;
@@ -651,8 +651,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 
   /* Allocate address and weight arrays for mapping 1 */
 
-  rv->src_grid_add = (int*) malloc(rv->num_links*sizeof(int));
-  rv->tgt_grid_add = (int*) malloc(rv->num_links*sizeof(int));
+  rv->src_cell_add = (int*) malloc(rv->num_links*sizeof(int));
+  rv->tgt_cell_add = (int*) malloc(rv->num_links*sizeof(int));
 
   rv->wts = (double*) malloc(rv->num_wts*rv->num_links*sizeof(double));
 
@@ -758,13 +758,13 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 
   nce(nc_get_var_double(nc_file_id, nc_dstgrdfrac_id, tgt_grid->cell_frac));
 
-  nce(nc_get_var_int(nc_file_id, nc_srcadd_id, rv->src_grid_add));
-  nce(nc_get_var_int(nc_file_id, nc_dstadd_id, rv->tgt_grid_add));
+  nce(nc_get_var_int(nc_file_id, nc_srcadd_id, rv->src_cell_add));
+  nce(nc_get_var_int(nc_file_id, nc_dstadd_id, rv->tgt_cell_add));
 
   for ( i = 0; i < rv->num_links; i++ )
     {
-      rv->src_grid_add[i]--;
-      rv->tgt_grid_add[i]--;
+      rv->src_cell_add[i]--;
+      rv->tgt_cell_add[i]--;
     }
 
   nce(nc_get_var_double(nc_file_id, nc_rmpmatrix_id, rv->wts));
diff --git a/src/remap_search_latbins.c b/src/remap_search_latbins.c
index 381f170..aeb1218 100644
--- a/src/remap_search_latbins.c
+++ b/src/remap_search_latbins.c
@@ -156,15 +156,15 @@ void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
 }
 
 
-long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr2,
+long get_srch_cells(long tgt_cell_add, long nbins, int *bin_addr1, int *bin_addr2,
 		    restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, long src_grid_size, int *srch_add)
 {
   long num_srch_cells;  /* num cells in restricted search arrays   */
   long min_add;         /* addresses for restricting search of     */
   long max_add;         /* destination grid                        */
   long n, n2;           /* generic counters                        */
-  long src_grid_add;    /* current linear address for src cell     */
-  long src_grid_addm4;
+  long src_cell_add;    /* current linear address for src cell     */
+  long src_cell_addm4;
   restr_t bound_box_lat1, bound_box_lat2, bound_box_lon1, bound_box_lon2;
 
   /* Restrict searches first using search bins */
@@ -175,7 +175,7 @@ long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr
   for ( n = 0; n < nbins; ++n )
     {
       n2 = n<<1;
-      if ( tgt_grid_add >= bin_addr1[n2] && tgt_grid_add <= bin_addr1[n2+1] )
+      if ( tgt_cell_add >= bin_addr1[n2] && tgt_cell_add <= bin_addr1[n2+1] )
 	{
 	  if ( bin_addr2[n2  ] < min_add ) min_add = bin_addr2[n2  ];
 	  if ( bin_addr2[n2+1] > max_add ) max_add = bin_addr2[n2+1];
@@ -190,16 +190,16 @@ long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr
   bound_box_lon2 = tgt_cell_bound_box[3];
 
   num_srch_cells = 0;
-  for ( src_grid_add = min_add; src_grid_add <= max_add; ++src_grid_add )
+  for ( src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
     {
-      src_grid_addm4 = src_grid_add<<2;
-      if ( (src_cell_bound_box[src_grid_addm4+2] <= bound_box_lon2)  &&
-	   (src_cell_bound_box[src_grid_addm4+3] >= bound_box_lon1) )
+      src_cell_addm4 = src_cell_add<<2;
+      if ( (src_cell_bound_box[src_cell_addm4+2] <= bound_box_lon2)  &&
+	   (src_cell_bound_box[src_cell_addm4+3] >= bound_box_lon1) )
 	{
-	  if ( (src_cell_bound_box[src_grid_addm4  ] <= bound_box_lat2)  &&
-	       (src_cell_bound_box[src_grid_addm4+1] >= bound_box_lat1) )
+	  if ( (src_cell_bound_box[src_cell_addm4  ] <= bound_box_lat2)  &&
+	       (src_cell_bound_box[src_cell_addm4+1] >= bound_box_lat1) )
 	    {
-	      srch_add[num_srch_cells] = src_grid_add;
+	      srch_add[num_srch_cells] = src_cell_add;
 	      num_srch_cells++;
 	    }
 	}
@@ -218,22 +218,22 @@ long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr
 	  bound_box_lon2 -= RESTR_SCALE(PI2);
 	}
 
-      for ( src_grid_add = min_add; src_grid_add <= max_add; ++src_grid_add )
+      for ( src_cell_add = min_add; src_cell_add <= max_add; ++src_cell_add )
 	{
-	  src_grid_addm4 = src_grid_add<<2;
-	  if ( (src_cell_bound_box[src_grid_addm4+2] <= bound_box_lon2)  &&
-	       (src_cell_bound_box[src_grid_addm4+3] >= bound_box_lon1) )
+	  src_cell_addm4 = src_cell_add<<2;
+	  if ( (src_cell_bound_box[src_cell_addm4+2] <= bound_box_lon2)  &&
+	       (src_cell_bound_box[src_cell_addm4+3] >= bound_box_lon1) )
 	    {
-	      if ( (src_cell_bound_box[src_grid_addm4  ] <= bound_box_lat2)  &&
-		   (src_cell_bound_box[src_grid_addm4+1] >= bound_box_lat1) )
+	      if ( (src_cell_bound_box[src_cell_addm4  ] <= bound_box_lat2)  &&
+		   (src_cell_bound_box[src_cell_addm4+1] >= bound_box_lat1) )
 		{
 		  long ii;
 		  for ( ii = 0; ii < num_srch_cells; ++ii )
-		    if ( srch_add[ii] == src_grid_add ) break;
+		    if ( srch_add[ii] == src_cell_add ) break;
 		  
 		  if ( ii == num_srch_cells )
 		    {
-		      srch_add[num_srch_cells] = src_grid_add;
+		      srch_add[num_srch_cells] = src_cell_add;
 		      num_srch_cells++;
 		    }
 		}
diff --git a/src/remap_store_link.c b/src/remap_store_link.c
index 844b715..e2a5a8e 100644
--- a/src/remap_store_link.c
+++ b/src/remap_store_link.c
@@ -4,288 +4,245 @@
 #include "remap_store_link.h"
 
 
-int  remap_store_link_fast = TRUE;
+static
+int cmp_adds(const void *s1, const void *s2)
+{
+  int cmp = 0;
+  const addweight_t* c1 = (const addweight_t*) s1;
+  const addweight_t* c2 = (const addweight_t*) s2;
+
+  if      ( c1->add < c2->add ) cmp = -1;
+  else if ( c1->add > c2->add ) cmp =  1;
 
+  return (cmp);
+}
 
-void grid_store_init(grid_store_t* grid_store, long gridsize)
+static
+int cmp_adds4(const void *s1, const void *s2)
 {
-  long iblk;
-  long blksize[] = {128, 256, 512, 1024, 2048, 4096, 8192};
-  long nblks = sizeof(blksize)/sizeof(long);
-  long nblocks;
+  int cmp = 0;
+  const addweight4_t* c1 = (const addweight4_t*) s1;
+  const addweight4_t* c2 = (const addweight4_t*) s2;
 
-  for ( iblk = nblks-1; iblk >= 0; --iblk )
-    if ( gridsize/blksize[iblk] > 99 ) break;
+  if      ( c1->add < c2->add ) cmp = -1;
+  else if ( c1->add > c2->add ) cmp =  1;
+
+  return (cmp);
+}
 
-  if ( iblk < 0 ) iblk = 0;
+static
+void sort_addweights(size_t num_weights, addweight_t *addweights)
+{
+  size_t n;
 
-  /* grid_store->blk_size = BLK_SIZE; */
-  grid_store->blk_size = blksize[iblk];
-  grid_store->max_size = gridsize;
+  for ( n = 1; n < num_weights; ++n )
+    if ( addweights[n].add < addweights[n-1].add ) break;
+  if ( n == num_weights ) return;
 
-  grid_store->nblocks = grid_store->max_size/grid_store->blk_size;
-  if ( grid_store->max_size%grid_store->blk_size > 0 ) grid_store->nblocks++;
+  qsort(addweights, num_weights, sizeof(addweight_t), cmp_adds);
+}
 
-  if ( cdoVerbose )
-    fprintf(stdout, "blksize = %d  lastblksize = %d  max_size = %d  nblocks = %d\n", 
-	    grid_store->blk_size, grid_store->max_size%grid_store->blk_size, 
-	    grid_store->max_size, grid_store->nblocks);
+static
+void sort_addweights4(size_t num_weights, addweight4_t *addweights)
+{
+  size_t n;
 
-  grid_store->blksize = (int*) malloc(grid_store->nblocks*sizeof(int));
-  grid_store->nlayers = (int*) malloc(grid_store->nblocks*sizeof(int));
-  grid_store->layers  = (grid_layer_t **) malloc(grid_store->nblocks*sizeof(grid_layer_t *));
+  for ( n = 1; n < num_weights; ++n )
+    if ( addweights[n].add < addweights[n-1].add ) break;
+  if ( n == num_weights ) return;
 
-  nblocks = grid_store->nblocks;
-  for ( iblk = 0; iblk < nblocks; ++iblk )
-    {
-      grid_store->blksize[iblk] = grid_store->blk_size;
-      grid_store->nlayers[iblk] = 0;
-      grid_store->layers[iblk]  = NULL;
-    }
-  if ( grid_store->max_size%grid_store->blk_size > 0 )
-    grid_store->blksize[grid_store->nblocks-1] = grid_store->max_size%grid_store->blk_size;
+  qsort(addweights, num_weights, sizeof(addweight4_t), cmp_adds);
 }
 
 
-void grid_store_delete(grid_store_t* grid_store)
+void sort_add_and_wgts(size_t num_weights, int *src_add, double *wgts)
 {
-  grid_layer_t *grid_layer, *grid_layer_f;
-  long j;
-  long nblocks = grid_store->nblocks;
+  size_t n;
 
-  for ( long iblk = 0; iblk < nblocks; ++iblk )
+  for ( n = 1; n < num_weights; ++n )
+    if ( src_add[n] < src_add[n-1] ) break;
+  if ( n == num_weights ) return;
+
+  addweight_t addweights[num_weights];
+
+  for ( n = 0; n < num_weights; ++n )
     {
-      j = 0;
-      grid_layer = grid_store->layers[iblk];
-      long nlayers = grid_store->nlayers[iblk];
-      long blksize =  grid_store->blksize[iblk];
-      for ( long ilayer = 0; ilayer < nlayers; ++ilayer )
-	{
-	  if ( cdoVerbose )
-	    {
-	      for ( long i = 0; i < blksize; ++i )
-		if ( grid_layer->grid2_link[i] != -1 ) j++;
-	    }
-	      
-	  grid_layer_f = grid_layer;
-	  free(grid_layer->grid2_link);
-	  grid_layer = grid_layer->next;
-	  free(grid_layer_f);
-	}
-      /*
-      if ( cdoVerbose )
-	{
-	  fprintf(stderr, "block = %ld nlayers = %ld  allocated = %ld  used = %ld\n",
-		  iblk+1, nlayers, nlayers*blksize, j);
-	}
-      */
+      addweights[n].add    = src_add[n];
+      addweights[n].weight = wgts[n];
     }
 
-  free(grid_store->blksize);
-  free(grid_store->layers);
-  free(grid_store->nlayers);  
+  qsort(addweights, num_weights, sizeof(addweight_t), cmp_adds);
+
+  for ( n = 0; n < num_weights; ++n )
+    {
+      src_add[n] = addweights[n].add;
+      wgts[n]    = addweights[n].weight;
+    }  
 }
 
-/*
-    This routine stores the address and weight for this link in the appropriate 
-    address and weight arrays and resizes those arrays if necessary.
-*/
-void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts, double* weights, grid_store_t* grid_store)
+
+void sort_add_and_wgts4(size_t num_weights, int *src_add, double wgts[4][4])
 {
-  /*
-    Input variables:
-    int  add1         ! address on source grid
-    int  add2         ! address on target grid
-    double weights[]  ! array of remapping weights for this link
-  */
-  /* Local variables */
-  long nlink; /* link index */
-  long ilayer, i, iblk, iadd2;
-  long nlayer, blksize;
-  int lstore_link;
-  grid_layer_t *grid_layer, **grid_layer2;
-
-  /*  If all weights are ZERO, do not bother storing the link */
-
-  if ( num_wts == 3 )
-    {
-      if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) ) return;
-    }
-  else
-    {
-      if ( IS_EQUAL(weights[0], 0) ) return;
-    }
-    
-  /* If the link already exists, add the weight to the current weight arrays */
+  size_t n;
 
-  iblk  = BLK_NUM(add2);
-  iadd2 = BLK_IDX(add2);
+  for ( n = 1; n < num_weights; ++n )
+    if ( src_add[n] < src_add[n-1] ) break;
+  if ( n == num_weights ) return;
 
-  lstore_link = FALSE;
-  grid_layer2 = &grid_store->layers[iblk];
-  nlayer = grid_store->nlayers[iblk];
-  for ( ilayer = 0; ilayer < nlayer; ++ilayer )
-    {
-      grid_layer = *grid_layer2;
-      nlink = grid_layer->grid2_link[iadd2];
-      if ( nlink == -1 )
-	{
-	  break;
-	}
-      else if ( add1 == rv->src_grid_add[nlink] )
-	{
-	  lstore_link = TRUE;
-	  break;
-	}
-      grid_layer2 = &(*grid_layer2)->next;
-    }
+  addweight4_t addweights[num_weights];
 
-  if ( lstore_link )
+  for ( n = 0; n < num_weights; ++n )
     {
-      for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] += weights[i];	      
-      return;
+      addweights[n].add       = src_add[n];
+      for ( long k = 0; k < 4; ++k )
+	addweights[n].weight[k] = wgts[n][k];
     }
 
-  /*
-     If the link does not yet exist, increment number of links and 
-     check to see if remap arrays need to be increased to accomodate 
-     the new link. Then store the link.
-  */
-  nlink = rv->num_links;
+  qsort(addweights, num_weights, sizeof(addweight4_t), cmp_adds4);
 
-  if ( ilayer < grid_store->nlayers[iblk] )
-    {
-      grid_layer->grid2_link[iadd2] = nlink;
-    }
-  else
+  for ( n = 0; n < num_weights; ++n )
     {
-      grid_layer = (grid_layer_t*) malloc(sizeof(grid_layer_t));
-      grid_layer->next = NULL;
-      grid_layer->grid2_link = (int*) malloc(grid_store->blksize[iblk]*sizeof(int));
+      src_add[n] = addweights[n].add;
+      for ( long k = 0; k < 4; ++k )
+	wgts[n][k] = addweights[n].weight[k];
+    }  
+}
 
-      blksize = grid_store->blksize[iblk];
-      for ( i = 0; i < blksize; ++i )
-	grid_layer->grid2_link[i] = -1;
 
-      grid_layer->grid2_link[iadd2] = nlink;
-      *grid_layer2 = grid_layer;
-      grid_store->nlayers[iblk]++;
-    }
-
-  rv->num_links++;
-  if ( rv->num_links >= rv->max_links )
-    resize_remap_vars(rv, rv->resize_increment);
+void store_weightlinks(long num_weights, int *srch_add, double *weights, long cell_add, weightlinks_t *weightlinks)
+{
+  weightlinks[cell_add].nlinks = 0;
+  weightlinks[cell_add].offset = 0;
 
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
+  if ( num_weights )
+    {
+      addweight_t *addweights = (addweight_t *) malloc(num_weights*sizeof(addweight_t));
+      for ( long n = 0; n < num_weights; ++n )
+	{
+	  addweights[n].add    = srch_add[n];
+	  addweights[n].weight = weights[n];
+	}
 
-  for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] = weights[i];	      
+      sort_addweights(num_weights, addweights);
 
-}  /* store_link_cnsrv_fast */
+      weightlinks[cell_add].addweights = addweights;
+      weightlinks[cell_add].nlinks     = num_weights;
+    }
+}
 
 
-/*
-    This routine stores the address and weight for this link in the appropriate 
-    address and weight arrays and resizes those arrays if necessary.
-*/
-void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict weights, int *link_add1[2], int *link_add2[2])
+void store_weightlinks4(long num_weights, int *srch_add, double weights[4][4], long cell_add, weightlinks4_t *weightlinks)
 {
-  /*
-    Input variables:
-    int  add1         ! address on source grid
-    int  add2         ! address on target grid
-    double weights[3] ! array of remapping weights for this link
-  */
-  /* Local variables */
-  long nlink, min_link, max_link; /* link index */
+  weightlinks[cell_add].nlinks = 0;
+  weightlinks[cell_add].offset = 0;
 
-  /*  If all weights are ZERO, do not bother storing the link */
-
-  if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) ) return;
+  if ( num_weights )
+    {
+      addweight4_t *addweights = (addweight4_t *) malloc(num_weights*sizeof(addweight4_t));
+      for ( long n = 0; n < num_weights; ++n )
+	{
+	  addweights[n].add       = srch_add[n];
+	  for ( long k = 0; k < 4; ++k )
+	    addweights[n].weight[k] = weights[n][k];
+	}
 
-  /*  Restrict the range of links to search for existing links */
+      sort_addweights4(num_weights, addweights);
 
-  min_link = MIN(link_add1[0][add1], link_add2[0][add2]);
-  max_link = MAX(link_add1[1][add1], link_add2[1][add2]);
-  if ( min_link == -1 )
-    {
-      min_link = 0;
-      max_link = -1;
+      weightlinks[cell_add].addweights = addweights;
+      weightlinks[cell_add].nlinks     = num_weights;
     }
+}
 
-  /* If the link already exists, add the weight to the current weight arrays */
-
-#if defined(SX)
-#define STRIPED 1
-#if STRIPED
-#define STRIPLENGTH 4096
-  {
-    long ilink = max_link + 1;
-    long strip, estrip;
-    nlink = 0;
-    for ( strip=min_link; strip <= max_link; strip+=STRIPLENGTH )
-      {
-	estrip = MIN(max_link-strip+1, STRIPLENGTH);
-	for ( nlink = 0; nlink < estrip; ++nlink )
-	  {
-	    if ( add2 == rv->tgt_grid_add[strip+nlink] &&
-		 add1 == rv->src_grid_add[strip+nlink] )
-	      ilink = strip + nlink;
-	  }
-	if (ilink != (max_link + 1)) break;
-      }
-    nlink += strip;
-    if (ilink != (max_link + 1)) nlink = ilink;
-  }
-#else
-  {
-    long ilink = max_link + 1;
-    for ( nlink = min_link; nlink <= max_link; ++nlink )
-      {
-	if ( add2 == rv->tgt_grid_add[nlink] )
-	  if ( add1 == rv->src_grid_add[nlink] ) ilink = nlink;
-      }
-    if ( ilink != (max_link + 1) ) nlink = ilink;
-  }
-#endif
-#else
-  for ( nlink = min_link; nlink <= max_link; ++nlink )
+
+void weightlinks2remaplinks(long tgt_grid_size, weightlinks_t *weightlinks, remapvars_t *rv)
+{
+  long tgt_cell_add;
+  long nlinks = 0;
+
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
-      if ( add2 == rv->tgt_grid_add[nlink] )
-	if ( add1 == rv->src_grid_add[nlink] ) break;
+      if ( weightlinks[tgt_cell_add].nlinks )
+	{
+	  weightlinks[tgt_cell_add].offset = nlinks;
+	  nlinks += weightlinks[tgt_cell_add].nlinks;
+	}
     }
-#endif
 
-  if ( nlink <= max_link )
+  rv->max_links = nlinks;
+  rv->num_links = nlinks;
+  if ( nlinks )
     {
-      rv->wts[3*nlink  ] += weights[0];
-      rv->wts[3*nlink+1] += weights[1];
-      rv->wts[3*nlink+2] += weights[2];
-
-      return;
+      rv->src_cell_add = (int*) malloc(nlinks*sizeof(int));
+      rv->tgt_cell_add = (int*) malloc(nlinks*sizeof(int));
+      rv->wts          = (double*) malloc(nlinks*sizeof(double));
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) \
+  shared(rv, weightlinks)		 \
+  private(tgt_cell_add)
+#endif
+      for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+	{
+	  long num_links = weightlinks[tgt_cell_add].nlinks;
+	  if ( num_links )
+	    {
+	      long offset    = weightlinks[tgt_cell_add].offset;
+	      for ( long ilink = 0; ilink < num_links; ++ilink )
+		{
+		  rv->src_cell_add[offset+ilink] = weightlinks[tgt_cell_add].addweights[ilink].add;
+		  rv->tgt_cell_add[offset+ilink] = tgt_cell_add;
+		  rv->wts[offset+ilink] = weightlinks[tgt_cell_add].addweights[ilink].weight;
+		}
+	      free(weightlinks[tgt_cell_add].addweights);
+	    }
+	}
     }
+}
 
-  /*
-     If the link does not yet exist, increment number of links and 
-     check to see if remap arrays need to be increased to accomodate 
-     the new link. Then store the link.
-  */
-  nlink = rv->num_links;
-
-  rv->num_links++;
-  if ( rv->num_links >= rv->max_links )
-    resize_remap_vars(rv, rv->resize_increment);
-
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
 
-  rv->wts[3*nlink  ] = weights[0];
-  rv->wts[3*nlink+1] = weights[1];
-  rv->wts[3*nlink+2] = weights[2];
+void weightlinks2remaplinks4(long tgt_grid_size, weightlinks4_t *weightlinks, remapvars_t *rv)
+{
+  long tgt_cell_add;
+  long nlinks = 0;
 
-  if ( link_add1[0][add1] == -1 ) link_add1[0][add1] = (int)nlink;
-  if ( link_add2[0][add2] == -1 ) link_add2[0][add2] = (int)nlink;
-  link_add1[1][add1] = (int)nlink;
-  link_add2[1][add2] = (int)nlink;
+  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+    {
+      if ( weightlinks[tgt_cell_add].nlinks )
+	{
+	  weightlinks[tgt_cell_add].offset = nlinks;
+	  nlinks += weightlinks[tgt_cell_add].nlinks;
+	}
+    }
 
-}  /* store_link_cnsrv */
+  rv->max_links = nlinks;
+  rv->num_links = nlinks;
+  if ( nlinks )
+    {
+      rv->src_cell_add = (int*) malloc(nlinks*sizeof(int));
+      rv->tgt_cell_add = (int*) malloc(nlinks*sizeof(int));
+      rv->wts          = (double*) malloc(4*nlinks*sizeof(double));
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(shared) \
+  shared(rv, weightlinks)		 \
+  private(tgt_cell_add)
+#endif
+      for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+	{
+	  long num_links = weightlinks[tgt_cell_add].nlinks;
+	  if ( num_links )
+	    {
+	      long offset    = weightlinks[tgt_cell_add].offset;
+	      addweight4_t *addweights = weightlinks[tgt_cell_add].addweights;
+	      for ( long ilink = 0; ilink < num_links; ++ilink )
+		{
+		  rv->src_cell_add[offset+ilink] = addweights[ilink].add;
+		  rv->tgt_cell_add[offset+ilink] = tgt_cell_add;
+		  for ( long k = 0; k < 4; ++k )
+		    rv->wts[(offset+ilink)*4+k] = addweights[ilink].weight[k];
+		}
+	      free(addweights);
+	    }
+	}
+    }
+}
diff --git a/src/remap_store_link.h b/src/remap_store_link.h
index ed3f223..e6ef089 100644
--- a/src/remap_store_link.h
+++ b/src/remap_store_link.h
@@ -1,35 +1,38 @@
 #ifndef _REMAP_STORE_LINK_H
 #define _REMAP_STORE_LINK_H
 
-extern int  remap_store_link_fast;
 
-/* used for store_link_fast */
-
-#define BLK_SIZE 4096
-#define BLK_NUM(x) (x/grid_store->blk_size)
-#define BLK_IDX(x) (x%grid_store->blk_size)
-struct grid_layer
+typedef struct
 {
-  int *grid2_link;
-  struct grid_layer *next;
-};
-
-typedef struct grid_layer grid_layer_t;
+  int    add;
+  double weight;
+} addweight_t;
 
 typedef struct
 {
-  int blk_size;
-  int max_size;
-  int nblocks;
-  int *blksize;
-  int *nlayers;
-  grid_layer_t **layers;
-} grid_store_t;
-
-void grid_store_init(grid_store_t *grid_store, long gridsize);
-void grid_store_delete(grid_store_t *grid_store);
-
-void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, long num_wts, double *weights, grid_store_t *grid_store);
-void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict weights, int *link_add1[2], int *link_add2[2]);
+  int    add;
+  double weight[4];
+} addweight4_t;
+
+typedef struct {
+  int nlinks;
+  int offset;
+  addweight_t *addweights;
+} weightlinks_t;
+
+typedef struct {
+  int nlinks;
+  int offset;
+  addweight4_t *addweights;
+} weightlinks4_t;
+
+
+void store_weightlinks(long num_weights, int *srch_add, double *weights, long cell_add, weightlinks_t *weightlinks);
+void store_weightlinks4(long num_weights, int *srch_add, double weights[4][4], long cell_add, weightlinks4_t *weightlinks);
+void weightlinks2remaplinks(long tgt_grid_size, weightlinks_t *weightlinks, remapvars_t *rv);
+void weightlinks2remaplinks4(long tgt_grid_size, weightlinks4_t *weightlinks, remapvars_t *rv);
+void sort_add_and_wgts(size_t num_weights, int *src_add, double *wgts);
+void sort_add_and_wgts4(size_t num_weights, int *src_add, double wgts[4][4]);
+
 
 #endif  /* _REMAP_STORE_LINK */
diff --git a/src/remap_store_link.c b/src/remap_store_link_cnsrv.c
similarity index 93%
copy from src/remap_store_link.c
copy to src/remap_store_link_cnsrv.c
index 844b715..26df1d9 100644
--- a/src/remap_store_link.c
+++ b/src/remap_store_link_cnsrv.c
@@ -1,7 +1,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "remap.h"
-#include "remap_store_link.h"
+#include "remap_store_link_cnsrv.h"
 
 
 int  remap_store_link_fast = TRUE;
@@ -132,7 +132,7 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
 	{
 	  break;
 	}
-      else if ( add1 == rv->src_grid_add[nlink] )
+      else if ( add1 == rv->src_cell_add[nlink] )
 	{
 	  lstore_link = TRUE;
 	  break;
@@ -176,8 +176,8 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
+  rv->src_cell_add[nlink] = add1;
+  rv->tgt_cell_add[nlink] = add2;
 
   for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] = weights[i];	      
 
@@ -228,8 +228,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 	estrip = MIN(max_link-strip+1, STRIPLENGTH);
 	for ( nlink = 0; nlink < estrip; ++nlink )
 	  {
-	    if ( add2 == rv->tgt_grid_add[strip+nlink] &&
-		 add1 == rv->src_grid_add[strip+nlink] )
+	    if ( add2 == rv->tgt_cell_add[strip+nlink] &&
+		 add1 == rv->src_cell_add[strip+nlink] )
 	      ilink = strip + nlink;
 	  }
 	if (ilink != (max_link + 1)) break;
@@ -242,8 +242,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
     long ilink = max_link + 1;
     for ( nlink = min_link; nlink <= max_link; ++nlink )
       {
-	if ( add2 == rv->tgt_grid_add[nlink] )
-	  if ( add1 == rv->src_grid_add[nlink] ) ilink = nlink;
+	if ( add2 == rv->tgt_cell_add[nlink] )
+	  if ( add1 == rv->src_cell_add[nlink] ) ilink = nlink;
       }
     if ( ilink != (max_link + 1) ) nlink = ilink;
   }
@@ -251,8 +251,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 #else
   for ( nlink = min_link; nlink <= max_link; ++nlink )
     {
-      if ( add2 == rv->tgt_grid_add[nlink] )
-	if ( add1 == rv->src_grid_add[nlink] ) break;
+      if ( add2 == rv->tgt_cell_add[nlink] )
+	if ( add1 == rv->src_cell_add[nlink] ) break;
     }
 #endif
 
@@ -276,8 +276,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->src_grid_add[nlink] = add1;
-  rv->tgt_grid_add[nlink] = add2;
+  rv->src_cell_add[nlink] = add1;
+  rv->tgt_cell_add[nlink] = add2;
 
   rv->wts[3*nlink  ] = weights[0];
   rv->wts[3*nlink+1] = weights[1];
diff --git a/src/remap_store_link.h b/src/remap_store_link_cnsrv.h
similarity index 88%
copy from src/remap_store_link.h
copy to src/remap_store_link_cnsrv.h
index ed3f223..b8e9bb8 100644
--- a/src/remap_store_link.h
+++ b/src/remap_store_link_cnsrv.h
@@ -1,5 +1,5 @@
-#ifndef _REMAP_STORE_LINK_H
-#define _REMAP_STORE_LINK_H
+#ifndef _REMAP_STORE_LINK_CNSRV_H
+#define _REMAP_STORE_LINK_CNSRV_H
 
 extern int  remap_store_link_fast;
 
@@ -32,4 +32,4 @@ void grid_store_delete(grid_store_t *grid_store);
 void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, long num_wts, double *weights, grid_store_t *grid_store);
 void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict weights, int *link_add1[2], int *link_add2[2]);
 
-#endif  /* _REMAP_STORE_LINK */
+#endif  /* _REMAP_STORE_LINK_CNSRV */
diff --git a/src/remaplib.c b/src/remaplib.c
index 151dd3e..2858c45 100644
--- a/src/remaplib.c
+++ b/src/remaplib.c
@@ -1,7 +1,7 @@
 /*
   This is a C library of the Fortran SCRIP version 1.4
 
-  ===>>> Please send bug reports to <https://code.zmaw.de/projects/cdo> <<<===
+  ===>>> Please send bug reports to <http://mpimet.mpg.de/cdo> <<<===
 
   Spherical Coordinate Remapping and Interpolation Package (SCRIP)
   ================================================================
@@ -57,7 +57,7 @@
 #include "cdo_int.h"
 #include "grid.h"
 #include "remap.h"
-#include "remap_store_link.h"
+#include "remap_store_link_cnsrv.h"
 #include "util.h"  /* progressStatus */
 
 
@@ -118,9 +118,9 @@ void remapVarsFree(remapvars_t *rv)
 
       rv->sort_add = FALSE;
 
-      free(rv->src_grid_add);
-      free(rv->tgt_grid_add);
-      free(rv->wts);
+      if ( rv->src_cell_add ) free(rv->src_cell_add);
+      if ( rv->tgt_cell_add ) free(rv->tgt_cell_add);
+      if ( rv->wts ) free(rv->wts);
 
       if ( rv->links.option == TRUE )
 	{
@@ -383,6 +383,10 @@ void check_lon_range(long nlons, double *lons)
 #endif
   for ( n = 0; n < nlons; ++n )
     {
+      // remove missing values
+      if ( lons[n] < -PI2 ) lons[n] = 0;
+      if ( lons[n] > 2*PI2) lons[n] = PI2;
+
       if ( lons[n] > PI2  ) lons[n] -= PI2;
       if ( lons[n] < ZERO ) lons[n] += PI2;
     }
@@ -983,8 +987,8 @@ void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remap
     {
       rv->pinit = TRUE;
 
-      rv->src_grid_add = NULL;
-      rv->tgt_grid_add = NULL;
+      rv->src_cell_add = NULL;
+      rv->tgt_cell_add = NULL;
       rv->wts          = NULL;
     }
 
@@ -994,17 +998,17 @@ void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remap
   if ( ompNumThreads > 1 )
     {
       if      ( map_type == MAP_TYPE_CONSERV     ) rv->sort_add = TRUE;
-      else if ( map_type == MAP_TYPE_CONSERV_YAC ) rv->sort_add = TRUE;
-      else if ( map_type == MAP_TYPE_BILINEAR    ) rv->sort_add = TRUE;
-      else if ( map_type == MAP_TYPE_BICUBIC     ) rv->sort_add = TRUE;
-      else if ( map_type == MAP_TYPE_DISTWGT     ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_CONSERV_YAC ) rv->sort_add = FALSE;
+      else if ( map_type == MAP_TYPE_BILINEAR    ) rv->sort_add = FALSE;
+      else if ( map_type == MAP_TYPE_BICUBIC     ) rv->sort_add = FALSE;
+      else if ( map_type == MAP_TYPE_DISTWGT     ) rv->sort_add = FALSE;
       else cdoAbort("Unknown mapping method!");
     }
   else
 #endif
     {
       if      ( map_type == MAP_TYPE_CONSERV     ) rv->sort_add = TRUE;
-      else if ( map_type == MAP_TYPE_CONSERV_YAC ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_CONSERV_YAC ) rv->sort_add = FALSE;
       else if ( map_type == MAP_TYPE_BILINEAR    ) rv->sort_add = FALSE;
       else if ( map_type == MAP_TYPE_BICUBIC     ) rv->sort_add = FALSE;
       else if ( map_type == MAP_TYPE_DISTWGT     ) rv->sort_add = FALSE;
@@ -1030,11 +1034,13 @@ void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remap
   rv->resize_increment = (int) (0.1 * MAX(src_grid_size, tgt_grid_size));
 
   /*  Allocate address and weight arrays for mapping 1 */
+  if ( map_type == MAP_TYPE_CONSERV )
+    {
+      rv->src_cell_add = (int*) realloc(rv->src_cell_add, rv->max_links*sizeof(int));
+      rv->tgt_cell_add = (int*) realloc(rv->tgt_cell_add, rv->max_links*sizeof(int));
 
-  rv->src_grid_add = (int*) realloc(rv->src_grid_add, rv->max_links*sizeof(int));
-  rv->tgt_grid_add = (int*) realloc(rv->tgt_grid_add, rv->max_links*sizeof(int));
-
-  rv->wts = (double*) realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
+      rv->wts = (double*) realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
+    }
 
   rv->links.option    = FALSE;
   rv->links.max_links = 0;
@@ -1064,8 +1070,8 @@ void resize_remap_vars(remapvars_t *rv, int increment)
 
   if ( rv->max_links )
     {
-      rv->src_grid_add = (int*) realloc(rv->src_grid_add, rv->max_links*sizeof(int));
-      rv->tgt_grid_add = (int*) realloc(rv->tgt_grid_add, rv->max_links*sizeof(int));
+      rv->src_cell_add = (int*) realloc(rv->src_cell_add, rv->max_links*sizeof(int));
+      rv->tgt_cell_add = (int*) realloc(rv->tgt_cell_add, rv->max_links*sizeof(int));
 
       rv->wts = (double*) realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
     }
@@ -1162,19 +1168,19 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 	{
 	  for ( n = 0; n < num_links; ++n )
 	    {
-	      dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n] +
-                                       src_grad1[src_add[n]]*map_wts[num_wts*n+1] +
-                                       src_grad2[src_add[n]]*map_wts[num_wts*n+2];
+	      dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[3*n] +
+                                       src_grad1[src_add[n]]*map_wts[3*n+1] +
+                                       src_grad2[src_add[n]]*map_wts[3*n+2];
 	    }
 	}
       else if ( num_wts == 4 )
 	{
       	  for ( n = 0; n < num_links; ++n )
 	    {
-              dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n] +
-                                       src_grad1[src_add[n]]*map_wts[num_wts*n+1] +
-                                       src_grad2[src_add[n]]*map_wts[num_wts*n+2] +
-                                       src_grad3[src_add[n]]*map_wts[num_wts*n+3];
+              dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[4*n] +
+                                       src_grad1[src_add[n]]*map_wts[4*n+1] +
+                                       src_grad2[src_add[n]]*map_wts[4*n+2] +
+                                       src_grad3[src_add[n]]*map_wts[4*n+3];
 	    }
 	}
     }
@@ -1519,7 +1525,7 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
 #if defined(SX)
 #pragma vdir nodep
 #endif
-  for ( n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_grid_add[n]]++;
+  for ( n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_cell_add[n]]++;
 
   imin = INT_MAX;
   imax = INT_MIN;
@@ -1787,13 +1793,13 @@ void reorder_links(remapvars_t *rv)
   lastval = -1;
   for ( n = 0; n < num_links; n++ )
     {
-      if ( rv->tgt_grid_add[n] == lastval ) nval++;
+      if ( rv->tgt_cell_add[n] == lastval ) nval++;
       else
 	{
 	  if ( nval > num_blks ) num_blks = nval;
 	  nval = 1;
 	  max_links++;
-	  lastval = rv->tgt_grid_add[n];
+	  lastval = rv->tgt_cell_add[n];
 	}
     }
 
@@ -1825,17 +1831,17 @@ void reorder_links(remapvars_t *rv)
 
       for ( n = 0; n < num_links; n++ )
 	{
-	  if ( rv->tgt_grid_add[n] == lastval ) nval++;
+	  if ( rv->tgt_cell_add[n] == lastval ) nval++;
 	  else
 	    {
 	      nval = 1;
-	      lastval = rv->tgt_grid_add[n];
+	      lastval = rv->tgt_cell_add[n];
 	    }
 	  
 	  if ( nval == j+1 )
 	    {
-	      rv->links.dst_add[j][nlinks] = rv->tgt_grid_add[n];
-	      rv->links.src_add[j][nlinks] = rv->src_grid_add[n];
+	      rv->links.dst_add[j][nlinks] = rv->tgt_cell_add[n];
+	      rv->links.src_add[j][nlinks] = rv->src_cell_add[n];
 	      rv->links.w_index[j][nlinks] = n;
 	      nlinks++;
 	    }
diff --git a/src/specspace.c b/src/specspace.c
index a7f1692..81e32fc 100644
--- a/src/specspace.c
+++ b/src/specspace.c
@@ -10,181 +10,29 @@
 #include "grid.h"
 
 
-#define  SQUARE_RADIUS   (-PlanetRadius * PlanetRadius)
-#define  C_EARTH_RADIUS  (6371000.0)
-double PlanetRadius = C_EARTH_RADIUS;
-
-
-void geninx(long ntr, double *f, double *g)
-{
-  long m2,n2;
-  long m, n ;
-
-  for ( m = 0; m <= ntr; m++ )
-    {
-      m2 = m * m;
-      for ( n = m; n <= ntr; n++ )
-	{
-	  n2 = n * n;
-	  if ( n )
-	    {
-	      *g++ = -PlanetRadius / n * sqrt((double)(n2-m2)/(double)(4*n2-1));
-	      *f++ = -PlanetRadius * m / (double)(n2+n);
-	    }
-	  else
-	    {
-	      *g++ = 0.0;
-	      *f++ = 0.0;
-	    }
-	}
-    }
-}
-
-
-void legini_old(int ntr, int nlat, double *poli, double *pold,
-		double *pol2, double *pol3, double *coslat, double *rcoslat, int flag)
-{
-  int waves, dimsp;
-  int jgl, jm, jn;
-  int jsp;
-  int pdim;
-  double *gmu, *gwt, *pnm;
-  double *hnm, gmusq, *ztemp1, *ztemp2;
-
-  waves =  ntr + 1;
-  dimsp = (ntr + 1) * (ntr + 2);
-  pdim  = dimsp / 2 * nlat;
-
-  gmu  = (double*) malloc(nlat * sizeof(double));
-  gwt  = (double*) malloc(nlat * sizeof(double));
-
-  gaussaw(gmu, gwt, nlat);
-
-#if ! defined(_OPENMP)
-  pnm    = (double*) malloc(dimsp * sizeof(double));
-  hnm    = (double*) malloc(dimsp * sizeof(double));
-  ztemp1 = (double*) malloc((waves<<1) * sizeof(double));
-  ztemp2 = (double*) malloc((waves<<1) * sizeof(double));
-#endif
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(jm, jn, jsp, gmusq, hnm, pnm, ztemp1, ztemp2)
-#endif
-  for ( jgl = 0; jgl < nlat; jgl++ )
-    {
-#if defined(_OPENMP)
-      pnm    = (double*) malloc(dimsp * sizeof(double));
-      hnm    = (double*) malloc(dimsp * sizeof(double));
-      ztemp1 = (double*) malloc((waves<<1) * sizeof(double));
-      ztemp2 = (double*) malloc((waves<<1) * sizeof(double));
-#endif
-      gmusq = 1.0 - gmu[jgl]*gmu[jgl];
-      coslat[jgl] =  sqrt(gmusq);
-      rcoslat[jgl] = 1.0 / coslat[jgl];
-
-      phcs(pnm, hnm, waves, gmu[jgl], ztemp1, ztemp2);
-
-      jsp = jgl;
-      for ( jm = 0; jm < waves; jm++ )
-	for ( jn = 0; jn < waves - jm; jn++ )
-	  {
-	              poli[jsp] = pnm[jm*waves+jn] * 2.0;
-	              pold[jsp] = pnm[jm*waves+jn] * gwt[jgl];
-	    if (flag) pol2[jsp] = hnm[jm*waves+jn] * gwt[jgl] /
-                                  (PlanetRadius    * gmusq);
-	    if (flag) pol3[jsp] = pnm[jm*waves+jn] * gwt[jgl] * jm /
-                                  (PlanetRadius    * gmusq);
-	    jsp += nlat;
-	  }
-#if defined(_OPENMP)
-      free(ztemp2);
-      free(ztemp1);
-      free(pnm);
-      free(hnm);
-#endif
-    }
-
-#if ! defined(_OPENMP)
-  free(ztemp2);
-  free(ztemp1);
-  free(pnm);
-  free(hnm);
-#endif
-  free(gwt);
-  free(gmu);
-}
-
-
-void legini(int ntr, int nlat, double *poli, double *pold, double *rcoslat)
-{
-  int waves, dimsp, dimpnm;
-  int jgl, jm, jn, is;
-  int isp, latn, lats;
-  double *gmu, *gwt, *pnm, *work;
-
-  waves  =  ntr + 1;
-  dimsp  = (ntr + 1)*(ntr + 2);
-  dimpnm = (ntr + 1)*(ntr + 4)/2;
-
-  gmu  = (double*) malloc(nlat * sizeof(double));
-  gwt  = (double*) malloc(nlat * sizeof(double));
-  pnm  = (double*) malloc(dimpnm * sizeof(double));
-  work = (double*) malloc(3*waves * sizeof(double));
-
-  gaussaw(gmu, gwt, nlat);
-  for ( jgl = 0; jgl < nlat; jgl++ ) gwt[jgl] *= 0.5;
-
-  for ( jgl = 0; jgl < nlat; jgl++ )
-    rcoslat[jgl] = 1.0 / sqrt(1.0 - gmu[jgl]*gmu[jgl]);
-
-  for ( jgl = 0; jgl < nlat/2; jgl++ )
-    {
-      jspleg1(pnm, gmu[jgl], ntr, work);
-
-      latn = jgl;
-      isp = 0;
-      for ( jm = 0; jm < waves; jm++ )
-	{
-#if defined(SX)
-#pragma vdir nodep
-#endif
-	  for ( jn = 0; jn < waves - jm; jn++ )
-	    {
-	      is = (jn+1)%2 * 2 - 1;
-	      lats = latn - jgl + nlat - jgl - 1;
-	      poli[latn] = pnm[isp];
-	      pold[latn] = pnm[isp] * gwt[jgl];
-	      poli[lats] = pnm[isp] * is;
-	      pold[lats] = pnm[isp] * gwt[jgl] * is;
-	      latn += nlat;
-	      isp++;
-	    }
-	  isp++;
-	}
-    }
+void geninx(long ntr, double *f, double *g);
+void scaluv(double *fu, double *rclat, int nlat, int lot);
+void uv2dv(double *fu, double *fv, double *sd, double *sv,
+           double *pol2, double *pol3, int klev, int nlat, int nt);
+void dv2uv(double *d, double *o, double *u, double *v, double *f, double *g,
+	   int nt, int nsp, int nlev);
+void dv2ps(const double * restrict div, double * restrict pot, long nlev, long ntr);
 
-  free(work);
-  free(pnm);
-  free(gwt);
-  free(gmu);
-}
+void after_legini_full(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict pdev,
+		       double *restrict pol2, double *restrict pol3, double *restrict coslat);
+void after_legini(int ntr, int nlat, double *restrict poli, double *restrict pold, double *restrict coslat);
 
 
 void grid2spec(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntr, nlat, nlon, nfc;
-  int nlev = 1;
-  int waves;
-  double *fpwork;
-    
-  ntr  = gridInqTrunc(gridIDout);
-  nlon = gridInqXsize(gridIDin);
-  nlat = gridInqYsize(gridIDin);
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDout);
+  int nlon  = gridInqXsize(gridIDin);
+  int nlat  = gridInqYsize(gridIDin);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
-  fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
+  double *fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
 
   gp2fc(sptrans->trig, sptrans->ifax, arrayIn, fpwork, nlat, nlon, nlev, nfc);
   fc2sp(fpwork, arrayOut, sptrans->pold, nlev, nlat, nfc, ntr);
@@ -195,19 +43,14 @@ void grid2spec(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
    
 void spec2grid(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntr, nlat, nlon, nfc;
-  int nlev = 1;
-  int waves;
-  double *fpwork;
-    
-  ntr  = gridInqTrunc(gridIDin);
-  nlon = gridInqXsize(gridIDout);
-  nlat = gridInqYsize(gridIDout);
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDin);
+  int nlon  = gridInqXsize(gridIDout);
+  int nlat  = gridInqYsize(gridIDout);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
-  waves = ntr + 1;
-  nfc   = waves * 2;
-
-  fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
+  double *fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
 
   sp2fc(arrayIn, fpwork, sptrans->poli, nlev, nlat, nfc, ntr);
   fc2gp(sptrans->trig, sptrans->ifax, fpwork, arrayOut, nlat, nlon, nlev, nfc);
@@ -218,15 +61,11 @@ void spec2grid(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 
 void four2spec(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntr, nlat, nfc;
-  int nlev = 1;
-  int waves;
-    
-  ntr  = gridInqTrunc(gridIDout);
-  nlat = sptrans->nlat;
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDout);
+  int nlat  = sptrans->nlat;
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
   fc2sp(arrayIn, arrayOut, sptrans->pold, nlev, nlat, nfc, ntr);
 }
@@ -234,15 +73,11 @@ void four2spec(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 
 void spec2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntr, nlat, nfc;
-  int nlev = 1;
-  int waves;
-    
-  ntr  = gridInqTrunc(gridIDin);
-  nfc  = gridInqSize(gridIDout);
-  nlat = nfc2nlat(nfc, ntr);
-
-  waves = ntr + 1;
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDin);
+  int nfc   = gridInqSize(gridIDout);
+  int nlat  = nfc2nlat(nfc, ntr);
+  int waves = ntr + 1;
   nfc   = waves * 2;
 
   sp2fc(arrayIn, arrayOut, sptrans->poli, nlev, nlat, nfc, ntr);
@@ -251,16 +86,12 @@ void spec2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 
 void four2grid(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntr, nlat, nlon, nfc;
-  int nlev = 1;
-  int waves;
-
-  ntr  = gridInqTrunc(gridIDin);
-  nlon = gridInqXsize(gridIDout);
-  nlat = gridInqYsize(gridIDout);
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDin);
+  int nlon  = gridInqXsize(gridIDout);
+  int nlat  = gridInqYsize(gridIDout);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
   fc2gp(sptrans->trig, sptrans->ifax, arrayIn, arrayOut, nlat, nlon, nlev, nfc);
 }
@@ -268,16 +99,12 @@ void four2grid(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 
 void grid2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int nlat, nlon, nfc, ntr;
-  int nlev = 1;
-  int waves;
-
-  ntr  = gridInqTrunc(gridIDout);
-  nlon = gridInqXsize(gridIDin);
-  nlat = gridInqYsize(gridIDin);
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
+  int nlev  = 1;
+  int ntr   = gridInqTrunc(gridIDout);
+  int nlon  = gridInqXsize(gridIDin);
+  int nlat  = gridInqYsize(gridIDin);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
   gp2fc(sptrans->trig, sptrans->ifax, arrayIn, arrayOut, nlat, nlon, nlev, nfc);
 }
@@ -285,10 +112,8 @@ void grid2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 
 void spec2spec(int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 {
-  int ntrIn, ntrOut;
-
-  ntrIn  = gridInqTrunc(gridIDin);
-  ntrOut = gridInqTrunc(gridIDout);
+  int ntrIn  = gridInqTrunc(gridIDin);
+  int ntrOut = gridInqTrunc(gridIDout);
 
   sp2sp(arrayIn, ntrIn, arrayOut, ntrOut);
 }
@@ -296,9 +121,7 @@ void spec2spec(int gridIDin, double *arrayIn, int gridIDout, double *arrayOut)
 
 void speccut(int gridIDin, double *arrayIn, double *arrayOut, int *waves)
 {
-  int ntr;
-
-  ntr = gridInqTrunc(gridIDin);
+  int ntr = gridInqTrunc(gridIDin);
 
   spcut(arrayIn, arrayOut, ntr, waves);
 }
@@ -306,16 +129,13 @@ void speccut(int gridIDin, double *arrayIn, double *arrayOut, int *waves)
 
 SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
 {
-  SPTRANS *sptrans;
-  int nsp;
-
-  sptrans = (SPTRANS*) malloc(sizeof(SPTRANS));
+  SPTRANS *sptrans = (SPTRANS*) malloc(sizeof(SPTRANS));
 
   sptrans->nlon = nlon;
   sptrans->nlat = nlat;
   sptrans->ntr  = ntr;
 
-  nsp = (ntr + 1)*(ntr + 2);
+  int nsp = (ntr + 1)*(ntr + 2);
   sptrans->poldim = nsp / 2 * nlat;
 
   sptrans->trig = (double*) malloc(nlon * sizeof(double));
@@ -323,6 +143,7 @@ SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
 
   sptrans->poli = (double*) malloc(sptrans->poldim * sizeof(double));
   sptrans->pold = (double*) malloc(sptrans->poldim * sizeof(double));
+  
   if ( flag )
     {
       sptrans->pol2 = (double*) malloc(sptrans->poldim * sizeof(double));
@@ -338,10 +159,13 @@ SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
   sptrans->rcoslat = (double*) malloc(nlat * sizeof(double));
 
   if ( flag )
-    legini_old(ntr, nlat, sptrans->poli, sptrans->pold,
-	       sptrans->pol2, sptrans->pol3, sptrans->coslat, sptrans->rcoslat, flag);
+    after_legini_full(ntr, nlat, sptrans->poli, sptrans->pold, NULL,
+		      sptrans->pol2, sptrans->pol3, sptrans->coslat);
   else
-    legini(ntr, nlat, sptrans->poli, sptrans->pold, sptrans->rcoslat);
+    after_legini(ntr, nlat, sptrans->poli, sptrans->pold, sptrans->coslat);
+
+  for ( int jgl = 0; jgl < nlat; ++jgl )
+    sptrans->rcoslat[jgl] = 1.0 / sptrans->coslat[jgl];
 
   return (sptrans);
 }
@@ -366,14 +190,11 @@ void sptrans_delete(SPTRANS *sptrans)
 
 DVTRANS *dvtrans_new(int ntr)
 {
-  DVTRANS *dvtrans;
-  int dimsp;
-
-  dvtrans = (DVTRANS*) malloc(sizeof(DVTRANS));
+  DVTRANS *dvtrans = (DVTRANS*) malloc(sizeof(DVTRANS));
 
   dvtrans->ntr = ntr;
 
-  dimsp = (ntr + 1)*(ntr + 2);
+  int dimsp = (ntr + 1)*(ntr + 2);
   dvtrans->fdim = dimsp / 2;
 
   dvtrans->f1 = (double*) malloc(dvtrans->fdim * sizeof(double));
@@ -397,234 +218,24 @@ void dvtrans_delete(DVTRANS *dvtrans)
 }
 
 
-void uv2dv(double *fu, double *fv, double *sd, double *sv,
-           double *pol2, double *pol3, int klev, int nlat, int nt)
-{
-  int lev, jmm, jfc, lat, nfc, nsp2;
-  double dir, dii, vor, voi;
-  double *ufr, *ufi, *vfr, *vfi;
-  double *ful, *fvl, *sdl, *svl;
-  double *po2, *po3;
-
-  nsp2 = (nt+1)*(nt+2);
-  nfc  = (nt+1)*2;
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(jmm, jfc, lat, po2, po3, ful, fvl, sdl, svl, ufr, ufi, vfr, vfi, dir, dii, vor, voi)
-#endif
-  for ( lev = 0; lev < klev; lev++ )
-    {
-      po2 = pol2;
-      po3 = pol3;
-      ful = fu + lev*nfc*nlat;
-      fvl = fv + lev*nfc*nlat;
-      sdl = sd + lev*nsp2;
-      svl = sv + lev*nsp2;
-      for ( jmm = 0; jmm <= nt; jmm++ )
-	{
-	  for  ( jfc = jmm; jfc <= nt; jfc++ )
-	    {
-	      ufr = ful;
-	      ufi = ful + nlat;
-	      vfr = fvl;
-	      vfi = fvl + nlat;
-	      dir = 0.0;
-	      dii = 0.0;
-	      vor = 0.0;
-	      voi = 0.0;
-	      for ( lat = 0; lat < nlat; lat++ )
-		{
-		  dir += vfr[lat] * po2[lat] - ufi[lat] * po3[lat];
-		  dii += vfi[lat] * po2[lat] + ufr[lat] * po3[lat];
-		  vor -= ufr[lat] * po2[lat] + vfi[lat] * po3[lat];
-		  voi -= ufi[lat] * po2[lat] - vfr[lat] * po3[lat];
-		}
-	      *sdl++ = dir;
-	      *sdl++ = dii;
-	      *svl++ = vor;
-	      *svl++ = voi;
-	      po2 += nlat;
-	      po3 += nlat;
-	    }
-	  ful += 2 * nlat;
-	  fvl += 2 * nlat;
-	}
-    }
-}
-
-
-void dv2uv(double *d, double *o, double *u, double *v, double *f, double *g,
-	   int nt, int nsp, int nlev)
-{
-  /* d(nsp,nlev), o(nsp,nlev)     ! divergence, vorticity        */
-  /* u(nsp,nlev), v(nsp,nlev)     ! zonal wind, meridional wind  */
-  /* f(nsp/2)   , g(nsp/2)        ! factor tables                */
-
-  int l, m, n;
-  int i;
-
-  for ( l = 0; l < nlev; l++ )
-    {
-      i = 0;
-
-      for ( m = 0; m < nt-1; m++ )
-	{
-	  /*********/
-	  /* n = m */
-	  /*********/
-
-	  if ( m == 0 )
-	    {
-	      *u++ = -g[i+1] * o[2*(i+1)  ];
-	      *u++ = -g[i+1] * o[2*(i+1)+1];
-	      *v++ =  g[i+1] * d[2*(i+1)  ];
-	      *v++ =  g[i+1] * d[2*(i+1)+1];
-	    }
-	  else
-	    {
-	      *u++ = -f[i] * d[2*i+1] - g[i+1] * o[2*(i+1)  ];
-	      *u++ =  f[i] * d[2*i  ] - g[i+1] * o[2*(i+1)+1];
-	      *v++ = -f[i] * o[2*i+1] + g[i+1] * d[2*(i+1)  ];
-	      *v++ =  f[i] * o[2*i  ] + g[i+1] * d[2*(i+1)+1];
-	    }
-	  ++i;
-
-	  /****************/
-	  /* m < n < nt-1 */
-	  /****************/
-
-	  for ( n = m+1; n < nt-1; n++ )
-	    {
-	      *u++ =  g[i] * o[2*(i-1)  ] - f[i] * d[2*i+1] - g[i+1] * o[2*(i+1)  ];
-	      *u++ =  g[i] * o[2*(i-1)+1] + f[i] * d[2*i  ] - g[i+1] * o[2*(i+1)+1];
-	      *v++ = -g[i] * d[2*(i-1)  ] - f[i] * o[2*i+1] + g[i+1] * d[2*(i+1)  ];
-	      *v++ = -g[i] * d[2*(i-1)+1] + f[i] * o[2*i  ] + g[i+1] * d[2*(i+1)+1];
-	      ++i;
-	    }
-
-	  /************/
-	  /* n = nt-1 */
-	  /************/
-
-	  *u++ =  g[i] * o[2*(i-1)  ] - f[i] * d[2*i+1];
-	  *u++ =  g[i] * o[2*(i-1)+1] + f[i] * d[2*i  ];
-	  *v++ = -g[i] * d[2*(i-1)  ] - f[i] * o[2*i+1];
-	  *v++ = -g[i] * d[2*(i-1)+1] + f[i] * o[2*i  ];
-	  ++i;
-
-	  /**********/
-	  /* n = nt */
-	  /**********/
-
-	  *u++ =  g[i] * o[2*(i-1)  ];
-	  *u++ =  g[i] * o[2*(i-1)+1];
-	  *v++ = -g[i] * d[2*(i-1)  ];
-	  *v++ = -g[i] * d[2*(i-1)+1];
-	  ++i;
-	}
-
-      /***************************/
-      /* m = nt-1  and  n = nt-1 */
-      /***************************/
-
-      *u++ = -f[i] * d[2*i+1];
-      *u++ =  f[i] * d[2*i  ];
-      *v++ = -f[i] * o[2*i+1];
-      *v++ =  f[i] * o[2*i  ];
-      ++i;
-
-      /*************************/
-      /* m = nt-1  and  n = nt */
-      /*************************/
-
-      *u++ =  g[i] * o[2*(i-1)  ];
-      *u++ =  g[i] * o[2*(i-1)+1];
-      *v++ = -g[i] * d[2*(i-1)  ];
-      *v++ = -g[i] * d[2*(i-1)+1];
-      ++i;
-
-      /***********************/
-      /* m = nt  and  n = nt */
-      /***********************/
-
-      *u++ = 0.0;
-      *u++ = 0.0;
-      *v++ = 0.0;
-      *v++ = 0.0;
-
-      d += nsp;
-      o += nsp;
-    }
-}
-
-
-void dv2ps(const double * restrict div, double * restrict pot, long nlev, long ntr)
-{
-  long l, m, n;
-  double fact;
-
-  for ( l = 0; l <  nlev; l++ )
-    {
-      /* m == 0 */
-      *pot++ = 0.0;
-      *pot++ = 0.0;
-      div += 2;
-
-      for ( n = 1; n <= ntr; n++ )
-	{
-	  fact = SQUARE_RADIUS / (n*n + n);
-	  *pot++ = *div++ * fact;
-	  *pot++ = *div++ * fact;
-	}
-
-      /* m >= 0 */
-      for ( m = 1; m <= ntr; m++ )
-	for ( n = m; n <= ntr; n++ )
-	  {
-	    fact = SQUARE_RADIUS / (n*n + n);
-	    *pot++ = *div++ * fact;
-	    *pot++ = *div++ * fact;
-	  }
-    }
-}
-
-
-void scaluv(double *fu, double *rclat, int nlat, int lot)
-{
-  int l,lat;
-
-  for (l = 0; l < lot; l++)
-    for (lat = 0; lat < nlat; lat++)
-      {
-        *fu *= rclat[lat];
-        fu++;
-      }
-}
-
-
 void trans_uv2dv(SPTRANS *sptrans, int nlev,
 		 int gridID1, double *gu, double *gv,
 		 int gridID2, double *sd, double *svo)
 {
-  int ntr, nlat, nlon, nfc;
-  int waves;
-  double *fpwork1, *fpwork2;
-
   if ( gridInqType(gridID1) != GRID_GAUSSIAN )
     Error("unexpected grid1 type: %s instead of Gaussian", gridNamePtr(gridInqType(gridID1)));
 
   if ( gridInqType(gridID2) != GRID_SPECTRAL )
     Error("unexpected grid2 type: %s instead of spectral", gridNamePtr(gridInqType(gridID2)));
     
-  ntr  = gridInqTrunc(gridID2);
-  nlon = gridInqXsize(gridID1);
-  nlat = gridInqYsize(gridID1);
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
+  int ntr   = gridInqTrunc(gridID2);
+  int nlon  = gridInqXsize(gridID1);
+  int nlat  = gridInqYsize(gridID1);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
 
-  fpwork1 = (double*) malloc(nlat*nfc*nlev*sizeof(double));
-  fpwork2 = (double*) malloc(nlat*nfc*nlev*sizeof(double));
+  double *fpwork1 = (double*) malloc(nlat*nfc*nlev*sizeof(double));
+  double *fpwork2 = (double*) malloc(nlat*nfc*nlev*sizeof(double));
 
   gp2fc(sptrans->trig, sptrans->ifax, gu, fpwork1, nlat, nlon, nlev, nfc);
   gp2fc(sptrans->trig, sptrans->ifax, gv, fpwork2, nlat, nlon, nlev, nfc);
@@ -643,33 +254,25 @@ void trans_dv2uv(SPTRANS *sptrans, DVTRANS *dvtrans, int nlev,
 		 int gridID1, double *sd, double *svo,
 		 int gridID2, double *gu, double *gv)
 {
-  int ntr, nlat, nlon, nfc;
-  int waves;
-  int dimsp;
-  double *fpwork;
-  double *su, *sv;
-
   if ( gridInqType(gridID1) != GRID_SPECTRAL )
     Warning("unexpected grid1 type: %s", gridNamePtr(gridInqType(gridID1)));
 
   if ( gridInqType(gridID2) != GRID_GAUSSIAN )
     Warning("unexpected grid2 type: %s", gridNamePtr(gridInqType(gridID2)));
 
-  ntr  = gridInqTrunc(gridID1);
-  nlon = gridInqXsize(gridID2);
-  nlat = gridInqYsize(gridID2);
-
-  waves = ntr + 1;
-  nfc   = waves * 2;
-
-  dimsp = (ntr + 1)*(ntr + 2);
+  int ntr   = gridInqTrunc(gridID1);
+  int nlon  = gridInqXsize(gridID2);
+  int nlat  = gridInqYsize(gridID2);
+  int waves = ntr + 1;
+  int nfc   = waves * 2;
+  int dimsp = (ntr + 1)*(ntr + 2);
 
-  su = gu;
-  sv = gv;
+  double *su = gu;
+  double *sv = gv;
 
   dv2uv(sd, svo, su, sv, dvtrans->f1, dvtrans->f2, ntr, dimsp, nlev);
 
-  fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
+  double *fpwork = (double*) malloc(nlat*nfc*nlev*sizeof(double));
 
   sp2fc(su, fpwork, sptrans->poli, nlev, nlat, nfc, ntr);
   scaluv(fpwork, sptrans->rcoslat, nlat, nfc*nlev);
diff --git a/src/specspace.h b/src/specspace.h
index 249da57..18e0920 100644
--- a/src/specspace.h
+++ b/src/specspace.h
@@ -1,3 +1,7 @@
+#ifndef _SPECSPACE_H
+#define _SPECSPACE_H
+
+#include "afterburner.h"
 
 typedef struct {
   long nlon;
@@ -49,17 +53,7 @@ void grid2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 void spec2spec(int gridIDin, double *arrayIn, int gridIDout, double *arrayOut);
 void speccut(int gridIDin, double *arrayIn, double *arrayOut, int *waves);
 
-void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nlat, long nfc, long nt);
-void fc2sp(double *fa, double *sa, double *poli, int nlev, int nlat, int nfc, int nt);
-
-void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlon, long nlev, long nfc);
-void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlon, long nlev, long nfc);
-
-void sp2sp(double *arrayIn, int ntrIn, double *arrayOut, int ntrOut);
 void spcut(double *arrayIn, double *arrayOut, int ntr, int *waves);
 
-void phcs(double *pnm, double *hnm, int waves, double pmu,
-	  double *ztemp1, double *ztemp2);
-void jspleg1(double *pleg, double plat, int ntr, double *work);
 
-void fft_set(double *trigs, long *ifax, long n);
+#endif
diff --git a/src/statistic.c b/src/statistic.c
index e966276..ddf0b02 100644
--- a/src/statistic.c
+++ b/src/statistic.c
@@ -10,12 +10,13 @@
 #include <string.h>
 #include <math.h>
 #include <time.h>
+#include "cdo_int.h"
 
 #define  FNORM_PRECISION  1e-12
 #define  MAX_JACOBI_ITER  12
 
 int jacobi_1side(double **M, double *A, long n);
-void annihilate_1side(double **M, long i, long j, long k, long n);
+void annihilate_1side(double **M, long i, long j, long n);
 
 int n_finished;
 
@@ -45,11 +46,9 @@ int max_jacobi_iter;
 #endif
 
 
-void make_symmetric_matrix_triangular (double **a, int n,
-                                       double *d, double *e, const char *prompt);
+void make_symmetric_matrix_triangular (double **a, int n, double *d, double *e);
 double pythagoras (double a, double b);
-void eigen_solution_of_triangular_matrix (double *d, double *e, int n,
-                                          double **a, int n_eig, const char *prompt);
+void eigen_solution_of_triangular_matrix (double *d, double *e, int n, double **a, const char *prompt);
 int lu_decomposition (double **a, int n, int *index, int *sign);
 void lu_backsubstitution (double **a, int n, int *index, double *b);
 
@@ -62,7 +61,7 @@ static double beta_help (double a, double b, double x, const char *prompt);
 
 
 void eigen_solution_of_symmetric_matrix (double **a, double *eig_val,
-					 int n, int n_eig, const char *prompt)
+					 int n, const char *prompt)
 /* After return the rows (!!!) of a are the eigenvectors */
 {
   double *e;
@@ -71,9 +70,9 @@ void eigen_solution_of_symmetric_matrix (double **a, double *eig_val,
   
   e = (double*) malloc(n * sizeof(double));
   
-  make_symmetric_matrix_triangular (a, n, eig_val, e, prompt);
+  make_symmetric_matrix_triangular (a, n, eig_val, e);
   
-  eigen_solution_of_triangular_matrix (eig_val, e, n, a, n_eig, prompt);
+  eigen_solution_of_triangular_matrix (eig_val, e, n, a, prompt);
   
   free (e);
 
@@ -84,6 +83,7 @@ void eigen_solution_of_symmetric_matrix (double **a, double *eig_val,
         a[i][j] = a[j][i];
         a[j][i] = temp;
       }
+  
   heap_sort (eig_val, a, n);
 }
 
@@ -147,15 +147,12 @@ void heap_sort (double *eig_val, double **a, int n)
 }
 
 
-void make_symmetric_matrix_triangular(double **a, int n,
-				      double *d, double *e, const char *prompt)
+void make_symmetric_matrix_triangular(double **a, int n, double *d, double *e)
 {
   int i, j, k;
   double f, g, h, hh, scale;
-  
-  UNUSED(prompt);
-
-  for (i = n - 1; i >= 1; i--)
+ 
+  for ( i = n - 1; i >= 1; i-- )
     {
       h = scale = 0;
       if (i > 1)
@@ -200,52 +197,25 @@ void make_symmetric_matrix_triangular(double **a, int n,
         }
       else
         e[i] = a[i][i - 1];
+
       d[i] = h;
-      /*
-       if (user_asked)
-       {
-       lock ();
-       fprintf (stderr,
-		   "%s: Status: Computing eigen solution pass 1 of 3"
-		   " cycle %ld of %ld.\n",
-		   prompt, (long) (n - i), (long) (n - 1));
-       fflush (stderr);
-       unlock ();
-       user_asked = FALSE;
-       }
-       */
     }
   
   d[0] = e[0] = 0;
-  for (i = 0; i < n; i++)
+  for ( i = 0; i < n; i++ )
     {
       if ( fabs(d[i]) > 0 )
         {
-          for (j = 0; j < i; j++)
+          for ( j = 0; j < i; j++ )
             {
               g = 0;
-              for (k = 0; k < i; k++)
-                g += a[i][k] * a[k][j];
-              for (k = 0; k < i; k++)
-                a[k][j] -= g * a[k][i];
+              for ( k = 0; k < i; k++ )  g += a[i][k] * a[k][j];
+              for ( k = 0; k < i; k++ )  a[k][j] -= g * a[k][i];
             }
         }
       d[i] = a[i][i];
       a[i][i] = 1;
-      for (j = 0; j < i; j++)
-        a[j][i] = a[i][j] = 0;
-      /*
-       if (user_asked)
-       {
-       lock ();
-       fprintf (stderr,
-		   "%s: Status: Computing eigen solution pass 2 of 3"
-		   " cycle %ld of %ld.\n", prompt, (long) (i + 1), (long) n);
-       fflush (stderr);
-       unlock ();
-       user_asked = FALSE;
-       }
-       */
+      for ( j = 0; j < i; j++ ) a[j][i] = a[i][j] = 0;
     }
 }
 
@@ -274,7 +244,7 @@ double pythagoras (double a, double b)
 #define MAX_ITER 1000
 
 void eigen_solution_of_triangular_matrix (double *d, double *e, int n,
-					  double **a, int n_eig, const char *prompt)
+					  double **a, const char *prompt)
 {
   int i, k, l, m, iter;
   double b, c, f, g, p, r, s;
@@ -284,7 +254,7 @@ void eigen_solution_of_triangular_matrix (double *d, double *e, int n,
     e[i - 1] = e[i];
   
   e[n - 1] = 0;
-  for (l = 0; l < n_eig; l++)
+  for (l = 0; l < n; l++)
     {
       iter = 0;
       while (1)
@@ -1260,9 +1230,9 @@ double fisher(double m, double n, double x, const char *prompt)
 /* ******************************************************************************** */
 
 
-void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, int n1, int n2, const char func[])
+void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, int n, const char func[])
 {
-  func = "statistics-module";
+  UNUSED(func);
 
   char *envstr;
   /* Get Environment variables if set */
@@ -1286,16 +1256,8 @@ void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, int n1,
     cdoPrint("Using FNORM_PRECISION %g from %s",
 	     fnorm_precision,envstr?"Environment":"default");
 
-  if ( n1 != n2 )
-    {
-      fprintf(stderr, 
-	      "WARNING: Parallel eigenvalue computation of non-squared matrices\n"
-	      "         Not implemented yet.\n"
-	      "         Using sequential algorithm");                              
-      eigen_solution_of_symmetric_matrix(M,A,n1,n2,func);
-    }
-  else
-    jacobi_1side(M,A,n1);
+  // eigen_solution_of_symmetric_matrix(M, A, n, func);
+  jacobi_1side(M, A, n);
 
   return;
 }
@@ -1308,41 +1270,44 @@ void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, int n1,
 /* changes columns i and j, this can be carried out for n/2 pairs of columns at     */
 /* the same time.                                                                   */
 /* ******************************************************************************** */
-void annihilate_1side(double **M, long i, long j, long k, long n)
+void annihilate_1side(double **M, long i, long j, long n)
 {
 
   double tk, ck, sk, alpha=0, beta=0, gamma=0, zeta=0;
-  double tmp, *mi=NULL, *mj=NULL;
   //  int first_annihilation = 0;
   long r;
 
-  UNUSED(k);
-
   i--; j--;
 
-  mi = (double*) malloc(n*sizeof(double));
-  mj = (double*) malloc(n*sizeof(double));
+  double *restrict mi = (double*) malloc(n*sizeof(double));
+  double *restrict mj = (double*) malloc(n*sizeof(double));
 
   if ( ! mj || ! mi) 
-    fprintf(stderr, 
-	    "ERROR: allocation error - cannot allocate memory\n"
-	    "ERROR: check stacksize and physically available memory\n");
+    fprintf(stderr, "ERROR: allocation error - cannot allocate memory\n"
+	            "ERROR: check stacksize and physically available memory\n");
 
   if ( j < i ) { int tmp = i; i = j; j = tmp; }
   
-  for ( r=0; r<n; r++ ) {
-      alpha += M[j][r]*M[j][r];
-      beta  += M[i][r]*M[i][r];
-      gamma += M[i][r]*M[j][r];
-  }
+  double *restrict Mi = M[i];
+  double *restrict Mj = M[j];
+
+#if defined(HAVE_OPENMP4)
+#pragma omp simd
+#endif
+  for ( r = 0; r < n; r++ )
+    {
+      alpha += Mj[r]*Mj[r];
+      beta  += Mi[r]*Mi[r];
+      gamma += Mi[r]*Mj[r];
+    }
 
   // 2011-08-15 Cedrick Ansorge: bug fix
   //  tmp = fabs(gamma/sqrt(alpha/beta));
-  tmp = fabs(gamma/sqrt(alpha*beta));
+  double tmp = fabs(gamma/sqrt(alpha*beta));
 
   if ( tmp < fnorm_precision ) {
 #if defined(_OPENMP)
-    #pragma omp critical 
+#pragma omp critical 
 #endif
     {
       n_finished++;
@@ -1354,20 +1319,19 @@ void annihilate_1side(double **M, long i, long j, long k, long n)
   
   zeta = (beta-alpha)/(2.*gamma);  // tan(2*theta)
   tk = 1./(fabs(zeta)+sqrt(1.+zeta*zeta)); 
-  tk = zeta>0? tk : -tk;       // = cot(2*theta)
-  ck = 1./sqrt(1.+tk*tk);      // = cos(theta)
-  sk = ck*tk;                  // = sin(theta)
+  tk = zeta>0? tk : -tk;           // = cot(2*theta)
+  ck = 1./sqrt(1.+tk*tk);          // = cos(theta)
+  sk = ck*tk;                      // = sin(theta)
   
   // calculate a_i,j - tilde
-  for ( r=0; r<n; r++ ) {
-    mi[r] =  ck*M[i][r]  + sk*M[j][r];
-    mj[r] = -sk*M[i][r]  + ck*M[j][r];
-  }
-  
-  for ( r=0; r<n; r++ ) {
-    M[i][r] = mi[r];
-    M[j][r] = mj[r];
-  }
+  for ( r = 0; r < n; r++ )
+    {
+      mi[r] =  ck*Mi[r]  + sk*Mj[r];
+      mj[r] = -sk*Mi[r]  + ck*Mj[r];
+    }
+
+  for ( r = 0; r < n; r++ ) Mi[r] = mi[r];
+  for ( r = 0; r < n; r++ ) Mj[r] = mj[r];
 
   free(mi);
   free(mj);
@@ -1431,31 +1395,31 @@ int jacobi_1side(double **M, double *A, long n)
   while ( n_iter < max_jacobi_iter && n_finished < count ) {
     n_finished = 0;
     if ( n%2 == 1 ) {
-      for(m=0;m<n;m++) {
+      for ( m = 0; m < n; m++ ) {
 #if defined(_OPENMP)
-	#pragma omp parallel for private(i,idx,i_ann,j_ann) shared(M,annihilations,n) reduction(+:n_finished)
+#pragma omp parallel for private(i,idx,i_ann,j_ann) shared(M,annihilations,n) reduction(+:n_finished)
 #endif
-        for(i=0;i<n/2;i++) {
+        for ( i = 0; i < n/2; i++) {
           idx = m*(n/2)+i;
 	  i_ann = annihilations[idx][0];
 	  j_ann = annihilations[idx][1];
-          if ( i_ann != j_ann && i_ann && j_ann ) 
-	    annihilate_1side(M,i_ann,j_ann,0,n);
+          if ( i_ann != j_ann && i_ann && j_ann )
+	    annihilate_1side(M, i_ann, j_ann, n);
 	}
       }
     }
     else { // n%2 == 0                                                                               
-      for(m=0;m<n;m++) {
+      for( m = 0; m < n; m++) {
 #if defined(_OPENMP)
-	#pragma omp parallel for private(i,idx,i_ann,j_ann) shared(M,annihilations,n) reduction(+:n_finished)
+#pragma omp parallel for private(i,idx,i_ann,j_ann) shared(M,annihilations,n) reduction(+:n_finished)
 #endif
-        for(i=0;i<n/2-(m%2);i++) {
+        for( i = 0; i < n/2-(m%2); i++) {
 	  idx = m/2 * ( n/2 + n/2-1);
           if ( m % 2 ) idx += n/2;
 	  i_ann = annihilations[idx+i][0];
 	  j_ann = annihilations[idx+i][1];
           if ( i_ann && j_ann && i_ann != j_ann ) 
-	    annihilate_1side(M,i_ann,j_ann,0,n);
+	    annihilate_1side(M, i_ann, j_ann, n);
         }
       }
     }
@@ -1463,7 +1427,7 @@ int jacobi_1side(double **M, double *A, long n)
   }
 
   if ( cdoVerbose ) 
-    cdoPrint("Finished one-sided jacobi scheme for eigenvalue computation after %i iterations",n_iter);
+    cdoPrint("Finished one-sided jacobi scheme for eigenvalue computation after %i iterations", n_iter);
 
   //  fprintf(stderr,"finished after %i sweeps (n_finished %i)\n",n_iter,n_finished);
 
diff --git a/src/statistic.h b/src/statistic.h
index 40752cb..d6fa55e 100644
--- a/src/statistic.h
+++ b/src/statistic.h
@@ -2,7 +2,7 @@
 
 #define _STATISTIC_H
 
-void eigen_solution_of_symmetric_matrix (double **a, double *eig_val, int n, int n_eig, const char *prompt);
+void eigen_solution_of_symmetric_matrix (double **a, double *eig_val, int n, const char *prompt);
 int solution_of_linear_equation (double **a, double *b, int n);
 int inverse_of_matrix (double **a, double **b, int n);
 void fft(double *real, double *imag, int n, int sign);
@@ -32,8 +32,7 @@ double fisher (double m, double n, double x, const char *prompt);
 void heap_sort (double *eig_val, double **a, int n);
 
 // make parallel eigen solution accessible for eigen value computation in EOF3d.c
-void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, 
-						 int n1, int n2, const char func[]);
+void parallel_eigen_solution_of_symmetric_matrix(double **M, double *A, int n, const char func[]);
 
 
 #endif
diff --git a/src/stdnametable.c b/src/stdnametable.c
index 49c937b..4ac54ce 100644
--- a/src/stdnametable.c
+++ b/src/stdnametable.c
@@ -17,6 +17,8 @@ stdnametable_t;
 
 const stdnametable_t stdnametable[] = {
   /* varid                       code    name                standard name                 units */
+  { air_pressure,                   1,  "apres",            "air_pressure",               "Pa" },
+  { pressure_thickness,             2,  "dpress",           "pressure_thickness",         "Pa" },
   { surface_geopotential,         129,  "geosp",            "surface_geopotential",       "m2 s-2" },
   { geopotential,                 129,  "z",                "geopotential",               "m2 s-2" },
   { air_temperature,              130,  "ta",               "air_temperature",            "K" },
diff --git a/src/stdnametable.h b/src/stdnametable.h
index f5472b0..831c1e4 100644
--- a/src/stdnametable.h
+++ b/src/stdnametable.h
@@ -1,7 +1,9 @@
 #ifndef _STDNAMETABLE_H
 #define _STDNAMETABLE_H
 
-enum stdnameid {surface_geopotential,
+enum stdnameid {air_pressure,
+		pressure_thickness,
+                surface_geopotential,
 		geopotential,
 		air_temperature,
                 specific_humidity,
diff --git a/src/table.c b/src/table.c
index bf9e215..f7bef07 100644
--- a/src/table.c
+++ b/src/table.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/timer.c b/src/timer.c
index 45aba4c..2d82828 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/util.c b/src/util.c
index 01d5671..f29d70c 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -19,10 +19,19 @@
 #define _XOPEN_SOURCE 600 /* ftello */
 #endif
 
+#if defined(HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
 #if defined(_OPENMP)
 #  include <omp.h>
 #endif
 
+#if defined(HAVE_FNMATCH_H)
+#include <fnmatch.h>
+#endif
+
+
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>   /* tolower */
@@ -34,6 +43,108 @@
 #include "util.h"
 
 
+#if ! defined(VERSION)
+#  define  VERSION  "0.0.1"
+#endif
+ 
+
+/* refactor: moved here from *.c */
+
+int CDO_opterr = 0;      // refactor: moved here from cdo_getopt.c
+char *CDO_optarg = NULL; // refactor: moved here from cdo_getopt.c
+int CDO_optind = 1;      // refactor: moved here from cdo_getopt.c
+int remap_genweights = TRUE;  // refactor: moved here from Remap.c
+
+
+/* refactor: moved here from cdo.c */
+
+char *Progname;
+char CDO_Version[] = "Climate Data Operators version "VERSION" (http://mpimet.mpg.de/cdo)"; // refactor: moved here from cdo.c
+
+int ompNumThreads = 1;
+
+int stdin_is_tty  = 0;
+int stdout_is_tty = 0;
+int stderr_is_tty = 0;
+
+char* cdoGridSearchDir   = NULL;
+
+int cdoDefaultFileType   = CDI_UNDEFID;
+int cdoDefaultDataType   = CDI_UNDEFID;
+int cdoDefaultByteorder  = CDI_UNDEFID;
+int cdoDefaultTableID    = CDI_UNDEFID;
+int cdoDefaultInstID     = CDI_UNDEFID;     // moved here from institution.c, was UNDEFID
+int cdoDefaultTimeType   = CDI_UNDEFID;
+
+int cdoLockIO            = FALSE;
+int cdoCheckDatarange    = FALSE;
+
+int CDO_Color            = FALSE;
+int CDO_Use_FFTW         = TRUE;
+int cdoDiag              = FALSE;
+
+int CDO_Reduce_Dim       = FALSE;
+int CDO_Append_History   = TRUE;
+int CDO_Reset_History    = FALSE;
+
+int cdoCompType          = COMPRESS_NONE;  // compression type
+int cdoCompLevel         = 0;              // compression level
+int cdoDebug             = 0;
+int cdoChunkType         = CDI_UNDEFID;
+int cdoLogOff            = FALSE;
+int cdoSilentMode        = FALSE;
+int cdoOverwriteMode     = FALSE;
+int cdoBenchmark         = FALSE;
+int cdoTimer             = FALSE;
+int cdoVerbose           = FALSE;
+int cdoCompress          = FALSE;
+int cdoInteractive       = FALSE;
+int cdoParIO             = FALSE;
+int cdoRegulargrid       = FALSE;
+
+int cdoNumVarnames       = 0;
+char **cdoVarnames       = NULL;
+
+char CDO_File_Suffix[32];
+
+int cdoExpMode           = -1;
+char *cdoExpName         = NULL;
+
+int timer_read, timer_write;
+
+
+#if defined(HAVE_FNMATCH_H)
+int wildcardmatch(const char *pattern, const char *string)
+{
+  return fnmatch(pattern, string, 0);
+}
+#else
+// The wildcardmatch function checks if two given strings match. 
+// The first string may contain wildcard characters
+// * --> Matches with 0 or more instances of any character or set of characters.
+// ? --> Matches with any one character.
+// source code from http://www.geeksforgeeks.org/wildcard-character-matching/
+int wildcardmatch(const char *w, const char *s)
+{
+    // If we reach at the end of both strings, we are done
+    if ( *w == '\0' && *s == '\0' ) return 0;
+ 
+    // Make sure that the characters after '*' are present in second string.
+    // This function assumes that the first string will not contain two consecutive '*'
+    if ( *w == '*' && *(w+1) != '\0' && *s == '\0' ) return 1;
+ 
+    // If the first string contains '?', or current characters of both strings match
+    if ( (*w == '?' && *s != '\0') || *w == *s ) return wildcardmatch(w+1, s+1);
+ 
+    // If there is *, then there are two possibilities
+    // a) We consider current character of second string
+    // b) We ignore current character of second string.
+    if ( *w == '*' ) return wildcardmatch(w+1, s) || wildcardmatch(w, s+1);
+
+    return 1;
+}
+#endif
+
 int cdo_omp_get_thread_num(void)
 {
   int threadnum = 0;
@@ -95,9 +206,9 @@ char *getOperatorName(const char *operatorArg)
       commapos = strchr(operatorArg, ',');
 
       if ( commapos )
-	len = commapos - operatorArg;
+        len = commapos - operatorArg;
       else
-	len = strlen(operatorArg);
+        len = strlen(operatorArg);
 
       operatorName = (char*) malloc(len+1);
 
@@ -130,10 +241,10 @@ void file_argument_free(argument_t *argument)
   if ( argument )
     {
       if ( argument->argc )
-	{
-	  assert(argument->argc == 1);
-	  free(argument->argv);
-	}
+        {
+          assert(argument->argc == 1);
+          free(argument->argv);
+        }
       free(argument);
     }
 }
@@ -163,27 +274,27 @@ void argument_free(argument_t *argument)
   if ( argument )
     {
       if ( argument->argc )
-	{
-	  int argc =  argument->argc;
-	  for ( int i = 0; i < argc; ++i )
-	    {
-	      if ( argument->argv[i] )
-		{
-		  free(argument->argv[i]);
-		  argument->argv[i] = NULL;
-		}
-	    }
-
-	  free(argument->argv);
-	  argument->argv = NULL;
-	  argument->argc = 0;
-	}
+        {
+          int argc =  argument->argc;
+          for ( int i = 0; i < argc; ++i )
+            {
+              if ( argument->argv[i] )
+                {
+                  free(argument->argv[i]);
+                  argument->argv[i] = NULL;
+                }
+            }
+
+          free(argument->argv);
+          argument->argv = NULL;
+          argument->argc = 0;
+        }
 
       if ( argument->args )
-	{
-	  free(argument->args);
-	  argument->args = NULL;
-	}
+        {
+          free(argument->args);
+          argument->args = NULL;
+        }
 
       free(argument);
     }
@@ -213,12 +324,12 @@ char *getFileArg(char *argument)
       blankpos = strchr(argument, ' ');
 
       if ( blankpos )
-	{
-	  parg = blankpos + 1;
-	  len = strlen(parg);
-	  fileArg = (char*) malloc(len+1);
-	  strcpy(fileArg, parg);
-	}
+        {
+          parg = blankpos + 1;
+          len = strlen(parg);
+          fileArg = (char*) malloc(len+1);
+          strcpy(fileArg, parg);
+        }
     }
 
   return (fileArg);
@@ -246,11 +357,53 @@ void strtolower(char *str)
     {
       len = (int) strlen(str);
       for ( i = 0; i < len; i++ )
-	str[i] = tolower((int) str[i]);
+        str[i] = tolower((int) str[i]);
     }
 }
 
 
+double parameter2double(const char *string)
+{
+  char *endptr = NULL;
+
+  double fval = strtod(string, &endptr);
+
+  if ( *endptr != 0 )
+    cdoAbort("Float parameter >%s< contains invalid character at position %d!",
+	     string, (int)(endptr-string+1));
+
+  return (fval);
+}
+
+
+int parameter2int(const char *string)
+{
+  char *endptr = NULL;
+
+  int ival = (int) strtol(string, &endptr, 10);
+
+  if ( *endptr != 0 )
+    cdoAbort("Integer parameter >%s< contains invalid character at position %d!",
+	     string, (int)(endptr-string+1));
+
+  return (ival);
+}
+
+
+int parameter2intlist(const char *string)
+{
+  char *endptr = NULL;
+
+  int ival = (int) strtol(string, &endptr, 10);
+
+  if ( *endptr != 0 && *endptr != '/' && (endptr - string) == 0 )
+    cdoAbort("Integer parameter >%s< contains invalid character at position %d!",
+	     string, (int)(endptr-string+1));
+
+  return (ival);
+}
+
+
 const char *seas_name_dec[4] = {"DJF", "MAM", "JJA", "SON"};
 const char *seas_name_jan[4] = {"JFM", "AMJ", "JAS", "OND"};
 
@@ -266,12 +419,12 @@ int get_season_start(void)
       else if ( strcmp(envstr, "JAN") == 0 ) season_start = START_JAN;
       
       if ( cdoVerbose )
-	{
-	  if      ( season_start == START_DEC )
-	    cdoPrint("Set SEASON_START to December");
-	  else if ( season_start == START_JAN )
-	    cdoPrint("Set SEASON_START to January");
-	}
+        {
+          if      ( season_start == START_DEC )
+            cdoPrint("Set SEASON_START to December");
+          else if ( season_start == START_JAN )
+            cdoPrint("Set SEASON_START to January");
+        }
     }
 
   return (season_start);
@@ -320,9 +473,9 @@ int userFileOverwrite(const char *filename)
   if ( len == 3 )
     {
       if ( pline[0] == 'y' && pline[1] == 'e' && pline[2] == 's' )
-	status = 1;
+        status = 1;
       else if ( pline[0] == 'Y' && pline[1] == 'E' && pline[2] == 'S' )
-	status = 1;
+        status = 1;
     }
   else if ( len == 1 )
     {
@@ -416,21 +569,21 @@ int str2datatype(const char *datatypestr)
   if ( len > 1 )
     {
       int ilen = atoi(datatypestr+1);
-      if      ( memcmp(datatypestr, "P0",  len) == 0 ) datatype = DATATYPE_PACK;
-      else if ( memcmp(datatypestr, "P",     1) == 0 &&
-		ilen > 0 && ilen <= 32 )               datatype = atoi(datatypestr+1);
-      else if ( memcmp(datatypestr, "C32", len) == 0 ) datatype = DATATYPE_CPX32;
-      else if ( memcmp(datatypestr, "C64", len) == 0 ) datatype = DATATYPE_CPX64;
-      else if ( memcmp(datatypestr, "F32", len) == 0 ) datatype = DATATYPE_FLT32;
-      else if ( memcmp(datatypestr, "F64", len) == 0 ) datatype = DATATYPE_FLT64;
-      else if ( memcmp(datatypestr, "I8",  len) == 0 ) datatype = DATATYPE_INT8;
-      else if ( memcmp(datatypestr, "I16", len) == 0 ) datatype = DATATYPE_INT16;
-      else if ( memcmp(datatypestr, "I32", len) == 0 ) datatype = DATATYPE_INT32;
-      else if ( memcmp(datatypestr, "U8",  len) == 0 ) datatype = DATATYPE_UINT8;
-      else if ( memcmp(datatypestr, "U16", len) == 0 ) datatype = DATATYPE_UINT16;
-      else if ( memcmp(datatypestr, "U32", len) == 0 ) datatype = DATATYPE_UINT32;
-      else if ( memcmp(datatypestr, "real",   len) == 0 ) datatype = DATATYPE_FLT32;
-      else if ( memcmp(datatypestr, "double", len) == 0 ) datatype = DATATYPE_FLT64;
+      if      ( strncmp(datatypestr, "P0",  len) == 0 ) datatype = DATATYPE_PACK;
+      else if ( strncmp(datatypestr, "P",     1) == 0 &&
+                ilen > 0 && ilen <= 32 )               datatype = atoi(datatypestr+1);
+      else if ( strncmp(datatypestr, "C32", len) == 0 ) datatype = DATATYPE_CPX32;
+      else if ( strncmp(datatypestr, "C64", len) == 0 ) datatype = DATATYPE_CPX64;
+      else if ( strncmp(datatypestr, "F32", len) == 0 ) datatype = DATATYPE_FLT32;
+      else if ( strncmp(datatypestr, "F64", len) == 0 ) datatype = DATATYPE_FLT64;
+      else if ( strncmp(datatypestr, "I8",  len) == 0 ) datatype = DATATYPE_INT8;
+      else if ( strncmp(datatypestr, "I16", len) == 0 ) datatype = DATATYPE_INT16;
+      else if ( strncmp(datatypestr, "I32", len) == 0 ) datatype = DATATYPE_INT32;
+      else if ( strncmp(datatypestr, "U8",  len) == 0 ) datatype = DATATYPE_UINT8;
+      else if ( strncmp(datatypestr, "U16", len) == 0 ) datatype = DATATYPE_UINT16;
+      else if ( strncmp(datatypestr, "U32", len) == 0 ) datatype = DATATYPE_UINT32;
+      else if ( strncmp(datatypestr, "real",   len) == 0 ) datatype = DATATYPE_FLT32;
+      else if ( strncmp(datatypestr, "double", len) == 0 ) datatype = DATATYPE_FLT64;
     }
 
   return (datatype);
@@ -449,14 +602,14 @@ off_t filesize(const char *filename)
     {
       fp = fopen(filename, "r");
       if ( fp == NULL )
-	{
-	  fprintf(stderr, "Open failed on %s\n", filename);
-	}
+        {
+          fprintf(stderr, "Open failed on %s\n", filename);
+        }
       else
-	{
-	  fseek(fp, 0L, SEEK_END);
-	  pos = ftello(fp);
-	}
+        {
+          fseek(fp, 0L, SEEK_END);
+          pos = ftello(fp);
+        }
     }
   
   return pos;
@@ -520,3 +673,88 @@ void repl_filetypeext(char file[], const char *oldext, const char *newext)
   // add new file extension
   strcat(file, newext);
 }
+
+
+void cdoGenFileSuffix(char *filesuffix, size_t maxlen, int filetype, int vlistID, const char *refname)
+{
+  if ( strncmp(CDO_File_Suffix, "NULL", 4) != 0 )
+    {
+      if ( CDO_File_Suffix[0] != 0 )
+        {
+          strncat(filesuffix, CDO_File_Suffix, maxlen-1);
+        }
+      else
+        {
+          int lready = FALSE;
+          int lcompsz = FALSE;
+          
+          if ( filetype == cdoDefaultFileType && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
+            {
+              size_t len = 0;
+              if ( refname != NULL && *refname != 0 && *refname != '-' && *refname != '.' ) len = strlen(refname);
+
+              if ( len > 2 )
+                {
+                  char *result = strrchr(refname, '.');
+                  if ( result != NULL && result[1] != 0 )
+                    {
+                      int firstchar = tolower(result[1]);
+                      switch (firstchar)
+                        {
+                        case 'g':
+                          if ( cdoDefaultFileType == FILETYPE_GRB || cdoDefaultFileType == FILETYPE_GRB2 ) lready = TRUE;
+                          break;
+                        case 'n':
+                          if ( cdoDefaultFileType == FILETYPE_NC || cdoDefaultFileType == FILETYPE_NC2 ||
+                               cdoDefaultFileType == FILETYPE_NC4 || cdoDefaultFileType == FILETYPE_NC4C ) lready = TRUE;
+                          break;
+                        case 's':
+                          if ( cdoDefaultFileType == FILETYPE_SRV ) lready = TRUE;
+                          break;
+                        case 'e':
+                          if ( cdoDefaultFileType == FILETYPE_EXT ) lready = TRUE;
+                          break;
+                        case 'i':
+                          if ( cdoDefaultFileType == FILETYPE_IEG ) lready = TRUE;
+                          break;
+                        }
+                    }
+
+                  //if ( lready )  strncat(filesuffix, result, maxlen-1);
+		  if ( lready && ((len=strlen(result)) < (maxlen-1)) )
+		    {
+		      while ( len-- )
+			{
+			  if ( *result == '.' || isalnum(*result) ) 
+			    strncat(filesuffix, result, 1);
+			  result++;
+			}
+		    }
+                }
+            }
+
+          if ( !lready )
+            {
+              strncat(filesuffix, streamFilesuffix(cdoDefaultFileType), maxlen-1);
+              if ( cdoDefaultFileType == FILETYPE_GRB && vlistIsSzipped(vlistID) ) lcompsz = TRUE;
+            }
+
+          if ( cdoDefaultFileType == FILETYPE_GRB && cdoCompType == COMPRESS_SZIP ) lcompsz = TRUE;
+          if ( lcompsz ) strncat(filesuffix, ".sz", maxlen-1);
+        }
+    }
+}
+
+
+int cdoFiletype(void)
+{
+  if ( cdoDefaultFileType == CDI_UNDEFID )
+    {
+      cdoDefaultFileType = FILETYPE_GRB;
+      if ( ! cdoSilentMode )
+        cdoPrint("Set default filetype to GRIB");
+    }
+
+  return (cdoDefaultFileType);
+}
+
diff --git a/src/util.h b/src/util.h
index 868c5ab..8794c04 100644
--- a/src/util.h
+++ b/src/util.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -18,6 +18,85 @@
 #ifndef _UTIL_H
 #define _UTIL_H
 
+
+/* dummy use of unused parameters to silence compiler warnings */
+#define  UNUSED(x) (void)x
+
+#undef   TRUE
+#define  TRUE   1
+#undef   FALSE
+#define  FALSE  0
+
+#undef   MIN
+#define  MIN(a,b)  ((a) < (b) ? (a) : (b))
+#undef   MAX
+#define  MAX(a,b)  ((a) > (b) ? (a) : (b))
+
+#define  ADD_PLURAL(n)  ((n)>1 ? "s" : "")
+
+#define  UNCHANGED_RECORD  (processSelf() == 0 && cdoStreamName(0)->argv[0][0] != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
+
+extern char *Progname;
+extern char *cdoGridSearchDir;
+extern int CDO_Reduce_Dim;
+extern int CDO_Append_History;
+extern int CDO_Reset_History;
+extern int timer_read, timer_write; // refactor: both pstream.c and CDIread.c CDIwrite.c defined in cdo.c
+
+extern int   CDO_optind;
+extern char *CDO_optarg;
+extern int CDO_opterr;
+extern int remap_genweights;
+
+extern char *cdoExpName;
+extern int ompNumThreads;
+
+extern int stdin_is_tty;
+extern int stdout_is_tty;
+extern int stderr_is_tty;
+
+extern int cdoDefaultFileType;
+extern int cdoDefaultDataType;
+extern int cdoDefaultByteorder;
+extern int cdoDefaultTableID;
+extern int cdoDefaultInstID;
+extern int cdoDefaultTimeType;
+extern int cdoLogOff;
+
+extern int cdoLockIO;
+extern int cdoCheckDatarange;
+
+extern int cdoSilentMode;
+extern int cdoOverwriteMode;
+extern int cdoRegulargrid;
+extern int cdoBenchmark;
+extern int cdoTimer;
+extern int cdoVerbose;
+extern int cdoDebug;
+extern int cdoCompress;
+extern int cdoInteractive;
+extern int cdoParIO;
+
+extern int cdoCompType;
+extern int cdoCompLevel;
+
+extern int cdoChunkType;
+
+extern int cdoExpMode;
+
+extern int CDO_Color;
+extern int CDO_Use_FFTW;
+extern int cdoDiag;
+
+extern int cdoNumVarnames;
+extern char **cdoVarnames;
+extern char CDO_File_Suffix[32]; // refactor: added keyword extern
+
+
+/* moved here from *.c */
+extern char CDO_Version[]; // refactor: moved here from pstream.c
+
+
 typedef struct {
   int    argc;
   int    argl;
@@ -102,6 +181,8 @@ int     cdoDefineZaxis(const char *zaxisfile);
 
 int     vlistInqNWPV(int vlistID, int varID);
 int     vlistIsSzipped(int vlistID);
+int     vlist_check_gridsize(int vlistID);
+
 
 void cdoGenFileSuffix(char *filesuffix, size_t maxlen, int filetype, int vlistID, const char *refname);
 
@@ -112,4 +193,15 @@ void cdiDefTableID(int tableID);
 int gridFromName(const char *gridname);
 int zaxisFromName(const char *zaxisname);
 
+/* refactor: moved here from cdo.h */
+int cdo_omp_get_thread_num(void);
+void strtolower(char *str);
+
+/* refactor: moved here from cdo.c */
+void exp_run(int argc, char *argv[], char *cdoExpName); // job.c
+void printFeatures(void); // features.c
+void printLibraries(void);  // features.c  
+
+int wildcardmatch(const char *w, const char *s);
+
 #endif  /* _UTIL_H */
diff --git a/src/vct_l191.h b/src/vct_l191.h
new file mode 100644
index 0000000..6a46580
--- /dev/null
+++ b/src/vct_l191.h
@@ -0,0 +1,388 @@
+const
+double VCT_L191[] = {
+   /*     0  */  0.0000000E+00,
+   /*     1  */  0.1989182E+01,
+   /*     2  */  0.3978941E+01,
+   /*     3  */  0.5969277E+01,
+   /*     4  */  0.7960190E+01,
+   /*     5  */  0.9951681E+01,
+   /*     6  */  0.1194375E+02,
+   /*     7  */  0.1393640E+02,
+   /*     8  */  0.1592962E+02,
+   /*     9  */  0.1792342E+02,
+   /*    10  */  0.1991780E+02,
+   /*    11  */  0.2169803E+02,
+   /*    12  */  0.2346212E+02,
+   /*    13  */  0.2522733E+02,
+   /*    14  */  0.2700198E+02,
+   /*    15  */  0.2879443E+02,
+   /*    16  */  0.3061303E+02,
+   /*    17  */  0.3246615E+02,
+   /*    18  */  0.3436218E+02,
+   /*    19  */  0.3630951E+02,
+   /*    20  */  0.3831656E+02,
+   /*    21  */  0.4040030E+02,
+   /*    22  */  0.4255329E+02,
+   /*    23  */  0.4477730E+02,
+   /*    24  */  0.4707262E+02,
+   /*    25  */  0.4945101E+02,
+   /*    26  */  0.5192537E+02,
+   /*    27  */  0.5450990E+02,
+   /*    28  */  0.5722043E+02,
+   /*    29  */  0.6006341E+02,
+   /*    30  */  0.6304558E+02,
+   /*    31  */  0.6617471E+02,
+   /*    32  */  0.6945839E+02,
+   /*    33  */  0.7290482E+02,
+   /*    34  */  0.7652187E+02,
+   /*    35  */  0.8031786E+02,
+   /*    36  */  0.8430153E+02,
+   /*    37  */  0.8848209E+02,
+   /*    38  */  0.9286930E+02,
+   /*    39  */  0.9747336E+02,
+   /*    40  */  0.1023051E+03,
+   /*    41  */  0.1073764E+03,
+   /*    42  */  0.1126994E+03,
+   /*    43  */  0.1182874E+03,
+   /*    44  */  0.1241543E+03,
+   /*    45  */  0.1303102E+03,
+   /*    46  */  0.1367707E+03,
+   /*    47  */  0.1435521E+03,
+   /*    48  */  0.1506724E+03,
+   /*    49  */  0.1581446E+03,
+   /*    50  */  0.1659855E+03,
+   /*    51  */  0.1742163E+03,
+   /*    52  */  0.1828540E+03,
+   /*    53  */  0.1919227E+03,
+   /*    54  */  0.2014427E+03,
+   /*    55  */  0.2114318E+03,
+   /*    56  */  0.2219189E+03,
+   /*    57  */  0.2329250E+03,
+   /*    58  */  0.2444784E+03,
+   /*    59  */  0.2566022E+03,
+   /*    60  */  0.2693276E+03,
+   /*    61  */  0.2826821E+03,
+   /*    62  */  0.2967018E+03,
+   /*    63  */  0.3114205E+03,
+   /*    64  */  0.3268631E+03,
+   /*    65  */  0.3430727E+03,
+   /*    66  */  0.3600884E+03,
+   /*    67  */  0.3779500E+03,
+   /*    68  */  0.3966980E+03,
+   /*    69  */  0.4163636E+03,
+   /*    70  */  0.4370087E+03,
+   /*    71  */  0.4586880E+03,
+   /*    72  */  0.4814459E+03,
+   /*    73  */  0.5053349E+03,
+   /*    74  */  0.5304061E+03,
+   /*    75  */  0.5567164E+03,
+   /*    76  */  0.5843365E+03,
+   /*    77  */  0.6133445E+03,
+   /*    78  */  0.6437992E+03,
+   /*    79  */  0.6757712E+03,
+   /*    80  */  0.7093336E+03,
+   /*    81  */  0.7445564E+03,
+   /*    82  */  0.7815272E+03,
+   /*    83  */  0.8203336E+03,
+   /*    84  */  0.8610668E+03,
+   /*    85  */  0.9038228E+03,
+   /*    86  */  0.9487021E+03,
+   /*    87  */  0.9958097E+03,
+   /*    88  */  0.1045256E+04,
+   /*    89  */  0.1097158E+04,
+   /*    90  */  0.1151637E+04,
+   /*    91  */  0.1208822E+04,
+   /*    92  */  0.1268845E+04,
+   /*    93  */  0.1331849E+04,
+   /*    94  */  0.1397981E+04,
+   /*    95  */  0.1467398E+04,
+   /*    96  */  0.1540261E+04,
+   /*    97  */  0.1616741E+04,
+   /*    98  */  0.1697019E+04,
+   /*    99  */  0.1781285E+04,
+   /*   100  */  0.1869734E+04,
+   /*   101  */  0.1962575E+04,
+   /*   102  */  0.2060026E+04,
+   /*   103  */  0.2162316E+04,
+   /*   104  */  0.2269685E+04,
+   /*   105  */  0.2382386E+04,
+   /*   106  */  0.2500682E+04,
+   /*   107  */  0.2624852E+04,
+   /*   108  */  0.2755189E+04,
+   /*   109  */  0.2891997E+04,
+   /*   110  */  0.3035597E+04,
+   /*   111  */  0.3186328E+04,
+   /*   112  */  0.3344622E+04,
+   /*   113  */  0.3510779E+04,
+   /*   114  */  0.3685152E+04,
+   /*   115  */  0.3868165E+04,
+   /*   116  */  0.4060295E+04,
+   /*   117  */  0.4261875E+04,
+   /*   118  */  0.4473389E+04,
+   /*   119  */  0.4695541E+04,
+   /*   120  */  0.4928601E+04,
+   /*   121  */  0.5173514E+04,
+   /*   122  */  0.5430807E+04,
+   /*   123  */  0.5700842E+04,
+   /*   124  */  0.5984263E+04,
+   /*   125  */  0.6281830E+04,
+   /*   126  */  0.6593892E+04,
+   /*   127  */  0.6921389E+04,
+   /*   128  */  0.7265031E+04,
+   /*   129  */  0.7624853E+04,
+   /*   130  */  0.8001610E+04,
+   /*   131  */  0.8396169E+04,
+   /*   132  */  0.8808917E+04,
+   /*   133  */  0.9240285E+04,
+   /*   134  */  0.9689937E+04,
+   /*   135  */  0.1015810E+05,
+   /*   136  */  0.1064388E+05,
+   /*   137  */  0.1114578E+05,
+   /*   138  */  0.1166126E+05,
+   /*   139  */  0.1218736E+05,
+   /*   140  */  0.1272024E+05,
+   /*   141  */  0.1325880E+05,
+   /*   142  */  0.1380106E+05,
+   /*   143  */  0.1434555E+05,
+   /*   144  */  0.1488822E+05,
+   /*   145  */  0.1542401E+05,
+   /*   146  */  0.1594836E+05,
+   /*   147  */  0.1645946E+05,
+   /*   148  */  0.1695481E+05,
+   /*   149  */  0.1743284E+05,
+   /*   150  */  0.1788861E+05,
+   /*   151  */  0.1831755E+05,
+   /*   152  */  0.1871637E+05,
+   /*   153  */  0.1908261E+05,
+   /*   154  */  0.1941345E+05,
+   /*   155  */  0.1970464E+05,
+   /*   156  */  0.1995197E+05,
+   /*   157  */  0.2015255E+05,
+   /*   158  */  0.2030349E+05,
+   /*   159  */  0.2040116E+05,
+   /*   160  */  0.2044152E+05,
+   /*   161  */  0.2042110E+05,
+   /*   162  */  0.2033644E+05,
+   /*   163  */  0.2018368E+05,
+   /*   164  */  0.1995849E+05,
+   /*   165  */  0.1965700E+05,
+   /*   166  */  0.1927563E+05,
+   /*   167  */  0.1881073E+05,
+   /*   168  */  0.1825982E+05,
+   /*   169  */  0.1761487E+05,
+   /*   170  */  0.1687312E+05,
+   /*   171  */  0.1603171E+05,
+   /*   172  */  0.1508720E+05,
+   /*   173  */  0.1403435E+05,
+   /*   174  */  0.1286901E+05,
+   /*   175  */  0.1159188E+05,
+   /*   176  */  0.1019584E+05,
+   /*   177  */  0.8788987E+04,
+   /*   178  */  0.7438805E+04,
+   /*   179  */  0.6144316E+04,
+   /*   180  */  0.4941777E+04,
+   /*   181  */  0.3850913E+04,
+   /*   182  */  0.2887697E+04,
+   /*   183  */  0.2063780E+04,
+   /*   184  */  0.1385913E+04,
+   /*   185  */  0.8553618E+03,
+   /*   186  */  0.4673335E+03,
+   /*   187  */  0.2103939E+03,
+   /*   188  */  0.6588920E+02,
+   /*   189  */  0.7367700E+01,
+   /*   190  */  0.0000000E+00,
+   /*   191  */  0.0000000E+00,
+
+   /*     0  */  0.0000000E+00,
+   /*     1  */  0.0000000E+00,
+   /*     2  */  0.0000000E+00,
+   /*     3  */  0.0000000E+00,
+   /*     4  */  0.0000000E+00,
+   /*     5  */  0.0000000E+00,
+   /*     6  */  0.0000000E+00,
+   /*     7  */  0.0000000E+00,
+   /*     8  */  0.0000000E+00,
+   /*     9  */  0.0000000E+00,
+   /*    10  */  0.0000000E+00,
+   /*    11  */  0.0000000E+00,
+   /*    12  */  0.0000000E+00,
+   /*    13  */  0.0000000E+00,
+   /*    14  */  0.0000000E+00,
+   /*    15  */  0.0000000E+00,
+   /*    16  */  0.0000000E+00,
+   /*    17  */  0.0000000E+00,
+   /*    18  */  0.0000000E+00,
+   /*    19  */  0.0000000E+00,
+   /*    20  */  0.0000000E+00,
+   /*    21  */  0.0000000E+00,
+   /*    22  */  0.0000000E+00,
+   /*    23  */  0.0000000E+00,
+   /*    24  */  0.0000000E+00,
+   /*    25  */  0.0000000E+00,
+   /*    26  */  0.0000000E+00,
+   /*    27  */  0.0000000E+00,
+   /*    28  */  0.0000000E+00,
+   /*    29  */  0.0000000E+00,
+   /*    30  */  0.0000000E+00,
+   /*    31  */  0.0000000E+00,
+   /*    32  */  0.0000000E+00,
+   /*    33  */  0.0000000E+00,
+   /*    34  */  0.0000000E+00,
+   /*    35  */  0.0000000E+00,
+   /*    36  */  0.0000000E+00,
+   /*    37  */  0.0000000E+00,
+   /*    38  */  0.0000000E+00,
+   /*    39  */  0.0000000E+00,
+   /*    40  */  0.0000000E+00,
+   /*    41  */  0.0000000E+00,
+   /*    42  */  0.0000000E+00,
+   /*    43  */  0.0000000E+00,
+   /*    44  */  0.0000000E+00,
+   /*    45  */  0.0000000E+00,
+   /*    46  */  0.0000000E+00,
+   /*    47  */  0.0000000E+00,
+   /*    48  */  0.0000000E+00,
+   /*    49  */  0.0000000E+00,
+   /*    50  */  0.0000000E+00,
+   /*    51  */  0.0000000E+00,
+   /*    52  */  0.0000000E+00,
+   /*    53  */  0.0000000E+00,
+   /*    54  */  0.0000000E+00,
+   /*    55  */  0.0000000E+00,
+   /*    56  */  0.0000000E+00,
+   /*    57  */  0.0000000E+00,
+   /*    58  */  0.0000000E+00,
+   /*    59  */  0.0000000E+00,
+   /*    60  */  0.0000000E+00,
+   /*    61  */  0.0000000E+00,
+   /*    62  */  0.0000000E+00,
+   /*    63  */  0.0000000E+00,
+   /*    64  */  0.0000000E+00,
+   /*    65  */  0.0000000E+00,
+   /*    66  */  0.0000000E+00,
+   /*    67  */  0.0000000E+00,
+   /*    68  */  0.0000000E+00,
+   /*    69  */  0.0000000E+00,
+   /*    70  */  0.0000000E+00,
+   /*    71  */  0.0000000E+00,
+   /*    72  */  0.0000000E+00,
+   /*    73  */  0.0000000E+00,
+   /*    74  */  0.0000000E+00,
+   /*    75  */  0.0000000E+00,
+   /*    76  */  0.0000000E+00,
+   /*    77  */  0.0000000E+00,
+   /*    78  */  0.0000000E+00,
+   /*    79  */  0.0000000E+00,
+   /*    80  */  0.0000000E+00,
+   /*    81  */  0.0000000E+00,
+   /*    82  */  0.0000000E+00,
+   /*    83  */  0.0000000E+00,
+   /*    84  */  0.0000000E+00,
+   /*    85  */  0.0000000E+00,
+   /*    86  */  0.0000000E+00,
+   /*    87  */  0.0000000E+00,
+   /*    88  */  0.0000000E+00,
+   /*    89  */  0.0000000E+00,
+   /*    90  */  0.0000000E+00,
+   /*    91  */  0.0000000E+00,
+   /*    92  */  0.0000000E+00,
+   /*    93  */  0.0000000E+00,
+   /*    94  */  0.0000000E+00,
+   /*    95  */  0.0000000E+00,
+   /*    96  */  0.0000000E+00,
+   /*    97  */  0.0000000E+00,
+   /*    98  */  0.0000000E+00,
+   /*    99  */  0.0000000E+00,
+   /*   100  */  0.0000000E+00,
+   /*   101  */  0.0000000E+00,
+   /*   102  */  0.0000000E+00,
+   /*   103  */  0.0000000E+00,
+   /*   104  */  0.0000000E+00,
+   /*   105  */  0.0000000E+00,
+   /*   106  */  0.0000000E+00,
+   /*   107  */  0.0000000E+00,
+   /*   108  */  0.0000000E+00,
+   /*   109  */  0.0000000E+00,
+   /*   110  */  0.0000000E+00,
+   /*   111  */  0.0000000E+00,
+   /*   112  */  0.0000000E+00,
+   /*   113  */  0.0000000E+00,
+   /*   114  */  0.0000000E+00,
+   /*   115  */  0.0000000E+00,
+   /*   116  */  0.0000000E+00,
+   /*   117  */  0.0000000E+00,
+   /*   118  */  0.0000000E+00,
+   /*   119  */  0.0000000E+00,
+   /*   120  */  0.0000000E+00,
+   /*   121  */  0.7804972E-06,
+   /*   122  */  0.1167083E-05,
+   /*   123  */  0.9855922E-06,
+   /*   124  */  0.1377863E-06,
+   /*   125  */  0.0000000E+00,
+   /*   126  */  0.0000000E+00,
+   /*   127  */  0.0000000E+00,
+   /*   128  */  0.0000000E+00,
+   /*   129  */  0.1054137E-04,
+   /*   130  */  0.3000794E-04,
+   /*   131  */  0.6023544E-04,
+   /*   132  */  0.1054117E-03,
+   /*   133  */  0.1708793E-03,
+   /*   134  */  0.2687827E-03,
+   /*   135  */  0.4137881E-03,
+   /*   136  */  0.6199548E-03,
+   /*   137  */  0.9161179E-03,
+   /*   138  */  0.1342796E-02,
+   /*   139  */  0.1943264E-02,
+   /*   140  */  0.2764098E-02,
+   /*   141  */  0.3827799E-02,
+   /*   142  */  0.5169721E-02,
+   /*   143  */  0.6821727E-02,
+   /*   144  */  0.8854456E-02,
+   /*   145  */  0.1132517E-01,
+   /*   146  */  0.1430050E-01,
+   /*   147  */  0.1780783E-01,
+   /*   148  */  0.2188450E-01,
+   /*   149  */  0.2658871E-01,
+   /*   150  */  0.3198998E-01,
+   /*   151  */  0.3815571E-01,
+   /*   152  */  0.4513576E-01,
+   /*   153  */  0.5298176E-01,
+   /*   154  */  0.6175103E-01,
+   /*   155  */  0.7152569E-01,
+   /*   156  */  0.8236921E-01,
+   /*   157  */  0.9432708E-01,
+   /*   158  */  0.1074572E+00,
+   /*   159  */  0.1218557E+00,
+   /*   160  */  0.1376028E+00,
+   /*   161  */  0.1547317E+00,
+   /*   162  */  0.1733313E+00,
+   /*   163  */  0.1934747E+00,
+   /*   164  */  0.2152692E+00,
+   /*   165  */  0.2387823E+00,
+   /*   166  */  0.2641039E+00,
+   /*   167  */  0.2913149E+00,
+   /*   168  */  0.3204254E+00,
+   /*   169  */  0.3516649E+00,
+   /*   170  */  0.3850510E+00,
+   /*   171  */  0.4207101E+00,
+   /*   172  */  0.4586671E+00,
+   /*   173  */  0.4990536E+00,
+   /*   174  */  0.5420371E+00,
+   /*   175  */  0.5876358E+00,
+   /*   176  */  0.6359682E+00,
+   /*   177  */  0.6837495E+00,
+   /*   178  */  0.7288000E+00,
+   /*   179  */  0.7716000E+00,
+   /*   180  */  0.8113000E+00,
+   /*   181  */  0.8474000E+00,
+   /*   182  */  0.8797000E+00,
+   /*   183  */  0.9079000E+00,
+   /*   184  */  0.9319000E+00,
+   /*   185  */  0.9518000E+00,
+   /*   186  */  0.9676000E+00,
+   /*   187  */  0.9797000E+00,
+   /*   188  */  0.9883000E+00,
+   /*   189  */  0.9940000E+00,
+   /*   190  */  0.9976000E+00,
+   /*   191  */  0.1000000E+01,
+};
diff --git a/src/vinterp.c b/src/vinterp.c
deleted file mode 100644
index ce3cbb3..0000000
--- a/src/vinterp.c
+++ /dev/null
@@ -1,427 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h> /* exit */
-#include <string.h>
-#include <math.h>
-
-#ifndef _VINTERP_H
-#  include "vinterp.h"
-#endif
-
-#define  SCALEHEIGHT     (-7000.)
-#define  SCALESLP        (101325.0)
-
-#define  C_EARTH_GRAV    (9.80665)
-#define  C_RKBOL         (1.380658e-23)     /* Boltzmann constant in J/K   */
-#define  C_RNAVO         (6.0221367e+23)    /* Avogadro constant in 1/mol  */
-#define  C_RMD           (28.9644)          /* molecular weight of dry air */
-#define  C_R             (C_RKBOL * C_RNAVO)
-#define  C_EARTH_RD      (1000. * C_R / C_RMD)
-
-double Grav          = C_EARTH_GRAV;
-double RD            = C_EARTH_RD;
-
-int Mars = 0;
-
-
-void h2p(double * restrict phlev, const double * restrict hlev, long nphlev)
-{
-  long k;
-  double exp_arg;
-  double height;
-
-  for ( k = 0; k < nphlev; k++ )
-    {
-      height  = hlev[k];
-      /*
-	unitsel == 1 : hlev[k] is given in meters
-	unitsel == 2 : hlev[k] is given in kilometers
-	h2p needs meters (MKSC-standard)
-      */
-
-      exp_arg = height / SCALEHEIGHT;
-
-      phlev[k] = SCALESLP * exp(exp_arg);
-    }
-
-}  /* h2p */
-
-
-void p2h(double * restrict hlev, const double * restrict plev, long nphlev)
-{
-  long  k;
-
-  for ( k = 0; k < nphlev; k++ )
-    {
-      hlev[k] = log(plev[k]/SCALESLP)*SCALEHEIGHT;
-    }
-
-}  /* p2h */
-
-
-void presh(double * restrict fullp, double * halfp, const double *restrict vct,
-	   const double *restrict ps, long nhlev, long ngp)
-{
-  long i, lh;
-  double zp, ze;
-  double *halfpres = halfp;
-
-  if ( ps == NULL )
-    {
-      fprintf(stderr, "ps undefined!\n");
-      exit(EXIT_FAILURE);
-    }
-
-  for ( lh = 0; lh < nhlev; lh++ )
-    {
-      zp = vct[lh];
-      ze = vct[lh+nhlev+1];
-
-      for ( i = 0; i < ngp; i++ ) halfpres[i] = zp + ze * ps[i];
-
-      halfpres += ngp;
-    }
-  memcpy(halfpres, ps, ngp*sizeof(double));
-
-  if ( fullp )
-    {
-      halfpres = halfp;
-      for ( i = 0; i < ngp*nhlev; i++ )
-	fullp[i] = 0.5 * (halfpres[i] + halfpres[i+ngp]);
-    }
-
-} /* presh */
-
-
-void genind(int *nx, const double * restrict plev, const double * restrict fullp, long ngp, long nplev, long nhlev)
-{
-  long  i, lp, lh;
-  int *nxl;
-  double pres;
-
-  memset(nx, 0, ngp*nplev*sizeof(int));
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(i, lh, pres, nxl)
-#endif
-  for ( lp = 0; lp < nplev; lp++ )
-    {
-      pres = plev[lp];
-      nxl  = nx + lp*ngp;
-      for ( lh = 0; lh < nhlev; lh++ )
-	for ( i = 0; i < ngp ; i++ )
-	   {
-	     if ( pres > fullp[lh*ngp+i] ) nxl[i] = lh;
-	   }
-    }
-
-}  /* genind */
-
-
-void genindmiss(int *nx, const double * restrict plev, int ngp, int nplev, const double * restrict ps_prog, int * restrict pnmiss)
-{
-  long i, lp;
-  int *nxl;
-  double pres;
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(i, pres, nxl)
-#endif
-  for ( lp = 0; lp < nplev; lp++ )
-    {
-      pnmiss[lp] = 0;
-      pres = plev[lp];
-      nxl  = nx + lp*ngp;
-      for ( i = 0; i < ngp; i++ )
-	{
-	  if ( pres > ps_prog[i] )
-	    {
-	      nxl[i] = -1;
-	      pnmiss[lp]++;
-	    }
-	}
-    }
-
-}  /* genindmiss */
-
-
-void extra_P(double * restrict slp, const double * restrict halfp, const double * restrict fullp,
-	     const double * restrict geop, const double * restrict temp, long ngp)
-{
-  double alpha, tstar, tmsl, zprt, zprtal;
-  double zrg;
-  double zlapse = 0.0065;
-  long j;
-
-  zrg = 1.0 / Grav;
-
-  for ( j = 0; j < ngp; ++j )
-    {
-      if ( geop[j] < 0.0001 && geop[j] > -0.0001 ) slp[j] = halfp[j];
-      else
-	{
-	  alpha = RD * zlapse * zrg;
-	  tstar = (1.0 + alpha * (halfp[j]/fullp[j] - 1.0)) * temp[j];
-
-	  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
-
-	  tmsl = tstar + zlapse * zrg * geop[j];
-	  if ( tmsl > 290.5 && tstar > 290.5 )
-	    {
-	      tstar = 0.5 * (290.5 + tstar);
-	      tmsl  = tstar;
-	    }
-
-	  if ( tmsl-tstar < 0.000001 && tstar-tmsl < 0.000001 )
-	    alpha = 0.0;
-	  else if ( geop[j] > 0.0001 || geop[j] < -0.0001 )
-	    alpha = RD * (tmsl-tstar) / geop[j];
-
-	  zprt   = geop[j] / (RD * tstar);
-	  zprtal = zprt * alpha;
-	  slp[j] = halfp[j] * exp(zprt*(1.0-zprtal*(0.5-zprtal/3.0)));
-	}
-    }
-
-}  /* extrap */
-
-
-static 
-double extra_T(double pres, double halfp, double fullp, double geop, double temp)
-{
-  double tstar, ztsz, z1, ztmsl, zalph, peval, zhts, zalp;
-  double zrg;
-  double zlapse = 0.0065;
-
-  zrg   = 1.0 / Grav;
-  tstar = (1.0 + zlapse * RD * zrg * (halfp/fullp - 1.0)) * temp;
-  ztsz  = tstar;
-  z1    = tstar + zlapse * zrg * geop;
-
-  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
-
-  ztmsl = tstar + zlapse * zrg * geop;
-
-  if ( ztmsl > 290.5 && tstar > 290.5 )
-    {
-      tstar = 0.5 * (290.5 + tstar);
-      ztmsl = tstar;
-    }
-
-  if ( ztmsl > 290.5 && tstar <= 290.5 ) ztmsl=290.5;
-
-  zalph = RD*zlapse*zrg;
-
-  if ( ztmsl-tstar < 0.000001 && tstar-ztmsl < 0.000001 ) zalph=0.0;
-
-  if ( (ztmsl-tstar > 0.000001 || tstar-ztmsl > 0.000001 ) &&
-       (geop > 0.0001 || geop < -0.0001) )
-    zalph = RD*(ztmsl-tstar)/geop;
-
-  if ( pres <= halfp )
-    peval = ((halfp-pres)*temp+ (pres-fullp)*tstar)/ (halfp-fullp);
-  else
-    {
-      ztmsl = z1;
-      tstar = ztsz;
-      zhts  = geop * zrg;
-
-      if ( zhts > 2000. && z1 > 298. )
-	{
-	  ztmsl = 298.;
-	  if ( zhts < 2500. ) ztmsl = 0.002*((2500.-zhts)*z1+(zhts-2000.)*ztmsl);
-	}
-
-      if ( (ztmsl-tstar) < 0.000001 )
-	zalph = 0.;
-      else if (geop > 0.0001 || geop < -0.0001)
-	zalph = RD*(ztmsl-tstar)/geop;
-      else
-	zalph = RD*zlapse*zrg;
-
-      zalp  = zalph*log(pres/halfp);
-      peval = tstar*(1.0+zalp*(1.0+zalp*(0.5+0.16666666667*zalp)));
-    }
-
-  return peval;
-
-}  /* extra_T */
-
-
-static 
-double extra_Z(double pres, double halfp, double fullp, double geop, double temp)
-{
-  double alpha, tstar, tmsl, zalp, zalpal;
-  double zrg;
-  double zlapse = 0.0065;
-  double ztlim = 290.5;
-
-  zrg   = 1.0 / Grav;
-  alpha = RD * zlapse * zrg;
-  tstar = (1.0 + alpha * (halfp/fullp - 1.0)) * temp;
-
-  if ( tstar < 255.0 ) tstar = 0.5 * (255.0 + tstar);
-
-  tmsl = tstar + zlapse * zrg * geop;
-
-  if ( tmsl > ztlim && tstar > ztlim )
-    {
-      tstar = 0.5 * (ztlim + tstar);
-      tmsl  = tstar;
-    }
-
-  if ( tmsl > ztlim && tstar <= ztlim ) tmsl = ztlim;
-
-  if ( tmsl-tstar < 0.000001 && tstar-tmsl < 0.000001 )
-    alpha = 0.0;
-  else if ( geop > 0.0001 || geop < -0.0001 )
-    alpha = RD * (tmsl-tstar) / geop;
-
-  zalp   = log(pres/halfp);
-  zalpal = zalp * alpha;
-
-  return ((geop - RD*tstar*zalp*(1.0 + zalpal*(0.5 + zalpal/6.0)))*zrg);
-}  /* extra_Z */
-
-
-void interp_X(const double * restrict gt, double *pt, const double * restrict hyb_press, const int *nx,
-	      const double * restrict plev, long nplev, long ngp, long nhlev, double missval)
-{
-  long lp, i;
-  long nl, nh;
-  const int *nxl;
-  double *ptl;
-  double pres;
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, ptl)
-#endif
-  for ( lp = 0; lp < nplev; lp++ )
-    {
-      pres = plev[lp];
-      nxl  = nx + lp*ngp;
-      ptl  = pt + lp*ngp;
-      for ( i = 0; i < ngp; i++ )
-	{
-	  if ( nxl[i] == -1 )
-	    ptl[i] = missval;
-	  else
-	    {
-	      nl = nxl[i] * ngp + i;
-	      nh = nl + ngp;
-	      if ( nh >= ngp*nhlev )
-		ptl[i] = gt[nl];
-	      else
-		ptl[i] =  gt[nl] + (pres-hyb_press[nl])
-		       * (gt[nh] - gt[nl]) / (hyb_press[nh] - hyb_press[nl]);
-	    }
-	}
-    }
-}  /* interp_X */
-
-
-void interp_T(const double * restrict geop, const double * restrict gt, double *pt, const double * restrict fullp,
-	      const double * restrict halfp, const int *nx, const double * restrict plev, long nplev, long ngp,
-	      long nhlev, double missval)
-{
-  long lp, i;
-  long nl, nh;
-  const int *nxl;
-  double *ptl;
-  double pres;
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, ptl)
-#endif
-  for ( lp = 0; lp < nplev; lp++ )
-    {
-      pres = plev[lp];
-      nxl  = nx + lp*ngp;
-      ptl  = pt + lp*ngp;
-#if defined(CRAY)
-#pragma _CRI inline extra_T
-#endif
-      for ( i = 0; i < ngp; i++ )
-	{
-	  nl = nxl[i];
-	  if ( nl < 0 )
-	    ptl[i] = missval;
-	  else
-	    {
-	      if ( nl > nhlev-2 )
-		{
-		  if ( Mars )
-		    ptl[i] = gt[(nhlev-1)*ngp+i];
-		  else
-#if defined(SX)
-#pragma cdir inline
-#endif
-		    ptl[i] = extra_T(pres, halfp[nhlev*ngp+i],
-				     fullp[(nhlev-1)*ngp+i], geop[i],
-				     gt[(nhlev-1)*ngp+i]);
-		}
-	      else
-		{
-		  nh = nl + 1;
-		  ptl[i] =  gt[nl*ngp+i] + (pres-fullp[nl*ngp+i])
-                         * (gt[nh*ngp+i] - gt[nl*ngp+i])
-                         / (fullp[nh*ngp+i] - fullp[nl*ngp+i]);
-		}
-	    }
-	}
-    }
-}  /* interp_T */
-
-
-void interp_Z(const double * restrict geop, const double * restrict gz, double *pz, const double * restrict fullp,
-	      const double * restrict halfp, const int *nx, const double * restrict gt, const double * restrict plev,
-	      long nplev, long ngp, long nhlev, double missval)
-{
-  long lp, i;
-  long nl, nh;
-  const int *nxl;
-  double *pzl;
-  double pres;
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(i, pres, nl, nh, nxl, pzl)
-#endif
-  for ( lp = 0; lp < nplev; lp++ )
-    {
-      pres = plev[lp];
-      nxl  = nx + lp*ngp;
-      pzl  = pz + lp*ngp;
-#if defined(CRAY)
-#pragma _CRI inline extra_Z
-#endif
-      for ( i = 0; i < ngp; i++ )
-	{
-	  nl = nxl[i];
-	  if ( nl < 0 )
-	    pzl[i] = missval;
-	  else
-	    {
-	      if ( pres > halfp[(nl+1)*ngp+i] ) nl++;
-
-	      if ( nl > nhlev-1 )
-		{
-		  if ( Mars )
-		    pzl[i] = gt[(nhlev-1)*ngp+i];
-		  else
-#if defined(SX)
-#pragma cdir inline
-#endif
-		    pzl[i] = extra_Z(pres, halfp[nhlev*ngp+i],
-				     fullp[(nhlev-1)*ngp+i], geop[i],
-				     gt[(nhlev-1)*ngp+i]);
-		}
-	      else
-		{
-		  nh = nl + 1;
-		  pzl[i] =  gz[nl*ngp+i] + (pres-halfp[nl*ngp+i])
-		         * (gz[nh*ngp+i] - gz[nl*ngp+i])
-                         / (halfp[nh*ngp+i] - halfp[nl*ngp+i]);
-		}
-	    }
-	}
-    }
-}  /* interp_Z */
diff --git a/src/zaxis.c b/src/zaxis.c
index 1658bc8..f9484a4 100644
--- a/src/zaxis.c
+++ b/src/zaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2014 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
+  Copyright (C) 2003-2015 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -177,65 +177,65 @@ int zaxisFromFile(FILE *gfp, const char *dname)
       pline = line;
       while ( isspace((int) *pline) ) pline++;
       if ( pline[0] == '\0' ) continue;
-      if ( memcmp(pline, "zaxistype", 9) == 0 || 
-	   memcmp(pline, "type", 4) == 0 )
+      if ( cmpstrlen(pline, "zaxistype", len) == 0 || 
+	   cmpstrlen(pline, "type", len) == 0 )
 	{
 	  if ( *pline == 'z' )
 	    pline = skipSeparator(pline + 9);
 	  else
 	    pline = skipSeparator(pline + 4);
 
-	  if ( memcmp(pline, "pressure", 6) == 0 )
+	  if ( cmpstrlen(pline, "pressure", len) == 0 )
 	    zaxis.type = ZAXIS_PRESSURE;
-	  else if ( memcmp(pline, "hybrid_half", 11)  == 0 )
+	  else if ( cmpstrlen(pline, "hybrid_half", len)  == 0 )
 	    zaxis.type = ZAXIS_HYBRID_HALF;
-	  else if ( memcmp(pline, "hybrid", 6)  == 0 )
+	  else if ( cmpstrlen(pline, "hybrid", len)  == 0 )
 	    zaxis.type = ZAXIS_HYBRID;
-	  else if ( memcmp(pline, "height", 6) == 0 )
+	  else if ( cmpstrlen(pline, "height", len) == 0 )
 	    zaxis.type = ZAXIS_HEIGHT;
-	  else if ( memcmp(pline, "depth below sea", 15) == 0 ||
-		    memcmp(pline, "depth_below_sea", 15) == 0 )
+	  else if ( cmpstrlen(pline, "depth below sea", len) == 0 ||
+		    cmpstrlen(pline, "depth_below_sea", len) == 0 )
 	    zaxis.type = ZAXIS_DEPTH_BELOW_SEA;
-	  else if ( memcmp(pline, "depth below land", 16) == 0 ||
-		    memcmp(pline, "depth_below_land", 16) == 0 )
+	  else if ( cmpstrlen(pline, "depth below land", len) == 0 ||
+		    cmpstrlen(pline, "depth_below_land", len) == 0 )
 	    zaxis.type = ZAXIS_DEPTH_BELOW_LAND;
-	  else if ( memcmp(pline, "isentropic", 10)  == 0 )
+	  else if ( cmpstrlen(pline, "isentropic", len)  == 0 )
 	    zaxis.type = ZAXIS_ISENTROPIC;
-	  else if ( memcmp(pline, "surface", 7)  == 0 )
+	  else if ( cmpstrlen(pline, "surface", len)  == 0 )
 	    zaxis.type = ZAXIS_SURFACE;
-	  else if ( memcmp(pline, "generic", 7)  == 0 )
+	  else if ( cmpstrlen(pline, "generic", len)  == 0 )
 	    zaxis.type = ZAXIS_GENERIC;
 	  else
 	    cdoAbort("Invalid zaxisname : %s (zaxis description file: %s)", pline, dname);
 	}
-      else if ( memcmp(pline, "size", 4)  == 0 )
+      else if ( cmpstrlen(pline, "size", len)  == 0 )
 	{
-	  zaxis.size = atol(skipSeparator(pline + 4));
+	  zaxis.size = atol(skipSeparator(pline + len));
 	}
-      else if ( memcmp(pline, "vctsize", 7)  == 0 )
+      else if ( cmpstrlen(pline, "vctsize", len)  == 0 )
 	{
-	  zaxis.vctsize = atol(skipSeparator(pline + 7));
+	  zaxis.vctsize = atol(skipSeparator(pline + len));
 	}
-      else if ( memcmp(pline, "name", 4)  == 0 )
+      else if ( cmpstrlen(pline, "name", len)  == 0 )
 	{
-	  strcpy(zaxis.name, skipSeparator(pline + 4));
+	  strcpy(zaxis.name, skipSeparator(pline + len));
 	}
-      else if ( memcmp(pline, "longname", 8)  == 0 )
+      else if ( cmpstrlen(pline, "longname", len)  == 0 )
 	{
-	  strcpy(zaxis.longname, skipSeparator(pline + 8));
+	  strcpy(zaxis.longname, skipSeparator(pline + len));
 	}
-      else if ( memcmp(pline, "units", 5)  == 0 )
+      else if ( cmpstrlen(pline, "units", len)  == 0 )
 	{
-	  strcpy(zaxis.units, skipSeparator(pline + 5));
+	  strcpy(zaxis.units, skipSeparator(pline + len));
 	}
-      else if ( memcmp(pline, "levels", 6)  == 0 )
+      else if ( cmpstrlen(pline, "levels", len)  == 0 )
 	{
 	  int i;
 	  double flev;
 
 	  if ( zaxis.size > 0 )
 	    {
-	      pline = skipSeparator(pline + 6);
+	      pline = skipSeparator(pline + len);
 	  
 	      zaxis.vals = (double*) malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
@@ -262,14 +262,14 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	      cdoAbort("size undefined (zaxis description file: %s)!", dname);
 	    }
 	}
-      else if ( memcmp(pline, "vct", 3)  == 0 )
+      else if ( cmpstrlen(pline, "vct", len)  == 0 )
 	{
 	  int i;
 	  double flev;
 
 	  if ( zaxis.vctsize > 0 )
 	    {
-	      pline = skipSeparator(pline + 3);
+	      pline = skipSeparator(pline + len);
 	  
 	      zaxis.vct = (double*) malloc(zaxis.vctsize*sizeof(double));
 	      for ( i = 0; i < zaxis.vctsize; i++ )
@@ -296,14 +296,14 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	      cdoAbort("vctsize undefined (zaxis description file: %s)!", dname);
 	    }
 	}
-      else if ( memcmp(pline, "lbounds", 7)  == 0 )
+      else if ( cmpstrlen(pline, "lbounds", len)  == 0 )
 	{
 	  int i;
 	  double flev;
 
 	  if ( zaxis.size > 0 )
 	    {
-	      pline = skipSeparator(pline + 7);
+	      pline = skipSeparator(pline + len);
 	  
 	      zaxis.lbounds = (double*) malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
@@ -330,14 +330,14 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	      cdoAbort("size undefined (zaxis description file: %s)!", dname);
 	    }
 	}
-      else if ( memcmp(pline, "ubounds", 7)  == 0 )
+      else if ( cmpstrlen(pline, "ubounds", len)  == 0 )
 	{
 	  int i;
 	  double flev;
 
 	  if ( zaxis.size > 0 )
 	    {
-	      pline = skipSeparator(pline + 7);
+	      pline = skipSeparator(pline + len);
 	  
 	      zaxis.ubounds = (double*) malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
@@ -383,7 +383,7 @@ int zaxisFromName(const char *zaxisname)
   zaxisInit(&zaxis);
 
   pline = zaxisname;
-  if ( memcmp(pline, "surface", 7) == 0 ) /* surface */
+  if ( cmpstr(pline, "surface") == 0 ) /* surface */
     {
       zaxis.type = ZAXIS_SURFACE;
       zaxis.size = 1;
diff --git a/test/Afterburner.test.in b/test/Afterburner.test.in
new file mode 100644
index 0000000..86b714e
--- /dev/null
+++ b/test/Afterburner.test.in
@@ -0,0 +1,142 @@
+#! @SHELL@
+#
+AFTERTESTFILE=ECHAM5_T42L19.grb
+if [ -f "$CDOTESTDATA/$AFTERTESTFILE" ]; then
+echo 1..4 # Number of tests to be executed.
+else
+echo 1..1 # Number of tests to be executed.
+fi
+#
+test -n "$CDO"      || CDO=cdo
+test -n "$DATAPATH" || DATAPATH=./data
+#
+CDOOUT=cout
+CDOERR=cerr
+FORMAT=""
+NTEST=1
+######################################################
+IFILE=$DATAPATH/gp2sp_ref
+RFILE=$DATAPATH/sp2gp_ref
+OFILE=sp2gp_res
+#
+RSTAT=0
+SELECT="TYPE=20 FORMAT=1"
+CDOTEST="$SELECT"
+CDOCOMMAND="$CDO $FORMAT after $IFILE $OFILE"
+echo "$CDOCOMMAND"
+echo $SELECT | $CDOCOMMAND
+test $? -eq 0 || let RSTAT+=1
+#
+$CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+test $? -eq 0 || let RSTAT+=1
+test -s $CDOOUT && let RSTAT+=1
+cat $CDOOUT $CDOERR
+#
+test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+#
+let NTEST+=1
+rm -f $OFILE
+rm -f $CDOOUT $CDOERR
+######################################################
+if [ -f "$CDOTESTDATA/$AFTERTESTFILE" ]; then
+######################################################
+SELECT=bot
+IFILE=$CDOTESTDATA/$AFTERTESTFILE
+RFILE=$CDOTESTDATA/after_${SELECT}_ref
+OFILE=after_${SELECT}_res
+#
+RSTAT=0
+CDOTEST="$SELECT"
+CDOCOMMAND="$CDO $FORMAT after $IFILE $OFILE"
+echo "$CDOCOMMAND"
+$CDOCOMMAND << EOR
+  CODE=91,92,93,94,95,96,97,102,103,104,105,106,107,108,109,110,111,112,113,
+       114,115,116,117,119,120,121,122,123,124,125,126,
+       129,134,139,140,141,142,143,144,145,146,147,150,151,160,161,164,165,166,
+       167,168,169,171,175,176,177,178,179,180,181,182,184,
+       185,186,187,188,193,197,203,204,205,206,207,208,209,
+       210,211,213,214,216,218,221,222,230,231,233,260
+  TYPE=20
+  FORMAT=1
+  MEAN=1
+EOR
+test $? -eq 0 || let RSTAT+=1
+#
+$CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+test $? -eq 0 || let RSTAT+=1
+test -s $CDOOUT && let RSTAT+=1
+cat $CDOOUT $CDOERR
+#
+test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+#
+let NTEST+=1
+rm -f $OFILE
+rm -f $CDOOUT $CDOERR
+######################################################
+SELECT=atm
+IFILE=$CDOTESTDATA/$AFTERTESTFILE
+RFILE=$CDOTESTDATA/after_${SELECT}_ref
+OFILE=after_${SELECT}_res
+#
+RSTAT=0
+CDOTEST="$SELECT"
+CDOCOMMAND="$CDO $FORMAT after $IFILE $OFILE"
+echo "$CDOCOMMAND"
+$CDOCOMMAND << EOR
+  CODE=130,131,132,133,135,153,154,156,157,223
+  LEVEL=100000,92500,85000,77500,70000,60000,50000,40000,30000,25000,
+         20000,15000,10000,7000,5000,3000,2000,1000,700,500,300,200,100,50,20,10
+  TYPE=30
+  FORMAT=1
+  MEAN=1
+EOR
+test $? -eq 0 || let RSTAT+=1
+#
+$CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+test $? -eq 0 || let RSTAT+=1
+test -s $CDOOUT && let RSTAT+=1
+cat $CDOOUT $CDOERR
+#
+test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+#
+let NTEST+=1
+rm -f $OFILE
+rm -f $CDOOUT $CDOERR
+######################################################
+SELECT=atm2
+IFILE=$CDOTESTDATA/$AFTERTESTFILE
+RFILE=$CDOTESTDATA/after_${SELECT}_ref
+OFILE=after_${SELECT}_res
+#
+RSTAT=0
+CDOTEST="$SELECT"
+CDOCOMMAND="$CDO $FORMAT after $IFILE $OFILE"
+echo "$CDOCOMMAND"
+$CDOCOMMAND << EOR
+  CODE=138,148,149,155
+  LEVEL=100000,92500,85000,77500,70000,60000,50000,40000,30000,25000,
+         20000,15000,10000,7000,5000,3000,2000,1000,700,500,300,200,100,50,20,10
+  TYPE=70
+  FORMAT=1
+  MEAN=1
+EOR
+test $? -eq 0 || let RSTAT+=1
+#
+$CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+test $? -eq 0 || let RSTAT+=1
+test -s $CDOOUT && let RSTAT+=1
+cat $CDOOUT $CDOERR
+#
+test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+#
+let NTEST+=1
+rm -f $OFILE
+rm -f $CDOOUT $CDOERR
+######################################################
+fi
+#
+exit 0
diff --git a/test/Arith.test.in b/test/Arith.test.in
index 674983a..d894f31 100644
--- a/test/Arith.test.in
+++ b/test/Arith.test.in
@@ -27,7 +27,7 @@ for STAT in $STATS; do
     CDOTEST="$STAT"
     CDOCOMMAND="$CDO $FORMAT ${STAT} $IFILE $CFILE $OFILE"
 
-    echo "Running test: $NTEST"
+    echo "Running test: $NTEST - $CDOTEST"
     echo "$CDOCOMMAND"
 
     $CDOCOMMAND
diff --git a/test/File.test.in b/test/File.test.in
index b7619b3..aa3af33 100644
--- a/test/File.test.in
+++ b/test/File.test.in
@@ -33,7 +33,7 @@ for OPERATOR in write read; do
     fi
     if [ "@ENABLE_GRIB@" = no -a "${FORMAT}" = grb ] ; then
       FILEFORMAT=GRIB
-      ENABLED_TEST=no;
+      ENABLED_TEST=no
     fi
     if [  "@ENABLE_GRIBAPI@" = no -a "${FORMAT}" = grb2 ] ; then
       FILEFORMAT=GRIB_API
diff --git a/test/Genweights.test.in b/test/Genweights.test.in
index b06ee00..a8bf4f6 100644
--- a/test/Genweights.test.in
+++ b/test/Genweights.test.in
@@ -1,10 +1,15 @@
 #! @SHELL@
-echo 1..26 # Number of tests to be executed.
+if [ "$USER" = "m214003" ]; then
+echo 1..32 # Number of tests to be executed.
+else
+echo 1..20 # Number of tests to be executed.
+fi
 #
 test -n "$CDO"      || CDO=cdo
 test -n "$DATAPATH" || DATAPATH=./data
 #
-ABSLIM=0.001
+ABSLIMMAX=0.001
+ABSLIMYCON=0.25
 CDOOUT=cout
 CDOERR=cerr
 FORMAT="-f srv -b 32"
@@ -18,9 +23,12 @@ for GRIDTYPE in "regular" "curvilinear" "unstructured"; do
   if [ "$GRIDTYPE" != "regular" ]; then SETGRID="-setgridtype,$GRIDTYPE"; fi
   for GRID in $GRIDS; do
 # remaplaf: sort could give different results"
-    RMODS="bil bic nn con ycon"
-    if [ "$GRIDTYPE" = "unstructured" ]; then RMODS="nn con ycon"; fi
+    RMODS="bil bic con ycon"
+    if [ "$GRIDTYPE" = "unstructured" ]; then RMODS="con ycon"; fi
+    if [ "$USER" = "m214003" ]; then RMODS="dis nn $RMODS"; fi
     for RMOD in $RMODS; do
+      ABSLIM=$ABSLIMMAX
+      if [ $RMOD = ycon ]; then ABSLIM=$ABSLIMYCON; fi
       RSTAT=0
       OFILE=${GRID}_${RMOD}
       RFILE=$DATAPATH/${OFILE}_ref
diff --git a/test/Gradsdes.test.in b/test/Gradsdes.test.in
new file mode 100644
index 0000000..0822cab
--- /dev/null
+++ b/test/Gradsdes.test.in
@@ -0,0 +1,52 @@
+#! @SHELL@
+echo 1..1 # Number of tests to be executed.
+#
+test -n "$CDO"      || CDO=cdo
+test -n "$DATAPATH" || DATAPATH=./data
+#
+CDOOUT=cout
+CDOERR=cerr
+#
+IFILE=$DATAPATH/pl_data.grb
+OFILE=pl_data.grb
+RFILE1=pl_data.ctl
+RFILE2=pl_data.gmp
+cp $IFILE $OFILE
+#
+NTEST=1
+#
+RSTAT=0
+#
+CDOTEST="gradsdes GRIB1"
+CDOCOMMAND="$CDO gradsdes $OFILE"
+
+echo "Running test: $NTEST - $CDOTEST"
+echo "$CDOCOMMAND"
+
+$CDOCOMMAND
+test $? -eq 0 || let RSTAT+=1
+#cp $DATAPATH/pl_data.ctl pl_data.ctl
+#cp $DATAPATH/pl_data.gmp pl_data.gmp
+
+head -12 $DATAPATH/$RFILE1 > h1
+head -12 $RFILE1 > h2
+#diff $DATAPATH/$RFILE1  $RFILE1 > $CDOOUT 2> $CDOERR
+diff h1  h2 > $CDOOUT 2> $CDOERR
+test $? -eq 0 || let RSTAT+=1
+rm -f h1 h2
+
+test -s $CDOOUT && let RSTAT+=1
+test -s $CDOERR && let RSTAT+=1
+cat $CDOOUT $CDOERR
+
+cmp -s $DATAPATH/$RFILE2  $RFILE2
+test $? -eq 0 || let RSTAT+=1
+
+rm -f $OFILE $RFILE1 $RFILE2
+
+test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+#
+rm -f $CDOOUT $CDOERR
+#
+exit 0
diff --git a/test/Makefile.am b/test/Makefile.am
index 6e2630f..0ea0e00 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -2,19 +2,29 @@ CLEANFILES =
 
 export
 
+# COLOR ALWAYS also if no color capable terminal detected
+#     this is needed i.e. to run the tests via a oneline ssh cmd:
+#     ssh host '... make check'
+AM_COLOR_TESTS=always
+
 TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
                   $(top_srcdir)/config/tap-driver.sh
 
+# tests which should pass
 TESTS = File.test Read_grib.test Read_netcdf.test Copy_netcdf.test Cat.test Gridarea.test Detrend.test \
-        Genweights.test Remap.test Select.test Spectral.test Timstat.test Vertint.test Arith.test
+        Genweights.test Remap.test Select.test Spectral.test Timstat.test Vertint.test Afterburner.test Arith.test \
+        Gradsdes.test wildcard.test
+
+# tests which should fail
+XFAIL_TESTS = 
 
 #        $(top_srcdir)/test/test_Remap.sh \
-#       $(top_srcdir)/test/test_info.py
-#	$(top_srcdir)/test/test_diff.py
-#	$(top_srcdir)/test/test_Arith.py
-#	$(top_srcdir)/test/test_Arithc.py
-#	$(top_srcdir)/test/test_Selvar.py
-#	$(top_srcdir)/test/test_intgridbil.py
+#        $(top_srcdir)/test/test_info.py
+#        $(top_srcdir)/test/test_diff.py
+#        $(top_srcdir)/test/test_Arith.py
+#        $(top_srcdir)/test/test_Arithc.py
+#        $(top_srcdir)/test/test_Selvar.py
+#        $(top_srcdir)/test/test_intgridbil.py
 
 #EXTRA_DIST = $(TESTS) $(top_srcdir)/test/testStreams.py
 
diff --git a/test/Makefile.in b/test/Makefile.in
index 2eefc54..298aef7 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -77,6 +77,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+XFAIL_TESTS =
 subdir = test
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/config/mkinstalldirs $(srcdir)/File.test.in \
@@ -85,8 +86,9 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(srcdir)/Gridarea.test.in $(srcdir)/Genweights.test.in \
 	$(srcdir)/Remap.test.in $(srcdir)/Select.test.in \
 	$(srcdir)/Spectral.test.in $(srcdir)/Timstat.test.in \
-	$(srcdir)/Vertint.test.in $(srcdir)/Detrend.test.in \
-	$(srcdir)/Arith.test.in README
+	$(srcdir)/Vertint.test.in $(srcdir)/Afterburner.test.in \
+	$(srcdir)/Detrend.test.in $(srcdir)/Arith.test.in \
+	$(srcdir)/Gradsdes.test.in $(srcdir)/wildcard.test.in README
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -100,7 +102,8 @@ CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES = File.test Read_grib.test Read_netcdf.test \
 	Copy_netcdf.test Cat.test Gridarea.test Genweights.test \
 	Remap.test Select.test Spectral.test Timstat.test Vertint.test \
-	Detrend.test Arith.test
+	Afterburner.test Detrend.test Arith.test Gradsdes.test \
+	wildcard.test
 CONFIG_CLEAN_VPATH_FILES =
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -366,6 +369,7 @@ ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
 ENABLE_IEG = @ENABLE_IEG@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
+ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
 ENABLE_NETCDF = @ENABLE_NETCDF@
 ENABLE_SERVICE = @ENABLE_SERVICE@
 EXEEXT = @EXEEXT@
@@ -498,20 +502,28 @@ top_srcdir = @top_srcdir@
 
 #.PHONY: $(TESTS)
 CLEANFILES = `ls *.pyc`
+
+# COLOR ALWAYS also if no color capable terminal detected
+#     this is needed i.e. to run the tests via a oneline ssh cmd:
+#     ssh host '... make check'
+AM_COLOR_TESTS = always
 TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
                   $(top_srcdir)/config/tap-driver.sh
 
+
+# tests which should pass
 TESTS = File.test Read_grib.test Read_netcdf.test Copy_netcdf.test Cat.test Gridarea.test Detrend.test \
-        Genweights.test Remap.test Select.test Spectral.test Timstat.test Vertint.test Arith.test
+        Genweights.test Remap.test Select.test Spectral.test Timstat.test Vertint.test Afterburner.test Arith.test \
+        Gradsdes.test wildcard.test
 
 
 #        $(top_srcdir)/test/test_Remap.sh \
-#       $(top_srcdir)/test/test_info.py
-#	$(top_srcdir)/test/test_diff.py
-#	$(top_srcdir)/test/test_Arith.py
-#	$(top_srcdir)/test/test_Arithc.py
-#	$(top_srcdir)/test/test_Selvar.py
-#	$(top_srcdir)/test/test_intgridbil.py
+#        $(top_srcdir)/test/test_info.py
+#        $(top_srcdir)/test/test_diff.py
+#        $(top_srcdir)/test/test_Arith.py
+#        $(top_srcdir)/test/test_Arithc.py
+#        $(top_srcdir)/test/test_Selvar.py
+#        $(top_srcdir)/test/test_intgridbil.py
 
 #EXTRA_DIST = $(TESTS) $(top_srcdir)/test/testStreams.py
 CDO = $(top_builddir)/src/cdo
@@ -575,10 +587,16 @@ Timstat.test: $(top_builddir)/config.status $(srcdir)/Timstat.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 Vertint.test: $(top_builddir)/config.status $(srcdir)/Vertint.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+Afterburner.test: $(top_builddir)/config.status $(srcdir)/Afterburner.test.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 Detrend.test: $(top_builddir)/config.status $(srcdir)/Detrend.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 Arith.test: $(top_builddir)/config.status $(srcdir)/Arith.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+Gradsdes.test: $(top_builddir)/config.status $(srcdir)/Gradsdes.test.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+wildcard.test: $(top_builddir)/config.status $(srcdir)/wildcard.test.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
 mostlyclean-libtool:
 	-rm -f *.lo
diff --git a/test/Remap.test.in b/test/Remap.test.in
index 7293adb..85fdff2 100644
--- a/test/Remap.test.in
+++ b/test/Remap.test.in
@@ -1,10 +1,15 @@
 #! @SHELL@
-echo 1..26 # Number of tests to be executed.
+if [ "$USER" = "m214003" ]; then
+echo 1..32 # Number of tests to be executed.
+else
+echo 1..20 # Number of tests to be executed.
+fi
 #
 test -n "$CDO"      || CDO=cdo
 test -n "$DATAPATH" || DATAPATH=./data
 #
-ABSLIM=0.001
+ABSLIMMAX=0.001
+ABSLIMYCON=0.25
 CDOOUT=cout
 CDOERR=cerr
 FORMAT="-f srv -b 32"
@@ -18,9 +23,12 @@ for GRIDTYPE in "regular" "curvilinear" "unstructured"; do
   if [ "$GRIDTYPE" != "regular" ]; then SETGRID="-setgridtype,$GRIDTYPE"; fi
   for GRID in $GRIDS; do
 # remaplaf: sort could give different results"
-    RMODS="bil bic nn con ycon"
-    if [ "$GRIDTYPE" = "unstructured" ]; then RMODS="nn con ycon"; fi
+    RMODS="bil bic con ycon"
+    if [ "$GRIDTYPE" = "unstructured" ]; then RMODS="con ycon"; fi
+    if [ "$USER" = "m214003" ]; then RMODS="dis nn $RMODS"; fi
     for RMOD in $RMODS; do
+      ABSLIM=$ABSLIMMAX
+      if [ $RMOD = ycon ]; then ABSLIM=$ABSLIMYCON; fi
       RSTAT=0
       OFILE=${GRID}_${RMOD}
       RFILE=$DATAPATH/${OFILE}_ref
diff --git a/test/Select.test.in b/test/Select.test.in
index 1adce78..c21abbf 100644
--- a/test/Select.test.in
+++ b/test/Select.test.in
@@ -30,7 +30,7 @@ for SELECT in $SELARGS; do
   CDOCOMMAND="$CDO ${OPERATOR},${SELECT} $IFILE $OFILE"
 
   echo "Running test: $NTEST"
-  #echo "$CDOCOMMAND"
+  echo "$CDOCOMMAND"
 
   $CDOCOMMAND
   test $? -eq 0 || let RSTAT+=1
diff --git a/test/Spectral.test.in b/test/Spectral.test.in
index 9220e7e..c7aaea0 100644
--- a/test/Spectral.test.in
+++ b/test/Spectral.test.in
@@ -31,6 +31,7 @@ test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
 #
 let NTEST+=1
 rm -f $OFILE
+rm -f $CDOOUT $CDOERR
 ######################################################
 IFILE=$DATAPATH/gp2sp_ref
 RFILE=$DATAPATH/sp2gp_ref
@@ -53,6 +54,7 @@ test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
 #
 let NTEST+=1
 rm -f $OFILE
+rm -f $CDOOUT $CDOERR
 ######################################################
 IFILE=$DATAPATH/t21_geosp_tsurf.grb
 RFILE=$DATAPATH/gp2spl_ref
@@ -74,6 +76,7 @@ test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
 #
 let NTEST+=1
 rm -f $OFILE
+rm -f $CDOOUT $CDOERR
 ######################################################
 IFILE=$DATAPATH/gp2spl_ref
 RFILE=$DATAPATH/sp2gpl_ref
@@ -95,5 +98,6 @@ test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
 #
 let NTEST+=1
 rm -f $OFILE
+rm -f $CDOOUT $CDOERR
 #
 exit 0
diff --git a/test/data/._netcdf_testfile01.nc b/test/data/._netcdf_testfile01.nc
new file mode 100644
index 0000000..308c64b
Binary files /dev/null and b/test/data/._netcdf_testfile01.nc differ
diff --git a/test/data/Makefile.am b/test/data/Makefile.am
index 81224a8..6ba987b 100644
--- a/test/data/Makefile.am
+++ b/test/data/Makefile.am
@@ -7,9 +7,10 @@ NETCDF_REF   = netcdf_testfile01_sinfon_ref netcdf_testfile01_infon_ref netcdf_t
 TIMSTAT_REF  = timmin_ref timmax_ref timsum_ref timavg_ref timmean_ref timstd_ref timstd1_ref timvar_ref timvar1_ref
 SPECTRAL_REF = sp2gp_ref sp2gpl_ref gp2sp_ref gp2spl_ref
 VERTINT_REF  = ml2pl_ref
-REMAP_REF    = n16_bic_ref n16_bil_ref n16_con_ref n16_ycon_ref n16_laf_ref n16_nn_ref \
-               n32_bic_ref n32_bil_ref n32_con_ref n32_ycon_ref n32_laf_ref n32_nn_ref
+REMAP_REF    = n16_bic_ref n16_bil_ref n16_con_ref n16_ycon_ref n16_laf_ref n16_nn_ref n16_dis_ref \
+               n32_bic_ref n32_bil_ref n32_con_ref n32_ycon_ref n32_laf_ref n32_nn_ref n32_dis_ref
 SELECT_REF   = select1_ref select2_ref select3_ref select4_ref select5_ref
 DETREND_REF  = detrend_ref
+GRADSDES_REF = pl_data.ctl pl_data.gmp
 
-EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF) $(DETREND_REF)
+EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF) $(DETREND_REF) $(GRADSDES_REF)
diff --git a/test/data/Makefile.in b/test/data/Makefile.in
index 08a6c67..b2f54cd 100644
--- a/test/data/Makefile.in
+++ b/test/data/Makefile.in
@@ -155,6 +155,7 @@ ENABLE_GRIBAPI = @ENABLE_GRIBAPI@
 ENABLE_IEG = @ENABLE_IEG@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
+ENABLE_NC4HDF5 = @ENABLE_NC4HDF5@
 ENABLE_NETCDF = @ENABLE_NETCDF@
 ENABLE_SERVICE = @ENABLE_SERVICE@
 EXEEXT = @EXEEXT@
@@ -293,12 +294,13 @@ NETCDF_REF = netcdf_testfile01_sinfon_ref netcdf_testfile01_infon_ref netcdf_tes
 TIMSTAT_REF = timmin_ref timmax_ref timsum_ref timavg_ref timmean_ref timstd_ref timstd1_ref timvar_ref timvar1_ref
 SPECTRAL_REF = sp2gp_ref sp2gpl_ref gp2sp_ref gp2spl_ref
 VERTINT_REF = ml2pl_ref
-REMAP_REF = n16_bic_ref n16_bil_ref n16_con_ref n16_ycon_ref n16_laf_ref n16_nn_ref \
-               n32_bic_ref n32_bil_ref n32_con_ref n32_ycon_ref n32_laf_ref n32_nn_ref
+REMAP_REF = n16_bic_ref n16_bil_ref n16_con_ref n16_ycon_ref n16_laf_ref n16_nn_ref n16_dis_ref \
+               n32_bic_ref n32_bil_ref n32_con_ref n32_ycon_ref n32_laf_ref n32_nn_ref n32_dis_ref
 
 SELECT_REF = select1_ref select2_ref select3_ref select4_ref select5_ref
 DETREND_REF = detrend_ref
-EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF) $(DETREND_REF)
+GRADSDES_REF = pl_data.ctl pl_data.gmp
+EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF) $(DETREND_REF) $(GRADSDES_REF)
 all: all-am
 
 .SUFFIXES:
diff --git a/test/data/grib_testfile01.grb b/test/data/grib_testfile01.grb
index 49f1b12..852795d 100644
Binary files a/test/data/grib_testfile01.grb and b/test/data/grib_testfile01.grb differ
diff --git a/test/data/grib_testfile01_info_ref b/test/data/grib_testfile01_info_ref
index 87e5eaa..09fb857 100644
--- a/test/data/grib_testfile01_info_ref
+++ b/test/data/grib_testfile01_info_ref
@@ -1,13 +1,13 @@
     -1 :       Date     Time   Level Gridsize    Miss :     Minimum        Mean     Maximum : Parameter ID
-     1 : 0000-01-00 00:00:00       0     2592       0 :     -48.800      3.1647      32.001 : 1             
-     2 : 0000-02-00 00:00:00       0     2592       0 :     -48.700      2.4530      30.800 : 1             
-     3 : 0000-03-00 00:00:00       0     2592       0 :     -62.300      2.2681      30.899 : 1             
-     4 : 0000-04-00 00:00:00       0     2592       0 :     -68.500      3.5152      32.699 : 1             
-     5 : 0000-05-00 00:00:00       0     2592       0 :     -69.200      5.4965      34.101 : 1             
-     6 : 0000-06-00 00:00:00       0     2592       0 :     -69.000      6.9265      35.199 : 1             
-     7 : 0000-07-00 00:00:00       0     2592       0 :     -70.300      7.2876      35.700 : 1             
-     8 : 0000-08-00 00:00:00       0     2592       0 :     -70.200      6.9544      34.999 : 1             
-     9 : 0000-09-00 00:00:00       0     2592       0 :     -68.900      5.8636      32.901 : 1             
-    10 : 0000-10-00 00:00:00       0     2592       0 :     -60.800      4.6208      30.700 : 1             
-    11 : 0000-11-00 00:00:00       0     2592       0 :     -47.000      3.8041      31.000 : 1             
-    12 : 0000-12-00 00:00:00       0     2592       0 :     -46.300      3.5452      31.800 : 1             
+     1 : 0000-01-01 00:00:00       0     2592       0 :     -48.800      3.1647      32.001 : 1             
+     2 : 0000-02-01 00:00:00       0     2592       0 :     -48.700      2.4530      30.800 : 1             
+     3 : 0000-03-01 00:00:00       0     2592       0 :     -62.300      2.2681      30.899 : 1             
+     4 : 0000-04-01 00:00:00       0     2592       0 :     -68.500      3.5152      32.699 : 1             
+     5 : 0000-05-01 00:00:00       0     2592       0 :     -69.200      5.4965      34.101 : 1             
+     6 : 0000-06-01 00:00:00       0     2592       0 :     -69.000      6.9265      35.199 : 1             
+     7 : 0000-07-01 00:00:00       0     2592       0 :     -70.300      7.2876      35.700 : 1             
+     8 : 0000-08-01 00:00:00       0     2592       0 :     -70.200      6.9544      34.999 : 1             
+     9 : 0000-09-01 00:00:00       0     2592       0 :     -68.900      5.8636      32.901 : 1             
+    10 : 0000-10-01 00:00:00       0     2592       0 :     -60.800      4.6208      30.700 : 1             
+    11 : 0000-11-01 00:00:00       0     2592       0 :     -47.000      3.8041      31.000 : 1             
+    12 : 0000-12-01 00:00:00       0     2592       0 :     -46.300      3.5452      31.800 : 1             
diff --git a/test/data/grib_testfile01_sinfo_ref b/test/data/grib_testfile01_sinfo_ref
index 47b7be9..fe92662 100644
--- a/test/data/grib_testfile01_sinfo_ref
+++ b/test/data/grib_testfile01_sinfo_ref
@@ -8,7 +8,8 @@
    Vertical coordinates :
      1 : surface                  : levels=1
    Time coordinate :  unlimited steps
+     RefTime =  0000-01-01 00:00:00  Units = hours  Calendar = proleptic_gregorian
   YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss  YYYY-MM-DD hh:mm:ss
-  0000-01-00 00:00:00  0000-02-00 00:00:00  0000-03-00 00:00:00  0000-04-00 00:00:00
-  0000-05-00 00:00:00  0000-06-00 00:00:00  0000-07-00 00:00:00  0000-08-00 00:00:00
-  0000-09-00 00:00:00  0000-10-00 00:00:00  0000-11-00 00:00:00  0000-12-00 00:00:00
+  0000-01-01 00:00:00  0000-02-01 00:00:00  0000-03-01 00:00:00  0000-04-01 00:00:00
+  0000-05-01 00:00:00  0000-06-01 00:00:00  0000-07-01 00:00:00  0000-08-01 00:00:00
+  0000-09-01 00:00:00  0000-10-01 00:00:00  0000-11-01 00:00:00  0000-12-01 00:00:00
diff --git a/test/data/n16_dis_ref b/test/data/n16_dis_ref
new file mode 100644
index 0000000..a2d46b5
Binary files /dev/null and b/test/data/n16_dis_ref differ
diff --git a/test/data/n32_dis_ref b/test/data/n32_dis_ref
new file mode 100644
index 0000000..6a24115
Binary files /dev/null and b/test/data/n32_dis_ref differ
diff --git a/test/data/pl_data.ctl b/test/data/pl_data.ctl
new file mode 100644
index 0000000..0efaf6d
--- /dev/null
+++ b/test/data/pl_data.ctl
@@ -0,0 +1,16 @@
+* Generated by CDO operator gradsdes
+*
+DSET  ^pl_data.grb
+DTYPE  GRIB
+INDEX  ^pl_data.gmp
+XDEF 12 LINEAR -165.000000 30.000000
+YDEF 6 LINEAR -75.000000 30.000000
+ZDEF 4 LEVELS 900 90 9 0.9 
+TDEF 5 LINEAR 12:00Z02jan1978 1dy
+TITLE  pl_data.grb  12x6 grid
+UNDEF  -9e+33
+VARS  3
+t                  4  130,100  temperature  [K]
+lsp                0  152,1  log surface pressure
+geosp              0  129,1  surface geopotential (orography)  [m^2/s^2]
+ENDVARS
diff --git a/test/data/pl_data.gmp b/test/data/pl_data.gmp
new file mode 100644
index 0000000..7106fb4
Binary files /dev/null and b/test/data/pl_data.gmp differ
diff --git a/test/wildcard.test.in b/test/wildcard.test.in
new file mode 100644
index 0000000..67e1248
--- /dev/null
+++ b/test/wildcard.test.in
@@ -0,0 +1,69 @@
+#! @SHELL@
+
+# Checks whether cdo handles the inputargument right,
+# most of the operators accept only one input argument.
+# If you want to feed several inputfiles you can escape the files
+# to make them one argument.
+
+if [ "$USER" = "m214003" ]; then
+echo 1..3 # Number of tests to be executed.
+else
+echo 1..1 # Number of tests to be executed.
+fi
+#
+test -n "$CDO"      || CDO='cdo'
+test -n "$DATAPATH" || DATAPATH=./data
+#
+IFILE1="testfile01"
+IFILE2="testfile0?"
+IFILE3="test*0?"
+if [ "$USER" = "m214003" ]; then
+  IFILES="$IFILE1 $IFILE2 $IFILE3"
+else
+  IFILES="$IFILE1"
+fi
+#
+CDOOUT=cout
+CDOERR=cerr
+#
+NTEST=1
+#
+for IFILE in $IFILES; do
+  RSTAT=0
+  CDOTEST="'$IFILE'"
+  echo "Running test: $NTEST"
+  INFILE=`ls $DATAPATH/grib_${IFILE}.grb`
+  echo $INFILE
+
+  for OPERATOR in info sinfo; do
+    CDOCOMMAND="$CDO ${OPERATOR} $INFILE"
+    echo "$CDOCOMMAND"
+
+    $CDOCOMMAND  > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+    cat $CDOOUT $CDOERR
+    mv $CDOOUT ref1
+
+    CDOCOMMAND="$CDO ${OPERATOR} $DATAPATH/grib_${IFILE}.grb"
+    echo "$CDOCOMMAND"
+
+    $CDOCOMMAND  > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+    cat $CDOOUT $CDOERR
+    mv $CDOOUT ref2
+
+    diff ref1 ref2 > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+
+    rm -f ref1 ref2
+  done
+ 
+  test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
+  test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
+ 
+  let NTEST+=1
+done
+#
+rm -f $CDOOUT $CDOERR
+#
+exit 0

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



More information about the debian-science-commits mailing list